KF32 PWM与IC

一、介绍

PWM(脉冲调制)利用mcu的数字输出实现对模拟电路的控制,来输出不同的电压。可以用来控制灯的亮度,输出不同占空比,灯的亮度不同,可实现呼吸灯的功能;还可以输出不同占空比控制电机的转速。

使用pwm实现呼吸灯功能,在低电平灯会灭,只是时间短,肉眼观察不到。

IC输入捕获模块,可测量PWM的频率和占空比。

二、重要参数

  1. 频率(f)

单位时间内完成高低电平变化的次数。

  1. 占空比

一个脉冲周期内,高电平的时间占整个周期时间的比例。例:占空比为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;