串口全双工通信与串口中断

这篇具有很好参考价值的文章主要介绍了串口全双工通信与串口中断。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.串口通信编程

STC-ISP串口助手的使用:

串口全双工通信与串口中断

 文本模式和HEX模式的区别:文本模式就是那些可打印的字符。HEX模式就是这些可打印字符对应的16进制。它们都对应相同的ASCII码(用十进制表示)。

  1. 很多小白在程序编写完成后调试时会搞不清楚到底是程序问题还是上位机传送的数据问题,比如在习题3中,到底写成cmd == 1 还是 cmd == '1' 需要简单考虑一下。

代码心得:

  • 当我们想让串口中打印的字符串换行,并且对齐时,需要在字符串后面加上\r\n,注意\r和\n缺一不可,它不像我们写C语言程序时只用转义字符'\n'代表换行,这里是回车加换行的意思。

1、发送中断请求标志位TI:(习题1中使用了TI)

  • 使用原因:在习题1中,我们通过不断往SBUF寄存器写入1个字符的方法来输出字符串,但是发现在给SBUF连续写入字符时没有延时的话PC端不能显示一整个字符串,只能显示一个字符。回忆我们上一节刚刚讲过串行移位寄存器。串口在输出数据时,先往8位的输出数据缓冲寄存器SBUF中写入数据(1个字符),然后再放到串行输出移位寄存器中,由它将二进制数顺序发送给PC。我们需要注意的是,我们在用单片机给PC发送数据时,单片机先把数据扔到SBUF中,然后经过移位,串口数据移位的过程是需要时间的,所以我们不能以非常快的速度把数据一股脑扔到SBUF中。那么每往SUBF写入一个字符后,隔多少时间进行下一次写入比较合适呢(延时有点多的话,比如说10ms,那么PC上打印的字符串会出现刷屏的现象)?答:查阅手册,我们发现有比延时更好用的东西,就是SCON寄存器的发送中断请求标志位TI,可以控制串口数据的移位时间
  • 原理:目前不使用串口的中断,而是利用了串口中断触发的特点(硬件底层的电气特性),也就是串行发送数据的第8位结束后硬件会自动将TI“置1”。回忆超声波测距传感器demo,我们可以用空循环体等待串行发送数据第8位结束的方法来间接表示一位数据的发送时间,最后软件复位TI。这样就不需要知道你串行发送完一个字节数据需要多少时间,就可以解决PC上打印的字符串刷屏的现象。串口全双工通信与串口中断串口全双工通信与串口中断

  

习题1(向PC发送字符串):【项目工程文件夹

  1. 思路:
    全局变量:
    1.sfr指令直接找到AUXR寄存器: sfr AUXR = 0X8E;    //因为AUXR没有在reg52.h中声明
    1. 调用API2. 初始化串口: UartInit();
    2. while死循环,每隔一秒通过串口给PC发送一个字符串
        2.1 调用API1,软件延时1s: Delay1000ms();
        2.2 调用API4,给输出数据缓冲寄存器SBUF发送一条字符串: sendString("hello shuaige\r\n");
    /* 一级函数:f1、f2、f4 */
    f1. 封装软件延时1s的API,用于每隔一秒给串口缓冲寄存器发送字符串: void Delay1000ms();
    f2. 封装初始化串口的API: void UartInit(void);
        f2.1 禁用ALE信号: AUXR = 0X01;
        f2.2 让串口以方式1工作(8位UART,可变波特率),并允许串口接收: SCON = 0x50;
        f2.3 让定时器1以8位重载工作模式工作:
            TMOD &= 0xDF;
            TMOD |= 0x20;
        f2.4 根据波特率为9600,波特率不翻倍,设置定时器1的初值:
            TH1 = 0xFD;
            TL1 = 0xFD;
        f2.5 定时器开始数数: TR1 = 1;
    f4. 封装给PC发送字符串的API: void sendString(char *str); //形参是字符串的地址
        f4.1 定义一个字符指针变量p用来保存字符串首地址: char *p = str;
        f4.2 while循环,控制循环的变量是*p,当*p != '\0' 时,进入循环,进行单个字符的发送
            f4.2.1 通过指针间接访问字符串字符,再调用API3. 发送单个字符: sendByte(*p);
            f4.2.2 修改循环变量p的值,让指针p偏移: p++;
    /* 二级函数:f3 */
    f3. 封装定时给PC发送一个字符的API: void sendByte(char data_msg);  //形参是字符值
        f3.1 往SBUF寄存器中写入字符data_msg: SBUF = data_msg;
        f3.2 根据串口发送中断触发位TI,利用空循环体暂停程序: while(TI == 0);
        f3.3 程序复位TI: TI = 0;
  2. 代码:
    #include "reg52.h"
    #include "intrins.h"
    
    sfr AUXR = 0x8E;
    
    /* API1. 软件延时1s,用于每隔一秒给串口缓冲寄存器发送字符串 */
    void Delay1000ms();
    /* API2. 初始化串口 */
    void UartInit(void);
    /* API3. 软件延时10ms,用于给串行移位寄存器移动数据预留时间(弃用) */
    void Delay10ms();
    /* API3. 通过串口定时给PC发送一个字符 */
    void sendByte(char data_msg);
    /* API4. 通过串口给PC发送一个字符串 */
    void sendString(char *str);
    
    void main(void)
    {
        UartInit();
    	while(1){
    		Delay1000ms();
    		sendString("hello shuaige\r\n");
    	}
    }
    
    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(void)		//9600bps@11.0592MHz
    {
    	AUXR = 0x01;
    	SCON = 0x50;	//8位UART,允许串口接收
    	TMOD &= 0xDF;
    	TMOD |= 0x20;	//定时器8位重载工作模式
    	TH1 = 0xFD;
    	TL1 = 0xFD;		//9600波特率初值
    	TR1 = 1;
    }
    
    void Delay10ms()		//@11.0592MHz
    {
    	unsigned char i, j;
    
    	i = 18;
    	j = 235;
    	do
    	{
    		while (--j);
    	} while (--i);
    }
    
    void sendByte(char data_msg)
    {
    	SBUF = data_msg;
    	// Delay10ms();
    	while(TI == 0);
    	TI = 0;
    }
    
    void sendString(char *str)
    {
    	char *p = str;
    	while(*p != '\0'){
    		sendByte(*p);
    		p++;
    	}
    }

