单片机的串口通信

news2024/9/28 5:55:50

        今天,完整地总结一下普中科技的单片机的串口通信的硬件与编程,记录一下以后如果需要也比较方便捡起来。

        单片机的串口部分的电路图。开发板上集成了 1 个串口通信电路,是 USB 转串口模块,它既可下载程序也可实现串口通信功能。

        对这个模块简要分析一下输入输出。

         描述一下CH340芯片的作用。(带你全面解析USB转串口芯片CH340 - 采芯网 (findic.com))

        实现的功能是:51 单片机通过串口(UART)实现与 PC 机对话, 51 单片机的串口收到 PC 机发来的数据后原封不动的返回给 PC 机显示。

        单片机串行口的结构

        串口相关的寄存器。

 

我们一般选择串口工作在方式1下,定时器1工作在方式2下(8位自动重装)。

        定时器(定时器1)与波特率的关系。

SBUF介绍

 串口初始化。

void uart_init(u8 baud)
{
TMOD|=0X20; //设置计数器工作方式 2
SCON=0X50; //设置为工作方式 1
PCON=0X80; //波特率加倍
TH1=baud; //计数器初始值设置
TL1=baud;
ES=1; //打开串口中断
EA=1; //打开总中断
/*定时器1的方式2是8位自动重装,定时器一旦溢出,就自动重装,与中断无关,所以定时器1进入中断后无事可做,所以无需打开定时器1的中断*/
TR1=1; //打开计数器
}

void main()
{
uart_init(0XFA);//波特率为 9600
while(1)
{
}
}
void uart() interrupt 4 //串口通信中断函数
{
u8 rec_data;
RI = 0; //清除接收中断标志位
rec_data=SBUF; //存储接收到的数据
SBUF=rec_data; //将接收到的数据放入到发送寄存器
while(!TI); //等待发送数据完成
TI=0; //清除发送完成标志位
}

完整程序如下所示

#include "reg52.h"

typedef unsigned int u16;	//对系统默认数据类型进行重定义
typedef unsigned char u8;


/*******************************************************************************
* 函 数 名       : uart_init
* 函数功能		 : 串口通信中断配置函数,通过设置TH和TL即可确定定时时间
* 输    入       : baud:波特率对应的TH、TL装载值
* 输    出    	 : 无
*******************************************************************************/
void uart_init(u8 baud)
{
	TMOD|=0X20;	//设置计数器工作方式2
	SCON=0X50;	//设置为工作方式1
	PCON=0X80;	//波特率加倍
	TH1=baud;	//计数器初始值设置
	TL1=baud;
	ES=1;		//打开接收中断
	EA=1;		//打开总中断
	TR1=1;		//打开计数器		
}

/*******************************************************************************
* 函 数 名       : main
* 函数功能		 : 主函数
* 输    入       : 无
* 输    出    	 : 无
*******************************************************************************/
void main()
{	
	uart_init(0XFA);//波特率为9600

	while(1)
	{			
							
	}		
}

void uart() interrupt 4 //串口通信中断函数
{
	u8 rec_data;

	RI = 0;			//清除接收中断标志位
	rec_data=SBUF;	//存储接收到的数据
	SBUF=rec_data;	//将接收到的数据放入到发送寄存器
	while(!TI);		//等待发送数据完成
	TI=0;			//清除发送完成标志位				
}

        我在其他博客看到的一些串口代码。


#include <REGX52.H>
 
 
 
/* **
   * @brief 串口初始化		//4800bps@11.0592MHz
   * @param 无
   * @retval 无
   */
void UART_Init(void)		//4800bps@11.0592MHz
{
	PCON |= 0x80;		//使能波特率倍速位SMOD
	SCON = 0x50;		//8位数据,可变波特率
	TMOD &= 0x0F;		//清除定时器1模式位
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	TL1 = 0xF4;		//设定定时初值
	TH1 = 0xF4;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
	EA = 1;			//启动所有中断
	ES = 1;			//启动串口中断
}
 
 
 
