4、基础实验——电机驱动实验
在电机驱动实验之前先来个简单的——led闪烁实验。
实验的目:建立一个工程文件。
我根据这个文件《在keil MDK环境下建立有固件库的工程文件》建立了我的第一个工程文件。我的固件库是v3.5版本的,和QQ群里给的工程文件一样。
main.c是led灯的闪烁。开始只有这么多:
#include "main.h"
int main(void)
{
SystemInit(); //系统初始化
delay_init(72); //延时初始化
JTAG_Set(JTAG_SWD_DISABLE); //关闭JTAG接口
JTAG_Set(SWD_ENABLE); //打开SWD接口,利用主板SWD接口调试
led_init(); //初始化与LED连接的硬件接口
while(1)
{
GPIOB->ODR|=1<<8; //PB8 输出高 灯灭
delay_ms (500);
GPIOB->ODR=~(1<<8);//PB8 输出低 灯亮
delay_ms (500);
}
}
然后遇到了以下这3个编译问题
1、error: L6235E: More than one section matches selector - cannot all be FIRST/LAST.
我看到QQ群里的工程启动文件左边有三个红点,而我的没有。于是我百度了一下,找到原因如下:
项目中同时包含以下启动文件,
startup_stm32f10x_hd.s
startup_stm32f10x_md.s
startup_stm32f10x_ld.s
......
应该针对不同的CPU选择不同的启动文件。
解决办法1:从项目中删除不相关的启动文件
解决办法2:右击不相关的启动文件,点击 options for file 'startup_stm32f10x_md.s'...
在弹出的对话框中的properties页,勾去灰化的'Include in Target Build'和‘Always Build’两项。
2、后来又遇到一些symbol未定义的问题,例如temperature等,我发现QQ原程序中在main.c里面有对一些参数进行定义。于是我加上了这段,main.c变成了这样:
#include "main.h"
u8 Way_Angle=1; //获取角度的算法
u8 Flag_Qian,Flag_Hou,Flag_Left,Flag_Right; //蓝牙遥控相关的变量
u8 Flag_Stop=1,Flag_Show=1; //停止标志位和 显示标志位 默认停止 显示打开
int Encoder_Left,Encoder_Right; //左右编码器的脉冲计数
int Moto1,Moto2; //电机PWM变量 应是Motor的 向Moto致敬
int Temperature; //显示温度
int Voltage; //电池电压采样相关的变量
float Angle_Balance,Gyro_Balance,Gyro_Turn; //平衡倾角 平衡陀螺仪 转向陀螺仪
float Show_Data_Mb; //全局显示变量,用于显示需要查看的数据
int main(void)
{
SystemInit(); //系统初始化
delay_init(72); //延时初始化
JTAG_Set(JTAG_SWD_DISABLE); //关闭JTAG接口
JTAG_Set(SWD_ENABLE); //打开SWD接口,利用主板SWD接口调试
led_init(); //初始化与LED连接的硬件接口
while(1)
{
GPIOB->ODR|=1<<8; //PB8 输出高 灯灭
delay_ms (500);
GPIOB->ODR=~(1<<8);//PB8 输出低 灯亮
delay_ms (500);
}
}
3、后来又遇到STM32编译器assert_failed未定义的问题,百度了一下加上了这个:
#ifdef USE_FULL_ASSERT
void assert_failed(u8* file, u32 line)
{
while (1)
{
}
}
#endif
最后加进去,再编译就OK了。在此提供需要的人,如果用库函数时出现assert_failed定义问题,可像以上方法解决。
但是小白在次有个疑问,为啥QQ群里的程序main.c里咋没有这段程序????
最终led闪烁实验程序:
#include "main.h"
u8 Way_Angle=1; //获取角度的算法
u8 Flag_Qian,Flag_Hou,Flag_Left,Flag_Right; //蓝牙遥控相关的变量
u8 Flag_Stop=1,Flag_Show=1; //停止标志位和 显示标志位 默认停止 显示打开
int Encoder_Left,Encoder_Right; //左右编码器的脉冲计数
int Moto1,Moto2; //电机PWM变量
int Temperature; //显示温度
int Voltage; //电池电压采样相关的变量
float Angle_Balance,Gyro_Balance,Gyro_Turn; //平衡倾角 平衡陀螺仪 转向陀螺仪
float Show_Data_Mb; //全局显示变量,用于显示需要查看的数据
int main(void)
{
SystemInit(); //系统初始化
delay_init(72); //延时初始化
JTAG_Set(JTAG_SWD_DISABLE); //关闭JTAG接口
JTAG_Set(SWD_ENABLE); //打开SWD接口,利用主板SWD接口调试
led_init(); //初始化与LED连接的硬件接口
while(1)
{
GPIOB->ODR|=1<<8; //PB8 输出高 灯灭
delay_ms (500);
GPIOB->ODR=~(1<<8);//PB8 输出低 灯亮
delay_ms (500);
}
}
#ifdef USE_FULL_ASSERT
void assert_failed(u8* file, u32 line)
{
while (1)
{
}
}
#endif
实验现象:蓝光闪烁
电机驱动实验;
TB6612的任务书可以知道通过设置PWM、IN1、IN2可以控制电机的正反转,CCW表示逆时针、CW表示顺时针
由
A、B分别控制两个电机
电机实验主程序:
#include "main.h"
int main(void)
{
SystemInit(); //系统初始化
delay_init(72); //延时初始化
JTAG_Set(JTAG_SWD_DISABLE); //关闭JTAG接口
JTAG_Set(SWD_ENABLE); //打开SWD接口,利用主板SWD接口调试
led_init(); //初始化与LED连接的硬件接口
MiniBalance_PWM_Init(3599,0); //f = 72 000 000 /((3599+1)*(0+1)) = 20K
//初始化PWM 20KHZ 高频可以防止电机低频时的尖叫声
while(1)
{
PWMA = 2000; //#define PWMA TIM3->CCR4 在2000时电平发生翻转
PWMB = 2000; //#define PWMB TIM3->CCR3 在2000时电平发生翻转
GPIOB->ODR=~(1<<8);//PB8低输出 灯亮
// AIN1 = 0; //逆时针转(CCW)快前
// AIN2 = 1;
// AIN1 = 1; //顺时针转(CW)慢后
// AIN2 = 0;
// BIN1 = 0; //顺时针快前CW
// BIN2 = 1;
BIN1 = 1; //逆时针慢后CCW
BIN2 = 0;
}
}
#ifdef USE_FULL_ASSERT
void assert_failed(u8* file, u32 line)
{
while (1)
{
}
}
#endif