51单片机 您所在的位置:网站首页 蓝牙模块教程 51单片机

51单片机

2023-06-25 19:52| 来源: 网络整理| 查看: 265

一.半双工,全双工和单工区别

半双工:接口任意时刻只能发送数据或者接收数据,并存在最大传输距离限制。

全双工:接口可以同时发送和接收数据,最大吞吐量可达到设备速率,且消除了半双工的物理限制。

单工:接口任意时刻只能发数据。

二.通信分划情况

异步串行通信:由下图可知,我们常用的单片机都是用的Uart通信,因为单片机与电脑的通信速度不一样,而uart通信可以让他们保持通信速度一样进行发送和接收,Uart包括TTL电平的串口和RS232电平的串口;RXD是接收端口,TXD是发送端口,Uart串行通信通过RXD与TXD由他们组成的通信接口叫串行接口,简称串口。

RS232电平:逻辑1为-3v — -15v的电压,逻辑0为3v—15v的电压。

TTL电平:5v为逻辑1,0v为逻辑0.

 三.串口通信接线方式

 四.串口通信与单片机相关的寄存器?

1.51单片机中有两个寄存器与串口通信有关,分别是输入(接收)/输出(发送)数据缓冲器都叫SBUF,都用的99H地址码,但是是两个独立的8位寄存器。

2.看下图可知,单片机接收数据过程(读)和单片机发送数据过程(写)。

 五.波特率

1.Uart异步串行通信,通信双方使用时钟不同,因为双方硬件不同,所以要约定通信速度,叫波特率(波特率可以看成人讲话的速度)。

2.对于电脑来说,别人想做好软件,鼠标点点就可以了,而单片机的波特率则需要写入代码,让电脑与单片机的波特率相同。

六单片机串行通信代码

//接收数据 char datas; datas=SBUF; //发送数据 char datas; SBUF=datas;

七.寄存器配置

 

 

 1.由上图可知,SCON寄存器配置,一般我们SM0,SM1选用工作方式1,是01, SM2为0,REN为1时,则单片机运行接收数据,REN为0时单片机不允许接收数据,这里我们选1,TB8和RB8都为0,TI是发送中断请求标志位,一开始为0,单片机发送一个数据(八位),结束时,TI会置1,表示第一个数据发送成功,需要手动用软件置0,RI为接收中断请求标志位,一开始为0,单片机接收一个数据(8位),结束时,RI会置1,表示第一个数据接收完成,需要手动置0,所以配置SCON=0x50(01010000)。

2. 由上图可知,PCON寄存器配置,(上图打印错误,SMOD=0时波特率不加倍),一般我们选波特率不加倍,所以让SMOD=0即可,其他无需管之前是多少,所以位逻辑与0111 1111,PCON&=0x7F。

 3.我们还要设置单片机的波特率,波特率又与时间有关系,因此使用定时器设置波特率(具体看手册),51单片机串行通信只有定时器的模式2,所以使用8位自动重载,平时使用stc-isp(上图)的波特率计算器来配置波特率。

八.单片机向电脑发送数据代码

//单片机以一秒向pc发送一个字符A数据 #include #include "INTRINS.H" sfr AUXR=0x8E; void Delayms(unsigned char xms) //@11.0592MHz { unsigned char i, j; while(xms--) { _nop_(); _nop_(); _nop_(); i = 11; j = 190; do { while (--j); } while (--i); } } void UartInit(void) //[email protected] { PCON &= 0x7F; //波特率不倍速 SCON = 0x50; //8位数据,可变波特率 AUXR &= 0xBF; //定时器1时钟为Fosc/12,即12T AUXR &= 0xFE; //串口1选择定时器1为波特率发生器 TMOD &= 0x0F; //清除定时器1模式位 TMOD |= 0x20; //设定定时器1为8位自动重装方式 TL1 = 0xFD; //设定定时初值 TH1 = 0xFD; //设定定时器重装值 ET1 = 0; //禁止定时器1中断 TR1 = 1; //启动定时器1 } void Uart_Sendchar(unsigned char Char) { SBUF=Char; while(!TI);//TI一开始为0,!后为1,while(1)卡着,当发送一个字符后,TI为1,此时就跳过 TI=0; } void main() { UartInit();//配置c51串口通信方式 while(1) { Delayms(1000); Uart_Sendchar('A'); } } //单片机以每秒向PC发送字符串 #include #include "INTRINS.H" sfr AUXR =0x8E; void UartInit() { AUXR =0x01; SCON = 0x40;//配置串口1,REN使能不接收,串口模式 TMOD &= 0x0F;//定时器模式 TMOD |= 0x20; TH1 = 0xFD;//9600波特率的初值 TL1 = 0xFD; TR1 = 1;//开始计时 ET1 = 0;//禁止定时器中断 ES =1;//串口中断开启 EA =1; } void Delayms(unsigned char xms) //@11.0592MHz { unsigned char i, j; while(xms--) { _nop_(); _nop_(); _nop_(); i = 11; j = 190; do { while (--j); } while (--i); } } void Uart_SendByte(unsigned char Char) { SBUF=Char; while(TI==0);//一个字符八位,发送8位以后,到第九位时自动中断,TI等于1,需要手动恢复成0 TI=0; } void Uart_SendString(unsigned char *string)//输入字符串,指针只是有了字符串第一个字符的地址,*string就是第一个字符 { while(*string!='\0') { Uart_SendByte(*string);//这里*string就是第一个字符,然后string++,就到下一个 string++; } } void main() { UartInit(); while(1) { Delayms(1000); Uart_SendString("you\r\n"); } }

九.pc发送指令给单片机点灯代码(单片机接收跟单片机发送需要分开,因此用到中断系统)

