基于51单片机下通过蓝牙串口控制LCD1602屏幕显示步进电机正反转以及转速

本文主要是介绍基于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	蓝牙模块

步进电机
LCD1602
蓝牙模块

三. 原理图
【还没画完,半成品,最近要忙着准备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屏幕显示步进电机正反转以及转速的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/351087

相关文章

Python异步编程中asyncio.gather的并发控制详解

《Python异步编程中asyncio.gather的并发控制详解》在Python异步编程生态中,asyncio.gather是并发任务调度的核心工具,本文将通过实际场景和代码示例,展示如何结合信号量... 目录一、asyncio.gather的原始行为解析二、信号量控制法:给并发装上"节流阀"三、进阶控制

使用DrissionPage控制360浏览器的完美解决方案

《使用DrissionPage控制360浏览器的完美解决方案》在网页自动化领域,经常遇到需要保持登录状态、保留Cookie等场景,今天要分享的方案可以完美解决这个问题:使用DrissionPage直接... 目录完整代码引言为什么要使用已有用户数据?核心代码实现1. 导入必要模块2. 关键配置(重点!)3.

SpringSecurity 认证、注销、权限控制功能(注销、记住密码、自定义登入页)

《SpringSecurity认证、注销、权限控制功能(注销、记住密码、自定义登入页)》SpringSecurity是一个强大的Java框架,用于保护应用程序的安全性,它提供了一套全面的安全解决方案... 目录简介认识Spring Security“认证”(Authentication)“授权” (Auth

python之流程控制语句match-case详解

《python之流程控制语句match-case详解》:本文主要介绍python之流程控制语句match-case使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录match-case 语法详解与实战一、基础值匹配(类似 switch-case)二、数据结构解构匹

如何使用C#串口通讯实现数据的发送和接收

《如何使用C#串口通讯实现数据的发送和接收》本文详细介绍了如何使用C#实现基于串口通讯的数据发送和接收,通过SerialPort类,我们可以轻松实现串口通讯,并结合事件机制实现数据的传递和处理,感兴趣... 目录1. 概述2. 关键技术点2.1 SerialPort类2.2 异步接收数据2.3 数据解析2.

Java反转字符串的五种方法总结

《Java反转字符串的五种方法总结》:本文主要介绍五种在Java中反转字符串的方法,包括使用StringBuilder的reverse()方法、字符数组、自定义StringBuilder方法、直接... 目录前言方法一:使用StringBuilder的reverse()方法方法二:使用字符数组方法三:使用自

Spring Security注解方式权限控制过程

《SpringSecurity注解方式权限控制过程》:本文主要介绍SpringSecurity注解方式权限控制过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、摘要二、实现步骤2.1 在配置类中添加权限注解的支持2.2 创建Controller类2.3 Us

Python中如何控制小数点精度与对齐方式

《Python中如何控制小数点精度与对齐方式》在Python编程中,数据输出格式化是一个常见的需求,尤其是在涉及到小数点精度和对齐方式时,下面小编就来为大家介绍一下如何在Python中实现这些功能吧... 目录一、控制小数点精度1. 使用 round() 函数2. 使用字符串格式化二、控制对齐方式1. 使用

Springboot控制反转与Bean对象的方法

《Springboot控制反转与Bean对象的方法》文章介绍了SpringBoot中的控制反转(IoC)概念,描述了IoC容器如何管理Bean的生命周期和依赖关系,它详细讲解了Bean的注册过程,包括... 目录1 控制反转1.1 什么是控制反转1.2 SpringBoot中的控制反转2 Ioc容器对Bea

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定