[ZigBee] 13、ZigBee基礎階段性回顧與加深理解——用定時器1產生PWM來控制LED亮度(七色燈)


 

引言:PWM對於很多軟件工程師可能又熟悉又陌生,以PWM調節LED亮度為例,其本質是在每個周期都偷工減料一些,整體表現出LED欠壓亮度不同的效果。像大家看到的七色彩燈其原理也類似,只是用3路PWM分別控制紅、綠、藍三種顏色的燈輸出亮度,再結合混色原理表現出豐富多彩的炫光效果~

 

寫在前面:前十幾篇介紹了CC2530的一些外設的基本用法,接下來幾篇拿幾個例子回顧並加深一下之前的知識點,上面引言是普及、下面高能預警!

 

第一個例子:用定時器1產生PWM來控制LED亮度

  我們在《[ZigBee] 5、ZigBee基礎實驗——圖文與代碼詳解定時器1(16位定時器)(長文)》中講過定時器1 是一個支持典型的定時/計數功能的獨立16 位定時器,支持輸入捕獲,輸出比較和PWM等功能。該工程就是利用定時計數器1產生1毫秒PWM,20%的占空比,用PWM來調節LED的亮度,如果led的亮度比較暗可調整pwm頻率和占空比來控制Led燈的亮度。

 1 /****************************************************************************
 2 * 文 件 名: main.c
 3 * 描    述: cc2530 定時計數器1產生1毫秒PWM,20%的占空比,led的亮度比較暗
 4 *           可調整pwm頻率和占空比來控制Led燈的亮度
 5 ****************************************************************************/
 6 #include <ioCC2530.h>
 7 
 8 typedef unsigned char uchar;
 9 typedef unsigned int  uint;
10 
11 #define LED1 P1_0       // P1.0口控制LED1
12 
13 
14 /****************************************************************************
15 * 名    稱: InitLed()
16 * 功    能: 設置LED燈相應的IO口
17 * 入口參數: 無
18 * 出口參數: 無
19 ****************************************************************************/
20 void InitLed(void)
21 {
22     P1DIR |= 0x01;           //P1.0定義為輸出
23     LED1 = 1;                //使LED1燈上電默認為熄滅     
24 }
25 
26 /****************************************************************************
27 * 名    稱: InitT1()
28 * 功    能: 定時器初始化,TICKSPD 是16 MHz系統不配置時默認是2分頻,即16MHz
29 * 入口參數: 無
30 * 出口參數: 無
31 ****************************************************************************/
32 void InitT1()
33 {
34     CLKCONCMD &= ~0x40;      //設置系統時鍾源為32MHZ晶振
35     while(CLKCONSTA & 0x40); //等待晶振穩定為32M
36     CLKCONCMD &= ~0x07;      //設置系統主時鍾頻率為32MHZ   
37     CLKCONCMD |= 0x38;       //時鍾速度32 MHz 定時器標記輸出設置[5:3]250kHz
38 
39 PERCFG |= 0x40; //定時器1 的IO位置 1:備用位置2  40 P2SEL &= ~0x10; //定時器1優先 41 P2DIR |= 0xC0; //第1優先級:定時器1通道2-3 42 43 P1DIR |= 0xff; //端口1為輸出  44 P1SEL |= 0x01; //timer1 通道2映射口P1_0 45 46 T1CC2H = 0x00; //20%占空比為200us 47 T1CC2L = 0x32; //修改T1CC2L可調整led的亮度 48 T1CC0H = 0x00; //1ms的周期時鍾,頻率為976.516HZ 49 T1CC0L = 0xff; 50 T1CCTL2 = 0x1c; // 模式選擇 通道2比較模式 51 T1CTL = 0x02; //250KHz 1分頻
52 }
53 
54 /****************************************************************************
55 * 程序入口函數
56 ****************************************************************************/
57 void main(void)
58 {
59     InitLed();                 //調用初始化函數
60     InitT1();                //定時器初始化及pwm配置
61     while(1)
62     {
63     }
64 }

可見代碼中的核心在於39~51行:

