KF32 PWM与IC
一、介绍
PWM(脉冲调制)利用mcu的数字输出实现对模拟电路的控制,来输出不同的电压。可以用来控制灯的亮度,输出不同占空比,灯的亮度不同,可实现呼吸灯的功能;还可以输出不同占空比控制电机的转速。
使用pwm实现呼吸灯功能,在低电平灯会灭,只是时间短,肉眼观察不到。
IC输入捕获模块,可测量PWM的频率和占空比。
二、重要参数
-
频率(f)
单位时间内完成高低电平变化的次数。
-
占空比
一个脉冲周期内,高电平的时间占整个周期时间的比例。例:占空比为50%,25%,如下图:
三、定时器与PWM
1.先了解一下定时器计数模式(以Timer_A为例)
比较器TAxCCR0为16位周期寄存器,最大值为0FFFFh。
(1)增计数
计数器TAR可以增计数到TAxCCR0的值,增加到的最大值由TAxCCR0的值决定,增加到TAxCCR0后,再重新从0开始计数。例TA0CCR0=5000;计数器TAR由0增加到5000,再从0重新计数。
(2)连续计数
计数器TAR可以增计数到0FFFFh的值,再重新从0开始计数。
(3)增减计数
计数器TAR可以增计数到TAxCCR0的值,增加到的最大值由TAxCCR0的值决定,由0增加到TAxCCR0后,然后从TAxCCR0开始减少到0,再重新计数,周期为增模式的2倍。例TA0CCR0=5000;计数器TAR由0增加到5000,再从5000减少到0。
2.使用定时器产生PWM波形(增模式)
占空比调节(捕获/比较值)ccpx。
计数器TAR的值小于ccpx的值时,IO 输出高电平 ,计数器TAR的值大等于ccpx的值时,IO 输出低电平 ,这样就输出了方波。
改变ccpx的值就可以改变占空比的大小,而改变比较器TAxCCR0值,即改变周期。
四、程序
PWM
1.初始化
//配置为 重映射IO口功能模式 ,以PA0为例
GPIO_Write_Mode_Bits(GPIOA_SFR, GPIO_PIN_MASK_0, GPIO_MODE_RMP);
//引脚映射AF选择,需要查询手册确认
GPIO_Pin_RMP_Config(GPIOA_SFR, GPIO_Pin_Num_0 ,GPIO_RMP_AF11);
2.输出不同占空比波形
//入参为ccpx,通道,选择需要查手册,周期,占空比(0—100)
void CCPx_PWM_PPX_Duty(CCP_SFRmap *CCPx, uint32_t Channel, uint16_t Period, uint16_t Duty)
{
/* 定时器外设复位,启用外设时钟*/
TIM_Reset(CCPx);
/* PWM功能通道模式*/
CCP_PWM_Mode_Config(CCPx, Channel, CCP_PWM_MODE);
/* 配置CCP通道输出以控制PWM输出,高效 */
CCP_Channel_Output_Control(CCPx, Channel, CCP_CHANNEL_OUTPUT_PWM_ACTIVE);
/* 设置PWM占空比 */
CCP_Set_Compare_Result(CCPx, Channel, Duty);
/* 立即更新 */
GPTIM_Updata_Immediately_Config(CCPx, TRUE);
/* 配置更新使能 */
GPTIM_Updata_Enable(CCPx, TRUE);
/* GPTIM定时/计数模式选择*/
GPTIM_Work_Mode_Config(CCPx, GPTIM_TIMER_MODE);
/* 设置GPTIM初值 */
GPTIM_Set_Counter(CCPx, 0);
/* 设置GPTIM周期的大小*/
GPTIM_Set_Period(CCPx, Period);
/* 设置计时器预分频器值,为7分频*/
GPTIM_Set_Prescaler(CCPx, 7);
/* 工作模式选择*/
#if CCP_PWM_WORK == PWM_Edge_Out
/*增计数模式,即边缘对齐PWM信号*/
GPTIM_Counter_Mode_Config(CCPx, GPTIM_COUNT_UP_OF);
#else
/*增减计数模式,即中心对齐PWM信号*/
GPTIM_Counter_Mode_Config(CCPx, GPTIM_COUNT_UP_DOWN_OF);
#endif
/* 配置时钟*/
GPTIM_Clock_Config(CCPx, GPTIM_SCLK);
/* 定时器使能 */
GPTIM_Cmd(CCPx, TRUE);
}
IC
1.初始化
void CCPx_Capture_Mode_init(CCP_SFRmap *CCPx)
{
/* 设置计时器的预分频器值和捕获通道的模式*/
/* 定时器外设复位,启用外设时钟*/
TIM_Reset(CCPx);
/* 设置从模式:重置模式 */
GPTIM_Slave_Mode_Config(CCPx, GPTIM_SLAVE_RESET_MODE);
/* 设置触发源 : CH1 */
GPTIM_Trigger_Select_Config(CCPx, GPTIM_TRIGGER_CCPXCH1);
/* 设置捕获通道模式:捕获每个上升沿 */
CCP_Capture_Mode_Config(CCPx, CCP_CHANNEL_1, CCP_CAP_RISING_EDGE);
/* 立即更新 */
GPTIM_Updata_Immediately_Config(CCPx, TRUE);
/* 配置更新使能 */
GPTIM_Updata_Enable(CCPx, TRUE);
/*GPTIM定时/计数模式选择 */
GPTIM_Work_Mode_Config(CCPx, GPTIM_TIMER_MODE);
/* 设置GPTIM周期的大小 */
GPTIM_Set_Counter(CCPx, 0);
/*定时器预分频器值预分频器为119+1=120,主时钟为120M,1us计数一次*/
GPTIM_Set_Prescaler(CCPx, 119);
/* 增计数,溢出会生成中断标志 */
GPTIM_Counter_Mode_Config(CCPx, GPTIM_COUNT_UP_OF);
/* 选择 SCLK 作为时钟源 */
GPTIM_Clock_Config(CCPx, GPTIM_SCLK);
/* 定时器使能*/
GPTIM_Cmd(CCPx, TRUE);
}
void Ic_Init(void)
{
GPIO_Write_Mode_Bits(GPIOA_SFR, GPIO_PIN_MASK_0, GPIO_MODE_RMP);
GPIO_Pin_RMP_Config(GPIOA_SFR, GPIO_PIN_MASK_0, GPIO_RMP_AF1);
CCPx_Capture_Mode_init(CCP1_SFR);
}
2.获取占空比,频率
读取CCP捕捉寄存器
float DW_PLUSE_WIDTH;
DW_PLUSE_WIDTH= CCP_Get_Capture_Result(CCP18_SFR, CCP_CHANNEL_1);
占空比
float duty;
duty=DW_PLUSE_WIDTH/100;
频率:(系统时钟120MHz,120分频后为1MHz)
float Freq;
Freq=1000000/DW_PLUSE_WIDTH;