两个51单片机之间进行串行通信

两个51单片机之间进行串行通信文章目录案例介绍 案例分析 硬件设计案例介绍 利用单片机 a 将一段流水灯控制程序发送到单片机 b 来控制单片机 b 的 P1 口 点亮 8 位 LED 灯 案例分析 a 完成发送 b 完成接收 编写程序设置 a 令 SM0 0 SM1 1 串行口工作方式 1 设置 b 令 SM0 0 SM1 1 REN 1 使接收允许 1 数据发送程序 include reg51 h unsignedchar 0xfe 0xfd 0xfb 0xf7 0xef 0xdf 0xbf 0x7f reg51 h

前言:利用a单片机按键按下发送数值给单片机b,b单片机收到对应的数值,来控制从单片机b的P1口,点亮对于的8位LED灯。

提示:本次博主都把软件和硬件全部介绍,也希望对大家有帮助,有什么好的意见或者建议,能告诉博主将会十分感激。


一、项目分析

两个单片机都使用串口方式1进行通信,并且必须保证两单片机通信波特率完全一致,否则接受不到正确的数。在发送数据时,向SBUF中写入一个数据后,使用 “while(!TI);” 等待是否发送完毕,因为当发送完毕后,TI被硬件置1,然后才退出 “while(!TI);” 接下来在将TI手动清零,同理,在接受数据时,在中断服务程序中也需要将接受中断标志位RI置零。

二、程序设计

a完成发送,b完成接收。编写程序设置a,令SM0=0,SM1=1(串行口工作方式1)。设置b,令SM0=0,SM1=1,REN=1,使接收允许。

(1)a单片机程序[数据发送程序]

#include  
      //单片机头文件 //宏定义 #define uint unsigned int  #define uchar unsigned char //位声明 sbit k1=P2^0; sbit k2=P2^1; sbit k3=P2^2; sbit k4=P2^3; sbit k5=P2^4; sbit k6=P2^5; sbit k7=P2^6; sbit k8=P2^7; //函数声明 void Usart_Init(void); void DelayMs(uint xms); void Send_Data(uchar Key_val); void Keyscan(void); //主函数 void main() { 
     while(1) //循环 { 
     Keyscan(); } } //串口中断初始化 void Usart_Init(void) { 
     TMOD=0X20;//定时器1方式2 TH1=0xF3; //计数器初始值设置,注意波特率是4800 TL1=0xF3; TR1=1;//打开定时器 SM0=0;//设置串口工作方式 SM1=1; EA=1;//打开总中断 ES=1;//打开串口中断 } //延时函数 void DelayMs(uint xms) { 
     uchar i,j; for(i=xms;i>0;i--) for(j=110;j>0;j--); } //发送数据函数 void Send_Data(uchar Key_val) { 
     SBUF=Key_val; //将要发送的数据存入发送缓冲器中 while(!TI); //若发送中断标志位没有置1(正在发送数据),就等待 TI=0; //若发送完成,TI自动置1,这里把它清零 } //按键函数 void Keyscan(void) { 
     uchar Val; //定义局部变量 if(k1==0) //如果按下k1 { 
     DelayMs(10);//消抖 if(k1==0) //确认按下k1 { 
     Usart_Init(); Val=0; } while(!k1); //等待按键释放 Send_Data(Val); //发送“0” } if(k2==0) //如果按下k2 { 
     DelayMs(10);//消抖 if(k2==0) //确认按下k2 { 
     Usart_Init(); Val=1; } while(!k2); //等待按键释放 Send_Data(Val); //发送“1” } if(k3==0) //如果按下k3 { 
     DelayMs(10);//消抖 if(k3==0) //确认按下k3 { 
     Usart_Init(); Val=2; //发送“2” } while(!k3); //等待按键释放 Send_Data(Val); } if(k1==4) //如果按下k4 { 
     DelayMs(10);//消抖 if(k4==0) //确认按下k4 { 
     Usart_Init(); Val=3; //发送“3” } while(!k4); //等待按键释放 Send_Data(Val); } if(k5==0) //如果按下k5 { 
     DelayMs(10);//消抖 if(k5==0) //确认按下k5 { 
     Usart_Init(); Val=4; } while(!k5); //等待按键释放 Send_Data(Val); //发送“4” } if(k6==0) //如果按下k6 { 
     DelayMs(10);//消抖 if(k6==0) //确认按下k6 { 
     Usart_Init(); Val=5; } while(!k6); //等待按键释放 Send_Data(Val); //发送“6” } if(k7==0) //如果按下k7 { 
     DelayMs(10);//消抖 if(k7==0) //确认按下k7 { 
     Usart_Init(); Val=6; } while(!k7); //等待按键释放 Send_Data(Val); //发送“7” } if(k8==0) //如果按下k8 { 
     DelayMs(10);//消抖 if(k8==0) //确认按下k8 { 
     Usart_Init(); Val=7; } while(!k8); //等待按键释放 Send_Data(Val); //发送“7” } } 