39     PERCFG |= 0x40;          //定時器1 的IO位置   1:備用位置2 
40     P2SEL &= ~0x10;          //定時器1優先
41     P2DIR |= 0xC0;           //第1優先級:定時器1通道2-3
42 
43     P1DIR |= 0xff;           //端口1為輸出    
44     P1SEL |= 0x01;           //timer1 通道2映射口P1_0
45     
46     T1CC2H = 0x00;           //20%占空比為200us
47     T1CC2L = 0x32;           //修改T1CC2L可調整led的亮度
48     T1CC0H = 0x00;           //1ms的周期時鍾,頻率為976.516HZ
49     T1CC0L = 0xff; 50 T1CCTL2 = 0x1c; // 模式選擇 通道2比較模式 51 T1CTL = 0x02; //250KHz 1分頻

 

1.1、第一步:調用外設控制寄存器設置外設所映射IO引腳的方案 

其中第39行令PERCFG |= 0x40,PERCFG是外設控制寄存器,如下圖該寄存器用來設置一些外設的I/O的位置。這里操作的是第六位T1CFG,選擇定時器1的IO為備用位置2。

這里所說的IO映射位置方案1和方案2需要在表《Peripheral I/O Pin Mapping》中查看,在第七節《[ZigBee] 7、ZigBee之UART剖析(ONLY串口發送)》中我已經用UART的例子詳細介紹如何看這個表:

以USART0為例,第一種映射關系是RT-P05\CT-P04\TX-P03\RX-P02;另一種映射關系是TX-P15\RX-P14\RT-P13\CT-P12。

那么在使用過程中,一種模式對應兩種映射肯定會出現矛盾!

那么外設控制寄存器就是用來設置選擇哪種方案的!這里設置為0x40即選用定時器1的引腳映射方案2:P07對應通道3、P06-通道4、P12-通道0、P11-通道1、P10-通道2~

 

1.2、第二步:調用Port2功能選擇和Port1設備優先級控制寄存器,設置timer1占Port1引腳的外設優先級為高

在第七節《[ZigBee] 7、ZigBee之UART剖析(ONLY串口發送)》中同樣有介紹,上面外設控制寄存器僅僅解決了同一個外設多個IO映射方案的沖突問題,但是並沒有解決不同外設IO映射沖突問題。P2SEL寄存器就是處理這個問題!

3、4、5、6位用於設置同一個IO上兩個設備當PERCFG賦值時的優先級,因此這里設置P2SEL &= ~0x10,將定時器設置為最優先。

 

1.3、第三步:調用Port2方向選擇和Port0設備優先級控制寄存器,設置timer1占Port0引腳的外設優先級為高

在第七節《[ZigBee] 7、ZigBee之UART剖析(ONLY串口發送)》中同樣有介紹,由於timer1引腳映射占了Port0和Port1,因此上面P2SEL寄存器用來設置port1部分timer所占引腳的優先級,這里調用P2DIR設置其占Port0引腳的優先級,代碼中P2DIR |= 0xC0,即設置7~6位為11使定時器1通道2-3最優先。

 


規律:不難發現這里timer的用法和第七篇中介紹的uart初始化很類似,前三行做端口映射、優先級選定,一般外設會涉及兩個端口,因此需要用P0SEL和P2DIR分別設置。接下來就是針對具體外設的參數設置了!


 

1.4、第四步:選擇PWM通道,並使能

在1.1中介紹定時器1的引腳映射方案選用是備用2方案:P07對應通道3、P06-通道4、P12-通道0、P11-通道1、P10-通道2~

在1.3中設置通道2、3優先級最高

從1.1~1.3為timer1的PWM的的初始化,也設置了通道的優先級,如果想使能通道還需要進一步設置:

43     P1DIR |= 0xff;           //端口1為輸出    
44     P1SEL |= 0x01;           //timer1 通道2映射口P1_0

其中第43行設置端口1為全部輸出,第44行比較關鍵,用來將IO引腳設置為普通IO引腳還是設置成IO外設引腳,這里將P1_0設置為外設引腳。根據前面的設置,我們知道是將P10設置為了定時器1的通道2輸出口。

 

1.5、定時器1通道2輸出比較模式選擇&設置周期與占空比

關於輸出比較模式在《[ZigBee] 5、ZigBee基礎實驗——圖文與代碼詳解定時器1(16位定時器)(長文)》里的第9段介紹比較詳細:PWM 輸出可以通過選擇定時器正計數/倒計數模式生成。根據PWM 信號所需的極性選擇通道輸出比較模式4 或5(由T1CCTLn.CMP 位定義,其中n 是1 或2)。PWM 信號的周期由T1CC0 確定,通道輸出的占空比由T1CCn 確定,其中n 是PWM 通道1 或2。某些類型的電機驅動應用程序會需要中心對齊的PWM 模式,一般地這比邊沿對齊的PWM 模式產生的噪音更少,因為I/O 引腳傳輸不集中在同一個時鍾邊沿上。

46     T1CC2H = 0x00;           //20%占空比為200us
47     T1CC2L = 0x32;           //修改T1CC2L可調整led的亮度
48     T1CC0H = 0x00;           //1ms的周期時鍾,頻率為976.516HZ
49     T1CC0L = 0xff; 
50 T1CCTL2 = 0x1c; // 模式選擇 通道2比較模式
51     T1CTL = 0x02;            //250KHz 1分頻

其中第50行用來設置定時器1通道2捕獲/比較控制寄存器為0x1C,[5:3]=011則選擇了輸出比較模式4,其PWM信號周期由T1CC0決定,占空比由T1CCn確定(正計數到計數模式生成PWM比邊沿模式生成PWM更適合這里,如果你聽不懂這句話請看第5篇)!因此,46~49行就是設置PWM的周期和占空比~

  

 


 

注意:這里0x0032/0x00ff不等於20%,為什么注釋中說占空比為20%呢?我們用一個簡單的例子解釋這個問題的特殊性(繪制定時器counter的值變化線如下):左邊的一個設T1CC0=4,T1CC2=2,顯然占空比不是2/4,也不是3/9,因為最后一個綠色框內的時期屬於下一個周期了,一個完整周期應該為0~4~1,因此占空比為3/8;同理右邊的占空比為3/6。這里T1CC2設置為0x0032,則低段有:0~0x0032,0x0032~1,總共(0x0032-0+1)+(0x0032-1+1)=0x0032*2+1=0x0065=101;總周期為0x00FF*2=0x01FE=510,占空比為0x65/0x01FE約等於5


其中最后一行T1CTL = 0x02,用來設置自由運行模式(關於模式也在第七篇介紹),采用1分頻,250KHz~

 

總結:這樣就能用PWM輸出通道2直接關聯到P10來控制LED的亮度,簡單有效~

 

 

 

Zigbee系列文章:

[ZigBee] 1、 ZigBee簡介

[ZigBee] 2、 ZigBee開發環境搭建

[ZigBee] 3、ZigBee基礎實驗——GPIO輸出控制實驗-控制Led亮滅

[ZigBee] 4、ZigBee基礎實驗——中斷

[ZigBee] 5、ZigBee基礎實驗——圖文與代碼詳解定時器1(16位定時器)(長文)

[ZigBee] 6、ZigBee基礎實驗——定時器3和定時器4(8 位定時器)

[ZigBee] 7、ZigBee之UART剖析(ONLY串口發送)

[ZigBee] 8、ZigBee之UART剖析·二(串口收發)

[ZigBee] 9、ZigBee之AD剖析——AD采集CC2530溫度串口顯示

[ZigBee] 10、ZigBee之睡眠定時器

[ZigBee] 11、ZigBee之睡眠定時器二

[ZigBee] 12、ZigBee之看門狗定時器——餓了就咬人的GOOD DOG

 

 

PS:如果您覺得還不錯,點個贊,讓更多人受益~

@beautifulzzzz 2016-07-22 continue~  
e-mail:beautifulzzzz@qq.com 
sina:http://weibo.com/beautifulzzzz?is_all=1

 


免責聲明!

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



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