单片机实验板功能设计

为验证数据通信内容,让单片机板上的四个按键与android手机客户端上的四个LED灯相互控制;为达到上述基本实验要求,采用单字符传输数据即可,硬件需设计两块相同的单片机电路板,包含单片机最小系统,四路输入,四路输出,MAX232模块,九针插口,由于Zigbee模块与蓝牙模块即插即用,即分别设计四路插口即可。单片机的功能图如下图所示:

实际单片机效果图为:

单片机模块通过蓝牙模块与安卓客户端连接,进而进行数据的传输。

单片机写入的程序如下:

#include<reg52.h>

sbit key1=P2^;//上
sbit key2=P2^;//左
sbit key3=P2^;//右
sbit key4=P2^;//下 sbit led1=P0^;//上
sbit led2=P0^;//左
sbit led3=P0^;//右
sbit led4=P0^;//下 void delay(unsigned int xms)
{
unsigned int i,j;
for(i=xms;i>;i--)
for(j=;j>;j--);
} void Send_bit(unsigned char b)
{
SBUF=b;
while(!TI);//判断是否发送完成
TI=;
} void init(void)
{
SCON=0x50;
TMOD|=0x20;
TH1=0xFA;
TR1=;
EA=;
} void main()
{
init();
ES=;
key1=;//初始化定义按键和小灯泡最开始的值
key2=;
key3=;
key4=;
led1=;
led2=;
led3=;
led4=;
while()
{
if(!key1)//第一个灯的控制上
{
delay();
if(key1==)
{
Send_bit();
}
} if(!key2)//第二个灯的控制下
{
delay();
if(key2==)
{
Send_bit();
}
} if(!key3)//第三个灯的控制左
{
delay();
if(key3==)
{
Send_bit();
}
} if(!key4)//第四个灯的控制右
{
delay();
if(key4==)
{
Send_bit();
}
}
} } void Serial_INT(void)interrupt
{
int a;
if(RI)//如果有接受到字符
{
RI=;
a=SBUF;
if(a=='')
{
led1=!led1;
}
if(a=='')
{
led2=!led2;
}
if(a=='')
{
led3=!led3;
}
if(a=='')
{
led4=!led4;
}
if(TI)//判断与此同时是否有发送,在中断过程中只接受而不发送
{
TI=;
}
}
}

android手机客户端

选用安卓手机,编写安卓程序。设计界面完成“连接”、“断开”和“上”、“下”、“左”、“右”四个方向按键,以及读取连接状态的显示。

安卓软件编写环境:

Android Studio 3.1.2

JRE:1.8.0_152-release-1024-b02 amd64

JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o

通过编程完成各按键功能。界面及功能如下图所示:

下面为android端接收单片机传来的数据,实现截图中间四个模拟led灯亮灭的代码,以及读写数据的代码:

// 该Handler从BluetoothChatService中获取信息
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_STATE_CHANGE:
if (D)
Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1); switch (msg.arg1)
{
case BluetoothChatService.STATE_CONNECTED:
mTitle.setText(R.string.title_connected_to);
mTitle.append(mConnectedDeviceName);
mConversationView.setText(null);
break; case BluetoothChatService.STATE_CONNECTING:
mTitle.setText(R.string.title_connecting);
break; case BluetoothChatService.STATE_LISTEN:
case BluetoothChatService.STATE_NONE:
mTitle.setText(R.string.title_not_connected);
break;
}
break; case MESSAGE_WRITE:
byte[] writeBuf = (byte[]) msg.obj;
// 自动发送
if (auto == true) { // 自动发送模块
mHandler.postDelayed(runnable, 1000);
} else if (auto == false) {
mHandler.removeCallbacks(runnable);
}
// 发送计数
if (outhex == true) {
String writeMessage = Data_syn.Bytes2HexString(writeBuf);
countout += writeMessage.length() / 2;
outcount.setText("" + countout);
} else if (outhex == false) {
String writeMessage = null;
try {
writeMessage = new String(writeBuf, "GBK");
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
countout += writeMessage.length();
outcount.setText("" + countout);
}
break;
case MESSAGE_READ: byte[] readBuf = (byte[]) msg.obj; //检错误码计算函数 if (inhex == true) {
String readMessage = " "
+ Data_syn.bytesToHexString(readBuf, msg.arg1);
fmsg += readMessage;
mConversationView.append(readMessage);
// 接收计数,更显UI
countin += readMessage.length() / 2;
incount.setText("" + countin); } else if (inhex == false) {
String readMessage = null;
try {
readMessage = new String(readBuf, 0, msg.arg1, "GBK");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
fmsg += readMessage;
mConversationView.append(readMessage);
// 接收计数,更新UI
countin += readMessage.length();
incount.setText("" + countin); //将字符型的readmessage转换为int型的
int messAge=Integer.valueOf(readMessage); //对接收到的控制指令进行计数,分别表示上下左右的次数 if(messAge==1){
countI=countI+1;
//Toast.makeText(BluetoothChat.this,"I:"+countI,Toast.LENGTH_SHORT).show(); }else {
if(messAge==2){
countJ=countJ+1;
//Toast.makeText(BluetoothChat.this,"J:"+countJ,Toast.LENGTH_SHORT).show();
}else {
if (messAge==3){
countK=countK+1;
//Toast.makeText(BluetoothChat.this,"K:"+countK,Toast.LENGTH_SHORT).show();
}else {
countL=countL+1;
//Toast.makeText(BluetoothChat.this,"L:"+countL,Toast.LENGTH_SHORT).show();
}
}
} //根据上面的次数,进行背景的变换,即模拟led亮灭
switch (messAge){
case 1: {
if (countI % 2 == 1) {
upled.setImageResource(R.drawable.circle);//更换背景
} else {
upled.setImageResource(R.drawable.circleline);
}
} case 2: {
if (countJ % 2 == 1) {
downled.setImageResource(R.drawable.circle);//更换背景
} else {
downled.setImageResource(R.drawable.circleline);
}
}
case 3: {
if (countK % 2 == 1) {
leftled.setImageResource(R.drawable.circle);//更换背景
} else {
leftled.setImageResource(R.drawable.circleline);
}
}
case 4:{
if(countL % 2==1) {
rightled.setImageResource(R.drawable.circle);//更换背景
}else {
rightled.setImageResource(R.drawable.circleline);
}
}
} }
break;
case MESSAGE_DEVICE_NAME:
// 保存已连接设备的名称
mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
Toast.makeText(getApplicationContext(),
"连接到 " + mConnectedDeviceName, Toast.LENGTH_SHORT)
.show();
break;
case MESSAGE_TOAST:
Toast.makeText(getApplicationContext(),
msg.getData().getString(TOAST), Toast.LENGTH_SHORT)
.show();
break;
}
}
};

android端点击上下左右控制单片机端小灯亮灭的代码实现,即点击按钮,发送不同的字符01、02、03、04控制亮灭。

功能演示部分截图