2、接收中断请求标志位RI:

  • 使用原因:我们上一节刚刚讲过串行移位寄存器。串口在接收数据时,PC先将二进制数顺序发送给串行输入移位寄存器,再由它把数据顺序移动到输入数据缓冲寄存器SBUF中,最后串口从缓冲区接收到数据。同样的,数据经过移位是耗费时间的。所以我们想知道PC什么时候已经完成“通过串口将数据输入给单片机”这件事。而用“接收中断请求标志位RI”来帮助单片机判断是否接收到1字节数据。
  • 原理:目前不使用串口的中断,而是利用了串口中断触发的特点(硬件底层的电气特性),也就是串行接收数据的第8位结束后硬件会自动将RI“置1”。所以我们可以用查询法来判断一个字符是否已经通过串行移位寄存器移动到SBUF寄存器,最后软件复位RI串口全双工通信与串口中断串口全双工通信与串口中断

 

习题2(PC发送字符指令给单片机):PC通过串口点亮单片机LED灯【项目工程文件夹

  • tip1【SCON寄存器的REN“置1”后单片机才能接收数据】:我们在串口初始化函数中已经设置好了串口全双工通信与串口中断串口全双工通信与串口中断

 

  1. 思路:在习题1的基础上修改代码
    全局变量 | 增加
    1. sbit指令找到P3这个I/O口组的第7位P3^7,也就是D5这个LED: sbit ledD5 = P3^7;
    main函数 | 修改
    1. 调用API2. 初始化串口: UartInit();
    2. 让D5先灭: ledD5 = 1;
    3. while死循环,每隔一秒通过串口给PC发送一个字符串,并且从PC接收一个字符数据
        3.1 调用API1,软件延时1s: Delay1000ms();
        3.2 调用API4,给输出数据缓冲寄存器SBUF发送一条字符串: sendString("hello shuaige\r\n");
    	3.3 用“接收中断请求标志位RI”来帮助单片机判断是否接收到1字节数据,判据是RI == 1
            3.3.1 如果是,说明已经接收到1位数据
            	从输入数据缓冲寄存器SBUF中接收数据,保存在变量cmd中: cmd = SBUF;
    			如果cmd是'o',则点亮D5,如果cmd是'C',则关闭D5;
    	3.4 在接受到1字节数据后,程序复位RI: RI = 0;
  2. 代码:
    #include "reg52.h"
    #include "intrins.h"
    
    sfr AUXR = 0x8E;
    sbit ledD5 = P3^7;
    
    /* API1. 软件延时1s,用于每隔一秒给串口缓冲寄存器发送字符串 */
    void Delay1000ms();
    /* API2. 初始化串口 */
    void UartInit(void);
    /* API3. 通过串口给PC发送一个字符 */
    void sendByte(char data_msg);
    /* API4. 通过串口给PC发送一个字符串 */
    void sendString(char *str);
    
    void main(void)
    {
    	char cmd;
        UartInit();
    	ledD5 = 1;
    	while(1){
    		Delay1000ms();
    		sendString("hello shuaige\r\n");
    		if(RI == 1){
    			cmd =  SBUF;
    			if(cmd == 'o'){
    				ledD5 = 0;
    			}else if(cmd == 'c'){
    				ledD5 = 1;
    			}
    		}
    		RI = 0;
    	}
    }
    
    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(void)		//9600bps@11.0592MHz
    {
    	AUXR = 0x01;
    	SCON = 0x50;	//8位UART,允许串口接收
    	TMOD &= 0xDF;
    	TMOD |= 0x20;	//定时器8位重载工作模式
    	TH1 = 0xFD;
    	TL1 = 0xFD;		//9600波特率初值
    	TR1 = 1;
    }
    
    void sendByte(char data_msg)
    {
    	SBUF = data_msg;
    	// Delay10ms();
    	while(TI == 0);
    	TI = 0;
    }
    
    void sendString(char *str)
    {
    	char *p = str;
    	while(*p != '\0'){
    		sendByte(*p);
    		p++;
    	}
    }

