实验2:输出比较功能(Output Compare)
所谓输出比较功能就是根据需要设置输出比较寄存器的值,自由运行计数器的值与输出比较寄存器的值每隔4个总线周期比较一次,当两者相等时,会在规定的通道引脚上输出预定的电平。如果允许中断,会产生一次输出比较中断。
相应需要操作的寄存器有如下几个:
TCx 寄存器(Timer Input Capture/Output Compare 0-7)
总共8个16位寄存器,分别对应8个输出比较通道。当 TCx = TCNT 时满足输出比较条件,这时根据程序设置在对应输出管腿输出特定的电平(具体方法见TCTL1/TCTL2 寄存器的功能设置)或者产生对应的中断事件。
TIOS寄存器(Timer Input Capture/Output Compare Select)
用来设定某一通道是输入捕捉功能还是输出比较功能。IOSx = 1 对应位为输出比较功能,IOSx = 0 对应位为输入捕捉功能。
图 7 TIOS寄存器
TIE寄存器(Timer Interrupt Enable Register)
其中某一位置 1 后则使能相应的通道的中断,这里控制的中断既包括输出比较中断也包括后面要介绍的输入捕捉中断。
图 8 TIE寄存器
TCTL1/TCTL2 寄存器(Timer Control Register 1/2)
用来决定输出比较时的输出模式和输出电平。具体参见表格 1。
表格 1 输出比较动作
OMx
|
OLx
|
动作
|
0 |
0 |
不输出
|
0 |
1 |
每次翻转OCx 的电平
|
1 |
0 |
OCx = 0
|
1 |
1 |
OCx = 1
|
图 9 TCTL1/TCTL2 寄存器
TFLG1寄存器(Main Timer Interrupt Flag 1)
用来标识中断条件发生了,对某一位写1则清除对应位。
图 10 TFLG1寄存器
有了这些就可以开始第二个例子了。第二个例子利用通道0和通道1的输出比较功能。在 TCNT = TC0 时将对应的PT0 管腿的输出电平翻转,并且产生相应中断。在 TCNT = TC1时将对应的PT1 管腿的输出电平翻转,并且产生相应中断。这样,PT0和PT1 就会输出两个具有恒定相位差的同频方波信号了。
- #include /* common defines and macros */
- #include "derivative.h" /* derivative-specific definitions */
- #include "sci.h"
-
- void ECTInit(void)
- {
- //TSCR2_PR = 7; //prescale factor is 8, bus clock/128=8Mhz/8
- TSCR2_TOI = 1; //timer overflow interrupt enable
- TSCR1_TEN = 1; //timer enable
-
- TIOS_IOS0 = 1; // channel 0 as output compare
- TIOS_IOS1 = 1; // channel 1 as output compare
- TC0 = 10000;
- TC1 = 20000;
- TIE_C0I = 1; // 使能 channel 0 中断
- TIE_C1I = 1; // 使能 channel 1 中断
-
- TCTL2_OL0 = 1;
- TCTL2_OM0 = 0;
-
- TCTL2_OL1 = 1;
- TCTL2_OM1 = 0;
- }
- void main(void)
- {
- SCIInit();
- SCISetBaudRate (SCI0, 9600, 8192000L);
- ECTInit();
- DDRM_DDRM0 = 1;
- DDRM_DDRM1 = 1;
- DDRM_DDRM2 = 1;
- EnableInterrupts;
-
- for(;;)
- {
- _FEED_COP(); /* feeds the dog */
- } /* loop forever */
- }
-
-
- interrupt VectorNumber_Vtimovf void ECT_TimerOverflow_ISR(void)
- {
- TFLG2 = TFLG2_TOF_MASK; //clear timer overflow interrupt flag
- PTM_PTM0 = ~ PTM_PTM0;
- }
-
- interrupt VectorNumber_Vtimch0 void ECT_0_ISR(void)
- {
- unsigned int value;
-
- TFLG1 = TFLG1_C0F_MASK; //clear channel 0 interrupt flag
- PTM_PTM1 = ~ PTM_PTM1;
- }
- interrupt VectorNumber_Vtimch1 void ECT_1_ISR(void)
- {
- TFLG1 = TFLG1_C1F_MASK; //clear channel 1 interrupt flag
- PTM_PTM2 = ~ PTM_PTM2;
- }
- interrupt VectorNumber_Vtimch7 void ECT_7_ISR(void)
- {
- TFLG1 = TFLG1_C7F_MASK; //clear channel 7 interrupt flag
- }
下面是用 USBee 抓下来的波形图。Port M 0 是在溢出中断中翻转的。PT0 、PT1分别对应两个输出比较通道,两个上升沿的时间间隔为 1/8192=1.22ms,测量结果与理论值完全相同。
下面将程序做一个很小的修改。将 TC0 和 TC1 的值改成相同的。
- void ECTInit(void)
- {
- //TSCR2_PR = 7; //prescale factor is 8, bus clock/128=8Mhz/8
- TSCR2_TOI = 1; //timer overflow interrupt enable
- TSCR1_TEN = 1; //timer enable
-
- TIOS_IOS0 = 1; // channel 0 as output compare
- TIOS_IOS1 = 1; // channel 1 as output compare
- TC0 = 10000;
- TC1 = 10000;
- TIE_C0I = 1; // 使能 channel 0 中断
- TIE_C1I = 1; // 使能 channel 1 中断
-
- TCTL2_OL0 = 1;
- TCTL2_OM0 = 0;
-
- TCTL2_OL1 = 1;
- TCTL2_OM1 = 0;
- }
从波形图中可以看出,输出是正常的。但是有些低版本的 ECT 模块有些问题,在这种情况下只有 通道 0 的中断能够响应,通道1的中断无法响应。
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』