(2)b单片机程序[数据接收程序]

#include  
      //单片机头文件 //宏定义 #define uint unsigned int #define uchar unsigned char //位声明 sbit led0=P1^0; sbit led1=P1^1; sbit led2=P1^2; sbit led3=P1^3; sbit led4=P1^4; sbit led5=P1^5; sbit led6=P1^6; sbit led7=P1^7; //定义全局变量 uchar i; //函数声明 void Uart_init(); //主函数 void main() { 
     Uart_init(); //串口初始化 while(1); } //串口初始化函数 void Uart_init() { 
     TMOD=0X20;//定时器1方式2 TH1=0xF3; //计数器初始值设置,注意波特率是4800 TL1=0xF3; TR1=1;//打开定时器 SM0=0;//设置串口工作方式 SM1=1; REN=1; EA=1;//打开总中断 ES=1;//打开串口中断 } //串口中断服务函数 void uart() interrupt 4 { 
     uchar receiveData; i=SBUF; switch(i) { 
     case 0: //收到“0” led0=0; break; case 1: //收到“1” led1=0; break; case 2: //收到“2” led2=0; break; case 3: //收到“3” led3=0; break; case 4: //收到“4” led4=0; break; case 5: //收到“5” led5=0; break; case 6: //收到“6” led6=0; break; case 7: //收到“7” led7=0; break; default: P2=0XFF; break; } receiveData=SBUF; //出去接收到的数据 RI=0; //清除接收中断标志位 } 

三、硬件设计

a单片机与b单片机连线(把这两个程序分别烧写到两块板子上,然后用连接线分别连接两个板子的发送引脚和接收引脚。)

四、功能实现展示

在这里插入图片描述


总结

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/215299.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午2:13
下一篇 2026年3月18日 下午2:14


相关推荐

  • python升级版本命令-CentOS7 下升级Python版本

    python升级版本命令-CentOS7 下升级Python版本来博客园的第一篇博客 以后要坚持养成记录 分享的习惯啊 这样生活才会有痕迹 服务器版本 CentOS7 364 位旧 Python 版本 2 7 5 新 Python 版本 3 8 0 说明 本次配置使用 root 用户进行操作 故在代码中未使用 sudo 语句 请使用非 root 用户留意 1 切换工作目录至 usr local 在 Linux 系统下 路径 usr local 相当于 C ProgremFiles 通常安

    2026年3月19日
    2
  • addr2line 动态库[通俗易懂]

    addr2line 动态库[通俗易懂]一、导读Backtrace中,一般都只有一些地址。但是利用addr2line这个工具,就可以找到对应的代码行。前提条件是可执行程序或者动态链接库编译的时候带-g选项。具体来说,分两种情况:如果关注的一行backtrace位于一个可执行文件中,那么直接addr2line-e<executable><address>如果关注的backtrace位于一个动态链接库中,那么麻烦一些,因为动态链接库的基地址不是固定的。这个时候,首先要把进程的memorymap找来。在L

    2025年6月17日
    4
  • noscript的使用

    noscript的使用HTML noscript 标签 noscript 标签提供无法使用脚本时的替代内容 比方在浏览器禁用脚本时 或浏览器不支持客户端脚本时 noscript 元素可包含普通 HTML 页面的 body 元素中能够找到的所有元素 只有在浏览器不支持脚本或者禁用脚本时 才会显示 noscript 元素中的内容 DOC noscript noscript noscript noscript

    2026年3月16日
    2
  • matlab 求矩阵秩,求Matlab中矩阵的秩和迹 | 学步园[通俗易懂]

    matlab 求矩阵秩,求Matlab中矩阵的秩和迹 | 学步园[通俗易懂]1、Matlab中求矩阵的秩>>a=rand(6)a=0.81470.27850.95720.79220.67870.70600.90580.54690.48540.95950.75770.03180.12700.95750.80030.65570.74310…

    2022年5月7日
    48
  • Java和C++的区别

    Java和C++的区别Java和C++的区别:1.Java是解释型语言,所谓的解释型语言,就是源码会先经过一次编译,成为中间码,中间码再被解释器解释成机器码。对于Java而言,中间码就是字节码(.class),而解释器在JVM中内置了。2.C++是编译型语言,所谓编译型语言,就是源码一次编译,直接在编译的过程中链接了,形成了机器码。3.C++比Java执行速度快,但是Java可以利用JVM跨平台。4….

    2022年7月7日
    29
  • autosize 碰到 WebView.

    autosize 碰到 WebView.autosize一般来说一个挺好用的安卓缩放框架.最近碰到了一次失效的时候,积累一下解决办法.覆写Activity.onCreateViewoverridefunonCreateView(name:String,context:Context,attrs:AttributeSet):View?{AutoSize.autoConvertDensityOfGlobal(this)returnsuper.onCreateView(nam

    2022年5月24日
    49

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号