赞
踩
实验条件
STM32F103开发板
TB6612电机驱动模块
参考代码:
#include "car.h" //初始化定时器,实现PWM输出 void PWM_Init(u16 arr,u16 psc){ GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //①使能定时器 3 时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE); //①使能 GPIO 和 AFIO 复用功能时钟 GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE); //②重映射 TIM3_CH2->PB5 //设置该引脚为复用输出功能,输出 TIM3 CH2 的 PWM 脉冲波形 GPIOB.5 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //TIM_CH2 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); //①初始化 GPIO //初始化 TIM3 TIM_TimeBaseStructure.TIM_Period = arr; //设置在自动重装载周期值 TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置预分频值 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM 向上计数模式 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //③初始化 TIMx //初始化 TIM3 Channel2 PWM 模式 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择 PWM 模式 2 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性高 TIM_OC1Init(TIM3, &TIM_OCInitStructure); //④初始化外设 TIM3 OC2 TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能预装载寄存器 TIM_OC2Init(TIM3, &TIM_OCInitStructure); //④初始化外设 TIM3 OC2 TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能预装载寄存器 TIM_Cmd(TIM3, ENABLE); //⑤使能 TIM3 } /************************************************************************** 函数功能:电机的正反转 入口参数:mode mode=0时为正转 mode=1时反转 mode=2是停止 返回 值:无 **************************************************************************/ void MOTO(int mode) { if(mode==PosMode )//正转 { GPIO_SetBits(GPIOB, GPIO_Pin_13); // 高电平 GPIO_ResetBits(GPIOB, GPIO_Pin_14); // 低电平} GPIO_SetBits(GPIOA, GPIO_Pin_4); // 高电平 GPIO_ResetBits(GPIOA, GPIO_Pin_5); // 低电平 } if(mode==NegMode)//反转 { GPIO_ResetBits(GPIOB, GPIO_Pin_13); // 低电平 GPIO_SetBits(GPIOB, GPIO_Pin_14); // 高电平 GPIO_ResetBits(GPIOA, GPIO_Pin_4); // 低电平 GPIO_SetBits(GPIOA, GPIO_Pin_5); // 高电平 } if(mode==StopMode)//停止 { GPIO_ResetBits(GPIOB, GPIO_Pin_13); // 低电平 GPIO_ResetBits(GPIOB, GPIO_Pin_14); // 低电平} GPIO_ResetBits(GPIOA, GPIO_Pin_4); // 低电平 GPIO_ResetBits(GPIOA, GPIO_Pin_5); // 低电平 } } //初始化所需GPIO void CAR_Gpio_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; //定义结构体GPIO_InitStructure RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE); // 使能PB端口时钟 RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE); // 使能PA端口时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13| GPIO_Pin_14; //PB4 PB3 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽,增大电流输出能力 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度 GPIO_Init(GPIOB, &GPIO_InitStructure); //GBIOB初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4| GPIO_Pin_5; //PB4 PB5 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽,增大电流输出能力 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度 GPIO_Init(GPIOA, &GPIO_InitStructure); //GBIOA初始化 } void CAR_Speed(u16 speed){ TIM_SetCompare1(TIM3,speed); TIM_SetCompare2(TIM3,speed); }
主函数参考代码:
#include "stm32f10x.h" #include "lcd.h" #include "delay.h" #include "remote.h" #include "motor.h" #include "key.h" #include "led.h" #include "usart.h" #define MAXSPEED 7000 #define MINSPEED 1000 #define FILTERNUM 20 int main(void) { u8 Remote_key;//遥控器键值 u8 Key;//按键值 u8 *str=0;//遥控器显示 u16 speed=1000; u16 PWM=0; u16 filter=FILTERNUM; delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 uart_init(115200); //串口初始化为115200 LCD_Init();//初始化LCD功能; 320*240 Remote_Init(); //红外接收初始化 LED_Init(); //LED端口初始化 //TIM3_PWM_Init(7199,0); //不分频。PWM频率=72000000/900=80Khz PWM_Init(7199,0); KEY_Init(); CAR_Gpio_Init(); LCD_ShowString(30,60,300,16,16,"My RoBot"); LCD_ShowString(30,80,300,16,16,"MOTOR TEST:"); LCD_ShowString(30,100,300,16,16,"PWM: %"); MOTO(PosMode); CAR_Speed(speed);//设置速度 while(1){ Remote_key=Remote_Scan(); Key=KEY_Scan(0); //TIM_SetCompare2(TIM3,led0pwmval); if(Remote_key) { switch(Remote_key) { case 0:str="ERROR";break; case 162: str="STOP"; MOTO(StopMode); break; case 98:str="UP";break; case 2:str="PLAY";break; case 226: str="Go!"; MOTO(PosMode); break; case 194:str="RIGHT";break; case 34:str="LEFT";break; case 224: str="VOL-"; filter--; if(!filter){ filter=FILTERNUM; speed-=1000; if(speed<1000){ speed=MINSPEED; } } break; case 168:str="DOWN";break; case 144: str="VOL+"; filter--; if(!filter){ filter=FILTERNUM; speed+=500; if(speed>7000){ speed=MAXSPEED; } } break; case 104:str="1";break; case 152:str="2";break; case 176:str="3";break; case 48:str="4";break; case 24:str="5";break; case 122:str="6";break; case 16:str="7";break; case 56:str="8";break; case 90:str="9";break; case 66:str="0";break; case 82:str="DELETE";break; } }else delay_ms(10); if(Key==KEY0_PRES){//减速 speed-=1000; if(speed<1000){ speed=MINSPEED; } }else if(Key==KEY1_PRES){ //加速 speed+=500; if(speed>7000){ speed=MAXSPEED; } } CAR_Speed(speed); LCD_Fill(30+12*8,80,300,80+16,WHITE); //清楚之前的显示 LCD_ShowString(30+12*8,80,300,16,16,str); //显示SYMBOL PWM=speed*100/7200; LCD_ShowNum(30+4*8, 100, PWM, 2, 16); } }
引脚连接:
A01——电机负
B01——电机正
PC6——PWMA
PC7——PWMB
AIN1——PB14
AIN2——PB13
BIN1——PA5
BIN2——PA4
TB6612逻辑电源、使能信号-由降压3V3提供
单片机电源5V5OUT连接降压源3V3
编码器连线:
PA9——右轮B
PA8——右轮A
PA0——左轮B
PA1——左轮A
编码器参考代码:
#include "encoder.h" /************************************************************************** 函数功能:把TIM1初始化为编码器接口模式 入口参数:无 返回 值:无 **************************************************************************/ void Encoder_Init_TIM1(void) { TIM_TimeBaseInitTypeDef TIM1_TimeBaseStructure; TIM_ICInitTypeDef TIM1_ICInitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9; //端口配置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA TIM_TimeBaseStructInit(&TIM1_TimeBaseStructure); TIM1_TimeBaseStructure.TIM_Prescaler = 0x0; // 预分频器 TIM1_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD; //设定计数器自动重装值 TIM1_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//选择时钟分频:不分频 TIM1_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM向上计数 TIM_TimeBaseInit(TIM1, &TIM1_TimeBaseStructure); TIM_EncoderInterfaceConfig(TIM1, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); TIM_ICStructInit(&TIM1_ICInitStructure); TIM1_ICInitStructure.TIM_ICFilter = 10; TIM_ICInit(TIM1, &TIM1_ICInitStructure);//根据TIM_ICInitStruct中指定的参数初始化TIM TIM_ClearFlag(TIM1, TIM_FLAG_Update);//清除TIM的更新标志位 TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE); //使能或者失能指定的TIM中断 TIM_SetCounter(TIM1,0); TIM_Cmd(TIM1, ENABLE); //使能或者使能TIMx外设 } void Encoder_Init_TIM2(void) { NVIC_InitTypeDef NVIC_InitStruct; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_ICInitTypeDef TIM_ICInitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//使能定时器2的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能PA端口时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; //端口配置 PA0 PA1 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn; //定时器2中断 NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //使能IRQ通道 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级1 NVIC_InitStruct.NVIC_IRQChannelSubPriority = 3; //响应优先级3 NVIC_Init(&NVIC_InitStruct); TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // 预分频器 TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD; //设定计数器自动重装值 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//选择时钟分频:不分频 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//边沿计数模式 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //初始化定时器 TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用编码器模式3 TIM_ICStructInit(&TIM_ICInitStructure); //把TIM_ICInitStruct 中的每一个参数按缺省值填入 TIM_ICInitStructure.TIM_ICFilter = 10; //设置滤波器长度 TIM_ICInit(TIM2, &TIM_ICInitStructure);//根据 TIM_ICInitStruct 的参数初始化外设 TIMx TIM_ClearFlag(TIM2, TIM_FLAG_Update);//清除TIM的更新标志位 TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//使能定时器中断 TIM_SetCounter(TIM2,0); TIM_Cmd(TIM2, ENABLE); //使能定时器 } /************************************************************************** 函数功能:单位时间读取编码器计数 入口参数:定时器 返回 值:速度值 **************************************************************************/ int Read_Velocity(u8 TIMX) { int Encoder_TIM; switch(TIMX) { case 1: Encoder_TIM= (short)TIM1 -> CNT; TIM1->CNT=0; break; case 2: Encoder_TIM= (short)TIM2 -> CNT; TIM2->CNT=0; break; default: Encoder_TIM=0; } return Encoder_TIM; } void TIM1_IRQHandler(void)//中断处理函数为空,清除中断标志位后结束中断 { if(TIM_GetFlagStatus(TIM2,TIM_FLAG_Update)==SET)//溢出中断 { } TIM_ClearITPendingBit(TIM2,TIM_IT_Update); //清除中断标志位 } void TIM2_IRQHandler(void)//中断处理函数为空,清除中断标志位后结束中断 { if(TIM_GetFlagStatus(TIM2,TIM_FLAG_Update)==SET)//溢出中断 { } TIM_ClearITPendingBit(TIM2,TIM_IT_Update); //清除中断标志位 }
参考主函数:
#include "stm32f10x.h" #include "lcd.h" #include "delay.h" #include "remote.h" #include "motor.h" #include "key.h" #include "led.h" #include "usart.h" #include "encoder.h" #define MAXSPEED 7000 #define MINSPEED 1000 #define FILTERNUM 20 int main(void) { u8 Remote_key;//遥控器键值 u8 Key;//按键值 u8 *str=0;//遥控器显示 u16 speed=1000; u16 PWM=0; u16 filter=FILTERNUM; int Encoder_TIM=0; delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 uart_init(115200); //串口初始化为115200 LCD_Init();//初始化LCD功能; 320*240 Remote_Init(); //红外接收初始化 LED_Init(); //LED端口初始化 //TIM3_PWM_Init(7199,0); //不分频。PWM频率=72000000/900=80Khz PWM_Init(7199,0); KEY_Init(); CAR_Gpio_Init(); Encoder_Init_TIM1(); Encoder_Init_TIM2(); LCD_ShowString(30,60,300,16,16,"My RoBot"); LCD_ShowString(30,80,300,16,16,"MOTOR TEST:"); LCD_ShowString(30,100,300,16,16,"PWM: %"); MOTO(PosMode); CAR_Speed(speed);//设置速度 while(1){ Encoder_TIM=Read_Velocity(1); LCD_ShowxNum(30, 120,Encoder_TIM , 4, 16,0); USART_SendData(USART2,Encoder_TIM); //printf("TIM1=%d\n\r",Encoder_TIM); Encoder_TIM=Rea/d_Velocity(2); //printf("TIM2=%d\n\r",Encoder_TIM); USART_SendData(USART2,Encoder_TIM); LCD_ShowxNum(30, 140,Encoder_TIM , 4, 16,0); Remote_key=Remote_Scan(); Key=KEY_Scan(0); //TIM_SetCompare2(TIM3,led0pwmval); if(Remote_key) { switch(Remote_key) { case 0:str="ERROR";break; case 162: str="STOP"; MOTO(StopMode); break; case 98:str="UP";break; case 2:str="PLAY";break; case 226: str="Go!"; MOTO(PosMode); break; case 194:str="RIGHT";break; case 34:str="LEFT";break; case 224: str="VOL-"; filter--; if(!filter){ filter=FILTERNUM; speed-=1000; if(speed<1000){ speed=MINSPEED; } } break; case 168:str="DOWN";break; case 144: str="VOL+"; filter--; if(!filter){ filter=FILTERNUM; speed+=500; if(speed>7000){ speed=MAXSPEED; } } break; case 104:str="1";break; case 152:str="2";break; case 176:str="3";break; case 48:str="4";break; case 24:str="5";break; case 122:str="6";break; case 16:str="7";break; case 56:str="8";break; case 90:str="9";break; case 66:str="0";break; case 82:str="DELETE";break; } }else delay_ms(10); if(Key==KEY0_PRES){//减速 speed-=1000; if(speed<1000){ speed=MINSPEED; } }else if(Key==KEY1_PRES){ //加速 speed+=500; if(speed>7000){ speed=MAXSPEED; } } CAR_Speed(speed); LCD_Fill(30+12*8,80,300,80+16,WHITE); //清楚之前的显示 LCD_ShowString(30+12*8,80,300,16,16,str); //显示SYMBOL PWM=speed*100/7200; LCD_ShowNum(30+4*8, 100, PWM, 2, 16); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。