2.串口中断

1、为什么需要串口中断?:

  1. 在习题2中,经过测试可以发现电脑通过串口点亮单片机的LED有点延迟,这是因为我们让串口处于全双工通信状态下时,每隔一秒无脑给PC发送数据的同时又要对从PC那里接收到的数据进行判断,这导致PC的数据即使已经被保存在输入数据缓冲寄存器SBUF中了,但是单片机因为还在数数(软件延时)没有马上去取这个数据。
  2. 类比于感应开关盖垃圾桶项目中利用外部中断记住振动传感器的信号,我们需要在单片机串口接收到PC的数据后,立马挂起串口发送的程序,先去响应接收中断,再进行串口发送。
  3. 你可能在有点工作经验的人口中听到“心跳包”这个词,或者hearbeat,意思就是让单片机每隔1秒给PC(或者服务器、上位机)发送一个字符或者一个字符串的心跳包,代表单片机“没死”。然后让我们的具体业务放在另一个“线程”当中。

2、串口中断配置:

  1. 串口中断触发方式:SCON寄存器的TI 和 RI,分别是串口发送中断请求标志(transfer interrupt) 和 串口接收中断请求标志(receive interrupt)。另外我们可以发现串口中断程序没有细分为发送中断还是接收中断,因此需要人为的在中断处理程序根据用串口中断触发方式进行判断。串口全双工通信与串口中断
  2. 串口中断号: 4 ,查阅51芯片手册第6.1小节的表6-1。串口全双工通信与串口中断
  3. 串口中断开关:先在51芯片手册中找到中断系统结构图示意图(6.1小节),发现串口对应的中断开关有ES和EA,再在手册中查找ES(enable serial),我们发现它是IE寄存器的第4位,是串行口1中断允许位串口全双工通信与串口中断

 

 

 