/* *	串口发送模板
   * @brief 串口发送一个字节数据
   * @param Byte 要发送的一个数据
   * @retval 无
   */
 
void UART_SendByte(unsigned char Byte)
{
	SBUF = Byte;
	while(TI == 0); //一执行完就要复位
	TI = 0;         //TI为发射控制器;RI为接受控制器;
}
	
/*串口中断函数模板
void UART_Routine() interrupt 4
{
	if(RI = 1)
	{
		RI = 0;
	}
}*/

        串口的发送与接收数据的过程与串口中断一点关系都没有,并不是不开串口中断就说明禁止了单片机的串口通信,单片机的串口中断只是提供了那么一种方法,即当你接收完数据或者发送完数据,想要先停止此时的串口通讯,进行其他的诸如数据处理的任务,不管是否开中断,只要将数据放入到SBUF中,就一定会将数据发送出去。定时器也是如此,不管有没有开中断,定时器都是在定时的,只不过有些工作方式在定时一次后,再一次定时时初始值会发生变化(工作方式2会自动重装)。

        在串口发送数据的时候,自己不用考虑起始位以及停止位,将数据写入到SBUF中(肯定没有起始位以及停止位),单片机发送的时候会自动将数据包装,在前面和后面加上起始位以及停止位。

串口调试工具

        我自己随便写了个PC端控制单片机LED亮灭的程序。

#include "reg52.h"

typedef unsigned int u16;	//对系统默认数据类型进行重定义
typedef unsigned char u8;

sbit LED1=P2^0;	//将P2.0管脚定义为LED1

/*******************************************************************************
* 函 数 名       : uart_init
* 函数功能		 : 串口通信中断配置函数,通过设置TH和TL即可确定定时时间
* 输    入       : baud:波特率对应的TH、TL装载值
* 输    出    	 : 无
*******************************************************************************/
void uart_init(u8 baud)
{
	TMOD|=0X20;	//设置计数器工作方式2
	SCON=0X50;	//设置为工作方式1
	PCON=0X80;	//波特率加倍
	TH1=baud;	//计数器初始值设置
	TL1=baud;
	ES=1;		//打开接收中断
	EA=1;		//打开总中断
	TR1=1;		//打开计数器		
}

void delay_10us(u16 ten_us)
{
	while(ten_us--);	
}
/*******************************************************************************
* 函 数 名       : main
* 函数功能		 : 主函数
* 输    入       : 无
* 输    出    	 : 无
*******************************************************************************/
void main()
{	
	uart_init(0XFA);//波特率为9600

	while(1)
	{						
	}		
}

void send_Byte(u8 rec_data)
{
	SBUF=rec_data;	//将接收到的数据放入到发送寄存器
	while(!TI);		//等待发送数据完成
	TI=0;			//清除发送完成标志位	
}

void uart() interrupt 4 //串口通信中断函数
{
	if(RI)
	{
		u8 rec_data;
		rec_data=SBUF;	//存储接收到的数据
		if(rec_data == 'G' || rec_data == 'g')
		{
			LED1=0;	//点亮
			delay_10us(50000); //大约延时450ms
			LED1=1;	//熄灭
			delay_10us(50000);
		}
		
		send_Byte(rec_data);
		RI = 0;			//清除接收中断标志位
			
	}
}
printf重定向简介

char putchar(char c)
{
    SendByte(c);
    return c;
}

void SendByte(unsigned char data)
{
    SBUF = data;
    while(!TI);
    TI = 0;
}

附录:

51单片机之寄存器-3.3单片机串口通信之发送与接收 - 微波EDA网 (mweda.com)

单片机串行通信总结_单片机接收sbuff的条件为ri_tony_0620的博客-CSDN博客

51单片机的串口通信(UART)及其应用_51单片机 uart_小菜冀的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/920831.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【面试题】UDP和TCP有啥区别?

