如月之恒,如日之升。
1、任务计划
(1)查找高级定时器对应的时钟
(2)找到高级定时器时钟对应的通道
(3)查找高级定时器通道对应的IO口
(4)今天务必调出六路互补的、占空比为40%、带死区的PWM波,把课题二结束。
2、计划完成度
(1)高级定时器对应的时钟只有两个,TIM1和TIM8。
(2)每个高级定时器都有四个通道。
TIM1_OC1Init:初始化TIM1通道1;
TIM1_OC2Init:初始化TIM1通道2;
TIM1_OC3Init:初始化TIM1通道3;
TIM1_OC4Init:初始化TIM1通道4;
(3)高级定时器通道对应的IO口为:
TIM1_CH1:PA8,PE9; TIM_CH1N:PA7,PB13,PE8;
TIM1_CH2:PA9,PE11;
TIM_CH2N:PB0,PB14,PE10;
TIM1_CH3:PA10,PE13;
TIM_CH3N:PB1,PB15,PE12;
TIM1_CH4:PA11,PE14;
TIM8_CH1:PC6,PI5; TIM_CH1N:PA5,PA7,PH13;
TIM8_CH2:PC7,PI6; TIM_CH2N:PB0,PB14,PH14;
TIM8_CH3:PC8,PI7; TIM_CH3N:PB1,PB15,PH15;
TIM8_CH4:PC9,PI8;
(4)经过一下午和晚上的调试,调试程序、示波器和导线在板子与示波器之间的连接。最终调出来了符合要求的六路互补的、占空比为40%、带死区的PWM波。
[1]我刚开始的时候,在main函数里面是这样写的
int main(void)
{
delay_init(168);
uart_init(115200);
TIM8_PWM_Init(10000-1,8400-1);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组
while(1)
{
delay_ms(10);
TIM_SetAutoreload(TIM8,10000); //设置自动重装载系数
TIM_SetCompare1(TIM8,4000); //设置捕获比较值
}
}
后来把
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组
放到了最前面,因为很多时候,语序的问题也会影响输出。
[2]TIM8_CH1可以调试出来40%的PWM波,但是它的互补通道是一条直线,没有波形。后来学姐帮我检查的时候发现,我在初始化IO口的时候,通道1对应的IO口PA5是单独初始化的,但是通道1的互补通道对应的IO口PC6是和PC7、PC8一初始化的。
我们就把每个IO口分别单独初始化
GPIO_PinAFConfig(GPIOA,GPIO_PinSource5,GPIO_AF_TIM8);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource0,GPIO_AF_TIM8);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource1,GPIO_AF_TIM8);
GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_TIM8);
GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_TIM8);
GPIO_PinAFConfig(GPIOC,GPIO_PinSource8,GPIO_AF_TIM8);
就可以发现,每个信号都可以输出路互补的波形了。
[3]调出波形来之后,学姐继续检查我的程序,说我的main函数的循环语句可以去掉。
因为在pwm.c文件中,我已经设置了自动重装载值
TIM_TimeBaseStructure.TIM_Period=arr;
它和
TIM_SetAutoreload(TIM8,10000);
作用是一样的,不用重复定义。
另外pwm.c的中
TIM_OCInitStruct.TIM_Pulse=4000;
和main函数中的
TIM_SetCompare1(TIM8,4000);
作用是一样的。
[4]这个任务做完之后,学姐让我们用PWM写一下呼吸灯的程序。
这次用通用定时器就好。写过高级定时器之后,就会觉得只用通用定时器写一个呼吸灯是相对轻松的。
基本的步骤和上次一样:
*先选择一个和PF9(灯)或PF10(灯)对应的定时器和通道。
*初始化相应的IO口和定时器的功能
*在main函数里面写相应的比较值函数即可。