标记重捕 发表于 2024-6-30 19:10:45

STC03 PWM实现呼吸灯

本帖最后由 标记重捕 于 2024-6-30 19:14 编辑

一 实验目标
使用PWM1P的输出,控制P20作为PWMA_1P,输出频率为1000Hz、占空比可调的PWM来驱动所连接的LED渐变亮灭,即呼吸灯的效果。
二 工作原理和硬件连接2.1 PWM呼吸灯工作原理
在一个周期的波形中,通过更改高电平占整个周期的时间比例,从而改变一个周期的等效输出电压,电压在改变,则LED的亮度也会改变。如果等效电压的变化趋势是从低,越来越高,紧接着从高,到越来越低,那么反映在LED上的变化就是由暗慢慢变亮,再由亮慢慢变暗的一个过程,类似“呼吸”的效果。
2.2 硬件连接


https://pic1.zhimg.com/80/v2-c01ecb573e72519a81f039425592c454_720w.webp

查阅数据手册,在连接了LED的端口中,其中之一的P20端口是PWMA_1P端口,可以用作PWM的输出,所以我选择使用P20口输出PWM控制LED。
三 代码步骤及实现
我们在“定时器0计时中断控制LED闪烁”的代码上增加PWM功能。

STC02 定时器0计时中断控制LED闪烁
https://www.stcaimcu.com/forum.php?mod=viewthread&tid=9243

3.1 PWM功能代码的封装

https://pic2.zhimg.com/80/v2-e166411f6bdc62b203270575ccf0d63d_720w.webp
将占空比按照100的步进,定义成枚举类型,100表示10%占空比,200表示20%占空比,一次类推。
https://pic1.zhimg.com/80/v2-7d8130fb80a577a78c257c4922d09740_720w.webp
用结构体组织PWM的成员,其成员有占空比,PWM初始化函数,占空比调节函数,并使用extern将PWM结构体提供给外部调用。


下面介绍配置PWM功能的步骤。
3.2 设置P20复用PWM功能

https://pic3.zhimg.com/80/v2-d5f10adde3ff51bdba5c81ad553be5da_720w.webp
PWM要求IO既能输出高电平,又能输出低电平,满足这样的要求的IO模式,可以选择准双向口或推挽输出,这两种模式都是可以输出高低电平的。这里我选择的是准双向口功能。

3.3 通道输出脚选择

https://pic4.zhimg.com/80/v2-e29087d012dc4cd0247b31b7f24cb60f_720w.webp

https://pic1.zhimg.com/80/v2-6c339f120646e1db1c5e7f76b6760310_720w.webp
我们的实验目标是使用P20作为PWM1P的输出口,所以C1PS选择01,其他位设置为0即可。

3.4 配置通道模式

https://pic2.zhimg.com/80/v2-12720e49dfad27c8b076d52a9ee42bed_720w.webp

https://pic1.zhimg.com/80/v2-435cd9d2a213616828f212df7add6d6c_720w.webp因为在配置通道模式时要设置“捕获/比较模式寄存器 1(PWMx_CCMR1) ”,其中的某些位要求通道关闭才可写入。所以在配置之前我们先关闭通道。
OC1CE:
我们选择不受ETRF影响。
https://pic3.zhimg.com/80/v2-6041d322be4ffdec3ca27ce57c8373b6_720w.webp
OC1M:
我们选择模式1。
https://pic3.zhimg.com/80/v2-d079d131f3cb657db7a8777a83404fee_720w.webp
OCnPE:
开启PWMn_CCR1寄存器的预装载功能。
https://pic2.zhimg.com/80/v2-0506ccc492e24998f9f2052fc66f011d_720w.webp
CC1S:
我们是输出波形。
https://pic4.zhimg.com/80/v2-625637c59ca2988408a5a7feb48f376b_720w.webp

https://pic1.zhimg.com/80/v2-a83f5d4f4dc9c3c7dc1d3d482a352bc0_720w.webp

通过对数据手册中对PWMx_CCMR1每一位的描述,我们将PWMx_CCMR1设置为0x68。
3.5 配置通道输出极性和使能

https://pic4.zhimg.com/80/v2-acd27331a06d1a8137a23878ebf2fc67_720w.webp

https://pic2.zhimg.com/80/v2-5d79f16407f74caedf10206d99168d8d_720w.webp

https://pic3.zhimg.com/80/v2-b91e4823434885330f623f1338f949ae_720w.webp

我们将PWMA_CCER1设置为:极性为高电平有效;开启比较输出功能。其他寄存器默认,我们设置为0。

3.6 设置PWM频率和计数时间

https://pic2.zhimg.com/80/v2-87f6f68e3dbcb4676036749f33d58ea1_720w.webp