//pc发送字符数据让单片机点灯 #include #include "INTRINS.H" sbit led4=P2^3; sfr AUXR=0x8E; char data_con; void Delayms(unsigned char xms) //@11.0592MHz { unsigned char i, j; while(xms--) { _nop_(); _nop_(); _nop_(); i = 11; j = 190; do { while (--j); } while (--i); } } void Uart_Init() { AUXR=0x01; SCON=0x50; PCON&=0x7F; TMOD &= 0x0F; //清除定时器1模式位 TMOD |= 0x20; //设定定时器1为8位自动重装方式 TL1 = 0xFD; //设定定时初值 TH1 = 0xFD; //设定定时器重装值 ET1 = 0; //禁止定时器1中断 TR1 = 1; //启动定时器1 EA = 1; //打开中断 ES = 1; } void Uart_Sendchar(unsigned char byte) { SBUF=byte; while(TI==0); TI=0; } void Uart_Sendstring(unsigned char*string) { while(*string!='\0') { Uart_Sendchar(*string); string++; } } void main() { led4=1; Uart_Init(); while(1) { Delayms(1000); Uart_Sendstring("hello\r\n"); } } void Uart_Rountime() interrupt 4 { if(RI==1)//怎么知道数据传进来,RI=1时说明已经有数据了 { RI=0;//恢复 data_con=SBUF; if(data_con=='o')//这里‘o’如果想电脑发送 { led4=0; } if(data_con=='c') { led4=1; } } } //pc发送字符串让led亮灭 #include #include "INTRINS.H" #include sbit switcher=P2^0;//继电器控制外接led亮灭 sbit AUXR=0x8E; char ctm[12]; void Uart_init() { AUXR=0x01; SCON=0x50; PCON&=0x7F; TMOD &= 0x0F; //清除定时器1模式位 TMOD |= 0x20; //设定定时器1为8位自动重装方式 TL1 = 0xFD; //设定定时初值 TH1 = 0xFD; //设定定时器重装值 ET1 = 0; //禁止定时器1中断 TR1 = 1; //启动定时器1 ES=1; EA=1; } void Delayms(unsigned char xms) //@11.0592MHz { unsigned char i, j; while(xms--) { _nop_(); _nop_(); _nop_(); i = 11; j = 190; do { while (--j); } while (--i); } } void Uart_Sendchar(unsigned char Byte) { SBUF=Byte; while(TI==0); TI=0; } void Uart_Sendstring(unsigned char*string) { while(*string!='\0') { Uart_Sendchar(*string); string++; } } void main() { Uart_init(); while(1) { Delayms(1000); Uart_Sendstring("lqyiloveyou\r\n"); } } void Uart_Rountime() interrupt 4//输入字符串的话,例如open,每次只能输入一个字符在重新中断 { static int i=0; if(RI==1) { RI=0; ctm[i]=SBUF; i++; if(i==12) { i=0; memset(ctm,'\0',12); } if(strstr(ctm,"en"))//输入open则亮灯 { switcher=0; i=0; memset(ctm,'\0',12); } if(strstr(ctm,"se"))//输入close则亮灯 { switcher=1; i=0; memset(ctm,'\0',12); } } }

补充知识:每当数组满的时候,或者用了数组想清空的时候用memset函数,strstr(1,2)函数是查找函数,查找1里面有没有2。

十.蓝牙模块(HC-08)

1.如何修改蓝牙名字?

使用USB转TTL电平,使RXD接蓝牙的TXD,TXD接蓝牙的RXD,然后用串口助手写指令让他修改,指令如下。

AT+NAME=xxx  //xxx为名字

 2.蓝牙如何操作单片机,让单片机亮灯?

此时蓝牙就好像pc一样,扫码蓝牙模块上面的二维码,下载app,打开后,输入写入单片机亮灯的指令则开灯,此时单片机的RXD接蓝牙的TXD,TXD接RXD。

3蓝牙让单片机亮灯代码

//蓝牙发指令让继电器开关使外接led亮灭 #include #include "INTRINS.H" #include sbit switcher=P2^0;//继电器控制外接led亮灭 sbit AUXR=0x8E; char ctm[12]; void Uart_init() { AUXR=0x01; SCON=0x50; PCON&=0x7F; TMOD &= 0x0F; //清除定时器1模式位 TMOD |= 0x20; //设定定时器1为8位自动重装方式 TL1 = 0xFD; //设定定时初值 TH1 = 0xFD; //设定定时器重装值 ET1 = 0; //禁止定时器1中断 TR1 = 1; //启动定时器1 ES=1; EA=1; } void Delayms(unsigned char xms) //@11.0592MHz { unsigned char i, j; while(xms--) { _nop_(); _nop_(); _nop_(); i = 11; j = 190; do { while (--j); } while (--i); } } void Uart_Sendchar(unsigned char Byte) { SBUF=Byte; while(TI==0); TI=0; } void Uart_Sendstring(unsigned char*string) { while(*string!='\0') { Uart_Sendchar(*string); string++; } } void main() { Uart_init(); while(1) { Delayms(1000); Uart_Sendstring("lqyiloveyou\r\n"); } } void Uart_Rountime() interrupt 4//输入字符串的话,例如open,每次只能输入一个字符在重新中断 { static int i=0; if(RI==1) { RI=0; ctm[i]=SBUF; i++; if(i==12) { i=0; memset(ctm,'\0',12); } if(strstr(ctm,"en"))//输入open则亮灯 { switcher=0; i=0; memset(ctm,'\0',12); } if(strstr(ctm,"se"))//输入close则灭灯 { switcher=1; i=0; memset(ctm,'\0',12); } } }



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有