打印
[STM32F1]

STM32高级定时器TIM1产生两路互补的PWM波

[复制链接]
1159|24
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
测试环境:Keil 5.20.0.0 STM32F103RBT6 固件库版本:STM32F10x_StdPeriph_Lib_V3.5.0(2011)

使用特权

评论回复
沙发
原来是wjc|  楼主 | 2021-10-25 23:33 | 只看该作者
本文使用TIM1的通道1,通道2,产生两路1khz,死区时间1us的互补PWM波。

使用特权

评论回复
板凳
原来是wjc|  楼主 | 2021-10-25 23:34 | 只看该作者
所使用的IO口:由下图知,我们使用引脚为PA9,PA10,互补输出使用PB14,PB15

使用特权

评论回复
地板
原来是wjc|  楼主 | 2021-10-25 23:35 | 只看该作者
所使用的IO口:由下图知,我们使用引脚为PA9,PA10,互补输出使用PB14,PB15

使用特权

评论回复
5
原来是wjc|  楼主 | 2021-10-25 23:35 | 只看该作者

使用特权

评论回复
6
原来是wjc|  楼主 | 2021-10-25 23:38 | 只看该作者
部分代码如下:
1 /* 配置TIM1复用输出PWM时用到的I/O */ 2 static void TIM1_GPIO_Config(void) 3 { 4 GPIO_InitTypeDef GPIO_InitStructure; 5 6 /* TIM1 clock enable */ 7 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); 8 9 /* GPIOA and GPIOB clock enable */10 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);11 12 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;13 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;14 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;15 16 GPIO_Init(GPIOA, &GPIO_InitStructure);17 18 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_15;19 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;20 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;21 22 GPIO_Init(GPIOB, &GPIO_InitStructure);23 24 }
初始化IO

使用特权

评论回复
7
原来是wjc|  楼主 | 2021-10-25 23:43 | 只看该作者
初始化定时器功能配置
1 u16 CCR2_Val = 500; 2 u16 CCR3_Val = 500;//占空比,周期为1000 3  4 /*配置TIM1输出的PWM信号的模式,如周期、极性、占空比 */ 5 void TIM1_Mode_Config(void) 6 { 7     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure; 8     TIM_BDTRInitTypeDef      TIM1_BDTRInitStruct; 9     TIM_OCInitTypeDef        TIM_OCInitStructure;10 11     /* Time base configuration */12     TIM_TimeBaseStructure.TIM_Period = 1000-1; //计数周期,向上记到此数,计数值清零13     TIM_TimeBaseStructure.TIM_Prescaler = 72-1;//定时器分频系数,Ftimer = 72M/(TIM_Prescaler+1) = 1ms14     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//与死区时间分频有关15     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式16     TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);17     18     /****** 配置BDTR寄存器,配置死区时间****************/19     /*20        定时器时钟 72M   TIM_ClockDivision = TIM_CKD_DIV1时,  Tdts = 13.89ns21        0 - 1.764us  用算法一22        1.778us - 3.505us  用算法二23        3.556us - 7.000us  用算法三 24        7.1117us - 14us    用算法四25        需要更长时间,使用TIM_ClockDivision分频26     */27     TIM1_BDTRInitStruct.TIM_OSSRState = TIM_OSSRState_Disable;28     TIM1_BDTRInitStruct.TIM_OSSIState = TIM_OSSIState_Disable;29     TIM1_BDTRInitStruct.TIM_LOCKLevel = TIM_LOCKLevel_OFF;30     TIM1_BDTRInitStruct.TIM_DeadTime = 205; //死区时间  72:1us 172:3us 205:5us31     TIM_BDTRConfig(TIM1,&TIM1_BDTRInitStruct);32  33 //    TIM1->BDTR |= 72;   //设置死区  注:上面那种方法也可以,这种快且简单34     35      /* PWM1 Mode configuration: Channel2 */36      TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;//PWM2模式37      TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能38      TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;//比较互补输出使能39      TIM_OCInitStructure.TIM_Pulse = CCR2_Val;   //比较值,即占空比40      TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  //输出极性41      TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;//互补输出极性42      TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;//指定空闲状态下的TIM输出比较的引脚状态。43      TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;//指定空闲状态下的TIM互补输出比较的引脚状态。44      TIM_OC2Init(TIM1, &TIM_OCInitStructure);   //初始化通道二比较输出45      TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);      //配置通道二,自动重装载使能46 47 48     /* PWM1 Mode configuration: Channel3 */49     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;50     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;51     TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;52     TIM_OCInitStructure.TIM_Pulse = CCR3_Val;53     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;54     TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;55     TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;56     TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;      57     TIM_OC3Init(TIM1, &TIM_OCInitStructure);58     TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);    59 60     TIM_ARRPreloadConfig(TIM1, ENABLE);//重载装载值 ENABLE 立即生效,DISABLE 下一个比较周期生效61 62     /* TIM1 enable counter */63     TIM_Cmd(TIM1, ENABLE);//使能定时器164     65     TIM_CtrlPWMOutputs(TIM1, ENABLE);//使能PWM外围输出    66 }

