cc2530 timer 1 PWM 輸出


需要在ZStack 協議棧里使用PWM,於是使用其16bit的timer 1來實現之。使用 P1_0口輸出,使用的是正計數/倒計數模式,占空比為50%。代碼如下:

 

 1 #include <ioCC2530.h>
 2 
 3 /*使用P1_0口為輸出、外設端口,來輸出PWM波形*/
 4 void init_port(void)
 5 {
 6     P1DIR |= 0x01;    // p1_0 output
 7     P1SEL |= 0x01;    // p1_0  peripheral
 8     P2SEL &= 0xEE;    // Give priority to Timer 1
 9     PERCFG |= 0x40; // set timer_1 I/O位置為2
10     return ;
11 }
12 
13 /*
14     將基准值放入T1CC0 寄存器, 將被比較值放入T1CC2寄存器
15     當T1CC2中的值與T1CC0中的值相等時,則T1CC2 設置or清除
16 */
17 
18 void init_timer(void)
19 {
20     T1CC0L = 0xff;   //PWM duty cycle  周期
21     T1CC0H = 0x7f;
22     
23     T1CC2L = 0x00;  //     PWM signal period 占空比
24     T1CC2H = 0x00;
25     
26     T1CCTL2 = 0x34;    // 等於T1CC0中的數值時候,輸出高電平 1; 等於T1CC2中的數值時候,輸出低電平 0  ,其實整個占空比就為50%了
27     T1CTL |= 0x0f; // divide with 128 and to do i up-down mode
28     return ;
29 }
30 
31 void start_pwm(void) 
32 {
33     init_port();
34     init_timer();
35 //    IEN1 |=0x02;     //Timer 1 中斷使能
36 //    EA = 1;            //全局中斷使能
37 //    while(1) {;}
38     return ;
39 }
40 
41 #if 0
42 /*irq function*/
43 #pragma vector=T1_VECTOR
44 //__interrupt void T1_IRQ(void)
45 volatile unsigned char count = 0;
46 __interrupt void _irq_timer1(void)
47 {
48     //TODO....
49 }
50 
51 #endif /*_irq_timer1*/

使用的時候,將start_pwm() 函數 放在需要的地方即可。注意不要和原來的timer 沖突。自己是選擇注釋掉原來的timer的代碼,直接寫寄存器,不用協議棧給出的API了。

解釋下:

1、

1 P2SEL &= 0xEE;    // Give priority to Timer 1

其中,P2SEL 寄存器的名字叫 "端口2功能選擇寄存器",但是它的管的范圍可不只有端口2 ,它的[2:0] 分別指定 P2.0、 P2_3、P2_4 是作為通用I/O還是外設引腳功能;而

[6:3] 則分別指定端口1 外設優先級的--一個端口可能同時可以被uart 和timer使用,那么誰優先使用這個端口,則是它來指定的。3 ~6 bit 分別對應端口 1的 P1_0 ~ P1_3.。

當然,類似於P2SEL這樣多功能的寄存器還有其他的,比如P2DIR,它同時指定端口2的方向,也管理着端口0的外設優先級。這個是奇怪了點,但還是按照數據手冊來吧。

2、

1     PERCFG |= 0x40; // set timer_1 I/O位置為2

PERCFG 這個寄存器名字叫“外設I/O控制寄存器”,其實它的功能就像一個撥碼開關一樣,起一個選擇路的作用。

看下面貼圖:

 

什么亂七八糟的備用位置1 備用位置2,我是沒明白的,但是看第一張圖,要使用timer 1 並且在P1_0,那么就必須設置到 Alt 2的位置上。那么相應的寄存器就是PERCFG 了,開始還糾結了一把,沒搞明白。 <ps:手冊里的I/O口映射並沒有標Alt 1,只是標了 Alt 2:如上圖USART1在P0端口,就是使用的Alt 1。如果有需要的話,還是一樣的用寄存器 PERCFG設置到 備用位置1 即可>

我程序里是 timer 1 P1_0,那么設置到 Alt 2的話,代碼顯然就該:

1 PERCFG |= 0x40; // set timer_1 I/O位置為2

3、32MHz / 128 = 250 Hz ?  不知道計算錯了沒,反正就是這么個公式吧。以這樣的頻率,計時器從0單步單步走到同T1CC2寄存器里面的值相等的時候,進行一次操作;然后繼續走到T1CC0 處再操作一次 --  比如給I/O端口的電平取反什么的,都可以,看心情。

4、其他,其他就沒了,其他的寄存器在手冊里面很容易理解了。 

 

5、 我和同事一起整理了個小的學習備忘錄文檔,鏈接如下:

 

文檔鏈接: http://pan.baidu.com/s/1o6qIjOY 

 

<ps:文檔表述不一定非常准確>

 

關鍵字: cc2530 timer1 pwm PWM

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM