历史上的今天
返回首页

历史上的今天

今天是:2025年04月09日(星期三)

正在发生

2019年04月09日 | ZigBee基础实验(十一)--PWM来控制LED亮度

2019-04-09 来源:eefocus

引言: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

 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的亮度。


推荐阅读

史海拾趣

DIOO公司的发展小趣事

DIOO公司的创始人李奥(Leo)是一位热衷于电子技术的工程师。在20世纪80年代初,他看到了电子行业的巨大潜力,并决定创立DIOO公司,专注于开发和生产高端电子产品。凭借对技术的热爱和对市场的敏锐洞察,李奥带领DIOO公司推出了第一款自主研发的电子产品——高性能音频放大器,该产品凭借其卓越的性能和独特的设计在市场上引起了轰动。

B&F Fastener Supply公司的发展小趣事

为了进一步完善电子供应链,B&F Fastener Supply公司积极寻求并购机会。经过多轮谈判和尽职调查,公司成功收购了某家专注于电子元器件供应的公司。这次并购使得B&F的产品线更加丰富,能够为客户提供一站式的电子供应链解决方案。

Beck IPC GmbH公司的发展小趣事

Beck IPC始终坚持以研发和创新为核心驱动力。公司每年投入大量资金用于研发新技术和产品,并建立了完善的研发团队和体系。通过不断的技术创新和产品升级,Beck IPC始终保持着在嵌入式通讯和工业物联网领域的领先地位。同时,公司还积极参与国际标准制定和行业交流活动,为推动行业发展贡献自己的力量。

Condor公司的发展小趣事

为了进一步增强公司的竞争力,Beck IPC积极寻求与其他优秀企业的收购与合作机会。在某一时期,公司成功收购了一家在边缘网关系列产品领域具有领先地位的企业。通过这次收购,Beck IPC不仅获得了更多先进的技术和产品,还进一步巩固了其在工业物联网领域的地位。此外,公司还与多家知名企业建立了战略合作关系,共同推动行业发展。

Hsuan Mao Technology Co公司的发展小趣事

为了进一步增强公司的竞争力,Beck IPC积极寻求与其他优秀企业的收购与合作机会。在某一时期,公司成功收购了一家在边缘网关系列产品领域具有领先地位的企业。通过这次收购,Beck IPC不仅获得了更多先进的技术和产品,还进一步巩固了其在工业物联网领域的地位。此外,公司还与多家知名企业建立了战略合作关系,共同推动行业发展。

Emhiser Research Inc公司的发展小趣事

Emhiser Research非常注重创新管理和人才培养。公司建立了一套完善的研发流程和激励机制,鼓励员工提出创新性的想法和解决方案。同时,公司还积极与高校和研究机构合作,引进和培养了一批高素质的研发人才。这些人才不仅为公司带来了源源不断的创新动力,也为公司的长期发展奠定了坚实的基础。

问答坊 | AI 解惑

关于今年电子竞赛

各位大哥,今年电子竞赛马上就要开始了,我们的开发板还在设计制作当中,用ARM单片机,祥和大家交流一下,每次竞赛地开发板上都有哪些必不可少的模块啊?谢谢了!…

查看全部问答>

全球首款MID又遭抄袭,三星跟风没新意

前几天看报道,发现三星在09年2月发布了一款叫Mondi的手持设备,怎么看都像去年英特尔和爱国者推的MID,看来三星设计方面也是江郎才尽啊,开始模仿别人的设计了….鄙视一下三星!发几个图给大家比较一下 这款MID是08年4月北京IDF发布的。 ...…

查看全部问答>

Actel 交流贴

我想在此地方发一个Actel的使用心得、体会,或在开发过程中所碰到的问题;现在本人还不知道怎么发贴;后面我会陆续上传一些Actel有关器件方面的资料;欢迎广大的RD朋友们莅临 11楼:ACTEL 8051S 例程13楼:ACTEL HDL 代码例程本文档详细介绍了常 ...…

查看全部问答>

不露面的LED手表~~

来看看这个表,酷吧~~ …

查看全部问答>

怎么想嵌入式linux系统中写入自己的程序

我想在一个嵌入式linux系统中写入自己的开发程序,  芯片是PPC linux内核是linux 2.6.26 目标机上拥有Jtag.可以用此和目标机相连. 宿主机就是一台普通的PC机,装有windows XP系统, 我不知道在宿主机上应该用什么调试器,编译器. 如果将开 ...…

查看全部问答>

找编写testbench(VHDL)文件高手帮忙

如何在testbench(VHDL)文件中读取文本内容,来生成激励文件,给个例子,小弟未曾用testbench编写过激励…

查看全部问答>

问问大 家用STM32跑什么系统比较好啊?还是裸奔更有前途呢?

本人新手,刚刚学习了一点CM3的知识嘿嘿请大虾们多多指教啊…

查看全部问答>

keil烧写(flash)cortex M4如何配置

大侠们,第一次使用cortex M4芯片(飞思卡尔K40X256)不知道如何配置,错误如图:…

查看全部问答>

关于新版LM3S811 仿真器ICDI-ND,有需求的可以看下.

新版的TI LM3S811开发板上采用了LM3S3601作为MCU的仿真器芯片,该芯片默认的固件只支持CCS的开发环境,想在KEIL的环境下使用,则需要更改内部的固件。 昨天有网友问到这个问题,今天上传一下两个固件。 连接仿真器后在 ..\\\\stellaris-icdi-n ...…

查看全部问答>

一个直流输出电路的附属电路分析

大家好。我们单位有一种产品,输入端是正弦MPU信号,输出端根据输入信号的大小输出直流4-20mA或是20-160mA信号。我将电路图附在下面。在电路图中我有几个问题想请教大家,能否帮我详细分析,谢谢!   问题1:TlE2082(U24)那个运放组成了什 ...…

查看全部问答>