习题3(PC串口中断发送字符给单片机):【项目工程文件夹

  1. 思路:在习题2的基础上修改
    全局变量 | 增加
    1. 定义一个用于接收PC通过串口发送来的字符的全局变量cmd: char cmd;  
    //cmd的传递路线为:SBUF ——> 串口中断(中断4)
    main函数 | 修改
    1. 调用API2. 初始化串口: UartInit();
    2. 让D5先灭: ledD5 = 1;
    3. while死循环,每隔一秒通过串口给PC发送一个字符串
        3.1 调用API1,软件延时1s: Delay1000ms();
        3.2 调用API4,给输出数据缓冲寄存器SBUF发送一条字符串: sendString("hello shuaige\r\n");
    中断: 
    中断4: 封装串口中断的中断服务程序, void Uart_Routine()   interrupt 4
    	4.1 中断处理程序中,对于接收中断的响应,判据是RI == 1
        	4.1.1 在接受到1字节数据后,程序复位RI: RI = 0;
    		4.1.2 从输入数据缓冲寄存器SBUF中接收数据,保存在变量cmd中: cmd = SBUF;
    		4.1.3 对指令cmd进行判断: 如果cmd是'o',则点亮D5,如果cmd是'C',则关闭D5;
        4.2 中断处理程序中,对于发送中断的响应,判据是TI == 1
        	暂时不做任何事情
    /* 一级函数:f1、f2、f4 */ | 修改f2
    f2. 封装初始化串口的API: void UartInit(void); | 增加开启串口中断的语句
        f2.1 禁用ALE信号: AUXR = 0X01;
        f2.2 让串口以方式1工作(8位UART,可变波特率),并允许串口接收: SCON = 0x50;
        f2.3 让定时器1以8位重载工作模式工作:
            TMOD &= 0xDF;
            TMOD |= 0x20;
        f2.4 根据波特率为9600,波特率不翻倍,设置定时器1的初值:
            TH1 = 0xFD;
            TL1 = 0xFD;
        f2.5 定时器开始数数: TR1 = 1;
    	f2.6 开启串口中断:
    		EA = 1;
    		ES = 1;
  2. 代码:
    #include "reg52.h"
    #include "intrins.h"
    
    sfr AUXR = 0x8E;
    sbit ledD5 = P3^7;
    char cmd;
    
    /* API1. 软件延时1s,用于每隔一秒给串口缓冲寄存器发送字符串 */
    void Delay1000ms();
    /* API2. 初始化串口 */
    void UartInit(void);
    /* API3. 通过串口给PC发送一个字符 */
    void sendByte(char data_msg);
    /* API4. 通过串口给PC发送一个字符串 */
    void sendString(char *str);
    
    void main(void)
    {
        UartInit();
    	ledD5 = 1;
    	while(1){
    		Delay1000ms();
    		sendString("hello shuaige\r\n");
    	}
    }
    
    void Uart_Routine()    interrupt 4
    {
    	/* 中断处理程序中,对于接收中断的响应 */
    	if(RI == 1){	
    		RI = 0;
    		cmd = SBUF;
    		if(cmd == 'o'){
    			ledD5 = 0;
    		}else if(cmd == 'c'){
    			ledD5 = 1;
    		}
    	}
    	/* 中断处理程序中,对于发送中断的响应 */
    	if(TI == 1){
    		// 暂时不做任何事情
    	}
    }
    
    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(void)		//9600bps@11.0592MHz
    {
    	AUXR = 0x01;
    	SCON = 0x50;	//8位UART,允许串口接收
    	TMOD &= 0xDF;
    	TMOD |= 0x20;	//定时器8位重载工作模式
    	TH1 = 0xFD;
    	TL1 = 0xFD;		//9600波特率初值
    	TR1 = 1;
    	EA = 1;
    	ES = 1;			//开启串口中断
    }
    
    void sendByte(char data_msg)
    {
    	SBUF = data_msg;
    	// Delay10ms();
    	while(TI == 0);
    	TI = 0;
    }
    
    void sendString(char *str)
    {
    	char *p = str;
    	while(*p != '\0'){
    		sendByte(*p);
    		p++;
    	}
    }

3.串口支持单词型指令控制

1、可能遇到的复杂指令:今后可能会遇到几种数据格式,一些模块将这些指令通过串口传递给单片机

  1. open 或 close
  2. cmd-open 或 cmd-close
  3. c:1:open 或 c:0:close

2、一种串口指令处理方法:

  1. 程序中用字符数组存储串口接收到的字符串指令。
  2. 以第1种数据格式的指令为例,数据缓冲寄存器SBUF读取到的字符串存放在我们定义的字符数组中,但是顺序不一定从第0位开始存放。所以字符串指令“open”或“close”的位置是不确定的,因此不能用strcmp()函数来判断。
  3. 比如我们只关心字符串中有没有子串"op"或"en",或者有没有子串"cl"或"se"。所以我们使用strstr()函数

总结:这种处理方法对于上述指令够用了,但是处理复杂指令时可能会出错。想要完美的解决这一问题需要比较厉害的C语言功底,写出来的代码量也会比较大。

