123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573 |
- #include "SN_PWM.h"
- /*
- 文件名:SN_PWM.c/.h
- 作者: SN_FAE_黄泽洪
- 免责声明:无版权,可随意传播和篡改,该代码仅供开发参考,如需使用请自行验证
- 本人不担负商业使用上带来的风险。
- */
- /* SN_PWM_TIM3_OUT_init模块的使用方法:
- 方法一:初始定时器3的pwm输出:
- int main(void){
-
- SN_SYSCLK_set(SYSCLK_48MHZ);
- std_delay_init();
- SN_PWM_TIM3_OUT_init(TIM3_CH1_PA0|TIM3_CH2_PA4 ,1000); //设置定时器3通道1 和 通道2 输出占空比数是1000的方波,输出io分别是PA0 ,PA4
-
- while(1){
- std_delayms(500);
- SN_PWM_TIMx_CH_Duty(TIM3,TIM_CHANNEL_1,3000); //调整通道1 输出的占空比大小
- }
- }
-
-
- 方法二:初始定时器1的pwm输出:
- int main(void){
-
- SN_SYSCLK_set(SYSCLK_48MHZ);
- std_delay_init();
- SN_PWM_TIM1_OUT_init(TIM1_CH1_PA0|TIM1_CH2_PA1 ,1000); //设置定时器3通道1 和 通道2 输出占空比数是1000的方波,输出io分别是PA0 ,PA4
-
- while(1){
- std_delayms(500);
- SN_PWM_TIMx_CH_Duty(TIM1,TIM_CHANNEL_1,3000); //调整通道1 输出的占空比大小
- }
- }
-
- 方法三: 初始定时器1 的互补PWM输出
- //注意:相关死区时间和空闲电平要在SN_PWM.h 文件中设定
- main.c文件:
- uint16_t EN = 0 ; //仿真中修改该变量,控制PWM输出或关闭
- uint32_t DUT = 1;
- int main(void){
-
- SN_SYSCLK_set(SYSCLK_48MHZ);
- std_delay_init();
- SN_PWM_TIM1_OUT_Complementary(TIM1_CH2N_PA0); //设置互补通道,注意要先设定互补通道后,才能初始化pwm输出
- SN_PWM_TIM1_OUT_init(TIM1_CH2_PA1,1000); //设置定时器3通道1 和 通道2 输出占空比数是1000的方波,输出io分别是PA0 ,PA4
- while(1){
- std_delayms(500);
-
- if(EN){
- SN_PWM_TIMx_CH_Duty(TIM1,TIM_CHANNEL_2,100*(DUT++)); //调整通道2 输出的占空比大小
- SN_TIM_PWM_Start(TIM1,TIM_CHANNEL_2);
- }else{
- SN_TIM_PWM_Stop(TIM1,TIM_CHANNEL_2);
- }
-
-
-
- }
- }
-
-
- */
- //全局变量是否开启tim1的pwm互补通道
- static uint8_t SN_G_OUTPUT_NEGTIVE = 0;
- //TIM3通道和io映射表
- const static uint16_t TIM3_CH_list[10] = {
- GPIO_PIN_0,
- GPIO_PIN_3,
- GPIO_PIN_4,
- GPIO_PIN_5,
- GPIO_PIN_6,
- GPIO_PIN_7,
- GPIO_PIN_0,
- GPIO_PIN_4,
- GPIO_PIN_5
- };
-
- /*
- 函数名称:SN_PWM_TIM3_OUT_init()
- 功能: 初始化PWM多通道输出
- @参数:通道编码 :
- @TIM3_CH1_PA0
- @TIM3_CH3_PA3
- @TIM3_CH2_PA4
- @TIM3_CH1_PA5
- @TIM3_CH3_PA6
- @TIM3_CH2_PA7
- @TIM3_CH1_PB0
- @TIM3_CH4_PB4
- @TIM3_CH3_PB5
- @TIM3_CH1_x|TIM3_CH1_y|TIM3_CH1_z
-
- @参数:占空比
- 0x0000 - 0xffff
-
- @返回值: 开启的通道
- 注意:同时初始化两个相同通道的不同io,最开始初始的那个有效
- */
- uint8_t SN_PWM_TIM3_OUT_init(uint16_t CHANNEL,uint32_t Duty_value){
- //设置IO
- uint8_t i ,CH = 0 ;
- uint16_t CHANNEL1 = CHANNEL;
-
- std_gpio_init_t tim3_gpio_init = {0};
- //前6个是PA ,后面3个是PB,最后一个是PC
- if(( CHANNEL & 0X003F )!= 0){std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOA);}
- if(( CHANNEL & 0X01F0 )!= 0){std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOB);}
- tim3_gpio_init.mode = GPIO_MODE_ALTERNATE;
- tim3_gpio_init.pull = GPIO_NOPULL;
- tim3_gpio_init.alternate = GPIO_AF3_TIM3;
-
- for(i = 0 ; i < 10 ; i++){
- if((CHANNEL1 & 0x0001 ) == 1 ){
- if(i < 6){
- tim3_gpio_init.pin = TIM3_CH_list[i];
- std_gpio_init(GPIOA, &tim3_gpio_init);
- }else if(i > 6 && i < 9){
- tim3_gpio_init.pin = TIM3_CH_list[i];
- std_gpio_init(GPIOB, &tim3_gpio_init);
- }else{
- tim3_gpio_init.pin = TIM3_CH_list[i];
- std_gpio_init(GPIOC, &tim3_gpio_init);
- }
- }
- CHANNEL1 >>= 1;
- }
-
-
-
- //设置定时器3
- std_tim_basic_init_t basic_init_struct = {0};
- std_tim_output_compare_init_t oc_config_struct = {0};
-
- /* TIM3时钟使能 */
- std_rcc_apb1_clk_enable(RCC_PERIPH_CLK_TIM3);
-
- /* 配置TIM3计数器参数 */
- basic_init_struct.prescaler = TIM3_PRESCALER_VALUE; //设置定时器的预分频
- basic_init_struct.period = TIM3_PERIOD_VALUE; //设置定时器的周期
- basic_init_struct.clock_div = TIM3_CLOCK_DTS_DIVx; //设置定时器的分频
- std_tim_init(TIM3, &basic_init_struct); //初始化定时器
-
- /* 配置TIM3为工作模式1 */
- std_tim_work_mode1_enable(TIM3);
-
- /* 配置通道1输出模式为PWM1模式 */
- oc_config_struct.output_compare_mode = TIM_OUTPUT_MODE_PWM1; //使用PWM模式一
- oc_config_struct.output_pol = TIM_OUTPUT_POL_HIGH; //设设置PWM输出的有效电平极性
- oc_config_struct.pulse = Duty_value; //设置通道1PWM的占空比 默认初始化 0
- oc_config_struct.output_state = TIM_OUTPUT_ENABLE; //设能通道
- if(( CHANNEL & 0x0049 ) != 0){
- std_tim_output_compare_init(TIM3, &oc_config_struct, TIM_CHANNEL_1);
- CH |= 0x01;
- }
-
- if(( CHANNEL & 0x0024 ) != 0){
- std_tim_output_compare_init(TIM3, &oc_config_struct, TIM_CHANNEL_2);
- CH |= 0x02;
- }
-
- if(( CHANNEL & 0x0112 ) != 0){
- std_tim_output_compare_init(TIM3, &oc_config_struct, TIM_CHANNEL_3);
- CH |= 0x04;
- }
-
- if(( CHANNEL & 0x0080 ) != 0){
- std_tim_output_compare_init(TIM3, &oc_config_struct, TIM_CHANNEL_4);
- CH |= 0x08;
- }
-
- std_tim_enable(TIM3);
- return CH;
- }
- //TIM1通道和io映射表
- const static uint16_t TIM1_CH_list[10] = {
- GPIO_PIN_0, //PA0 0
- GPIO_PIN_1, //PA1 1
- GPIO_PIN_1, //PA1 2
- GPIO_PIN_5, //PA5 3
- GPIO_PIN_0, //PB0 4
- GPIO_PIN_1, //PB1 5
- GPIO_PIN_2, //PB2 6
- GPIO_PIN_2, //PB2 7
- GPIO_PIN_7, //PB7 8
- GPIO_PIN_1, //PC1 9
- };
-
- /*
- 函数名称:SN_PWM_TIM1_OUT_init()
- 功能: 初始化PWM多通道输出
- @参数:通道编码 :
- TIM1_CH1_PA0
- TIM1_CH2_PA1
- TIM1_CH3_PA1
- TIM1_CH2_PA5
- TIM1_CH2_PB0
- TIM1_CH4_PB1
- TIM1_CH1_PB2
- TIM1_CH3_PB2
- TIM1_CH4_PB7
- TIM1_CH2_PC1
- 支持并集
- @参数: 开启的默认占空比(所有的通道pwm占空比一样)
- @参数: 是否使能互补PWM通道
- @返回值: 开启的通道
- 注意:同时初始化两个相同通道的不同io,最开始初始的那个有效
- */
- uint8_t SN_PWM_TIM1_OUT_init(uint16_t CHANNEL,uint32_t Duty_value){
- //设置IO
- uint8_t i ,CH = 0 ;
- uint16_t CHANNEL1 = CHANNEL;
- std_gpio_init_t tim1_gpio_init = {0};
-
- //选择不同的IO时钟
- if(( CHANNEL & 0X000F )!= 0){std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOA);}
- if(( CHANNEL & 0X01F0 )!= 0){std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOB);}
- if(( CHANNEL & 0x0200 )!= 0){std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOC);}
- tim1_gpio_init.mode = GPIO_MODE_ALTERNATE;
- tim1_gpio_init.pull = GPIO_NOPULL;
-
- for( i = 0; i < 10; i++){
-
- if(CHANNEL1 & 0x0001){
-
- if(i<4){
-
- if(i == 2){tim1_gpio_init.alternate = GPIO_AF4_TIM1;}else{tim1_gpio_init.alternate = GPIO_AF2_TIM1;}
- tim1_gpio_init.pin = TIM1_CH_list[i];
- std_gpio_init(GPIOA, &tim1_gpio_init);
- }else if(i > 3 && i < 9 ){
-
- if(i == 4 || i == 6){tim1_gpio_init.alternate = GPIO_AF2_TIM1;}else{tim1_gpio_init.alternate = GPIO_AF4_TIM1;}
- tim1_gpio_init.pin = TIM1_CH_list[i];
- std_gpio_init(GPIOB, &tim1_gpio_init);
-
- }else if(i == 9){
-
- tim1_gpio_init.alternate = GPIO_AF2_TIM1;
- tim1_gpio_init.pin = TIM1_CH_list[i];
- std_gpio_init(GPIOC, &tim1_gpio_init);
- }
-
- }
- CHANNEL1 >>= 1;
- }
-
-
- //TIM1
- std_tim_basic_init_t basic_init = {0};
- std_tim_output_compare_init_t output_init = {0};
- std_tim_break_init_t break_config = {0};
-
- /* TIM1时钟使能 */
- std_rcc_apb2_clk_enable(RCC_PERIPH_CLK_TIM1);
-
- /* 配置TIM1计数器参数 */
- basic_init.counter_mode = TIM_COUNTER_MODE_UP;
- basic_init.period = TIM1_PERIOD_VALUE;
- basic_init.clock_div = TIM1_CLOCK_DTS_DIV1;
- basic_init.prescaler = TIM1_PRESCALER_VALUE;
- std_tim_init(TIM1, &basic_init);
-
- /* 配置通道1输出模式为PWM1模式 */
- output_init.output_compare_mode = TIM_OUTPUT_MODE_PWM_x; //PWM模式
- output_init.pulse = Duty_value; //pwm占空比
- output_init.output_pol = TIM_OUTPUT_POL_x; //通道输出有效极性
- output_init.output_negtive_pol = TIM_OUTPUT_NEGTIVE_POL_x; //互补输出有效极性
- output_init.output_idle_state = TIM_OUTPUT_IDLE_x; //通道输出空闲电平
- output_init.output_negtive_idle_state = TIM_OUTPUT_NEGTIVE_IDLE_x; //互补通道输出空闲电平
- output_init.output_state = TIM_OUTPUT_ENABLE;
-
- if(SN_G_OUTPUT_NEGTIVE){
- output_init.output_negtive_state = TIM_OUTPUT_NEGTIVE_ENABLE;
- }else{
- output_init.output_negtive_state = TIM_OUTPUT_NEGTIVE_DISABLE;
- }
-
- if((CHANNEL & 0x0041) != 0){
- std_tim_output_compare_init(TIM1, &output_init, TIM_CHANNEL_1);
- std_tim_ccxn_channel_enable(TIM1, TIM_CHANNEL_1);
- CH |= 0x01;
- }
-
- if((CHANNEL & 0x021A) != 0){
- std_tim_output_compare_init(TIM1, &output_init, TIM_CHANNEL_2);
- std_tim_ccxn_channel_enable(TIM1, TIM_CHANNEL_2);
- CH |= 0x02;
-
- }
-
-
- if((CHANNEL & 0x0084) != 0){
- std_tim_output_compare_init(TIM1, &output_init, TIM_CHANNEL_3);
- std_tim_ccxn_channel_enable(TIM1, TIM_CHANNEL_3);
- CH |= 0x04;
- }
-
- if((CHANNEL & 0x0120) != 0){
- std_tim_output_compare_init(TIM1, &output_init, TIM_CHANNEL_4);
- std_tim_ccxn_channel_enable(TIM1, TIM_CHANNEL_4);
- CH |= 0x08;
- }
-
-
- // /* 配置断路输入源为GPIO */
- std_tim_brk_source_enable(TIM1, TIM_BREAK_INPUT_SRC_COMP2);
- std_tim_set_brk_pol(TIM1, TIM_BREAK_INPUT_SRC_COMP2, TIM_BREAK_INPUT_POL_HIGH);
-
- /* 配置断路输入参数 */
- break_config.off_state_run_mode = TIM_OSSR_ENABLE;
- break_config.off_state_idle_mode = TIM_OSSI_ENABLE;
- break_config.lock_level = TIM_LOCK_LEVEL_OFF;
- break_config.dead_time = 0x3F; //死区时间
- break_config.break_state = TIM_BREAK_ENABLE ; // TIM_BREAK_ENABLE TIM_BREAK_DISABLE
- std_tim_bdt_init(TIM1, &break_config);
-
-
-
-
-
- std_tim_arrpreload_enable(TIM1); /* 使能自动重加载 */
- std_tim_moen_enable(TIM1); /* 使能输出 */
- std_tim_onepulse_disable(TIM1); /* 关闭单脉冲输出 */
- std_tim_enable(TIM1); /* 使能计数 */
-
- return CH;
- }
- //TIM1互补通道和io映射表
- const static uint16_t TIM1_CHN_list[10] = {
- GPIO_PIN_0, //PA0 0
- GPIO_PIN_0, //PA0 1
- GPIO_PIN_3, //PA3 2
- GPIO_PIN_4, //PA4 3
- GPIO_PIN_1, //PB1 4
- GPIO_PIN_1, //PB1 5
- GPIO_PIN_2, //PB2 6
- GPIO_PIN_5, //PB2 7
- GPIO_PIN_7, //PB7 8
- GPIO_PIN_7, //PB7 9
- };
- /*
- 函数名称:SN_PWM_TIM1_OUT_Complementary
- 功能: 初始化PWM多通道互补输出
- @参数:通道编码 :
- TIM1_CH2N_PA0
- TIM1_CH3N_PA0
- TIM1_CH3N_PA3
- TIM1_CH2N_PA4
- TIM1_CH1N_PB1
- TIM1_CH2N_PB1
- TIM1_CH1N_PB2
- TIM1_CH3N_PB5
- TIM1_CH2N_PB7
- TIM1_CH1N_PB7
- @返回值: 开启的通道
- 注意:同时初始化两个相同通道的不同io,最开始初始的那个有效
- */
- void SN_PWM_TIM1_OUT_Complementary(uint16_t CHANNEL_N){
-
- uint8_t i ;
- uint16_t CHANNEL1 = CHANNEL_N;
- std_gpio_init_t gpio_init = {0};
- //初始gpio时钟
- if( CHANNEL_N & 0x000f ){std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOA);}
- if( CHANNEL_N & 0x03f0 ){std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOB);}
- gpio_init.mode = GPIO_MODE_ALTERNATE;
- gpio_init.pull = GPIO_NOPULL;
-
-
- //设置复用选项
- for(i = 0 ; i < 10 ;i++){
-
- if(CHANNEL1 & 0x0001){
-
- if(i<4){
- gpio_init.alternate = GPIO_AF2_TIM1;
- if(i == 0){gpio_init.alternate = GPIO_AF4_TIM1;}
- if(i == 1){gpio_init.alternate = GPIO_AF5_TIM1;}
- gpio_init.pin = TIM1_CHN_list[i];
- std_gpio_init(GPIOA, &gpio_init);
-
- }else if(i > 3 && i < 10 ){
- if(i == 5 || i == 6 || i == 9){gpio_init.alternate = GPIO_AF3_TIM1;}else{gpio_init.alternate = GPIO_AF2_TIM1;}
- gpio_init.pin = TIM1_CHN_list[i];
- std_gpio_init(GPIOB, &gpio_init);
-
- }
-
- }
- CHANNEL1 >>= 1;
- }
- SN_G_OUTPUT_NEGTIVE = 1;
- }
- /*
- 函数名称:TIM1_PWM_Start
- 功能:开启tim的PWM输出
- 参数:定时器 @TIM1
- @TIM3
- 参数:通道名称
- @TIM_CHANNEL_1
- @TIM_CHANNEL_2
- @TIM_CHANNEL_3
- @TIM_CHANNEL_4
- 返回值:无
- */
- void SN_TIM_PWM_Start(TIM_t *timx ,uint8_t TIM_CHANNEL_x){
- std_tim_ccx_channel_enable(timx, TIM_CHANNEL_x);
- if(timx == TIM1)std_tim_ccxn_channel_enable(TIM1, TIM_CHANNEL_x);
- std_tim_enable(timx);
- }
- /*
- 函数名称:TIM1_PWM_Start
- 功能:关闭tim的PWM输出
- 参数:定时器 @TIM1
- @TIM3
- 参数:通道名称
- @TIM_CHANNEL_1
- @TIM_CHANNEL_2
- @TIM_CHANNEL_3
- @TIM_CHANNEL_4
- 返回值:无
- */
- void SN_TIM_PWM_Stop(TIM_t *timx,uint8_t TIM_CHANNEL_x){
- std_tim_ccx_channel_disable(timx, TIM_CHANNEL_x);
- if(timx == TIM1)std_tim_ccxn_channel_disable(TIM1, TIM_CHANNEL_x);
- std_tim_disable(timx);
- }
- /*
- 函数名称:SN_PWM_TIMx_CH_Duty()
- 功能: 设置单通道占空比
- @参数: 定时器
- @参数: 设置通道号
- @TIM_CHANNEL_1
- @TIM_CHANNEL_2
- @TIM_CHANNEL_3
- @TIM_CHANNEL_4
- @参数: 占空比数
- 0x0000 - 0xffff
- @返回值: 无
- */
- void SN_PWM_TIMx_CH_Duty(TIM_t *timx,uint32_t TIM_CHANNEL_x ,uint32_t Duty_value){
- std_tim_set_ccx_value(timx, TIM_CHANNEL_x , Duty_value);
- }
- /*
- 函数名称:SN_PWM_TIM3_CH_mode(uint8_t mod)
- 功能: 设置定时器3,PWM精度,和通道数量
- @参数:
- @TIM3_CH_MOD_16BIT_CH1_2
- @TIM3_CH_MOD_8BIT_CH1_1_2_3_4
- 0:工作模式 0,2 通道输入,2 通道输出模式,精度为 16bit
- 默认:1:工作模式 1,2 通道输入,4 通道输出模式,精度为 8bit
- @返回值: 无
- */
- void SN_PWM_TIM3_CH_mode(uint8_t mod){
-
- if(mod){
- std_tim_work_mode1_enable(TIM3);
- }else{
- std_tim_work_mode1_disable(TIM3);
- }
- }
|