UDP UDP协议全称是用户数据报协议&#xff0c;在网络中它与TCP协议一样用于处理数据包&#xff0c;是一种无连接的协议。在OSI模型中&#xff0c;在第四层——传输层&#xff0c;处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点&#xff0c;也就…

【C++STL基础入门】vector增、删操作

文章目录 前言一、vector迭代器1.1 定义vector迭代器1.2 注意点 二、vector增函数2.1 尾添加示例代码&#xff1a; 2.2 中间添加2.3 效率问题 三、vector删除操作3.1 尾删除3.2 删除指定元素3.3 删除所有 总结 前言 一、vector迭代器 1.1 定义vector迭代器 vector<int>…

30款教育学习类应用评测体验报告

为方便开发者更好地衡量APP在同类产品中的表现和竞争力&#xff0c;有针对性地进行产品优化&#xff0c;软件绿色联盟策划了垂类APP评测体验专题&#xff0c;目前已发布了天气类APP和小说类APP评测体验报告&#xff0c;本期将对教育学习类APP围绕绿标五大标准进行体验评测&…

流程控制之条件判断

一、if单分支结构 准备知识&#xff1a; 查看系统内存&#xff1a;free指令 -m表示以MB的大小显示 mem是系统内存&#xff0c;swap是虚拟内存&#xff0c;需要将系统剩余内存大小过滤出来&#xff0c;之后与100M对比 也可以用awk指令 使用正则表达式过滤&#xff0c;以空格…

vue 简单实验 自定义组件 component

1.代码 <script src"https://unpkg.com/vuenext" rel"external nofollow" ></script> <div id"components-demo"><button-counter></button-counter> </div> <script> // 创建一个Vue 应用 const ap…

【MySQL】1、MySQL数据库的基本概念

数据库的基本概念 1.数据 1&#xff09;描述事物的符号记录称为数据&#xff1b;数字&#xff0c;文字&#xff0c;图形&#xff0c;图像&#xff0c;声音&#xff0c;档案记录等都是数据 2&#xff09;数据是以“记录”的形式按照统一的格式进行存储的&#xff0c;而不是杂乱…

c++都补了c语言哪些坑?

目录 1.命名空间 1.1 定义 1.2 使用 2.缺省参数 2.1 概念 2.2 分类 3.函数重载 4.引用 4.1 概念 4.2 特性 4.3 常引用 4.4 引用和指针的区别 5.内联函数 1.命名空间 在 C/C 中&#xff0c;变量、函数和后面要学到的类都是大量存在的&#xff0c;这些变量、函数和类的名称将…

像Vuex一样使用redux

redux基础知识 本篇文章主要介绍redux的基本使用方法&#xff0c;并简单封装&#xff0c;像vuex一样写redux 学习文档 英文文档: https://redux.js.org/ 中文文档: http://www.redux.org.cn/ Github: https://github.com/reactjs/redux redux是什么 redux和vuex几乎是一…

EasyExcel实现多sheet文件分批导入

文章目录 EasyExcel引入依赖表结构学生表课程表教师表 项目结构DozerUtils工具类实体类StudentCourseTeacher Controller监听类StudentListenerCourseListenerTeacherListener ServiceEasyExcelServiceStudentServiceCourseServiceTeacherService ServiceImplEasyExcelServiceI…

入行嵌入式,未来能干啥?

嵌入式技术近些年来发展迅猛&#xff0c;已经广泛应用于各个领域。那么&#xff0c;如果选择入行嵌入式&#xff0c;未来能够从事哪些有趣且有前景的工作呢&#xff1f; 1. 智能家居领域 随着物联网技术的快速发展&#xff0c;智能家居成为了人们追求便利和舒适的新时尚。作为嵌…

LeetCode 1267. 统计参与通信的服务器