习题4(PC发送字符串指令给单片机):【项目工程文件夹文章来源地址https://www.toymoban.com/news/detail-441486.html

  1. 思路:在习题3的基础上修改
    宏定义 | 增加
    1. 定义符号常量len,用它代表用来接收串口数据的字符数组的长度: #define len 12 
    全局变量 | 增加
    1. 定义一个用于接收串口数据的字符数组cmd[]: char cmd[len];  
    //cmd[]的传递路线为:SBUF ——> 串口中断(中断4)
    中断 | 修改中断4
    中断4: 封装串口中断的中断服务程序, void Uart_Routine()   interrupt 4
        4.1 定义一个静态全局区的静态变量,用来表示数组cmd的下标: static int i = 0;
    	4.2 中断处理程序中,对于接收中断的响应,判据是RI == 1
        	4.2.1 在接受到1字节数据后,程序复位RI: RI = 0;
    		4.2.2 从输入数据缓冲寄存器SBUF中接收数据,保存在数组cmd的第i个元素中: cmd[i] = SBUF;
    		4.2.3 偏移数组下标: i++;
    		4.2.4 判断字符数组cmd是否存满了,判据是 i == len
            	4.2.4.1 如果是,那么需要从头开始存放: i = 0;
                4.2.4.2 否则,那么什么也不做,继续往下执行
            //内在逻辑:由于cmd长度的限制,当字符串指令超过len时,我们需要覆盖掉原先的字符
            4.2.5 判断当前字符串cmd中是否含有子串"en",判据是strstr(cmd,"en")!=NULL
            	4.2.5.1 如果是,说明我们大概率读到了open,代表点亮LED
                	点亮D5这个LED: ledD5 = 0;
    				既然已经完成命令,我们希望SBUF中的数据能够从头开始存放新的指令: i = 0;
    				清空cmd字符串的内容: memset(cmd, '\0', len);
    			4.2.5.2 否则,如果字符串cmd中含有子串"se",说明我们大概率读到了close
                	熄灭D5这个LED: ledD5 = 1;
    				既然已经完成命令,我们希望SBUF中的数据能够从头开始存放新的指令: i = 0;
    				清空cmd字符串的内容: memset(cmd, '\0', len);
        4.3 中断处理程序中,对于发送中断的响应,判据是TI == 1
        	暂时不做任何事情
  2. 代码:
    #include "reg52.h"
    #include "intrins.h"
    #include <string.h>
    
    #define len 12
    sfr AUXR = 0x8E;
    sbit ledD5 = P3^7;
    char cmd[len];
    
    /* API1. 软件延时1s,用于每隔一秒给串口缓冲寄存器发送字符串 */
    void Delay1000ms();
    /* API2. 初始化串口 */
    void UartInit(void);
    /* API3. 通过串口给PC发送一个字符 */
    void sendByte(char data_msg);
    /* API4. 通过串口给PC发送一个字符串 */
    void sendString(char *str);
    
    void main(void)
    {
        UartInit();
    	ledD5 = 1;
    	while(1){
    		Delay1000ms();
    		sendString("hello shuaige\r\n");
    	}
    }
    
    void Uart_Routine()    interrupt 4
    {
    	static int i = 0;	//静态全局区的变量
    	/* 中断处理程序中,对于接收中断的响应 */
    	if(RI == 1){	
    		RI = 0;
    		cmd[i] = SBUF;
    		i++;
    		if(i == len){
    			i = 0;
    		}
    		if(strstr(cmd,"en")!=NULL){
    			ledD5 = 0;
    			i = 0;
    			memset(cmd,'\0',len);
    		}else if(strstr(cmd,"se")!=NULL){
    			ledD5 = 1;
    			i = 0;
    			memset(cmd,'\0',len);
    		}
    	}
    	/* 中断处理程序中,对于发送中断的响应 */
    	if(TI == 1){
    		// 暂时不做任何事情
    	}
    }
    
    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(void)		//9600bps@11.0592MHz
    {
    	AUXR = 0x01;
    	SCON = 0x50;	//8位UART,允许串口接收
    	TMOD &= 0xDF;
    	TMOD |= 0x20;	//定时器8位重载工作模式
    	TH1 = 0xFD;
    	TL1 = 0xFD;		//9600波特率初值
    	TR1 = 1;
    	EA = 1;
    	ES = 1;			//开启串口中断
    }
    
    void sendByte(char data_msg)
    {
    	SBUF = data_msg;
    	// Delay10ms();
    	while(TI == 0);
    	TI = 0;
    }
    
    void sendString(char *str)
    {
    	char *p = str;
    	while(*p != '\0'){
    		sendByte(*p);
    		p++;
    	}
    }