单片机与android手机通信(控制LED小灯亮灭)的更多相关文章

  1. 【.NET 与树莓派】PWM 调节LED小灯的亮度

    在开始本文内容之前,老周先纠正一个错误.在上一篇中,提到过 Arduino 开发板的 Vin 引脚,文中老周说这个供电口的输入电压不能高于 5.5V.这里有错,被卖家给的使用说明忽悠了,上 Ardui ...

  2. Android项目——触摸按键控制LED

    一.Android Studio应用编程 1.应用程序界面layout对应的界面是activity_main.xml,后台对应的java文件是MainActivity.java,修改activity_ ...

  3. Android 手机卫士14--Widget窗口小部件AppWidgetProvider

    1.AndroidManifest.xml根据窗体小部件广播接受者关键字android.appwidget.action.APPWIDGET_UPDATE 搜索android:resource=&qu ...

  4. CC2530学习路线-基础实验-GPIO 按键控制LED灯亮灭(2)

    目录 1.前期预备知识 1.1 新大陆Zigbee模块按键电路图 1.2 CC2530相关寄存器 1.3 CC2530中断走向图 1.4 使用C语言为51单片机编写中断程序 1.5 *函数指针 2. ...

  5. CC2530学习路线-基础实验-GPIO 控制LED灯亮灭(1)

    目录 1.前期预备知识 1.1 新大陆ZigBee模块LED灯电路 1.2 CC2530相关寄存器 1.3 寄存器操作技巧 1.4 CPU空转延时 1.4 操作流程图 2.程序代码 The End 1 ...

  6. 嵌入式Linux LED小灯点亮实验

    问:怎么写LED驱动程序? 1.搭建一个字符驱动的框架(上一节已经完成) 2.完善硬件的操作 问:驱动里操作硬件寄存器与单片机操作硬件寄存器有什么不一样的地方? 答:单片机操作的寄存器地址是物理地址, ...

  7. CC2530学习路线-基础实验-定时器控制LED灯亮灭(3)

    目录 1. 前期预备知识 1.1 定时器中断触发 1.2 相关寄存器 1.3 寄存器相关问题 1.4 T1.T3定时器初始化流程 2 程序及代码 THE END 1. 前期预备知识 1.1 定时器中断 ...

  8. cc2530 T3定时器控制引脚P1_1的亮灭

    /**************************************************************************** * 文 件 名: main.c * 作 者: ...

  9. 基于arm开发板四个按键控制四个灯亮

    基于s5pv2410,cortex a8的四个按键每一个按键点了对应的灯 对于用汇编来编程的话不难,重点在于数据手册,电路图,管脚的看懂 直接上代码 .globl _start_start: ldr ...

随机推荐

  1. 6.方法_EJ

    第38条: 检查参数的有效性 对于这一条,最常见的莫过于检查参数是否为null. 有时出现调用方未检查传入的参数是否为空,同时被调用方也没有检查参数是否为空,结果这就导致两边都没检查以至于出现null ...

  2. 网页导航栏 html + css的代码实现

    一般来讲,我们的网页导航栏是这么个模式来构建在结构上:1.首先我们需要给导航栏的div 给个类名 一般为nav2.然后就是一个无序表格 3.由于导航栏的文字一般都是链接用来跳转页面 要在li里面包含一 ...

  3. 多线程编程CompletableFuture与parallelStream

    一.简介 平常在页面中我们会使用异步调用$.ajax()函数,如果是多个的话他会并行执行相互不影响,实际上Completable我理解也是和它类似,是java 8里面新出的异步实现类,Completa ...

  4. loadrunner 脚本优化-检查点设置

    脚本优化-检查点设置 by:授客 QQ:1033553122 VuGen判断脚本是否执行成功是根据服务器返回的状态来确定的,如果服务器返回的是HTTP状态为200 OK,那么VuGen就认为脚本正确地 ...

  5. 小程序问题集:保存失败:Error: ENOENT: no such file or directory, open

    问题如图: 当编译的时候 会提示找不到这个文件(index),但是确信项目目录里已经删除了该页面路径,并且app.json的pages列表中也没有该页面:   这时候需要看一下当前已经打开的文件中是否 ...

  6. ubuntu12.0.4开启root用户登陆

    1.命令:sudo passwd root 为root分配密码,按提示进行设置就好. 2.打开终端,输入以下命令: sudo -s 进入root账户下: cd /etc/lightdm       g ...

  7. F5负载的应用IIS日志记录的不是真实IP的处理方法

    如果没有这一项,在服务里添加上 将F5XForwardedFor.dll拷贝到应用目录下 添加筛选器: 名称:F5XForwardedFor 可执行文件:F5XForwardedFor.dll所在的目 ...

  8. OkHttp的缓存

    看到很多小伙伴对OkHttp的缓存问题并不是十分了解,于是打算来说说这个问题.用好OkHttp中提供的缓存,可以帮助我们更好的使用Retrofit.Picasso等配合OkHttp使用的框架.OK,废 ...

  9. c# 采用datatable 快速导入数据至MSSQL的方法分享

    转自:http://www.maomao365.com/?p=5613 摘要:下文讲述使用c#代码快速将dataTable导入至mssql数据库的方法 实现思路:需要将datatable调整为同目标表 ...

  10. 自动化测试基础篇--Selenium浏览器操作

    摘自https://www.cnblogs.com/sanzangTst/p/7462056.html  学习 Selenium 主要提供的是操作页面上各种元素的方法,但它也提供了操作浏览器本身的方法 ...