嵌入式成长轨迹43 【Zigbee项目】【CC2430基础实验】【T4的使用】

CC2430/CC2431 包括四个定时器:一个一般的 16 位(Timer 1) 和两个8 位(Timer3,4)定时器,支持典型的定时/ 计数功能,例如测量时间间隔,对外部事件计数,产生周期性中断请求,输入捕捉、比较输出和PWM 功能。一个 16 位MAC定时器(Timer 2),用以为IEEE802.15.4 的CSMA-CA 算法提供定时以及为IEEE802.15.4 的MAC层提供定时。

本实验使用T4,输入捕捉、比较输出和PWM 功能。

脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。


P2SEL (0xF5) – Port 2 Function Select
P2SEL |= 0x02;
7  -  0 R0 Not used
6  PRI3P1 
Port 1 peripheral priority control. These bits shall determine the order of priority in the case when PERCFG assigns USART0 and USART1 to the same pins.
 0 USART0 has priority
 1 USART1 has priority
5  PRI2P1
Port 1 peripheral priority control. These bits shall determine the order of priority in the case when PERCFG assigns USART1 and timer 3 to the same pins.
 0 USART1 has priority
 1 Timer 3 has priority
4  PRI1P1
Port 1 peripheral priority control. These bits shall determine the order of priority in the case when PERCFG assigns timer 1 and timer 4 to the same pins.
 0 Timer 1 has priority
 1 Timer 4 has priority
3  PRI0P1  0 R/W
Port 1 peripheral priority control. These bits shall determine the order of priority in the case when PERCFG assigns USART0 and timer 1 to the same pins.
 0 USART0 has priority
 1 Timer 1 has priority
2  SELP2_4  P2_4 function select
 0 General purpose I/O
 1 Peripheral function
1  SELP2_3  P2_3 function select
 0 General purpose I/O
 1 Peripheral function
0  SELP2_0  P2_0 function select
 0 General purpose I/O
 1 Peripheral function


PERCFG (0xF1) – Peripheral Control
0x20
7  -  0 R0 Not used
6  T1CFG Timer 1 I/O location
 0 Alternative 1 location
 1 Alternative 2 location
5  T3CFG Timer 3 I/O location
 0 Alternative 1 location
 1 Alternative 2 location
4  T4CFG Timer 4 I/O location
 0 Alternative 1 location
 1 Alternative 2 location
3:2  -Not used
1  U1CFG USART1 I/O location
 0 Alternative 1 location
 1 Alternative 2 location
0  U0CFG USART0 I/O location
 0 Alternative 1 location
 1 Alternative 2 location


while(!XOSC_STABLE);          \
        asm("NOP");
NOP指令即“空指令”,在x86的CPU中机器码为0x90(144)。执行到NOP指令时,CPU什么也不做,仅仅当做一个指令执行过去并继续执行NOP后面的一条指令,所以NOP指令自然也会占用执行一个指令的CPU时间片。   常用于程序延时或精确计时,不过在较快的CPU上不明显。   主要作用:
   1、字节填充对齐
   2、精确延时和计时
   3、破解程序的call验证
   4、等待其他设备执行完毕
   5、清除由上一个算术逻辑指令设置的flag位
   6、辅助jmp、call等指令

使用PWM应调用:
TIMER34_PWM_CONFIG(timer)// Macro for configuring channel 1 of timer 3 or 4 for PWM mode.
TIMER34_SET_PWM_PULSE_LENGTH(timer, value) // Macro for setting pulse length of the timer in PWM mode