我们使用边沿对齐模式。PWM输出波形的频率和系统时钟SYSClk、预分频系数PWMx_PSCR、自动重装载寄存器PWMx_ARR有关。
系统时钟SYSClk我们使用的系统时钟是系统自带的24MHz时钟。
预分频系数PWMx_PSCR
https://pic3.zhimg.com/80/v2-120ff5b862a85dd19d9a5a356a023532_720w.webp

https://pic2.zhimg.com/80/v2-e1eddfeed9f0941bdfe3038810c26615_720w.webp

PWMx_PSCR是16位寄存器,我们要先配置高位,再配置低位。
自动重装载寄存器PWMx_ARR
https://pic4.zhimg.com/80/v2-4775ab0ad5605d8bd070f1254fc8651f_720w.webp

PWMx_ARR是16位寄存器,我们要先配置高位,再配置低位。
https://pic2.zhimg.com/80/v2-55d11f27204b440fb6ff5660f23f5f09_720w.webp

根据公式,我们要输出的PWM频率为1000,可以设置:
https://pic2.zhimg.com/80/v2-03f8321d7b579df3e8896858b4100009_720w.webp

PWMx_PSCR+1为24,即PWM1_PSCR=23;PWMx_ARR+1为1000,即PWM1_ARR=999;
3.7 设置占空比时间

https://pic1.zhimg.com/80/v2-34c91dd9930d19e642d5d2c56a1baf0c_720w.webp

https://pic3.zhimg.com/80/v2-29c603ead18379f30eaba88f46a08aae_720w.webp

我们就是通过改变PWM1_CCR寄存器的值来控制占空比的,因为PWM1_ARR为999,我们也设置硬件上电时默认PWM1_CCR=999,即占空比为100%。

3.8 使能端口输出
使能PWMA_1P还需要2处使能,分别是使能端口输出、使能主输出。
https://pic3.zhimg.com/80/v2-85f2d040bccbfa065ef18de0c5a756a6_720w.webp

https://pic2.zhimg.com/80/v2-e26ac402f5d397e04275c0780a93a3c9_720w.webp

https://pic1.zhimg.com/80/v2-51ca59530c5bf1e3b748febfe2b8c6fc_720w.webp

https://pic4.zhimg.com/80/v2-82837b682f55c3e02a376bb0c0871d1b_720w.webp

因为我们只需要PWM1_1P输出PWM,所以使能ENO1P即可,其他默认,然后打开主输出使能。
3.9 开始计时

https://pic3.zhimg.com/80/v2-9208129dd183bf2a08f3e6ad58e1eaba_720w.webp

https://pic2.zhimg.com/80/v2-5b67af9777ca0935f7465f2f86fc9ce9_720w.webp

https://pic1.zhimg.com/80/v2-6d4ae1d0d7c701720191f8d2828637b8_720w.webp

打开CENA,启动计数器计数。
3.10 改变占空比

https://pic1.zhimg.com/80/v2-1a74dfd2d1fd71e63c88b42b2bfe14dc_720w.webp

之前提到过,改变PWM1_CCR的值,就能改变PWM1_CCR/PWM1_ARR的比值,从而改变占空比,我们在定时器0的中断函数中,改变PWM1_CCR的值。在Timer0_INTR()中,中断每1ms进入一次,每进入一次,Timer0.Cnt+1,当计时未满1000时,Timer0.Cnt持续自增,当Timer0.Cnt计满1000时,Timer0.Cnt开始自减,当减少到0时,又开始自增。在Timer0.Cnt自减自增的过程中,Timer0.Cnt都时刻将值赋值给PWM.DutyAdj(),以实时更改PWM的占空比,从而实现呼吸灯效果。
3.11 系统初始化

https://pic2.zhimg.com/80/v2-4c9605447a460b9485e547f83b2476f5_720w.webp

在StartUpInit.SYS_Ready()中依次进行GPIO初始化、中断初始化、定时器0初始化及PWM初始化。
https://pic4.zhimg.com/80/v2-721d6fb362764a72e505a26cf05abf03_720w.webp

之后系统一直在后台运行定时器中断,在定时器中断中控制占空比,System.Run()实际不运行任何操作。
四 实验现象
https://pic3.zhimg.com/v2-061d3bee20d481b52f353f1849a67bd6_b.webp



xxkj2010 发表于 2024-6-30 21:03:41

我以为STC03是STC新出的型号-----

soma 发表于 2024-6-30 21:26:38

写的真详细啊

标记重捕 发表于 2024-6-30 22:17:00

soma 发表于 2024-6-30 21:26
写的真详细啊

详细点好,以防忘记
页: [1]
查看完整版本: STC03 PWM实现呼吸灯