【LetMeFly】1267.统计参与通信的服务器 力扣题目链接&#xff1a;https://leetcode.cn/problems/count-servers-that-communicate/ 这里有一幅服务器分布图&#xff0c;服务器的位置标识在 m * n 的整数矩阵网格 grid 中&#xff0c;1 表示单元格上有服务器&#xff0c;0 表…

<kernel>kernel 6.4 USB-之-usb_new_device()分析

&#xff1c;kernel&#xff1e;kernel 6.4 USB-之-usb_new_device()分析 kernel 6.4 USB系列文章如下&#xff1a; &#xff1c;kernel&#xff1e;kernel 6.4 USB-之-hub_event()分析 &#xff1c;kernel&#xff1e;kernel 6.4 USB-之-port_event()分析 &#xff1c;kernel…

​直播预告丨特邀中国人寿Soul专家分享APP合规与稳定性治理经验

由软件绿色联盟主办的月度技术活动将于7月28日19点进行线上直播。本次直播以“APP安全合规与稳定性治理”为主题&#xff0c;特邀中国人寿、Soul的专家&#xff0c;分别为大家带来《中国人寿寿险APP合规之路经验分享》、《Soul Android 端稳定性治理》议题直播。赶紧预约↑吧&a…

JAVA JNA 调用C接口的三种方式

文章目录 1. 准备一个共享库文件2. JNA姿势1—继承Library接口3. JNA姿势2—直接NativeLibrary.getInstance3. JNA姿势3—Native方法 1. 准备一个共享库文件 test.c #include <stdio.h> int test(char *input){printf("input:%s\n",input);return 0; }libtes…

智能离子风棒联网监控静电消除器的主要特点和功能

智能离子风棒联网监控静电消除器是一种利用互联网技术实现远程监测和控制的设备。它可以通过传感器感知静电水平&#xff0c;并将数据传输到云端服务器进行处理和存储。用户可以通过手机、电脑等终端设备&#xff0c;通过互联网接入平台&#xff0c;实时查看静电水平、工作状态…

EasyExcel实现Excel导出

文章目录 EasyExcel引入依赖项目结构导出模板类ControllerServiceServiceImplmapper 启动项目PostMan测试 EasyExcel EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。 他能让你在不用考虑性能、内存的等因素的情况下&#xff0c;快速完成Excel的…

SQL 数据库

安装配置 【1】 MySQL安装配置教程&#xff08;超级详细、保姆级&#xff09; 【2】 MySQLNavicat安装配置教程&#xff08;超级详细、保姆级&#xff09; 学习资料 【戴师兄】SQL入门免费教程 刷题链接&#xff1a;https://share.mubu.com/doc/4BHMMbbvIMb 学习笔记&#xf…

【无标题】CloudOS:物联网开发平台,云上开发,边端交付

什么是物联网&#xff1f; 物联网&#xff08;Internet of Things&#xff0c;简称IoT&#xff09;是指通过各种信息传感器、射频识别技术、全球定位系统、红外感应器、激光扫描器等各种装置与技术&#xff0c;实时采集任何需要监控、 连接、互动的物体或过程&#xff0c;采集…

RFID数据采集设备怎么选择?

RFID技术具有非接触识别的特性&#xff0c;可对贴有RFID标签的物体进行远距离非接触的批量识别&#xff0c;也是当下发展成熟的数据采集技术之一。RFID数据采集设备可对标签信息进行处理&#xff0c;并将读取到的标签信息传输到上位机中&#xff0c;针对不同的应用场景&#xf…

Linux系统root用户使用mv命令移动“/“根目录所有文件恢复方法

在使用mv命令对文件进行移动时&#xff0c;由于操作失误移动了根目录&#xff0c;导致除了cd命令&#xff0c;其他命令都无法使用。此时可以使用./ tab键查看当前目录下的文件此时无法再通过mv命令移动回去&#xff0c;因为执行mv命令的脚本ld-linux-x86-64.so.2找不到了。 正…