买了本《嵌入式系统——使用HCS12微控制器的设计与应用》这本书,看了觉得帮助不大。
因为里面有些东西讲得不够详细,并且这本书不是针对XS128来写的。
网上也有一些网友写的资料,那都只是针对某一方面的。
我觉得最好的资料还是英文版的说明文档,里面好多东西都讲得很详细,虽然看起来有点费劲,但那里值得的。
接下来就自己的学习经历。
TIM中的功能比较多,有输入捕捉、输出比较,还有脉冲累加器。
这里主要记一下输入捕捉和输出比较。
输入捕捉这个功能很有用,他不仅可以捕捉外界事件的发生(这个功能和51中的外部中断差不多),还可以捕捉外界事件发生的时间。
捕捉外界时间这个功能可以运用到驱动超声波测距中去。
IOC0~IOC7是输入捕捉\输出比较的外部针脚。
当IOSx=0时(IOSx=1时为输出比较),则将相应的通道配置为输入捕捉了。
当输入捕捉检测到有上升沿或下降沿时,就会把那时寄存器的值锁存到TCx中,这样就可以通过查询TCx来确定事件发生的时间了。
如果输入捕捉控制寄存器TIE(CxI=1)中允许输入捕捉中断,则捕捉到事件时,系统会产生一次中断。
接下来依次说明一下相关的寄存器设置:TSCR1:TEN是定时器允许位。
TEN=1时,允许定时器工作,TEN=0时,禁止定时器工作。
其余不常用,设为0即可。
TSCR2:TOI是定时器溢出中断允许位。
这个在输入捕捉中没用到,设为0即可。
TCRE是定时器计数寄存器复位允许位。
用在输出比较中,允许输出比较寄存器7的事件来复位定时器计数寄存器。
这里设为0即可。
PR2~PR0是定时器分频因子选择位。
不同的组合可以设定不同的定时器时钟:TIOS是输入捕捉和输出比较选择寄存器,在这里设定IOC0~IOC7是用于输入捕捉还是用于输出比较。
里面的8位对应着IOC0~IOC7八个通道,相应位位1,则设为输出比较。
相应位设为0,则为输入捕捉。
TCTL3和TCTL4是用来设定输入捕捉极性的寄存器,在这里可以设为上升沿、下降沿、上升沿或下降沿触发输入捕捉。
其中EDGxB和EDGxA一起来设相应通道输入捕捉极性,对应的功能如下:(0 0)为禁止输入捕捉。
(0 1)为上升沿捕捉(1 0)为下降沿捕捉(1 1)为上升沿或下降沿捕捉TIE是输入捕捉或输出比较中断允许位。
这里的每一位是和TIOS上的位一一对应的。
相应置1时,则捕捉到事件时,则系统会产生中断。
相应位设为0时,则不能。
TFLG1是输入捕捉或输出比较中断标位寄存器。
当发生输入捕捉或输出比较事件时,相应位置1。
向该位写1,可以清空该标志位。
通道寄存器TC0~TC7用于锁存发生捕捉事件时自由运行的计数器的计数值。
通过查询TC0~TC7相应的位,可以确定捕捉事件发生的时刻。
与输入捕捉相关的寄存器还有:ICOVW:输入控制修改寄存器ICSYS:输入控制系统控制寄存器DLYCT:延迟计数控制寄存器(可以自动处理窄脉冲干扰)这些不常,可以不管接下来按照上面的寄存器设置好相应的功能,程序就出来了:void ECT0_INIT() //输入捕捉通道0初始化函数{TSCR2=0X06; //关闭溢出中断且64分频TIOS_IOS0=0; //定通道0为输入捕捉,1为输出比较TCTL4=0X01; //上升沿捕捉0x02为下降沿捕捉TIE_C0I=1; //通道0中断使能TSCR1=0X80; //开启总定时器中断TFLG1_C0F=1; //标志位清零}中断程序:#pragma CODE_SEG __NEAR_SEG NON_BANKED //分配内存空间void interrupt 8 timer_onput() //输入捕捉通道0的中断向量为8{TFLG1_C0F=1; //标志位清零asm sei; //关总中断// PORTB=~PORTB;PORTB&=~(1<<7);delay_us(1);PORTB|=(1<<7);asm cli; //开总中断}输出比较看似不能,却磨折了我两天,其中大多都是些小细节问题在纠缠。
现在终于想明白其中一些道理。
不过有些寄存器还是没有理解,如强制输出比较寄存器CFORC,测试了好久,都未能得到想要的结果,希望路过的高手能指点一下。
接下来继续记一下学习输出比较的点点滴滴吧。
XS128的定时器模块中的输入捕捉和输出比较共用同一组管脚。
可以通过设置TIOS寄存器来选择。
我觉得输出比较的原理和PWM波的产生原理差不多,都是通过计数器的数值和某一寄存器里的值比较产生输出的高低电平变化。
在输出比较中,当计数器的值与某一输出比较通道的TCx(TC0~TC7)的值相等时,该通道上引脚会输出高电平、低电平,或是对引脚上的电平进行翻转。
这时标志位CxF会置位,如果开通中断的话(TIE中的CxI=1),系统还会产生一个中断。
输出比较用到的寄存器好多都是和输入捕捉的一样,现在按照输出比较的程序需要再过一遍。
定时器系统控制寄存器TSCR1:设置定时器正常工作定时器系统控制寄存器TSCR2:设置定时器溢出中断允许,和定时器时钟分频设置定时器计数寄存器TCNT:这是个16位寄存器,在一般情况下是不可以写的。
输入捕捉时,就是这个寄存器的值存入TCx中,输出比较时,也是这个寄存器的值与TCx的值比较。
它的时钟由TSCR2设置的分频决定。
程序中这个寄存器一般情况下不用理会。
主定时器国断标志寄存器TFLG2:在这个寄存器中只有最高位TOF有效,是定时器溢出标志位。
当TCNT运行产生溢出时,该位就置位了。
如果允许定时器溢出中断的话,则系统会产生一个中断。
输入捕捉和输出比较选择寄存器TIOS:设置相应的通道为输入捕捉或是输出比较。
主定时器中断标志寄存器TFLG1:输入捕捉或输出比较的各通道的中断标志位。
对相应的通道写1,可以清除标志位。
定时器中断允许寄存器TIE:里面有8位,对应输入捕捉或输出比较的8个通道,设置是否允许相应通道的中断。
通道寄存器TC0~TC7:在输出比较中随时可以写入,它的作用是,当TCx=TCNT 时,相应的x通道就会发生输出比较。
此时相应的引脚就可以输出高电平、低电平,或是翻转引脚的电平。
上面的寄存器都是和输入捕捉共用的,在输入捕捉中讲过。
接下来就具体说明输出比较特别有的寄存器设置。
TCTL1~TCTL2:这个两个寄存器中每个OMx和OLx组合在一起,来设置相应通道的引脚电平输出方式:(0 0):输出比较的通道与引脚逻辑断开,也就是输出比较的输出不会影响相应的引脚的电平。
(0 1):翻转输出比较的引脚的电平。
(1 0):在相应的引脚上输出低电平。
(1 1):在相应的引脚上输出高电平。
CFORC:定时器强制输出比较寄存器相应位置1时,可以把相应通道的输出比较设为强制输出比较。
一般情况下不用。
OC7M:输出比较通道7屏蔽寄存器OC7D:输出比较通道7数据寄存器通道7上的连续输出比较会覆盖所有其他通道的引脚上的输出结果。
OC7M就是设置其他通道的哪些通道会受通道7控制的。
当OC7M的某位置1时,相应通道的输出比较就会受通道7控制,此时受控的通道在其通道上设置的OMx和OLx无效了,而是按照OC7D中对应的OC7Dx 中的值输出到相应的引脚上。
总的来说,OC7M是选择受通道7控制的其他通道,而OC7D 是受控的通道在通道7发生输出比较时的输出结果。
TTOV:定时器溢出翻转寄存器相应通道置1时,计数器溢出时,允许翻转输出比较引脚上的电平。
这个寄存器只在输出比较模式下才有效。
一般情况下,用不到这个寄存器,程序中不用做设置。
OCPD(OCPD0~OCPD7):当相应位置1时,标志位正常,但是输出比较的结果不能输出到引脚上,也就是输出比较的寄存器与引脚逻辑断开了。
当相应位设为0时,标志位正常,引脚输出也正常。
下面是相应的程序:#include <hidef.h> /* common defines and macros */#include "derivative.h" /* derivative-specific definitions */void main(void){DDRB=0XFF;PORTB=0X7F;//DisableInterrupts;TSCR2=0X07; //设置定时器分频TIOS=0X01;//通道0为输出比较TCTL2=0X01; //模式为翻转引脚输出电平TC0=0XAAAA; //设置输出引脚在一个周期内翻转的时间,//如果这个值保持不变的话,那总的来看,//引脚输出电平的周期是不变的,周期等于计数器计数一周的时间//TTOV=0X00; ////CFORC=0X01; //加上这一句,似乎没什么影响。
还没清这个寄存器的具体作用。
TIE=0X01; //相应通道中断允许TSCR1=0X80; //打开定时器//PORTB=PTT;EnableInterrupts;while(1);}#pragma CODE_SEG __NEAR_SEG NON_BANKED interruptvoid interrupt 8 CH0_ISR(void) //要特别注意中断函数的书写格式,我就在这里吃了大亏{DisableInterrupts;TFLG1=0x01; //清零标志位if(TC0==0xAAAA) //改变引脚输出的占空比。
输出的周期由计数器计数一//周的时间决定,要改变,只能改变定时器的时钟分频TC0=0xffff;elseTC0=0xAAAA;PORTB_PB7=~PORTB_PB7; //测试是否进入中断EnableInterrupts;}XS128中的脉冲累加器和DG128的很不一样。
相对DG128来说,XS128的脉冲累加器大大简化了,其中只有三个寄存器需要设置:PACTL、PAFLG、PACNT。
16位脉冲累加器PACT与IOC7共用一个引脚。
顾名思义,脉冲累加器就是对有效边沿(上升沿或下降沿)进行计数,然后把计数的值保存在寄存器PACNT中。
寄存器PACTL是16位脉冲累加器的核心,几乎所有的设置都是在这个寄存器中。
接下来解剖一下这个核心寄存器PACTL:PAEN:脉冲累加器允许位,置1,则工作。
置0,则禁止。
PAEN与TEN无关,定时器TEN禁止时,脉冲累加器仍可以工作。
PAMOD:工作方式选择位。
置1,为门控时间累加器方式。
置0,为事件计数器方式。
门控时间累加器方式:输入引脚上的有效电平会触发脉冲累加器对64分频后的时钟进行计数。
事件计数器方式:脉冲累加器对引脚上的每个有效边沿计数。
引脚上每产生一个有效边沿,脉冲累加器计数器的值就会加1。
PEDGE:边沿跳变控制位。
它的功能和脉冲累加器的工作方式有关。