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

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

将占空比按照100的步进,定义成枚举类型,100表示10%占空比,200表示20%占空比,一次类推。

用结构体组织PWM的成员,其成员有占空比,PWM初始化函数,占空比调节函数,并使用extern将PWM结构体提供给外部调用。
下面介绍配置PWM功能的步骤。
3.2 设置P20复用PWM功能

PWM要求IO既能输出高电平,又能输出低电平,满足这样的要求的IO模式,可以选择准双向口或推挽输出,这两种模式都是可以输出高低电平的。 这里我选择的是准双向口功能。
3.3 通道输出脚选择


我们的实验目标是使用P20作为PWM1P的输出口,所以C1PS选择01,其他位设置为0即可。
3.4 配置通道模式

 因为在配置通道模式时要设置“捕获/比较模式寄存器 1(PWMx_CCMR1) ”,其中的某些位要求通道关闭才可写入。所以在配置之前我们先关闭通道。
OC1CE:
我们选择不受ETRF影响。

OC1M[2:0]:
我们选择模式1。

OCnPE:
开启PWMn_CCR1寄存器的预装载功能。

CC1S[1:0]:
我们是输出波形。


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



我们将PWMA_CCER1设置为: 极性为高电平有效; 开启比较输出功能。 其他寄存器默认,我们设置为0。
3.6 设置PWM频率和计数时间

我们使用边沿对齐模式。PWM输出波形的频率和系统时钟SYSClk、预分频系数PWMx_PSCR、自动重装载寄存器PWMx_ARR有关。
系统时钟SYSClk 我们使用的系统时钟是系统自带的24MHz时钟。
预分频系数PWMx_PSCR


PWMx_PSCR是16位寄存器,我们要先配置高位,再配置低位。
自动重装载寄存器PWMx_ARR

PWMx_ARR是16位寄存器,我们要先配置高位,再配置低位。

根据公式,我们要输出的PWM频率为1000,可以设置:

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


我们就是通过改变PWM1_CCR寄存器的值来控制占空比的,因为PWM1_ARR为999,我们也设置硬件上电时默认PWM1_CCR=999,即占空比为100%。
3.8 使能端口输出
使能PWMA_1P还需要2处使能,分别是使能端口输出、使能主输出。




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



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

之前提到过,改变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 系统初始化

在StartUpInit.SYS_Ready()中依次进行GPIO初始化、中断初始化、定时器0初始化及PWM初始化。

之后系统一直在后台运行定时器中断,在定时器中断中控制占空比,System.Run()实际不运行任何操作。
四 实验现象
|