想试着用一次PWM的……可是灯一直不亮……
先放一个T4的计数触发,以后再来收拾——

  1 //emot.h
  2 
  3 #ifndef EMOT_H
  4 #define EMOT_H
  5 
  6 #include <iocc2430.h>
  7 
  8 typedef unsigned int WORD;
  9 typedef unsigned char BYTE;
 10 typedef WORD UINT16;
 11 
 12 /*****************************************
 13 //IO功能定义
 14 *****************************************/
 15 #define IO_FUNC_PORT_PIN(port, pin, func)  \
 16    do {                                    \
 17       if((port == 2) && (pin == 3)){       \
 18          if (func) {                       \
 19             P2SEL |= 0x02;                 \
 20          } else {                          \
 21             P2SEL &= ~0x02;                \
 22          }                                 \
 23       }                                    \
 24       else if((port == 2) && (pin == 4)){  \
 25          if (func) {                       \
 26             P2SEL |= 0x04;                 \
 27          } else {                          \
 28             P2SEL &= ~0x04;                \
 29          }                                 \
 30       }                                    \
 31       else{                                \
 32          if (func) {                       \
 33             P##port##SEL |= (0x01<<(pin)); \
 34          } else {                          \
 35             P##port##SEL &= ~(0x01<<(pin));\
 36         }                                  \
 37       }                                    \
 38    } while (0)
 39 
 40 // where func is one of:
 41 #define IO_FUNC_GIO     0 // General purpose I/O
 42 #define IO_FUNC_PERIPH  1 // Peripheral function
 43 
 44 
 45 
 46 
 47 /*****************************************
 48 //时钟定义
 49 *****************************************/
 50 // Macro for getting the clock division factor
 51 #define CLKSPD  (CLKCON & 0x07)
 52 
 53 // Macro for getting the timer tick division factor.
 54 #define TICKSPD ((CLKCON & 0x38) >> 3)
 55 
 56 // Macro for checking status of the crystal oscillator
 57 #define XOSC_STABLE (SLEEP & 0x40)
 58 
 59 // Macro for checking status of the high frequency RC oscillator.
 60 #define HIGH_FREQUENCY_RC_OSC_STABLE    (SLEEP & 0x20)
 61 
 62 //macro for setting CLKCON.TICKSPD
 63 #define SET_TICKSPD_DIVIDE(val) do{CLKCON &= ~0X38 ; CLKCON |= (unsigned char)(val);}while(0)
 64 /*
 65 // Where _val_ is one of
 66 #define 32M_TICK      0x00
 67 #define 16M_TICK      0x08
 68 #define 8M_TICK       0x10
 69 #define 4M_TICK       0x18
 70 #define 2M_TICK       0x20
 71 #define 1M_TICK       0x28
 72 #define 0_5M_TICK     0x30
 73 #define 0_2_5M_TICK   0x38
 74 */
 75 
 76 
 77 // Macro for setting the 32 KHz clock source
 78 #define SET_32KHZ_CLOCK_SOURCE(source) \
 79    do {                                \
 80       if( source ) {                   \
 81          CLKCON |= 0x80;               \
 82       } else {                         \
 83          CLKCON &= ~0x80;              \
 84       }                                \
 85    } while (0)
 86 
 87 // Where _source_ is one of
 88 #define CRYSTAL 0x00
 89 #define RC      0x01
 90 
 91 // Macro for setting the main clock oscillator source,
 92 //turns off the clock source not used
 93 //changing to XOSC will take approx 150 us
 94 #define SET_MAIN_CLOCK_SOURCE(source) \
 95    do {                               \
 96       if(source) {                    \
 97         CLKCON |= 0x40;               \
 98         while(!HIGH_FREQUENCY_RC_OSC_STABLE); \
 99         if(TICKSPD == 0){             \
100           CLKCON |= 0x08;             \
101         }                             \
102         SLEEP |= 0x04;                \
103       }                               \
104       else {                          \
105         SLEEP &= ~0x04;               \
106         while(!XOSC_STABLE);          \
107         asm("NOP");                   \
108         CLKCON &= ~0x47;              \
109         SLEEP |= 0x04;                \
110       }                               \
111    }while (0)
112 
113 
114 /*****************************************
115 //T4配置定义
116 *****************************************/
117 // Where _timer_ must be either 3 or 4
118 // Macro for initialising timer 3 or 4
119 #define TIMER34_INIT(timer)   \
120    do {                       \
121       T##timer##CTL   = 0x06; \
122       T##timer##CCTL0 = 0x00; \
123       T##timer##CC0   = 0x00; \
124       T##timer##CCTL1 = 0x00; \
125       T##timer##CC1   = 0x00; \
126    } while (0)
127 
128 //Macro for enabling overflow interrupt
129 #define TIMER34_ENABLE_OVERFLOW_INT(timer,val) \
130   do{ (T##timer##CTL =  (val) ? T##timer##CTL | 0x08 : T##timer##CTL & ~0x08); \
131       EA = 1;                                                                  \
132       T##timer##IE = 1;                                                       \
133    }while(0)
134 
135 // Macros for configuring IO peripheral location:
136 #define IO_PER_LOC_TIMER4_AT_PORT1_PIN01()  do { PERCFG = (PERCFG&~0x10)|0x00; } while (0)
137 #define IO_PER_LOC_TIMER4_AT_PORT2_PIN03()  do { PERCFG = (PERCFG&~0x10)|0x10; } while (0)
138 
139 // Actual MCU pin configuration:
140 //
141 // Peripheral I/O signal     Alt1       Alt2
142 // -------------------------------------------
143 // Timer4 channel0           P1.0       P2.0
144 // Timer4 channel1           P1.1       P2.3
145 
146 
147 // Macro for enabling/ disabling interrupts from the channels of timer 1, 3 or 4.
148 #define TIMER_CHANNEL_INTERRUPT_ENABLE(timer, channel, value) \
149    do{                                                        \
150       if(value){                                              \
151          T##timer##CCTL##channel## |= 0x40;                   \
152       } else {                                                \
153          T##timer##CCTL##channel## &= ~0x40;                  \
154       }                                                       \
155    } while(0)
156 
157 
158 
159 
160 // Macro for configuring channel 1 of timer 3 or 4 for PWM mode.
161 #define TIMER34_PWM_CONFIG(timer)                 \
162    do{                                            \
163       T##timer##CCTL1 = 0x24;                     \
164       if(timer == 3){                             \
165          if(PERCFG & 0x20) {                      \
166             IO_FUNC_PORT_PIN(1,7,IO_FUNC_PERIPH); \
167          }                                        \
168          else {                                   \
169             IO_FUNC_PORT_PIN(1,4,IO_FUNC_PERIPH); \
170          }                                        \
171       }                                           \
172       else {                                      \
173          if(PERCFG & 0x10) {                      \
174              IO_FUNC_PORT_PIN(2,3,IO_FUNC_PERIPH);\
175          }                                        \
176          else {                                   \
177             IO_FUNC_PORT_PIN(1,1,IO_FUNC_PERIPH); \
178          }                                        \
179       }                                           \
180    } while(0)
181 
182 
183 
184 
185 // Macro for setting pulse length of the timer in PWM mode
186 #define TIMER34_SET_PWM_PULSE_LENGTH(timer, value) \
187    do {                                            \
188       T##timer##CC1 = (BYTE)value;                 \
189    } while (0)
190 
191 
192 // Macro for setting timer 3 or 4 as a capture timer
193 #define TIMER34_CAPTURE_TIMER(timer,edge)          \
194    do{                                             \
195       T##timer##CCTL1 = edge;                      \
196       if(timer == 3){                              \
197          if(PERCFG & 0x20) {                       \
198             IO_FUNC_PORT_PIN(1,7,IO_FUNC_PERIPH);  \
199          }                                         \
200          else {                                    \
201              IO_FUNC_PORT_PIN(1,4,IO_FUNC_PERIPH); \
202          }                                         \
203       }                                            \
204       else {                                       \
205          if(PERCFG & 0x10) {                       \
206             IO_FUNC_PORT_PIN(2,3,IO_FUNC_PERIPH);  \
207          }                                         \
208         else {                                     \
209            IO_FUNC_PORT_PIN(1,1,IO_FUNC_PERIPH);   \
210         }                                          \
211      }                                             \
212   }while(0)
213 
214 //Macro for setting the clock tick for timer3 or 4
215 #define TIMER34_START(timer,val)                         \
216     (T##timer##CTL = (val) ? T##timer##CTL | 0X10 : T##timer##CTL&~0X10)
217 
218 #define TIMER34_SET_CLOCK_DIVIDE(timer,val)        \
219   do{                                             \
220     T##timer##CTL &= ~0XE0;                               \
221       (val==2) ? (T##timer##CTL|=0X20):                   \
222       (val==4) ? (T##timer##CTL|=0x40):                   \
223       (val==8) ? (T##timer##CTL|=0X60):                   \
224       (val==16)? (T##timer##CTL|=0x80):                   \
225       (val==32)? (T##timer##CTL|=0xa0):                   \
226       (val==64) ? (T##timer##CTL|=0xc0):                  \
227       (val==128) ? (T##timer##CTL|=0XE0):                 \
228       (T##timer##CTL|=0X00);             /* 1 */          \
229   }while(0)
230 
231 //Macro for setting the mode of timer3 or 4
232 #define TIMER34_SET_MODE(timer,val)                \
233   do{                                             \
234     T##timer##CTL &= ~0X03;                               \
235     (val==1)?(T##timer##CTL|=0X01):  /*DOWN            */ \
236     (val==2)?(T##timer##CTL|=0X02):  /*Modulo          */ \
237     (val==3)?(T##timer##CTL|=0X03):  /*UP / DOWN       */ \
238     (T##timer##CTL|=0X00);           /*free runing */     \
239   }while(0)
240 #define T4_MODE_FREE    0X00
241 #define T4_MODE_DOWN    0X01
242 #define T4_MODE_MODULO  0X02
243 #define T4_MODE_UP_DOWN 0X03
244 
245 //macro for setting the compare value of timer3 or 4
246 #define TIMER34_SET_CPM_VALUE(timer,channel,val)  \
247   do{ T##timer##CC##channel## = (unsigned int)(val); }while(0)
248 // Where _timer_ must be either 3 or 4
249 // Where _channel_ must be either 1 or 2
250 
251 
252 /*********************************************************************
253 //键盘定义
254 *********************************************************************/
255 #define KEY1 P1_2
256 #define KEY2 P1_3
257 
258 #define ENABLE_KEY_ON_BOARD() \
259   do{                         \
260     P1SEL &= ~0X0C;           \
261     P1DIR &= ~0X0C;           \
262     P1INP |= 0x0c;            \
263   }while(0)
264 
265 
266 #endif //emot.h
 1 //main.c
 2 #include "emot.h"
 3 
 4 #define led1 P1_0
 5 #define led2 P1_1
 6 
 7 #define uchar unsigned char
 8 
 9 /*****************************************
10 //定义全局变量
11 *****************************************/
12 uchar counter = 0;
13 
14 /*****************************************
15 //T4及LED初始化
16 *****************************************/
17 void Init_T4_AND_LED(void)
18 {
19     P1DIR = 0X03;
20     led1 = 1;
21     led2 = 1;
22 
23     TIMER34_INIT(4);                  //初始化T4
24     TIMER34_ENABLE_OVERFLOW_INT(4,1);  //开T4中断
25 
26     TIMER34_SET_CLOCK_DIVIDE(4,128);
27     TIMER34_SET_MODE(4,0);                 //自动重装00->0xff
28 
29     TIMER34_START(4,1);                    //启动
30 };
31 
32 void main(void)
33 {
34     Init_T4_AND_LED();                  //初始化LED和T4
35     while(1);                           //等待中断
36 }
37 
38 
39 #pragma vector = T4_VECTOR
40  __interrupt void T4_ISR(void)
41  {
42      IRCON = 0x00;            //可不清中断标志,硬件自动完成
43         //led2 = 0;                       //for test
44          if(counter<200)counter++;    //200次中断LED闪烁一轮
45         else
46         {
47           counter = 0;                  //计数清零
48           led2 = led1;
49           led1 = !led1;                   //改变小灯的状态
50         }
51  }
原文地址:https://www.cnblogs.com/zeedmood/p/2666906.html