如何做一个购物网站,网站怎样做反向链接,茂名网页定制,专业嵌入式软件开发串口基本认知 串行接口简称串口#xff0c;也称 串行通信 接口或 串行通讯接口 #xff08;通常指 COM 接口 #xff09;#xff0c;是采用串行通信方 式的 扩展接口 。串行 接口#xff08;Serial Interface #xff09;是指数据一位一位地顺序传送。其特点是 通信线路…串口基本认知 串行接口简称串口也称 串行通信 接口或 串行通讯接口 通常指 COM 接口 是采用串行通信方 式的 扩展接口 。串行 接口Serial Interface 是指数据一位一位地顺序传送。其特点是 通信线路 简 单只要一对传输线就可以实现双向通信可以直接利用电话线作为传输线从而大大降低了成本特别适用于远距离通信但传送速度较慢 是设备间接线通信的一种方式 数据一位一位地顺序传送 双向通信全双工 传送速度相对较慢 串口关于电器标准和协议 串行接口按电气标准及协议来分包括 RS-232-C 、 RS-422 、 RS485 等。 RS-232-C 、 RS-422 与 RS-485 标准只对接口的电气特性做出规定不涉及接插件、电缆或协议。 RS-232 也称为标准串口最常用的一种串行通讯接口比如我们电脑主机的9针串口最高速率是20kb/sRS-232是为点对点设计的最长传输距离为15m适合本地设备之间的通信。 RS-422 支持点对点的双向通信最大传输距离为1219米最大传输速率为10Mb/s。 RS-482 是从RS-422基础上发展而来的无论四线还是二线连接方式总线上可多接32个设备。 串口的电平 异步串行是指 UART Universal Asynchronous Receiver/Transmitter 通用异步接收 / 发送。 UART 包含 TTL 电平的 串口 和 RS232 电平的串口 所以串口的概念比UART大一点。 怎么理解异步通信 由于单片机和电脑不同设备的频率和配置不同因此CPU运行速度不同所以各自使用各自的时钟来相互配合。 RS232电平和TTL电平有什么区别 对于RS232逻辑1是 -3 ~ -15V的电压逻辑0是 3 ~ 15V 的电压。 而TTL电平是Transistor-Transistor Logic即晶体管-晶体管逻辑的简称TTL电平信号应用广泛是因为其数据表示采用二进制规定5v等价于逻辑10v等价于逻辑0。 在数字电路中由TTL电子元器件组成电路的电平是个电压范围规定 输出高电平2.4V输出低电平0.4V; 输入高电平2.0V输入低电平0.8V; 串口通信 RXD数据输入引脚数据接受STC89系列对应P3.0口TXD数据发送引脚数据发送STC89系列对应P3.1口接线方式 笔记本电脑通过TTL电平和单片机通讯TX发送线端口RX接受线端口并使用CH340进行USB转TTL。
串口编程要素
串口的结构如下图所示 通过定时器T1计时由T1产生溢出率作为波特率发生器。 两个数据缓冲器SBUF。分别是发送数据的发送寄存器读取数据的接收寄存器。串口写入时写入的是发送寄存器即数据向发送寄存器SBUF写入。向串口读时读出的是接收寄存器即数据由接收寄存器SBUF读出。 定时器1产生波特率 串口一般使用定时器1模式2八位自动重装模式来产生溢出率从而产生波特率。而且在配置定时器相关的寄存器时不用配置定时器中断只是使用定时器1来产生波特率的功能。 移位寄存器在接受控制器的控制下将输入的数据逐位移入接收SBUF。 串行控制寄存器SCONSCON的功能是控制串行通信口的工作方式以及工作的状态。 输入 / 输出数据缓冲器都叫做 SBUF , 都用 99H 地址码但是是两个独立的 8 位寄存器 代码体现为 想要接收数据 char data SBUF(将缓存器的值读取到data即单片机读取SBUF的数据存入到data中)想要发送数据 SBUF data (将data的值写入缓存器即单片机发送data到SBUF中 再次回忆UART的概念”由于单片机和电脑不同设备的频率和配置不同因此CPU运行速度不同所以各自使用各自的时钟来相互配合。” 所以双方需要约定通讯速度这个速度就叫做波特率对于电脑来说别人做好了软件鼠标点点就能配置好而单片机的波特率则需要自己写代码。 对于电脑来说需要点击配置的东西是 所以在代码中我们也需要配置波特率校验位停止位。那在代码中的这些如何进行设置答案还是和设置定时器模式一样要操控寄存器。 而且也和定时器一样代码也可以从stc-isp助手里面得到 注意这里的波特率设置应该和之前电脑设置的波特率 串行通信口的控制寄存器
1 串行控制寄存器SCON SCON寄存器用来控制串行通信的工作方式及反映串行口的工作状态。SCON的地址是98H,可位寻址。如下图所示。 通过配置SCON寄存器来对串行通信的工作模式进行控制。 说说几个常用的位 SM0和SM1组合确定串行口的模式不同的模式下波特率不同功能也不同下面会详细介绍不同模式下的波特率该如何计算。REN,允许/禁止串行接收控制位。 由软件置位REN,即REN1为允许串行接收状态,可启动串行口接收数据。TI,发送中断请求标志位。主机通过串行口发送数据发送完成后TI会置1向串口申请中断如果TI为1 就表示SUBF的数据已经发送完成了要手动将TI位清零。(即SBUFData)RI,接收中断请求标志位。从机接收到主机通过串行口接收到的数据后RI会置1即会串口申请中断如果RI为1 就表示数据已经通过SBUF读取完成了要手动将RI位清零。(即DataSBUF) 2 电源控制寄存器PCON 这里我们只需要知道SMOD是啥就可以了。 SMOD位就是波特率是否加倍若SMOD0,波特率不变。SMOD1波特率加倍。SMOD默认为0。 3 配置寄存器
配置SCON寄存器 上图就是SCON寄存器的位图下面以串口通信的模式1来举例。 模式1那么SM0和SM1就要配置成 0 1注意这里SM0和SM1决定串口通信的模式REN可置1置1就是允许串行通信口接收数据当不需要接收数据的时候可以置0。 后面的几位直接不看一般用不到TI和RI,也默认为0当接收数据或发送数据的时候会由硬件置1继而触发中断这时要由软件置1。 这样SCON寄存器就配置好了。 这样我的SCON配置如下
SCON0x40; //方式1 REN置0 禁止数据接收的控制位 0100 0000
SCON0x50; //方式1 REN置1 允许数据接收的控制位 0101 0000 配置PCON寄存器
我们只需要明确一点我的波特率是否需要加倍如果加倍那么PCON的第一位SMOD就要置 这样我的PCON就配置好了如加倍不倍速可以不写
PCON 0x8F; //波特率加倍1.代码实现单片机向电脑发送一个字符
#include reg52.h
#include intrins.h //这个库加了delay函数里面的nop()才不会报错sbit led1 P3^7;//根据原理图电路图设备变量led1指向P3组IO口的第7口
sbit led2 P3^6;//根据原理图电路图设备变量led2指向P3组IO口的第6口sfr AUXR 0x8E;//配置了这句话才可以在UART的初始化里写AUXR寄存器原因见STC89系列的手册void Delay1000ms() //11.0592MHz
{unsigned char i, j, k;_nop_();i 8;j 1;k 243;do{do{while (--k);} while (--j);} while (--i);
}void UartInit() //9600bps11.0592MHz
{PCON 0x7F; //波特率不倍速SCON 0x50; //8位数据,可变波特率 0101 0000AUXR 0xBF; //定时器1时钟12T模式AUXR 0xFE; //串口1选择定时器1为波特率发生器TMOD 0x0F; //设置定时器1模式TMOD | 0x20; //设置定时器1为8位自动重装方式TL1 0xFD; //设置定时初始值TH1 0xFD; //设置定时重载值ET1 0; //禁止定时器1中断TR1 1; //启动定时器1
}void main()
{char data_msg a;//配置C51串口通信发送方式UartInit();while(1){Delay1000ms();//往发送缓冲器写入数据就完成数据的发送SBUF data_msg;} }
实现效果1
2.代码实现单片机向电脑发送字符串
在SCON寄存器中BIT1为TI即每发送一个BYTE一个char变量的大小TI就会被硬件置1根据这个我们可以编写使串口打印字符串
#include reg52.hsbit led1 P3^7;//根据原理图电路图设备变量led1指向P3组IO口的第7口
sbit led2 P3^6;//根据原理图电路图设备变量led2指向P3组IO口的第6口/*
void UartInit(void) //9600bps11.0592MHz
{PCON 0x7F; //波特率不倍速 SMOD在PCON里SCON 0x50; //8位数据,可变波特率AUXR 0xBF; //定时器时钟12T模式AUXR 0xFE; //串口1选择定时器1为波特率发生器TMOD 0x0F; //设置定时器模式TMOD | 0x20; //设置定时器模式TL1 0xFD; //设置定时初始值TH1 0xFD; //设置定时重载值ET1 0; //禁止定时器中断TR1 1; //定时器1开始计时
}
*/void Delay1000ms() //11.0592MHz
{unsigned char i, j, k;i 8;j 1;k 243;do{do{while (--k);} while (--j);} while (--i);
}void UartInit() //9600bps11.0592MHz
{SCON 0x40; //配置串口工作方式1REN不使能接收//配置定时器1,工作方式为8位自动重载TMOD 0x0f;//TMOD | 0x20;TH1 0xFD; TL1 0xFD; //9600波特率的初值TR1 1;//启动定时器}void Send_byte(char data_msg)
{SBUF data_msg;//往发送缓冲器里写入数据就完成了数据的发送while(!TI);//在请求中断时TI 1既TI0等待数据的发送完成响应中断结束后TI 0既TI 1将TI清零TI 0;}void Send_string(char* str)
{while(*str ! \0){Send_byte(*str);str;}
}void main()
{char data_msg a;//配置C51串口通信发送方式UartInit();while(1){Delay1000ms();//往发送缓冲器写入数据就完成数据的发送Send_string(wdnmd\t);} }
效果实现 3.代码实现使用串口点亮单片机LED
在SCON寄存器中BIT0为RI即收到数据后RI位会由硬件置1 我们需要如何接收数据呢 设置阻塞检测接收的数据此方法会影响程序的进程一般不使用 还是中断 查询手册可知使用中断的方式接收指令可以使得响应没有延时。 所以打开UART中断需要打开ES和EA 下方代码块为中断服务子函数模块 // 串口中断函数模板
void Uart_Routine() interrupt 4
{if(RI1) {RI0;}if(TI1){TI0;}
}#include reg52.hsbit D5 P3^7;//根据原理图电路图设备变量led1指向P3组IO口的第7口
sbit led2 P3^6;//根据原理图电路图设备变量led2指向P3组IO口的第6口/*
void UartInit(void) //9600bps11.0592MHz
{PCON 0x7F; //波特率不倍速 SMOD在PCON里SCON 0x50; //8位数据,可变波特率AUXR 0xBF; //定时器时钟12T模式AUXR 0xFE; //串口1选择定时器1为波特率发生器TMOD 0x0F; //设置定时器模式TMOD | 0x20; //设置定时器模式TL1 0xFD; //设置定时初始值TH1 0xFD; //设置定时重载值ET1 0; //禁止定时器中断TR1 1; //定时器1开始计时
}
*/void Delay1000ms() //11.0592MHz
{unsigned char i, j, k;i 8;j 1;k 243;do{do{while (--k);} while (--j);} while (--i);
}void UartInit() //9600bps11.0592MHz
{SCON 0x50; //配置串口工作方式1REN使能接收//配置定时器1,工作方式为8位自动重载TMOD 0x0f;//TMOD | 0x20;TH1 0xFD; TL1 0xFD; //9600波特率的初值TR1 1;//启动定时器}void Send_byte(char data_msg)
{SBUF data_msg;while(!TI);//在请求中断时TI 1既TI0等待数据的发送完成响应中断结束后TI 0既TI 1将TI清零TI 0;}void Send_string(char* str)
{while(*str ! \0){Send_byte(*str);str;}
}void main()
{char data_msg a;char cmd;D5 1;//配置C51串口通信发送方式UartInit();while(1){Delay1000ms();//往发送缓冲器写入数据就完成数据的发送Send_string(wdnmd\t);//怎么知道收到数据查询RI的值如果RT是1收到数据后由硬件置一//非中断触发/*if(RI 1) //RI 1时数据接收完毕{RI 0;//软件复位cmd SBUF; //从SBUF里面读发来的数据if(cmd o){D5 0;//点亮D5}if(cmd c){D5 1;//熄灭D5}}*/} }//中断触发
void Uart_Handler() interrupt 4
{if(RI)//中断处理函数中对于接收中断的响应{RI 0;//清除接收中断标志位cmd SBUF;if(cmd 1){D5 0;//点亮D5}if(cmd 0){D5 1;//熄灭D5}}if(TI){}
}
这次试验就很好的体现了串口的全双工“即可以不断同时的发送和接收数据。
同时注意在”发送缓冲区”中选择文本模式后要注意在文本模式下输入的任何东西都会被认为字符如果输入1则为字符1对应ASCII码中是数字49
4.代码实现使用串口点亮单片机LED
以上的代码实现的是接收字符来点亮LED如果是想要使用字符串来控制点亮LED需要修改代码
#include reg52.h
#include string.h#define SIZE 12
sbit D5 P3^7;//根据原理图电路图设备变量led1指向P3组IO口的第7口
sbit led2 P3^6;//根据原理图电路图设备变量led2指向P3组IO口的第6口char cmd[12];/*
void UartInit(void) //9600bps11.0592MHz
{PCON 0x7F; //波特率不倍速 SMOD在PCON里SCON 0x50; //8位数据,可变波特率AUXR 0xBF; //定时器时钟12T模式AUXR 0xFE; //串口1选择定时器1为波特率发生器TMOD 0x0F; //设置定时器模式TMOD | 0x20; //设置定时器模式TL1 0xFD; //设置定时初始值TH1 0xFD; //设置定时重载值ET1 0; //禁止定时器中断TR1 1; //定时器1开始计时
}
*/void Delay1000ms() //11.0592MHz
{unsigned char i, j, k;i 8;j 1;k 243;do{do{while (--k);} while (--j);} while (--i);
}void UartInit() //9600bps11.0592MHz
{SCON 0x50; //配置串口工作方式1REN使能接收//配置定时器1,工作方式为8位自动重载TMOD 0x0f;//TMOD | 0x20;TH1 0xFD; TL1 0xFD; //9600波特率的初值TR1 1;//启动定时器ES 1;//开启串口中断EA 1;//开启总中断}//TI 发送请求中断标志位是指单片机向电脑发送
//RI 接收请求中断标志位是指单片机接收电脑的消息void Send_byte(char data_msg)
{SBUF data_msg;while(!TI);//在请求中断时TI 1既TI0等待数据的发送完成响应中断结束后TI 0既TI 1将TI清零TI 0;}void Send_string(char* str)
{while(*str ! \0){Send_byte(*str);str;}
}void main()
{char data_msg a;D5 1;//配置C51串口通信发送方式UartInit();while(1){Delay1000ms();//往发送缓冲器写入数据就完成数据的发送Send_string(wdnmd\t);//怎么知道收到数据查询RI的值如果RT是1收到数据后由硬件置一} }void Uart_Handler() interrupt 4
{static int i 0;//静态变量被初始化一次 避免每次发生中断i都会清0if(RI)//中断处理函数中对于接收中断的响应 //如果是RI引起的中断{RI 0;//清除接收中断标志位软件复位cmd[i] SBUF;i;if(i SIZE){i 0;}if(strstr(cmd,open\r\n)){D5 0;//点亮D5i 0;memset(cmd,\0,SIZE);}if(strstr(cmd,close\r\n)){D5 1;//熄灭D5i 0;memset(cmd,\0,SIZE);}}if(TI){}
}
如此一来在串口中输入open“加上换行键再按下发送数据就可以点灯同样输入”close加上换行键再按下发送数据就可以关灯。
使用蓝牙模块HC08进行串口通讯 注意蓝牙的RXD要和串口的TXD相连同理蓝牙的TXD要和串口的RXD相连。使用上左图的蓝牙模块内置波特率9600正好可以对应再使用右图扫码小程序搜索“HC08即可连接成功 注意在串口中是检测换行符结束字符串的 \r’是回车前者使光标到行首 \n’是换行后者使光标下移一格 Unix系统里每行结尾只有“换行”即“\n” Windows系统里面每行结尾是“回车换行”即“\r\n” Mac系统里每行结尾是“回车”,即“\r 以下来自ChatGPT的解答 串口通信中有时需要在发送的数据后面加上\r\n回车换行符这主要是为了满足接收端或显示设备的特定要求确保数据能够被正确解析和显示。 具体来说\r回车符的作用是使光标移动到当前行的最前面而\n换行符的作用则是将光标移动到下一行的当前位置。因此\r\n组合起来可以实现光标跳到下一行的开始位置从而实现数据的换行显示。 在串口通信中如果接收端或显示设备需要按照特定的格式来解析和显示数据那么就需要在发送的数据后面加上相应的控制符。例如在某些情况下接收端可能期望每接收完一行数据后进行一些处理或者显示设备可能需要在每行数据的末尾换行以显示新的数据。在这些情况下就需要在发送的数据后面加上\r\n来实现换行。 需要注意的是不是所有的串口通信都需要加\r\n。是否添加以及添加的方式是\r\n、\n还是其他控制符取决于具体的通信协议和接收端或显示设备的要求。因此在进行串口通信时需要根据实际情况来确定是否需要添加\r\n以及其他控制符。