到了这里,关于串口全双工通信与串口中断的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STC-ISP烧录过程中显示“正在检测目标单片机...”问题的解决办法

    作者简介:大家好,我是⭐高高同学⭐。 个人主页:m0_60935947的博客_高高同学_CSDN博客 本系列记录博主学习51单片机开发板的全过程,旨在与大家一起学习进步! 学习不迷路: 😊点赞+评论+收藏😊 !将是我持续更新的动力! 初学51单片机时,可能在使用STC-ISP过程中遇到“

    2024年02月08日
    浏览(55)
  • A_A03_001 stc-isp 单片机烧录软件安装与使用

    stc-isp网盘链接 提取码:1dqt 其他所有资料获取 直戳获取 安装过程如有疑问,可留言或者私聊交流 1、此软件是免安装的,直接双击就行,需要更新的话有时间就更新下,公告点确认就好 2、这个为了方便可以直接复制快捷方式到桌面或者其它地方 以STC89C52RC为例 1、选型号,

    2024年02月02日
    浏览(46)
  • 【51单片机】STC-ISP软件保姆级烧录教程(以普中A2开发板为例)

            本章节实验到此已经完毕,考虑到大家的基础差异较大,刚接触51单片机的小伙伴可能对烧录过程有些困惑,作者便在篇末给大家提供保姆级烧录教程,帮助大家快速掌握单片机程序烧录技巧,希望对大家有所帮助! 本教程所需软件下载(win系统)         

    2023年04月08日
    浏览(51)
  • 1个串口用1根线实现多机半双工通信+开机控制电路

    功能需求: 主机使用一个串口,与两个从机进行双向通信,主机向从机发送数据,从机能够返回数据,由于结构限制,主机与从机之间只有3根线(电源、地、数据线),并且从机上没有设物理的电源开关,需要通过与主机连接的数据线来控制开机,总结如下: 1、数据线只有

    2023年04月22日
    浏览(41)
  • STC89C51——串行通信、串口介绍及配置

            本文介绍基于常见的51单片机,即如下图的芯片:  AT89C51具备一个全双工串行通信接口。设有2个相互独立的接收、发送缓冲器,可以同时发送和接收数据。 两个缓冲器(SBUF)共用一个物理地址即99H。如果CPU写SBUF,数据就会被送入发送寄存器准备发送;如果CPU读SB

    2024年02月05日
    浏览(59)
  • 采用串口中断方式实现串口通信

    中断方式 中断方式是处理器和外部设备的数据传输方式。一方通过申请中断的方式与另一方进行数据传输,收发双方可以并行工作。 中断系统 中断装置和中断处理程序统称为中断系统。 中断系统是计算机的重要组成部分。实时控制、故障自动处理、计算机与外围设备间的数

    2024年02月16日
    浏览(36)
  • 串口通信(6)应用定时器中断+串口中断实现接收一串数据

     本文为博主 日月同辉,与我共生,csdn原创首发。希望看完后能对你有所帮助,不足之处请指正!一起交流学习,共同进步! 发布人:@日月同辉,与我共生_单片机-CSDN博客 欢迎你为独创博主日月同辉,与我共生点赞❤❤❤+关注👍+收藏🌹+评论☺。 系列专栏: CSDN- 单片机串

    2024年02月06日
    浏览(57)
  • 学习笔记|串口通信的基础知识|同步/异步|RS232|常见的串口软件的参数|STC32G单片机视频开发教程(冲哥)|第二十集:串口通信基础

    百度百科:串口通信的概念 什么是通信? 例如U盘和电脑,我们电脑需要往U盘存东西,而U盘上只有四个触点,除去一个电源一个地,只剩下两个引脚了。此时我们坑定不能像点亮LED那样单纯的给他两个引脚上输出个高低电平就能写数据了对吧。总不至于输出一个高电平就能

    2024年02月07日
    浏览(65)
  • 51单片机:中断系统(外部中断,定时器中断,串口通信)

    目录 中断系统简介: 中断的优先级和嵌套: 8个中断请求源及其优先级: 中断的分别介绍: 1、外部中断0:INT0   2、外部中断1  3、T0和 T1:定时计数器的功能 4、串口中断(串口为什么使用定时器后面讲) 中断寄存器 (1)中断允许控制(IE) (2)中断请求标志(TCON) (

    2024年01月25日
    浏览(48)
  • STM32使用中断及串口通信

    采用中断模式编程,当开关接高电平时,LED亮灯;接低电平时,LED灭灯。单片机除了基本的连线外,我们另外只接一只LED灯。 使用外部中断的基本步骤如下: 1.设置对应时钟 2.设置中断 3.初始化IO 4. 把特定IO口设置为中断线路进行初始化 5. 在中断通道的响应函数中中断函数

    2024年02月04日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包