通过蓝牙串口发送指定数据到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年的电赛了,所有顾不上但大概的东西都在这儿了】
#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++;
}
}
#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;
}
#include "Uart.h"
void UartInit() //[email protected]
{
SCON = 0x50; // SCON: 模式1, 8-bit UART, 使能接收
TMOD |= 0x20;
TH1 = 0xfd; //波特率9600 初值
TL1 = 0xfd;
TR1 = 1;
EA = 1; //打开总中断
ES = 1; //打开串口中断
}
#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/Long1373766226/LCD1602-display-in-the-motor