腾讯网站建设的基本情况,自助建站系统是怎么实现,成都 网站 建设,排名好的网站关键词优化企业无限交互#xff0c;全新驾驶体验#xff01;智能语音小车#xff0c;与您共同开创未来出行。”#51单片机最终项目《智能语音小车》【上】 前言预备知识1. L9110S电机控制器接线1.1 L9110S概述1.2 L9110S IO口描述1.3 L9110S 实物图1.4 L9110S与单片机接线 2. L9110前… 无限交互全新驾驶体验智能语音小车与您共同开创未来出行。”#51单片机最终项目《智能语音小车》【上】 前言预备知识1. L9110S电机控制器接线1.1 L9110S概述1.2 L9110S IO口描述1.3 L9110S 实物图1.4 L9110S与单片机接线 2. L9110前后左右控制小车2.1 L9110前后左右控制小车2.1分别用高低电平测试B-1A和B-1B L9110电机驱动模块引脚A-1A和A-1B L9110电机驱动模块引脚。2.2 将测试结果封装函数2.3封装前后左右行走函数2.4主函数内进行间隔2秒调用前后左右函数2.5完整程序代码 3.电机相关代码封装_分文件3.1电机相关代码封装_分文件核心思路3.2将控制电机前进后退向左向右的函数封装到电机对应的C文件中。3.3建立电机头文件里面声明电机对应C文件中的函数3.4将延时2秒的函数封装到延时C文件中3.5建立延时头文件里面声明延时C文件中的函数。3.6主函数中包含电机头文件和延时头文件即可完美运行程序 4.串口控制小车4.1串口控制小车核心思路4.2找到wifi开灯项目中优化8266捕获联网失败的状态工程打开4.3拷贝串口使用相关声明定义串口初始化函数串口中断函数建立串口C文件和头文件。4.4在电机对应C文件中构造小车停止函数4.5在串口中断函数中通过接收指令操作小车运行4.6串口C文件代码 5.手机通过蓝牙控制小车_自定义按键5.1手机通过蓝牙控制小车_自定义按键核心思路5.2将蓝牙模块正确接线连接51单片机串口5.3给51单片机蓝牙模块上电打开手机APP HC蓝牙助手进行连接5.4通过自定义按钮使HC蓝牙助手发送相应控制小车指令 6.蓝牙小车的点动控制6.1蓝牙小车的点动控制核心思路6.2在主C文件主函数while(1)死循环中调用电机停止函数。6.3在串口中断函数中接收指令并执行调用电机相关函数时延时10毫秒实现点动6.4通过串口助手自动发送模拟长按一直发送一直运行的状态。 7.PWM软件调速7.1 PWM软件调速核心思路7.2打开感应开盖垃圾桶项目_舵机编程实战工程主C文件7.3在工程内新建time0.c文件7.4拷贝相关变量定时器0初始化函数定时器零中断函数7.5修改定时器0中断函数使之调用电机控制函数实现调速7.6建立time.h文件7.7主C文件内每隔1.5秒改变速度变量使小车电机变速7.8 PWM软件调速原理图 8.左右电机的各自调速管理8.1左右电机的各自调速管理核心思路8.2在motor.c文件内建立单独控制左右轮前进和停止函数并在motor.h文件中声明。8.3建立time1.c和time1.h文件用于对右轮的控制和初始化。8.4修改time0.c为左轮控制8.5主C文件内每隔1.5秒改变左右轮速度变量使小车左右轮电机差速运行 结束语 前言 本篇博文介绍的是用51单片机的最终项目《智能语音小车》【上】包含L9110S电机控制器接线 L9110前后左右控制小车电机相关代码封装–分文件串口控制小车手机通过蓝牙控制小车–自定义按键蓝牙小车的点动控制PWM软件调速左右电机的各自调速管理。看到这篇博文的朋友可以先赞再看吗
预备知识 一、需要我之前写的所有博文的知识如果还没看我之前的的博文可以去看看后再看本篇博文 二、C变量 三、基本输入输出 四、流程控制 五、函数 六、指针 七、字符串 如果以上知识不清楚请自行学习后再来浏览。如果我有没例出的请在评论区写一下。谢谢啦
1. L9110S电机控制器接线
1.1 L9110S概述 L9110S是一种双路H桥驱动器芯片通常用于控制直流电机或步进电机。该芯片具有内置的双H桥驱动器可实现电机的双向控制。它可以通过控制输入信号来控制电机的转向和速度并且通常被广泛应用于各种小型电动车辆、机器人以及其他需要电机控制的项目中。L9110S还具有过流保护功能能够保护电机和驱动器免受损坏。
1.2 L9110S IO口描述 以下资料来源官方但是不对 IA1输入高电平IA1输入低电平【OA1 OB1】电机正转 IA1输入低电平IA1输入高电平【OA1 OB1】电机反转 IA2输入高电平IA2输入低电平【OA2 OB2】电机正转 IA2输入低电平IA2输入高电平【OA2 OB2】电机反转
1.3 L9110S 实物图 1.4 L9110S与单片机接线
注意电源线千万别接错不然会在0.5秒内烧坏模块电源正常接通电源指示灯会亮。 2. L9110前后左右控制小车
2.1 L9110前后左右控制小车
分别用高低电平测试B-1A和B-1B L9110电机驱动模块引脚A-1A和A-1B L9110电机驱动模块引脚。将测试结果封装函数封装前后左右行走函数
2.1分别用高低电平测试B-1A和B-1B L9110电机驱动模块引脚A-1A和A-1B L9110电机驱动模块引脚。 将B-1A置1B-1B置0将A-1A置1A-1B置0。看一下电机的转向。 代码体现
RightControA 1;
RightControB 0;LeftControA 1;
LeftControB 0;测试结果为小车向后跑也就电机反转。
2.2 将测试结果封装函数 测试结果为小车向前跑封装向前函数。 代码体现。
void goBack()
{RightControA 1;RightControB 0;LeftControA 1;LeftControB 0;
}2.3封装前后左右行走函数
向前函数封装思路 将向后函数的高低电平兑换就实现了向前功能。
代码体现
void goFront()
{RightControA 0;RightControB 1;LeftControA 0;LeftControB 1;
}向左和向右行走函数思路 如果要实现向左行走就将控制左轮的引脚置零实现向右行走就将控制右轮的引脚置零。这样就实现了向左和向右行走。
代码体现
void goLeft()
{RightControA 0;RightControB 1;LeftControA 0;LeftControB 0;
}void goRight()
{RightControA 0;RightControB 0;LeftControA 0;LeftControB 1;
}2.4主函数内进行间隔2秒调用前后左右函数
代码体现
void main()
{while(1){goFront();Delay2000ms();goBack();Delay2000ms();goLeft();Delay2000ms();goRight();Delay2000ms();}
}2.5完整程序代码
#include reg52.h
#include intrins.hsbit RightControA P3^2; //右轮控制A
sbit RightControB P3^3; //右轮控制B
sbit LeftControA P3^4; //左轮控制A
sbit LeftControB P3^5; //左轮控制Bvoid Delay2000ms() //11.0592MHz
{unsigned char i, j, k;_nop_();i 15;j 2;k 235;do{do{while (--k);} while (--j);} while (--i);
}void goLeft()
{RightControA 0;RightControB 1;LeftControA 0;LeftControB 0;
}void goRight()
{RightControA 0;RightControB 0;LeftControA 0;LeftControB 1;
}void goBack()
{RightControA 1;RightControB 0;LeftControA 1;LeftControB 0;
}void goFront()
{RightControA 0;RightControB 1;LeftControA 0;LeftControB 1;
}void main()
{while(1){goFront();Delay2000ms();goBack();Delay2000ms();goLeft();Delay2000ms();goRight();Delay2000ms();}
}3.电机相关代码封装_分文件
3.1电机相关代码封装_分文件核心思路 将控制电机前进后退向左向右的函数封装到电机对应的C文件中。 建立电机头文件里面声明电机对应C文件中的函数 将延时2秒的函数封装到延时C文件中 建立延时头文件里面声明延时C文件中的函数。 主函数中包含电机头文件和延时头文件即可完美运行程序 注此工程基于L9110前后左右控制小车工程开发
3.2将控制电机前进后退向左向右的函数封装到电机对应的C文件中。
将声明电机控制引脚代码移动到电机对应的C文件中具体如何建立分文件请看温湿度检测系统博文代码体现如下。
sbit RightControA P3^2; //右轮控制A
sbit RightControB P3^3; //右轮控制B
sbit LeftControA P3^4; //左轮控制A
sbit LeftControB P3^5; //左轮控制B将控制电机前进后退向左向右的函数移动到电机对应的C文件中。代码体现如下
void goLeft()
{RightControA 0;RightControB 1;LeftControA 0;LeftControB 0;
}void goRight()
{RightControA 0;RightControB 0;LeftControA 0;LeftControB 1;
}void goBack()
{RightControA 1;RightControB 0;LeftControA 1;LeftControB 0;
}void goFront()
{RightControA 0;RightControB 1;LeftControA 0;LeftControB 1;
}电机对的C文件代码截图 3.3建立电机头文件里面声明电机对应C文件中的函数
需要声明的函数代码如下。 void goLeft();void goRight();void goBack();void goFront();电机头文件代码截图 3.4将延时2秒的函数封装到延时C文件中
将延时2秒的函数封装到延时C文件中代码体现
void Delay2000ms() //11.0592MHz
{unsigned char i, j, k;_nop_();i 15;j 2;k 235;do{do{while (--k);} while (--j);} while (--i);
}延时C文件代码截图 3.5建立延时头文件里面声明延时C文件中的函数。
需要声明的函数代码如下。
void Delay2000ms();延时头文件代码截图 3.6主函数中包含电机头文件和延时头文件即可完美运行程序
主函数中包含电机头文件和延时头文件代码体现
#include motor.h
#include delay.h主函数代码截图 4.串口控制小车
4.1串口控制小车核心思路
找到wifi开灯项目中优化8266捕获联网失败的状态工程打开主函数拷贝串口使用相关声明定义串口初始化函数串口中断函数建立串口C文件和头文件在电机对应C文件中构造小车停止函数在串口中断函数中通过接收指令操作小车运行 注此工程由电机相关代码封装_分文件工程开发
4.2找到wifi开灯项目中优化8266捕获联网失败的状态工程打开 4.3拷贝串口使用相关声明定义串口初始化函数串口中断函数建立串口C文件和头文件。
拷贝串口使用相关声明定义
#include reg52.h
#include string.h
#define SIZE 32sfr AUXR 0x8e; //声明AUXR寄存器地址
char buffer[SIZE]; 拷贝串口初始化函数
void UartInit(void) //自己配
{//配置串口工作方式为方式1从只收不发改为能收能发SCON 0x50;//配置辅助寄存器减少电磁辐射稳定晶振频率 AUXR 0x01;//设置定时器工作方式为定时器1的8位自动重装TMOD 0x0F;TMOD | 0x20;//设置串口波特率为9600,0误差TH1 0xFD;TL1 0xFD;//打开定时器1TR1 1;//打开总中断EA 1;//打开串口中断ES 1;
}拷贝串口中断函数
void UART_handler() interrupt 4
{//定义临时变量tmp用于判断接收的字符是否是需要的首字符。char tmp;//定义一个静态整型变量,在多次函数调用中只被执行一次初始化static int i 0;//在串口中段函数中可以对发送接收中断标志进行处理if(RI 1){RI 0; //必须软件置零tmp SBUF;if(tmpW || tmpO || tmpL || tmpF){i 0;}buffer[i] tmp;/*if(buffer[0]W buffer[5]G){con_Net_Flag 1;memset(buffer,\0,SIZE);}*/if(buffer[0]O buffer[1]K){at_OK_Flag 1;memset(buffer,\0,SIZE);}if(buffer[0]F buffer[1] A){statusLED1();sendString(RESET);Delay1000ms();sendString(cNetwork);memset(buffer,\0,SIZE);}//如果用1指令开灯0指令关灯if(buffer[0]L buffer[2]1) {LED1 0;memset(buffer,\0,SIZE);}if(buffer[0]L buffer[2]0){LED1 1;memset(buffer,\0,SIZE);}if(i SIZE){i 0;}}if(TI);}建立串口C文件和头文件。 一、将拷贝的所有代码整合到一起文件命名为uart.c。
#include reg52.h
#include string.h
#define SIZE 32sfr AUXR 0x8e; //声明AUXR寄存器地址
char buffer[SIZE]; void UartInit(void) //自己配
{//配置串口工作方式为方式1从只收不发改为能收能发SCON 0x50;//配置辅助寄存器减少电磁辐射稳定晶振频率 AUXR 0x01;//设置定时器工作方式为定时器1的8位自动重装TMOD 0x0F;TMOD | 0x20;//设置串口波特率为9600,0误差TH1 0xFD;TL1 0xFD;//打开定时器1TR1 1;//打开总中断EA 1;//打开串口中断ES 1;
}void UART_handler() interrupt 4
{//定义临时变量tmp用于判断接收的字符是否是需要的首字符。char tmp;//定义一个静态整型变量,在多次函数调用中只被执行一次初始化static int i 0;//在串口中段函数中可以对发送接收中断标志进行处理if(RI 1){RI 0; //必须软件置零tmp SBUF;if(tmpW || tmpO || tmpL || tmpF){i 0;}buffer[i] tmp;/*if(buffer[0]W buffer[5]G){con_Net_Flag 1;memset(buffer,\0,SIZE);}*/if(buffer[0]O buffer[1]K){at_OK_Flag 1;memset(buffer,\0,SIZE);}if(buffer[0]F buffer[1] A){statusLED1();sendString(RESET);Delay1000ms();sendString(cNetwork);memset(buffer,\0,SIZE);}//如果用1指令开灯0指令关灯if(buffer[0]L buffer[2]1) {LED1 0;memset(buffer,\0,SIZE);}if(buffer[0]L buffer[2]0){LED1 1;memset(buffer,\0,SIZE);}if(i SIZE){i 0;}}if(TI);}二、建立uart.h文件里面声明串口初始化函数。
void UartInit(void);4.4在电机对应C文件中构造小车停止函数
函数思路 将左右轮控制信号的A、B给与低电平信号实现轮子停止转动。
函数代码
void stop()
{RightControA 0;RightControB 0;LeftControA 0;LeftControB 0;
}4.5在串口中断函数中通过接收指令操作小车运行
在串口中断函数中通过接收指令操作小车运行思路 一、将串口中断函数中的13行if(tmp\W || tmp\O || tmp\L || tmpF)改为if(tmp\M) 二、删除串口中断函数中19到47行代码 三、使用if和switch嵌套进行操作小车 四、重要bug串口能收到指令却无法操作小车。解决办法不在if和switch嵌套中使用清理字符串函数在防止指针越界函数中使用。
在串口中断函数中通过接收指令操作小车运行代码
void UART_handler() interrupt 4
{//定义临时变量tmp用于判断接收的字符是否是需要的首字符。char tmp;//定义一个静态整型变量,在多次函数调用中只被执行一次初始化static int i 0;//在串口中段函数中可以对发送接收中断标志进行处理if(RI 1){RI 0; //必须软件置零tmp SBUF;if(tmpM){i 0;}buffer[i] tmp;if(buffer[0]M){switch(buffer[1]){case 1:goFront();break;case 2:goBack();break;case 3:goLeft();break;case 4:goRight();break;default:stop();break;}}if(i SIZE){i 0;memset(buffer,\0,SIZE);}}if(TI);}4.6串口C文件代码
#include reg52.h
#include motor.h
#include string.h#define SIZE 32sfr AUXR 0x8e; //声明AUXR寄存器地址
char buffer[SIZE];void UartInit() //自己配
{//配置串口工作方式为方式1从只收不发改为能收能发SCON 0x50;//配置辅助寄存器减少电磁辐射稳定晶振频率 AUXR 0x01;//设置定时器工作方式为定时器1的8位自动重装TMOD 0x0F;TMOD | 0x20;//设置串口波特率为9600,0误差TH1 0xFD;TL1 0xFD;//打开定时器1TR1 1;//打开总中断EA 1;//打开串口中断ES 1;
}void UART_handler() interrupt 4
{//定义临时变量tmp用于判断接收的字符是否是需要的首字符。char tmp;//定义一个静态整型变量,在多次函数调用中只被执行一次初始化static int i 0;//在串口中段函数中可以对发送接收中断标志进行处理if(RI 1){RI 0; //必须软件置零tmp SBUF;if(tmpM){i 0;}buffer[i] tmp;if(buffer[0]M){switch(buffer[1]){case 1:goFront();break;case 2:goBack();break;case 3:goLeft();break;case 4:goRight();break;default:stop();break;}}if(i SIZE){i 0;memset(buffer,\0,SIZE);}}if(TI);}5.手机通过蓝牙控制小车_自定义按键
5.1手机通过蓝牙控制小车_自定义按键核心思路
将蓝牙模块正确接线连接51单片机串口给51单片机蓝牙模块上电打开手机APP HC蓝牙助手进行连接通过自定义按钮使HC蓝牙助手发送相应控制小车指令
5.2将蓝牙模块正确接线连接51单片机串口 相关接线请看我写的串口通信博文
5.3给51单片机蓝牙模块上电打开手机APP HC蓝牙助手进行连接 5.4通过自定义按钮使HC蓝牙助手发送相应控制小车指令
点击自定义按钮 点击设置方向按钮 在设置按钮名称处填写你需要设置的按钮名称在设置按钮内容处填写你需要发送的指令最后点击确认 依次设置完前、后、左、右、停、五个指令后便可实现手机蓝牙控制小车。
6.蓝牙小车的点动控制
6.1蓝牙小车的点动控制核心思路
在主C文件主函数while(1)死循环中调用电机停止函数。在串口中断函数中接收指令并执行调用电机相关函数时延时10毫秒实现点动通过串口助手自动发送模拟长按一直发送一直运行的状态。 注此工程由串口控制小车工程开发
6.2在主C文件主函数while(1)死循环中调用电机停止函数。
函数调用代码
while(1)
{stop();
}主C文件代码
#include motor.h
#include delay.h
#include uart.hvoid main()
{UartInit();while(1){stop();}
}6.3在串口中断函数中接收指令并执行调用电机相关函数时延时10毫秒实现点动
延时10毫秒函数代码
void Delay10ms() //11.0592MHz
{unsigned char i, j;i 18;j 235;do{while (--j);} while (--i);
}在串口中断函数中调用代码
if(buffer[0]M)
{switch(buffer[1]){case 1:goFront();Delay10ms();break;case 2:goBack();Delay10ms();break;case 3:goLeft();Delay10ms();break;case 4:goRight();Delay10ms();break;default:stop();break;}}串口C文件代码
#include reg52.h
#include motor.h
#include string.h
#include delay.h#define SIZE 32sfr AUXR 0x8e; //声明AUXR寄存器地址
char buffer[SIZE];void UartInit() //自己配
{//配置串口工作方式为方式1从只收不发改为能收能发SCON 0x50;//配置辅助寄存器减少电磁辐射稳定晶振频率 AUXR 0x01;//设置定时器工作方式为定时器1的8位自动重装TMOD 0x0F;TMOD | 0x20;//设置串口波特率为9600,0误差TH1 0xFD;TL1 0xFD;//打开定时器1TR1 1;//打开总中断EA 1;//打开串口中断ES 1;
}void UART_handler() interrupt 4
{//定义临时变量tmp用于判断接收的字符是否是需要的首字符。char tmp;//定义一个静态整型变量,在多次函数调用中只被执行一次初始化static int i 0;//在串口中段函数中可以对发送接收中断标志进行处理if(RI 1){RI 0; //必须软件置零tmp SBUF;if(tmpM){i 0;}buffer[i] tmp;if(buffer[0]M){switch(buffer[1]){case 1:goFront();Delay10ms();break;case 2:goBack();Delay10ms();break;case 3:goLeft();Delay10ms();break;case 4:goRight();Delay10ms();break;default:stop();break;}}if(i SIZE){i 0;memset(buffer,\0,SIZE);}}if(TI);}6.4通过串口助手自动发送模拟长按一直发送一直运行的状态。
打开单片机下载器点击串口助手 打开串口写入指令M1设置发送周期为1ms点击自动发送。 观察小车车轮小车正在前行说明模拟成功。
7.PWM软件调速
7.1 PWM软件调速核心思路
打开感应开盖垃圾桶项目_舵机编程实战工程主C文件在工程内新建time0.c文件拷贝相关变量定时器0初始化函数定时器零中断函数修改定时器0中断函数使之调用电机控制函数实现调速建立time.h文件主C文件内每隔1.5秒改变速度变量使小车电机变速 注此工程由蓝牙小车的点动控制工程开发
7.2打开感应开盖垃圾桶项目_舵机编程实战工程主C文件 7.3在工程内新建time0.c文件 7.4拷贝相关变量定时器0初始化函数定时器零中断函数
拷贝相关变量代码
int cnt 0; //记录爆表次数
int angle; //记录舵机角度变量修改angle为speed也就是修改记录舵机角度变量为记录小车速度变量。把这两个变量类型修改为char型节省空间
char cnt 0; //记录爆表次数
char speed 0; //调速变量拷贝定时器0初始化函数代码
void initTime0() //初始化定时器T0
{//1.设置定时器为T016位模式TMOD 0xF0;TMOD | 0x01;//2.设置初值定时0.5毫秒TL0 0x33;TH0 0xFE;//3.启动定时器开始计时TR0 1; //TR0为启动定时器标志值为1启动定时器TF0 0;//4.打开定时器0的中断 赋1打开ET0 1;//5.打开总中断EA 赋1打开EA 1;
}拷贝定时器零中断函数
void Time0Handler() interrupt 1 //定时器T0中断函数中断号为interrupt 1
{cnt;//重新给定时器赋初值定时0.5毫秒TL0 0x33;TH0 0xFE;//判读记录爆表变量cnt的值是否小于角度变量的值小于继续给sg90舵机控制线高电平大于等于则给低电平if(cnt angle){sg90_con 1;}else{sg90_con 0;}//判断cnt是否加到40定时是否20毫秒PWM波形周期if(cnt 20){cnt 0; //定时到20豪秒cnt从0开始加sg90_con 1;//定时到20豪秒重新给舵机控制线一个高电平}
}7.5修改定时器0中断函数使之调用电机控制函数实现调速
把定时器零中断函数中第9行if(cnt angle)修改为if(cnt speed)把定时器零中断函数中第11行sg90_con 1修改为goFront();把定时器零中断函数中第15行sg90_con 0修改为stop();把定时器零中断函数中第21行sg90_con 1;删除。添加motor.h头文件。修改后的函数代码
void Time0Handler() interrupt 1 //定时器T0中断函数中断号为interrupt 1
{cnt;//重新给定时器赋初值定时0.5毫秒TL0 0x33;TH0 0xFE;//判读记录爆表变量cnt的值是否小于角度变量的值小于继续给sg90舵机控制线高电平大于等于则给低电平if(cnt speed){//前进goFront();}else{//停止stop();}//判断cnt是否加到40定时是否20毫秒PWM波形周期if(cnt 40){cnt 0; //定时到20豪秒cnt从0开始加}
}time0.c文件中的代码
#include reg52.h
#include motor.h
char cnt 0; //记录爆表次数
char speed 0; //调速变量void initTime0() //初始化定时器T0
{//1.设置定时器为T016位模式TMOD 0xF0;TMOD | 0x01;//2.设置初值定时0.5毫秒TL0 0x33;TH0 0xFE;//3.启动定时器开始计时TR0 1; //TR0为启动定时器标志值为1启动定时器TF0 0;//4.打开定时器0的中断 赋1打开ET0 1;//5.打开总中断EA 赋1打开EA 1;
}void Time0Handler() interrupt 1 //定时器T0中断函数中断号为interrupt 1
{cnt;//重新给定时器赋初值定时0.5毫秒TL0 0x33;TH0 0xFE;//判读记录爆表变量cnt的值是否小于角度变量的值小于继续给sg90舵机控制线高电平大于等于则给低电平if(cnt speed){//前进goFront();}else{//停止stop();}//判断cnt是否加到40定时是否20毫秒PWM波形周期if(cnt 40){cnt 0; //定时到20豪秒cnt从0开始加}
}7.6建立time.h文件
在time0.h中声明定时器0初始化函数代码体现
void initTime0();7.7主C文件内每隔1.5秒改变速度变量使小车电机变速
在主函数中调用定时器0初始化函数
initTime0();在主C文件中运用extern关键字声明速度变量char speed。
extern char speed;在主函数while(1)死循环中每隔1.5秒改变速度变量的值。
while(1)
{speed 10;Delay1500ms();speed 15;Delay1500ms();speed 20;Delay1500ms();speed 25;Delay1500ms();speed 30;Delay1500ms();speed 35;Delay1500ms();speed 40;Delay1500ms();
}在delay.c文件中建立延时1.5秒函数。
void Delay1500ms() //11.0592MHz
{unsigned char i, j, k;_nop_();i 11;j 130;k 111;do{do{while (--k);} while (--j);} while (--i);
}主C文件代码
#include motor.h
#include delay.h
#include uart.h
#include time0.hextern char speed;void main()
{initTime0();UartInit();while(1){speed 10; //10为最小速度驱动再小就无法运行Delay1500ms();speed 15;Delay1500ms();speed 20;Delay1500ms();speed 25;Delay1500ms();speed 30;Delay1500ms();speed 35;Delay1500ms();speed 40;Delay1500ms();}
}7.8 PWM软件调速原理图 8.左右电机的各自调速管理
8.1左右电机的各自调速管理核心思路 在motor.c文件内建立单独控制左右轮前进和停止函数并在motor.h文件中声明。 建立time1.c和time1.h文件用于对右轮的控制和初始化。 修改time0.c为左轮控制 主C文件内每隔1.5秒改变左右轮速度变量使小车左右轮电机差速运行 注此工程由PWM软件调速开发
8.2在motor.c文件内建立单独控制左右轮前进和停止函数并在motor.h文件中声明。
复制前进函数修改名字为goFrontLeft()。删除右轮代码。
修改前
void goFront()
{RightControA 0;RightControB 1;LeftControA 0;LeftControB 1;
}修改后void goFrontLeft()
{LeftControA 0;LeftControB 1;
}按照以上步骤可以建立右轮控制函数
void goFrontRight()
{RightControA 0;RightControB 1;
}复制停止函数修改名为stopLeft()。删除右轮代码
修改前
void stop()
{RightControA 0;RightControB 0;LeftControA 0;LeftControB 0;
}修改后
void stopLeft()
{LeftControA 0;LeftControB 0;
}按照以上步骤可以建立右轮停止函数函数
void stopRight()
{RightControA 0;RightControB 0;
}在motor.h中声明这四个函数
void goFrontLeft();void goFrontRight();void stopLeft();void stopRight();motor.c文件中的代码
#include reg52.hsbit RightControA P3^2; //右轮控制A
sbit RightControB P3^3; //右轮控制B
sbit LeftControA P3^4; //左轮控制A
sbit LeftControB P3^5; //左轮控制Bvoid goLeft()
{RightControA 0;RightControB 1;LeftControA 0;LeftControB 0;
}void goRight()
{RightControA 0;RightControB 0;LeftControA 0;LeftControB 1;
}void goBack()
{RightControA 1;RightControB 0;LeftControA 1;LeftControB 0;
}void goFront()
{RightControA 0;RightControB 1;LeftControA 0;LeftControB 1;
}void stop()
{RightControA 0;RightControB 0;LeftControA 0;LeftControB 0;
}void goFrontLeft()
{LeftControA 0;LeftControB 1;
}void goFrontRight()
{RightControA 0;RightControB 1;
}void stopLeft()
{LeftControA 0;LeftControB 0;
}void stopRight()
{RightControA 0;RightControB 0;
}motor.h文件中的代码 void goLeft();void goRight();void goBack();void goFront();void stop();void goFrontLeft();void goFrontRight();void stopLeft();void stopRight();8.3建立time1.c和time1.h文件用于对右轮的控制和初始化。
拷贝time0.c文件代码到time1.c文件中
#include reg52.h
#include motor.h
char cnt 0; //记录爆表次数
char speed 0; //调速变量void initTime0() //初始化定时器T0
{//1.设置定时器为T016位模式TMOD 0xF0;TMOD | 0x01;//2.设置初值定时0.5毫秒TL0 0x33;TH0 0xFE;//3.启动定时器开始计时TR0 1; //TR0为启动定时器标志值为1启动定时器TF0 0;//4.打开定时器0的中断 赋1打开ET0 1;//5.打开总中断EA 赋1打开EA 1;
}void Time0Handler() interrupt 1 //定时器T0中断函数中断号为interrupt 1
{cnt;//重新给定时器赋初值定时0.5毫秒TL0 0x33;TH0 0xFE;//判读记录爆表变量cnt的值是否小于角度变量的值小于继续给sg90舵机控制线高电平大于等于则给低电平if(cnt speed){//前进goFront();}else{//停止stop();}//判断cnt是否加到40定时是否20毫秒PWM波形周期if(cnt 40){cnt 0; //定时到20豪秒cnt从0开始加}
}将initTime0()修改为initTime1()将所有的TH0TL0替换为TH1和TL1。将TMOD的两个运算表达式后面的变量替换为0x0F和0x01 4;实现使用定时器116位模式。将TR0TF0ET0修改为TR1TF1ET1。
void initTime1() //初始化定时器T0
{//1.设置定时器为T016位模式TMOD 0x0F;TMOD | 0x01 4;//2.设置初值定时0.5毫秒TL1 0x33;TH1 0xFE;//3.启动定时器开始计时TR1 1; //TR0为启动定时器标志值为1启动定时器TF1 0;//4.打开定时器0的中断 赋1打开ET1 1;//5.打开总中断EA 赋1打开EA 1;
}将Time0Handler() 修改为 Time1Handler()interrupt 1 修改为 interrupt 3cnt 修改为 cntRightspeed修改为speedRightgoFront();修改为goFrontRight();stop();修改为stopRight();。
void Time1Handler() interrupt 3 //定时器T0中断函数中断号为interrupt 1
{cntRight;//重新给定时器赋初值定时0.5毫秒TL1 0x33;TH1 0xFE;//判读记录爆表变量cnt的值是否小于角度变量的值小于继续给sg90舵机控制线高电平大于等于则给低电平if(cntRight speedRight){//前进goFrontRight();}else{//停止stopRight();}//判断cnt是否加到40定时是否20毫秒PWM波形周期if(cntRight 40){cntRight 0; //定时到20豪秒cnt从0开始加}
}修改后的代码为
#include reg52.h
#include motor.h
char cntRight 0; //记录爆表次数
char speedRight 0; //调速变量void initTime1() //初始化定时器T0
{//1.设置定时器为T016位模式TMOD 0x0F;TMOD | 0x01 4;//2.设置初值定时0.5毫秒TL1 0x33;TH1 0xFE;//3.启动定时器开始计时TR1 1; //TR0为启动定时器标志值为1启动定时器TF1 0;//4.打开定时器0的中断 赋1打开ET1 1;//5.打开总中断EA 赋1打开EA 1;
}void Time1Handler() interrupt 3 //定时器T0中断函数中断号为interrupt 1
{cntRight;//重新给定时器赋初值定时0.5毫秒TL1 0x33;TH1 0xFE;//判读记录爆表变量cnt的值是否小于角度变量的值小于继续给sg90舵机控制线高电平大于等于则给低电平if(cntRight speedRight){//前进goFrontRight();}else{//停止stopRight();}//判断cnt是否加到40定时是否20毫秒PWM波形周期if(cntRight 40){cntRight 0; //定时到20豪秒cnt从0开始加}
}8.4修改time0.c为左轮控制
将cnt修改为cntLeftspeed修改为speedLeftgoFront();修改为goFrontLeft();stop();修改为stopLeft();。修改后的代码为
#include reg52.h
#include motor.h
char cntLeft 0; //记录爆表次数
char speedLeft 0; //调速变量void initTime0() //初始化定时器T0
{//1.设置定时器为T016位模式TMOD 0xF0;TMOD | 0x01;//2.设置初值定时0.5毫秒TL0 0x33;TH0 0xFE;//3.启动定时器开始计时TR0 1; //TR0为启动定时器标志值为1启动定时器TF0 0;//4.打开定时器0的中断 赋1打开ET0 1;//5.打开总中断EA 赋1打开EA 1;
}void Time0Handler() interrupt 1 //定时器T0中断函数中断号为interrupt 1
{cntLeft ;//重新给定时器赋初值定时0.5毫秒TL0 0x33;TH0 0xFE;//判读记录爆表变量cnt的值是否小于角度变量的值小于继续给sg90舵机控制线高电平大于等于则给低电平if(cntLeft speedLeft){//前进goFrontLeft();}else{//停止stopLeft();}//判断cnt是否加到40定时是否20毫秒PWM波形周期if(cntLeft 40){cntLeft 0; //定时到20豪秒cnt从0开始加}
}8.5主C文件内每隔1.5秒改变左右轮速度变量使小车左右轮电机差速运行
调速变量修改代码
while(1)
{speedRight 40;speedLeft 40;Delay1500ms();speedRight 10; //10为最小速度驱动再小就无法运行speedLeft 40;Delay1500ms();speedRight 15;speedLeft 35;Delay1500ms();speedRight 20;speedLeft 30;Delay1500ms();speedRight 25;speedLeft 25;Delay1500ms();speedRight 30;speedLeft 20;Delay1500ms();speedRight 35;speedLeft 15;Delay1500ms();speedRight 40;speedLeft 10;Delay1500ms();
}主C文件代码
#include motor.h
#include delay.h
#include uart.h
#include time0.h
#include time1.hextern char speedRight;
extern char speedLeft;void main()
{initTime0();initTime1();UartInit();while(1){speedRight 40;speedLeft 40;Delay1500ms();speedRight 10; //10为最小速度驱动再小就无法运行speedLeft 40;Delay1500ms();speedRight 15;speedLeft 35;Delay1500ms();speedRight 20;speedLeft 30;Delay1500ms();speedRight 25;speedLeft 25;Delay1500ms();speedRight 30;speedLeft 20;Delay1500ms();speedRight 35;speedLeft 15;Delay1500ms();speedRight 40;speedLeft 10;Delay1500ms();}
}结束语 很高兴您能看到这里点个赞再走呗。谢谢您啦