芯源半导体CW32
直播中

jf_15653518

1年用户 7经验值
擅长:嵌入式技术
私信 关注
[资料]

【CW32饭盒派开发板试用体验】CW32高级定时器,频率占空比可调功能演示

演示视频

频率、占空比任意可调的ATIM PWM设计

本例程的功能为,通过按键的短按去调整PWM当前输出的频率,按键长按时则修改当前输出的占空比,设计精度为小数点后两位。TFTLCD上实时显示当前的PWM的频率和占空比信息。功能截图如下,演示视频如上
逻辑分析仪抓取的波形图如下图
图片.jpg

实物展示功能如下图

图片2.jpg

实现过程:
一、设计ATIM高级定时器输出PWM,输出通道为1B,对应IO口为PA7
ATIM初始化函数如下



void DriverAtimInit()
{
__RCC_ATIM_CLK_ENABLE();
ATIM_InitTypeDef ATIM_InitStruct;
ATIM_OCInitTypeDef ATIM_OCInitStruct;
ATIM_InitStruct.BufferState = DISABLE;
ATIM_InitStruct.ClockSelect = ATIM_CLOCK_PCLK;
ATIM_InitStruct.CounterAlignedMode = ATIM_COUNT_MODE_EDGE_ALIGN;
ATIM_InitStruct.CounterDirection = ATIM_COUNTING_UP;
ATIM_InitStruct.CounterOPMode = ATIM_OP_MODE_REPETITIVE;
ATIM_InitStruct.OverFlowMask = DISABLE;
ATIM_InitStruct.Prescaler = ATIM_Prescaler_DIV1; // 计数时钟1MHz
ATIM_InitStruct.ReloadValue = 6400;              // 溢出周期10ms
ATIM_InitStruct.RepetitionCounter = 0;
ATIM_InitStruct.UnderFlowMask = DISABLE;

ATIM_Init(&ATIM_InitStruct);

ATIM_OCInitStruct.BufferState = ENABLE;
ATIM_OCInitStruct.OCDMAState = DISABLE;
ATIM_OCInitStruct.OCInterruptSelect = ATIM_OC_IT_UP_COUNTER;
ATIM_OCInitStruct.OCInterruptState = ENABLE;
ATIM_OCInitStruct.OCMode = ATIM_OCMODE_PWM1;
ATIM_OCInitStruct.OCPolarity = ATIM_OCPOLARITY_NONINVERT;
ATIM_OC1BInit(&ATIM_OCInitStruct);

//ATIM_ITConfig(ATIM_CR_IT_OVE, ENABLE);
ATIM_CH1Config(ATIM_CHxB_CIE, ENABLE);
ATIM_SetCompare1B(5000);
ATIM_Cmd(ENABLE);
ATIM_CtrlPWMOutputs(ENABLE);
}


ATIM修改PWM频率跟占空比函数如下



void DriverAtimPwmSet( const uint32_t Freq,const uint16_t Duty)
{
uint16_t FreqSetVlaue = 0;
uint16_t DutySet = 0;
ATIM_InitTypeDef ATIM_InitStruct;
ATIM_OCInitTypeDef ATIM_OCInitStruct;
ATIM_InitStruct.BufferState = DISABLE;
ATIM_InitStruct.ClockSelect = ATIM_CLOCK_PCLK;
ATIM_InitStruct.CounterAlignedMode = ATIM_COUNT_MODE_EDGE_ALIGN;
ATIM_InitStruct.CounterDirection = ATIM_COUNTING_UP;
ATIM_InitStruct.CounterOPMode = ATIM_OP_MODE_REPETITIVE;
ATIM_InitStruct.OverFlowMask = DISABLE;
ATIM_InitStruct.Prescaler = ATIM_Prescaler_DIV1; 钟1MHz
ATIM_InitStruct.RepetitionCounter = 0;
ATIM_InitStruct.UnderFlowMask = DISABLE;
FreqSetVlaue = _64M_HZ/Freq;

ATIM_InitStruct.ReloadValue = FreqSetVlaue;
DutySet = ( FreqSetVlaue * Duty)/10000;
ATIM_Init(&ATIM_InitStruct);
ATIM_SetCompare1B(DutySet);```

}

按键需要支持长按短按,本例程采用KEY1为操作按键,main函数处理逻辑如下



int main(void )
{
uint32_t time;
uint32_t Freq=1000;
uint16_t Duty=5000;
uint32_t FreqPeriod = 10000;
uint16_t DutyPeriod=1000;
uint8_t state  =0;
SysClikInit();
GpioInit();
Uart_Init();
Lcd_Init();
Lcd_Clear(GRAY0); //清屏
Gui_DrawFont_GBK16(15,5,BLACK,GRAY0,"Current Freq");
numToString(Freq/1000);
Gui_DrawFont_GBK16(15,25,BLACK,GRAY0,strValue);
Gui_DrawFont_GBK16(45,25,BLACK,GRAY0,"k");
Gui_DrawFont_GBK16(15,45,BLACK,GRAY0,"Current Duty");
numToString(Duty/100);
Gui_DrawFont_GBK16(15,65,BLACK,GRAY0,strValue);
Gui_DrawFont_GBK16(45,65,BLACK,GRAY0,"%");

DriverAtimInit();
DriverAtimPwmSet(5188,8777);



DriverKeyStructInit(&keyStruct_S1,DriverS1_KeyRead);
while(1)
{

`
if(globlTimes - time >500)
{
CW_GPIOC->ODR ^= GPIO_PIN_13;
time = globlTimes ;
}



switch(DriverKeyCheck(&keyStruct_S1))
{
case ShortPressState:
Freq+=FreqPeriod;

if(Freq>=200000)
{
Freq = 1000;
}
Lcd_Clear(GRAY0); 	
Gui_DrawFont_GBK16(15,5,BLACK,GRAY0,"Current Freq");
numToString(Freq/1000);
Gui_DrawFont_GBK16(15,25,BLACK,GRAY0,strValue);
Gui_DrawFont_GBK16(45,25,BLACK,GRAY0,"k");
Gui_DrawFont_GBK16(15,45,BLACK,GRAY0,"Current Duty");
numToString(Duty/100);
Gui_DrawFont_GBK16(15,65,BLACK,GRAY0,strValue);
Gui_DrawFont_GBK16(45,65,BLACK,GRAY0,"%");

break;

case LongPressState :
Duty+=DutyPeriod;

if(Duty>=10000)
{
Duty = 500;
}
Lcd_Clear(GRAY0);



Gui_DrawFont_GBK16(15,5,BLACK,GRAY0,"Current Freq");
numToString(Freq/1000);
Gui_DrawFont_GBK16(15,25,BLACK,GRAY0,strValue);
Gui_DrawFont_GBK16(45,25,BLACK,GRAY0,"k");		
Gui_DrawFont_GBK16(15,45,BLACK,GRAY0,"Current Duty");
numToString(Duty/100);
Gui_DrawFont_GBK16(15,65,BLACK,GRAY0,strValue);
Gui_DrawFont_GBK16(45,65,BLACK,GRAY0,"%");

break;

default:break;

}

}
return 0;
}











更多回帖

发帖
×
20
完善资料,
赚取积分