本文主要是介绍基于51单片机下通过蓝牙串口控制LCD1602屏幕显示步进电机正反转以及转速,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
通过蓝牙串口控制LCD1602屏幕显示正反转以及转速
简 述:
-
通过蓝牙串口发送指定数据到STC89C52RC单片机,控制28BYJ-48步进电机正转或者反转或者速度的快中慢,然后51单片机,
做相应的判断,在LCD1602屏幕上显示正反转状态 以及 转速 -
演示视频放在了哔哩哔哩上: https://www.bilibili.com/video/av61543899
-
完整程序的已经放在了文末。
二.准备
1. 单片机 :个人嫌麻烦用的开发板,可以使用STM32或者其他类型;
2. 24BYJ-48步进电机:该步进电机为4相5线式
4. LCD1602 有条件可以试试OLED12864之类
5. HC-05 蓝牙模块
三. 原理图
【还没画完,半成品,最近要忙着准备2019年的电赛了,所有顾不上但大概的东西都在这儿了】
四. 程序
1.说明
- 已经将程序整体工程化,方便移植,比如STM32,STM8等单片机上
- 思路:
- 1.蓝牙串口发送特定字符给51单片机
- 2.单片机接收到消息触发串口中断,进入串口中断服务函数
(注意:服务函数不要写过多,中断服务函数应该尽量简短,一般是做一些标识,不要在中断中做延时之类的
占用CPU很长时间的工作。----快进快出) - 3.中断函数制作判断标志位,然后给到其他函数去做具体事例
- 4.主函数中判断并做出相应的动作和屏幕显示
- 有个问题:主函数判断不知道为什么不能用switch,无法判断出来,希望看完知道的大佬指教下!
2. LCD1602显示程序(lcd.c)
#include "lcd.h"
sbit E = P2 ^ 7; //1602使能引脚
sbit RW = P2 ^ 6; //1602读写引脚
sbit RS = P2 ^ 5; //1602数据/命令选择引脚/********************************************************************
* 名称 : bit Busy(void)
* 功能 : 这个是一个读状态函数,读出函数是否处在忙状态
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/
bit Busy(void)
{bit busy_flag = 0;RS = 0;RW = 1;E = 1;delay3();busy_flag = (bit)(P0 & 0x80);E = 0;return busy_flag;
}/********************************************************************
* 名称 : wcmd(uchar del)
* 功能 : 1602命令函数
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/
void wcmd(uchar del)
{while(Busy());RS = 0;RW = 0;E = 0;delay3();P0 = del;delay3();E = 1;delay3();E = 0;
}/********************************************************************
* 名称 : wdata(uchar del)
* 功能 : 1602写数据函数
* 输入 : 需要写入1602的数据
* 输出 : 无
***********************************************************************/void wdata(uchar del)
{while(Busy());RS = 1;RW = 0;E = 0;delay3();P0 = del;delay3();E = 1;delay3();E = 0;
}/********************************************************************
* 名称 : L1602_init()
* 功能 : 1602初始化,请参考1602的资料
* 输入 : 无
* 输出 : 无
***********************************************************************/
void L1602_init(void)
{wcmd(0x38);Delay(5);wcmd(0x38);Delay(5);wcmd(0x38);Delay(5);wcmd(0x38);wcmd(0x08);wcmd(0x0c);wcmd(0x04);wcmd(0x01);
}//不用注释掉,防止报错未调用该函数 此处代码中未用到所以注释了
///********************************************************************
//* 名称 : L1602_char(uchar hang,uchar lie,char sign)
//* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下
// L1602_char(1,5,'b')
//* 输入 : 行,列,需要输入1602的数据
//* 输出 : 无
//***********************************************************************/
//void L1602_char(uchar hang, uchar lie, char sign)
//{
// uchar a;
// if(hang == 1) a = 0x80;
// if(hang == 2) a = 0xc0;
// a = a + lie - 1;
// wcmd(a);
// wdata(sign);
//}/********************************************************************
* 名称 : L1602_string(uchar hang,uchar lie,uchar *p)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下L1602_string(1,5,"ab cd ef;")
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void L1602_string(uchar hang, uchar lie, uchar *p)
{uchar a, b = 0;if(hang == 1) a = 0x80;if(hang == 2) a = 0xc0;a = a + lie - 1;while(1){wcmd(a++);if((*p == '\0') || (b == 16)) break;b++;wdata(*p);p++;}
}
3.控制步进电机正反转(motor.c)
#include "motor.h"int forward(uchar speed) //控制正转
{uchar i;for(i = 0; i < 8; i++){P1 = F_Rotation[i]; //顺时针转动Delay(speed); //改变转速}return speed;
}int back(uchar speed) //控制反转
{uchar i;for(i = 0; i < 8; i++){P1 = B_Rotation[i]; //逆时针转动Delay(speed); //改变转速}return speed;
}
4.开启串口定时器,且设置波特率为9600(Uart.c)
#include "Uart.h"void UartInit() //9600bps@11.0592MHz
{SCON = 0x50; // SCON: 模式1, 8-bit UART, 使能接收TMOD |= 0x20;TH1 = 0xfd; //波特率9600 初值TL1 = 0xfd;TR1 = 1;EA = 1; //打开总中断ES = 1; //打开串口中断
}
5.main.c
#include "123.h"main()
{L1602_init();Delay(100);UartInit();while(1){panduan();}
}void panduan()
{if(flag == 0) //判断正转{led = 0; //状态灯灭forward(speed); //电机执行正转且返回速度送给下面进行判断if(speed == 1) //如果为1 则速度显示为快速{LCD_display("Mo Dir: Goto","Mo Spd: Fast ^_^");}else if(speed == 3) //如果为3 则速度显示为中速{LCD_display("Mo Dir: Goto","Mo Spd: Norl ^_^");}else if(speed == 5) //如果为5 则速度显示为慢速{LCD_display("Mo Dir: Goto","Mo Spd: Slow ^_^");}}if(flag == 1) //判断反转{led = 1; //状态灯亮back(speed);if(speed == 1) //电机执行正转且返回速度送给下面进行判断{LCD_display("Mo Dir: Back","Mo Spd: Fast ^_^");}else if(speed == 3){LCD_display("Mo Dir: Back","Mo Spd: Norl ^_^");}else if(speed == 5){LCD_display("Mo Dir: Back","Mo Spd: Slow ^_^");}}
}void Usart() interrupt 4 //中断服务函数
{uchar n; //定义临时变量
// led = 1;if(RI) //判断是接收中断产生{RI = 0; //标志位清零n = SBUF; //读入缓冲区的值switch(n){case'0': //控制正转flag = 0;break;case'1': //控制反转flag = 1;break;case'2': //控制速度为慢speed = 5;break;case'3': //控制速度为中等speed = 3;break;case'4': //控制速度为快speed = 1;break;}TI = 1;SBUF = n; //把接收到的值再发回}if(TI) //如果是发送标志位,清零TI = 0;
}
五.源代码
完整程序的已经放在了github上:
https://github.com/lbmcu/LCD1602-display-in-the-motor
这篇关于基于51单片机下通过蓝牙串口控制LCD1602屏幕显示步进电机正反转以及转速的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!