制作出来的实物图如下:
(一) 功能说明 用L298N驱动一台直流减速电机,引脚IN1,IN2可用于PWM控制。仅用STM32的两个端口给出PWM信号控制IN1,IN2即可实现正反转、加减速等动作。 (二) 硬件说明: 控制板:STM32F03C8T6最小系统;
直流电机驱动板:L298N是SGS公司的产品,比较常见的是15脚MulTIwatt封装的L298N,内部同样包含4通道逻辑驱动电路。可以方便的驱动两个直流电机,或一个两相步进电机。
(三) 资源配置: STM32F03C8T6使用端口定义 | | | | | | | | | | | 控制板带的LED指示灯,周期性的变化,每变化一次,电机的转运方向变化一次。 由TIM3中断定时控制。 | |
(四) 软件实现 1:通用定时器TIM3的中断定时实现步骤 ① 使能定时器时钟。 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); ② 初始化定时器,配置【ARR自动装载值,PSC预分频系数。】 TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure); ③ 开启定时器中断,配置NVIC。 TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); NVIC_Init(&NVIC_InitStructure); ④ 使能定时器。 TIM_Cmd(TIM3,ENABLE); //实际是配置 控制寄存器1 (TIM3_CR1) ⑥ 编写中断服务函数。 TIMxIRQHandler(); 2:通用定时器TIM2的Channel1、Channel2的PWM实现步骤 ① 使能定时器2和相关IO口时钟。 使能定时器2时钟:RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); 使能GPIOB时钟:RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); ② 初始化IO口为复用功能输出。函数:GPIO_Init(); GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP; ③ 初始化定时器:ARR,PSC等:TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure); ④ 初始化输出比较参数: TIM_OC3Init(TIM2,&TIM_OCInitStructure); TIM_OC4Init(TIM2,&TIM_OCInitStructure); ⑤ 使能预装载寄存器:TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); ⑥ 使能定时器。TIM_Cmd(); ⑦ 不断改变比较值CCRx,达到不同的占空比效果:TIM_SetCompare3(); TIM_SetCompare4() ; 使用Keil5 模拟软件的Logic Analyzer功能,PA2,PA3,PC13的波形图如下所示:
(五) 附录:程序源码
- #include "delay.h"
- #include "sys.h"
- #include "timer.h"
- void GPIO_Config(void) //配置PA2, PA3
- {
- GPIO_InitTypeDef GPIO_InitStructure;
-
- /* GPIOA clock enable */
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC,ENABLE); //
-
- /*GPIOA Configuration: TIM3 channel 1 and 2 as alternate function push-pull */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; //LED0-->PC.13 端口配置
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
- GPIO_Init(GPIOC, &GPIO_InitStructure); //根据设定参数初始化GPIOC.13
- }
- int main(void)
- {
- delay_init(); //延时函数初始化
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
-
- //每隔5s的周期,变换电机的转向。
- //定时中断,最小单位钟频率=72MHz/36KHz=2KHz
- TIM3_Int_Init(9999,35999) ;
-
- GPIO_Config(); //LED,PWM端口初始化,配置PC13,PA2,PA3
- TIM2_PWM_Init(47999,2 ); //分频。最小单位钟频率=72000000/(2+1)=24Mhz
- while(1)
- {
-
- }
- }
复制代码
timer.c
- #include "timer.h"
-
- //通用定时器3中断初始化
- //这里时钟选择为APB1的2倍,而APB1为36M
- //arr:自动重装值。
- //psc:时钟预分频数
- //这里使用的是定时器3!
- #define PC13 PCout(13)// PC13
- void TIM3_Int_Init(u16 arr,u16 psc)
- {
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
- // RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO ,ENABLE );
- // GPIO_PinRemapConfig(GPIO_FullRemap_TIM3 ,ENABLE);
-
- TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到5000为500ms
- TIM_TimeBaseStructure.TIM_Prescaler = psc; //设置用来作为TIMx时钟频率除数的预分频值 10Khz的计数频率
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
-
- TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断
- NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
- NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
- TIM_Cmd(TIM3, ENABLE); //使能TIMx外设
- }
- //定时器3中断服务程序
- void TIM3_IRQHandler(void) //TIM3中断
- {
- if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
- {
- TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIMx的中断待处理位:TIM 中断源
- PC13=!PC13;
-
- if (PC13 ==1)
- {
- TIM_SetCompare3(TIM2,24000);
- TIM_SetCompare4(TIM2,0);
- }
- else
- {
- TIM_SetCompare3(TIM2,0);
- TIM_SetCompare4(TIM2,24000);
- }
- }
- }
- //TIM2 PWM部分初始化 两个PWM波形,分别控制电机的正转与反转
- //PWM输出初始化
- //arr:自动重装值
- //psc:时钟预分频数
- void TIM2_PWM_Init(u16 arr,u16 psc)
- {
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- TIM_OCInitTypeDef TIM_OCInitStructure;
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能定时器3时钟
-
- //初始化TIM2
- TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
- TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
- TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
- TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
-
- //初始化TIM2 Channel1 PWM模式
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
- TIM_OCInitStructure.TIM_Pulse = 13500 ;
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
- TIM_OC3Init(TIM2, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM2 OC4
- TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable); //使能TIM2在CCR2上的预装载寄存器
-
- //初始化TIM2 Channel2 PWM模式
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
- TIM_OCInitStructure.TIM_Pulse = 0;
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
- TIM_OC4Init(TIM2, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM2 OC4
- TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable); //使能TIM2在CCR2上的预装载寄存器
-
- TIM_ARRPreloadConfig(TIM2, ENABLE);
- TIM_Cmd(TIM2, ENABLE); //使能TIM2
- }
复制代码
全部资料51hei下载地址:
STM32F103C8T6核心板+L298N_PWM直流电机调速.rar
(3.36 MB, 下载次数: 1185)
|