使用特权

评论回复
8
原来是wjc|  楼主 | 2021-10-25 23:44 | 只看该作者
1 int main(void) 2 { 3 TIM1_GPIO_Config(); 4 TIM1_Mode_Config(); 5 while(1) 6 { 7 TIM1->CCR2 = CCR2_Val; 8 TIM1->CCR3 = CCR3_Val; 9 CCR2_Val+=5;10 CCR3_Val+=10;11 if(CCR2_Val>900) CCR2_Val = 100;12 if(CCR3_Val>900) CCR3_Val = 100; 13 Delay_mS(200);14 }15 }
main函数

使用特权

评论回复
9
原来是wjc|  楼主 | 2021-10-25 23:44 | 只看该作者
关于死区时间计算:

先贴几张关于TIM时钟的图:

第一张图:关于死区时间分频因子。(代码见,初始化定时器功能配置代码部分第14行所示)

使用特权

评论回复
10
原来是wjc|  楼主 | 2021-10-25 23:45 | 只看该作者

使用特权

评论回复
11
原来是wjc|  楼主 | 2021-10-25 23:46 | 只看该作者
第二张图:死区时间计算

168586176d1467eda6.png (72.17 KB )

168586176d1467eda6.png

使用特权

评论回复
12
原来是wjc|  楼主 | 2021-10-25 23:47 | 只看该作者
   定时器1时钟挂在APB2总线上,时钟为72M   当TIM_ClockDivision = TIM_CKD_DIV1时,  Tdts = 1/72M = 13.89ns
       0 - 1.764us  用算法一
       1.778us - 3.505us  用算法二
       3.556us - 7.000us  用算法三
       7.1117us - 14us    用算法四
       需要更长时间,使用TIM_ClockDivision分频后(可2分,4分频),设置死区时间。

使用特权

评论回复
13
原来是wjc|  楼主 | 2021-10-25 23:48 | 只看该作者
测试数据:

实验现象:产生了两路死区时间为1us的互补PWM信号,其频率都是1kHz,占空比在10% - 90%不断变化,通道三比通道二变化要快。

死区时间(以通道二为例):(黄:PA10  绿:PB15)

使用特权

评论回复
14
原来是wjc|  楼主 | 2021-10-25 23:48 | 只看该作者

使用特权

评论回复
15
原来是wjc|  楼主 | 2021-10-25 23:50 | 只看该作者
通道二抓拍波形  (黄:PA10  绿:PB15)

使用特权

评论回复
16
原来是wjc|  楼主 | 2021-10-25 23:51 | 只看该作者

使用特权

评论回复
17
原来是wjc|  楼主 | 2021-10-25 23:51 | 只看该作者
通道三抓拍波形  (黄:PA9 绿:PB14)

使用特权

评论回复
18
原来是wjc|  楼主 | 2021-10-25 23:52 | 只看该作者

使用特权

评论回复
19
原来是wjc|  楼主 | 2021-10-25 23:53 | 只看该作者

使用特权

评论回复
20
香水城| | 2021-10-27 09:47 | 只看该作者
楼主辛苦了!

谢谢分享!

如果可能 尽量基于Cube库来着手开发,毕竟很多系列都没有传统标准库而只有cube库了。谢谢!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

68

主题

905

帖子

0

粉丝