您好,欢迎访问三七文档
第6章嵌入式Linux驱动程序开发ARM的定时器和PWM2位号位名位值:0001101121,20GPB10输入输出nXDREQ0Reserved19,18GPB9输入输出nXDACK0Reserved17,16GPB8输入输出nXDREQ1Reserved15,14GPB7输入输出nXDACK1Reserved13,12GPB6输入输出nXBACKReserved11,10GPB5输入输出nXBREQReserved9,8GPB4输入输出TCLK0Reserved7,6GPB3输入输出TOUT3Reserved5,4GPB2输入输出TOUT2Reserved3,2GPB1输入输出TOUT1Reserved1,0GPB0输入输出TOUT0Reserved端口B引脚配置寄存器35个16位定时器:定时器0-3具有PWM(脉宽调制)功能,占空比可编程;初值自动重装,输出模式有连续和单脉冲两种;定时器0,1有死区产生器,通常用于大电流设备控制;定时器4是一个内部定时器,没有输出引脚,供内部使用。2个8位预分频器和2个4位分频器:定时器0、1分享同一个8位的预分频器和分频器定时器2、3、4分享另一个预分频器和分频器分频器有1/2、1/4、1/8、1/16共4种分频值。S3C2410X定时器的主要特性4PWM(脉宽调制):只对一个方波序列信号的占空比按要求进行调制,而不改变信号的幅度和周期,因此PWM信号的产生和传输都是数字式的。用PWM技术实现模拟信号:若调制信号的频率远远大于信号接受者的分辨率,则接收者并不能感知数字信号的0和1,它获得的是信号的平均效果,平均值与占空比成有关(正比关系)。PWM技术的应用:借助微处理器,使用PWM实现模拟信号,广泛应用在测量、通信、功率控制与变换等领域中。PWM(脉宽调制)概念5定时器结构预分频器8位分频器1/21/41/81/16TCLK0/1计数器观察寄存器比较寄存器PCLK五选一开关初值寄存器控制逻辑TOUT中断6装入初值启动计数计数结束产生中断请求,并且可以重装初值连续计数。(1)定时器工作过程7当计数寄存器TCNT中的值减到与比较寄存器TCMPB的值相同时,TOUT的输出取反。改变TCMPB便改变占空比。正相输出反相输出(2)PWM输出周期开始ToutTOUT的输出也可设置为反相输出。8死区发生器开启前后输出波形对比死区:是一小段时间间隔,在这个时间间隔内,禁止两个开关同时处于开启状态。死区是在功率设备控制中常采用的一种技术,防止两个开关同时打开起反作用。S3C2410的timer0具有死区发生器,可用于控制大功率设备。(3)死区产生器9定时器的DMA功能:5个定时器都有DMA请求功能,但是在同一时刻只能设置一个使用DMA功能。DMA请求过程:定时器可在任意时间产生DMA请求,并且保持DMA请求信号(nDMA_REQ)为低直到收到ACK信号。当定时器收到ACK信号时,它使请求信号变得无效。DMA请求与中断的关系:如果某个定时器被配置为DMA模式,该定时器不会产生中断请求。其他定时器正常产生中断。(4)DMA请求模式101)定时器输入时钟频率ftclk(即计数时钟频率):ftclk=[fpclk∕(Prescaler+1)]×分频值式中:Prescaler为预分频值,0---255;分频值为1/2、1/4、1/8、1/16。(实验板上fpclk=50.7MHz)2)PWM输出时钟频率:PWM输出时钟频率=ftclk∕TCNTBn3)PWM输出信号占空比(即高电平持续时间所占信号周期的比例):PWM输出信号占空比=TCMPBn∕TCNTBn计数时钟和输出计算11共有6种、17个寄存器TCNTBn---Timern计数初值(缓冲)寄存器,16位TCMPBn---Timern比较(缓冲)寄存器,16位TCNTOn---Timern计数读出寄存器,16位RegisterAddressR/WDescriptionResetValueTCFG00x51000000R/W配置寄存器00x00000000TCFG10x51000004R/W配置寄存器10x00000000TCON0x51000008R/W控制寄存器0x00000000TCNTBn0x510000xxR/W计数初值寄存器(5个)0x0000TCMPBn0x510000xxR/W比较寄存器(4个)0x0000TCNTOn0x510000xxR观察寄存器(5个)0x0000定时器专用寄存器12Deadzonelength---死区宽度设置位其值N为:0~255,以timer0的定时时间为单位死区宽度为:(N+1)×timer0的定时时间Prescaler1---timer2、3、4的预分频值Prescaler0---timer0、1的预分频值范围:0~255输出频率为:PCLK÷(N+1)31……2423……1615……87……0保留(为0)DeadzonelengthPrescaler1Prescaler0TCFG0---预分频器配置寄存器13DMAmode---DMA通道选择设置位0000:不使用DMA方式,所有通道都用中断方式0001:选择timer00010:选择timer10011:选择timer20100:选择timer30101:选择timer4011X:保留MUX4~MUX0---timer4~timer0分频值选择0000:1/20001:1/40010:1/80011:1/1601XX:选择外部TCLK0、1(timer0、1选TCLK0,timer4、3、2选TCLK1)31…2423…2019…1615…1211…87…43…0保留(为0)DMAmodeMUX4MUX3MUX2MUX1MUX0TCFG1---DMA模式与分频选择寄存器14TL4~TL0---计数初值自动重装控制位0:单次计数1:计数器减到0时,自动重装初值连续计数TUP4~TUP0---计数初值手动装载控制位0:不操作1:立即更新TCNTBn和TCMPBnTR4~TR0---运行控制位0:停止1:启动对应的TIMERTO3~TO0---输出控制位0:正相输出1:反相输出DZE---TIMER0死区操作控制位0:禁止死区操作1:使能死区操作121110987…543210TR2TL1TO1TUP1TR1保留DZETL0TO0TUP0TR031…2322212019181716151413保留TL4TUP4TR4TL3TO3TUP3TR3TL2TO2TUP2TCON---定时器控制寄存器151、定时器初始化(1)写TCFG0,设置计数时钟预分频值和Timer0死区宽度;(2)写TCFG1,选择定时器分频值和DMA、中断服务;(3)对TCNTBn和TCMPBn分别写入计数初值和比较初值;(4)写TCON,设置手动装载初值;(5)再写TCON,清除手动装载初值位、设置计数初值自动重装、设置正相输出、启动计数。2、定时器停止运行方法写TCON,禁止计数初值自动重装。(一般不使用运行控制位停止运行)定时器的使用16直流电机驱动示例17直流电机驱动控制方法当TOUT0/TOUT1输出0时,VDD50送往DC-MOTOR的1/2号脚,当TOUT0/TOUT1输出1时,GND送往1/2号脚。当VDD50(TOUT0输出0)送往1号脚、GND(TOUT1输出1)送往2号脚时,电机朝某一方向转动。可以通过调整VDD50持续时间长短即TOUT0的输出占空比来调整电机速度。当GND(TOUT0输出1)送往1号脚、VDD50(TOUT1输出0)送往2号脚时,电机朝反方向转动。可以通过调整VDD50持续时间长短即TOUT1的输出占空比来调整电机速度。如果TOUT0和TOUT1均交替输出0/1,则电机转动方向取决于哪个脚输出的0更多。18直流电机驱动控制要求要求1:电机正向,先加速再减速,如此循环;控制方法:让TOUT1输出1即GND接到2号脚,而TOUT0输出PWM波,占空比先减再增。要求2:电机反向,先加速再减速,如此循环;控制方法:让TOUT0输出1即GND接到1号脚,而TOUT1输出PWM波,占空比先减再增。要求3:电机正向,先加速再减速,反向,加速再减速,如此循环。控制方法1:要求1和要求2轮流调用。控制方法2:利用TIMER0的死区功能,此时TOUT1是TOUT0的反向输出,则:当TOUT0和TOUT1的占空比是50%时,电机停止;当TOUT0占空比50%且不断增加时,反转加速;当TOUT0占空比50%且不断减小时,正转加速。19dc-motor.c驱动代码分析-1//文件名dc-motor.c#includelinux/config.h#includelinux/module.h#includelinux/kernel.h#includelinux/init.h#includeasm/hardware.h#includeasm/uaccess.h#defineDEVICE_NAMEs3c2410-dc-motor#defineDCMRAW_MINOR1#defineDCM_IOCTRL_STARTPWM(0x10)#defineDCM_IOCTRL_SETPWM(0x20)#defineDCM_IOCTRL_STOPPWM(0x30)#defineDCM_TCNTB(16384)#defineDCM_TCFG0(2)staticintdcm_status=0;staticintdcm_major=0;20dc-motor.c驱动代码分析-2#undefDEBUG//#defineDEBUG#ifdefDEBUG#defineDPRINTK(x...){printk(__FUNCTION__(%d):,__LINE__);printk(##x);}#else#defineDPRINTK(x...)(void)(0)#endif#definetout01_enable()\({GPBCON&=~0xf;\GPBCON|=0xa;})#definetout01_disable()\({GPBCON&=~0xf;\GPBCON|=0x5;\GPBUP&=~0x3;})21dc-motor.c驱动代码分析-3#definedcm_stop_timer01()\({TCON&=~0x919;})/*停止timer0和timer1*/staticintdcm_start_timer01(void)/*单向转初始化*/{TCFG0&=~(0x00ff0000);TCFG0|=(DCM_TCFG0);TCFG1&=~(0xff);/*timer0/1分频均取1/2*/TCNTB0=DCM_TCNTB;TCMPB0=DCM_TCNTB-1;/*timer0/1初值*/TCNTB1=DCM_TCNTB;TCMPB1=DCM_TCNTB-1;TCON&=~(0xf0f);TCON|=(0x202);TCON&=~(0x202);TCON|=(0x909);return0;}22dc-motor.c驱动代码分析-4staticintdcm_start_timer0(void)/*正反转初始化*/{TCFG0&=~(0x00ff0000);TCFG0|=(DCM_TCFG0);TCFG1&=~(0xf);TCNTB0=DCM_TCNTB;TCMPB0=DCM_TCNTB/2;TCON&=~(0x1f);TCON|=(0x2);TCON&=~(0x2);TCON|=(0x19);/*启用死区功能*/return0;}23dc-motor.c驱动代码分析-5staticints3c2410_dcm_open(structinode*inode,structfile*filp){MOD_INC_USE_COUNT;DPRINTK(S3c2410DCMotordeviceopen!\n);tout01_e
本文标题:定时器和PWM
链接地址:https://www.777doc.com/doc-4476274 .html