串口每隔一定时间向电脑发送数据

目录

1.前言

2.串口相关概念

2.1 硬件电路

2.2 电平标准

2.3 常见通信接口比较

2.4 51单片机的UART

2.5 串口模式图

3. 串口相关寄存器

3.1 串行控制寄存器SCON

3.2 电源控制寄存器PCON

3.3 串行口数据缓冲寄存器SBUF

3.4 与串行口中断相关的寄存器E和IPH、IP

4.源码

4.1 main.c

4.2 UART.c

4.3 UART.h


1.前言

串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信。
单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信,极大的扩展了单片机的应用范围,增强了单片机系统的硬件实力。
51单片机内部自带UART(Universal Asynchronous Receiver Transmitter,通用异步收发器),可实现单片机的串口通信。

2.串口相关概念

2.1 硬件电路

简单双向串口通信有两根通信线(发送端TXD和接收端RXD)
TXD与RXD要交叉连接
当只需单向的数据传输时,可以直接一根通信线
当电平标准不一致时,需要加电平转换芯片

 

2.2 电平标准

电平标准是数据1和数据0的表达方式,是传输线缆中人为规定的电压与数据的对应关系,串口常用的电平标准有如下三种:

TTL电平:+5V表示1,0V表示0
RS232电平:-3~-15V表示1,+3~+15V表示0
RS485电平:两线压差+2~+6V表示1,-2~-6V表示0(差分信号)

2.3 常见通信接口比较

全双工:通信双方可以在同一时刻互相传输数据
半双工:通信双方可以互相传输数据,但必须分时复用一根数据线
单工:通信只能有一方发送到另一方,不能反向传输

异步:通信双方各自约定通信速率
同步:通信双方靠一根时钟线来约定通信速率

总线:连接各个设备的数据传输线路(类似于一条马路,把路边各住户连接起来,使住户可以相互交流)

2.4 51单片机的UART

STC89C52有1个UART
STC89C52的UART有四种工作模式:(本文用到模式1)
    模式0:同步移位寄存器                                      
    模式1:8位UART,波特率可变(常用)
    模式2:9位UART,波特率固定
    模式3:9位UART,波特率可变

波特率:串口通信的速率(发送和接收各数据位的间隔时间)
检验位:用于数据验证
停止位:用于数据帧间隔

2.5 串口模式图

SBUF:串口数据缓存寄存器,物理上是两个独立的寄存器,但占用相同的地址。写操作时,写入的是发送寄存器,读操作时,读出的是接收寄存器

TXD:发送端

RXD:接收端

定时器1的部分控制波特率;

3. 串口相关寄存器

STC89C52系列单片机的串行口设有两个控制寄存器:串行控制寄存器SCON和波特率选择特殊功能寄存器PCON。

3.1 串行控制寄存器SCON

串行控制寄存器SCON用于选择串行通信的工作方式和某些控制功能.其格式如下:SCON:串行控制寄存器(可位寻址)

SMO/FE:当PCON寄存器中的SMODO/PCON.6位为1时,该位用于帧错误检测。当检测到一个
无效停止位时,通过UART接收器设置该位。它必须由软件清零。
当PCON寄存器中的SMODO/PCON.6位为0时,该位和SM1一起指定串行通信的工作方式,如下表所示。
其中SM0、SM1按下列组合确定串行口的工作方式:(本文主要用到方式1)

SM2:允许方式2或方式3多机通信控制位。在方式2或方式3时,如SM2位为1,REN位为1,则
从机处于只有接收到RB8位为1(地址帧)时才激活中断请求标志位RI为1,并向主机请求中断处理。被确认为寻址的丛机则复位SM2位为0,从而才接收RB8为0的数据帧。在方式1时,如果SM2位为1,则只有在接收到有效的停止位时才置位中断请求标志位RI为1;在方式0时,SM2应为0。
REN:允许/禁止串行接收控制位。由软件置位REN,即REN=1为允许串行接收状态,可启动
串行接收器RxD,开始接收信息。软件复位REN,即REN=O,则禁止接收。
TB8:在方式2或方式3,它为要发送的第9位数据,按需要由软件置位或清0。例如,可用作数
据的校验位或多机通信中表示地址帧/数据帧的标志位。
RB8:在方式2或方式3,是接收到的第9位数据。在方式1,若SM2=O,则RB8是接收到的停止
位。方式0不用RB8。
TI:发送中断请求标志位。在方式0,当串行发送数据第8位结束时,由内部硬件自动置位,
即TI=1,向主机请求中断,响应中断后必须用软件复位,即TI=0。在其他方式中,则在停止位开始发送时由内部硬件置位,必须用软件复位。

RI:接收中断请求标志位。在方式0,当串行接收到第8位结束时由内部硬件自动置位RI=1,
向主机请求中断,响应中断后必须用软件复位,即RI=0。在其他方式中,串行接收到停止位的中间时刻由内部硬件置位,即RI=1(例外情况见SM2说明),必须由软件复位,即RI=O。
SCON的所有位可通过整机复位信号复位为全“O”。SCON的字节地址尾98H,可位寻址,各位地址为98H~~9FH,可用软件实现位设置。当用指令改变SCON的有关内容时,其改变的状态将在下一条指令的第一个机器周期的S1P1状态发生作用。如果一次串行发送已经开始,则输出TB8将是原先的值,不是新改变的值。
串行通信的中断请求:当一帧发送完成,内部硬件自动置位TI,即TI=1,请求中断处理;当接收完一帧信息时,内部硬件自动置位RI,即RI=1,请求中断处理。由于TI和RI以“或逻辑”关系向主机请求中断,所以主机响应中断时事先并不知道是TI还是RI请求的中断,必须在中断服务程序中查询TI和RI进行判别,然后分别处理。因此,两个中断请求标志位均不能由硬件自动置位,必须通过软件清0,否则将出现一次请求多次响应的错误。
电源控制寄存器PCON中的SMOD/PCON.7用于设置方式1、方式2、方式3的波特率是否加倍。


3.2 电源控制寄存器PCON

PCON:电源控制寄存器(不可位寻址)

SMOD:波特率选择位。当用软件置位SMOD,即SMOD=1,则使串行通信方式1、2、3的波
特率加倍;SMOD=0,则各工作方式的波特率加倍。复位时SMOD=0。
SMOD0:帧错误检测有效控制位。当SMODO=1,SCON寄存器中的SMO/FE位用于FE(帧错误
检测)功能;当SMODO=0,SCON寄存器中的SMO/FE位用于SMO功能,和SM1一起指定串行口的工作方式;复位时SMODO=0

3.3 串行口数据缓冲寄存器SBUF


STC89C52系列单片机的串行口缓冲寄存器(SBUF)的地址是99H,实际是2个缓冲器,写SBUF的操作完成待发送数据的加载,读SBUF的操作可获得已接收到的数据。两个操作分别对应两个不同的寄存器,1个是只写寄存器,1个是只读寄存器。
串行通道内设有数据寄存器。在所有的串行通信方式中,在写入SBUF信号的控制下,把数据装入相同的9位移位寄存器,前面8位为数据字节,其最低位为移位寄存器的输出位。根据不同的工作方式会自动将“1”或TB8的值装入移位寄存器的第9位,并进行发送。
串行通道的接收寄存器是一个输入移位寄存器。在方式0时它的字长为8位,其他方式时为9位。当一帧接收完毕,移位寄存器中的数据字节装入串行数据缓冲器SBUF中,其第9位则装入SCON寄存器中的RB8位。如果由于SM2使得已接收到的数据无效时,RB8和SBUF中内容不变。
由于接收通道内设有输入移位寄存器和SBUF缓冲器,从而能使一帧接收完将数据由移位寄存器装入SBUF后,可立即开始接收下一帧信息,主机应在该帧接收结束前从SBUF缓冲器中将数据取走,否则前一帧数据将丢失。SBUF以并行方式送往内部数据总线。

3.4 与串行口中断相关的寄存器E和IPH、IP


串行口中断允许位ES位于中断允许寄存器IE中,中断允许寄存器的格式如下:IE:中断允许寄存器(可位寻址)

EA:CPU的总中断允许控制位,EA=1,CPU开放中断,EA=0,CPU屏蔽所有的中断甲请。
EA的作用是使中断允许形成多级控制。即各中断源首先受EA控制;其次还受各中断源自己的中断允许控制位控制。
ES:串行口中断允许位,ES=1,允许串行口中断,ES=0,禁止串行口中断。
串行口中断优先级控制位PS/PSH位于中断优先级控制寄存器IP/IPH中;中断优先级控制寄存器IP/IPH,暂时用不到就不过多介绍了

4.源码

4.1 main.c

#include <REGX52.H>
#include "UART.h"

unsigned char Sec; //全局变量默认赋0;

void main()
{
	UART_Init(); //串口初始号
	while(1)
	{
		UART_SendByte(Sec);	//串口发送1个字节
		Sec++;				
		Delay(1000); //延时1s;每隔1s串口向电脑发送1个数据;
	}
}

4.2 UART.c

#include <REGX52.H>

//延时函数
void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}
//串口初始化;4800比特率
void UART_Init()
{
	SCON=0x40;
	PCON |= 0x80;
	TMOD &= 0x0F;	//设置定时器模式
	TMOD |= 0x20;	//0010 0000 定时器1工作方式二:8位自动重装
	TL1 = 0xF3;		//设定定时初值
	TH1 = 0xF3;		//设定定时器重装值
	ET1 = 0;		  //禁止定时器1中断
	TR1 = 1;		  //启动定时器1
}


void UART_SendByte(unsigned char Byte)
{
	SBUF=Byte;  //数据存到串口数据缓存寄存器中
	while(TI==0);//当TI=1时SBUF中的数据就通过控制门送到TXD(发送端)
	TI=0;  //为下次串口发送数据做准备;
}          //发送标志位为1,代表发送了数据;

4.3 UART.h

#ifndef __UART_H__
#define __UART_H__

void UART_Init();
void UART_SendByte(unsigned char Byte);
void Delay(unsigned int xms);

#endif

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
分享自己的串口接收GUI可实时观察数据图像-ADC DMA USART.rar 做这个软件的想法是这样的 先是阅读了飞哥的串口收发助手程序 其中 在第二版书中的P512页末端提出了一个串口接收数据的要求 即 假设计算机与某硬件设备用串口相连 设备每隔定时间(我这里是5mS 速度非常快)通过串口给计算机发送数据 这帧数据中包含有 帧头 两字节 0x55 0xAA 数据字节数20 一共每帧22个数据 飞哥提出的是仅用串口定时定时读取的方法 并且他说 “经实践证明是可以的” 费劲九牛二虎之力我把它实现了 还是挺艰辛的 程序刚刚完成基本调试 代码也不是特别整齐 我用单片机做上位机发送串口数据 按一帧20个数据并 2个帧起始位  帧发送间歇时间定时的5mS 为什么要做这个东西呢?因为 这个做法是很有意义的  实时地观察采样数据 我参加的智能车比赛中就意识到 上位机调试 看数据曲线十分重要  否则 不知道参数的变化情况 怎么调试? 大概描述一下这个程序 STM32底层A/D转换采样 通过DMA连接片上USART  定时发送数据到上位机 其中我对一个通道进行采样 采样十次 即同一个传感器  一共20个数据(STM32是12位的片上AD 参考电压3.3V) 数据传入Matlab的串口中 用矩阵相乘的方法求出平均值 后plot到axes图上   由于是定时器触发的读取数据函数 那么每次读取到的数据有以下几种情况: ||Data, Data,StartByte1,StartByte2,Data,...,StartByte1,StartByte2|| ||Data, Data,StartByte1,StartByte2,Data,...,StartByte1|| ||Data, Data,StartByte1,StartByte2,Data,...,Data||  %这一次定时定时接收的到的数据末尾的最后一帧的Data不满20个 不够一帧 ||StartByte1,StartByte2,Data,...,Data,Data,StartByte1,StartByte2|| %这次读到的数据末尾只有帧头的2位标志数据 连原始数据全部都得在下一次定时读取中才能读得到 情况比较多 即一帧的数据可能会被中间间断成2次读取!每一次定时读取的时候 就意味着至多会有2帧数据是不完整的! 大家一般的想法大概就是丢失被中断的帧 这样做程序简洁 方便读 但不可避免地会丢失掉一些数据 我在这里耽误了很久 写了很多段程序代码来完整地恢复了这些被打断的数据 (吹毛求疵吧 但我觉得如果在非常严格的数据观察里是有意义的) 程序有时还是有些不知道为什么的BUG 工科人 表达能力不行 分享一个小作品 可能程序写得比较乱 大家看不明白 或运行不了 有需要就问吧    使用方法 我把STM32 工程里的USER文件放进来了 整个工程太大放不下   连接STM32 ADC1 通道15到外设 把USART1接到电脑上 Matlab 打开GUI 'serial_communication2'  ‘打开串口’ OK 看看数据吧 (有时可能会Matlab报错 关闭再重新执行一次GUI 这BUG一直不知道错在哪)
以下是一个简单的 Verilog 模块实现 UART 串口通信的计数和数据发送功能: ```verilog module uart_tx( input clk, // 时钟输入 input reset, // 复位输入 input [7:0] data_in, // 待发送的数据 output reg tx_out // 串口输出 ); reg [31:0] count = 0; // 计数器,32 位宽度,可以计数约 4.3 秒 reg [7:0] bit_count = 0; // 发送位计数器,8 位宽度 reg [7:0] shift_reg = 0; // 移位寄存器,用于依次发送数据的每一位 reg start_bit = 1; // 起始位,始终为 1 reg stop_bit = 1; // 停止位,始终为 1 reg tx_busy = 0; // 发送忙标志,用于指示当前是否正在发送数据 always @(posedge clk) begin if (reset) begin count <= 0; bit_count <= 0; shift_reg <= 0; start_bit <= 1; stop_bit <= 1; tx_busy <= 0; end else begin if (count == 0) begin count <= 100000000; // 计数器初始值为 100000000,即 1 秒钟 if (!tx_busy) begin shift_reg <= {start_bit, data_in, stop_bit}; // 将起始位、数据和停止位组成一个 10 位的数据帧 bit_count <= 0; tx_busy <= 1; // 标记为正在发送数据 end end else if (bit_count < 10) begin tx_out <= ~shift_reg[bit_count]; bit_count <= bit_count + 1; end else begin tx_out <= 1; // 发送完毕,将输出置为 1 tx_busy <= 0; // 标记为发送完毕 end count <= count - 1; end end endmodule ``` 该模块实现了每隔 1 秒钟向电脑串口发送一次数据。其中,计数器 count 的初始值为 100000000,即 1 秒钟。当计数器减到 0 时,表示时间到了,可以开始发送数据发送数据时,先将起始位、数据和停止位组成一个 10 位的数据帧,然后依次将每一位发送出去,最后标记为发送完成。注意,发送数据时需要将数据的每一位进行移位操作,这里使用了一个 8 位的移位寄存器 shift_reg 和一个 8 位的发送位计数器 bit_count 来实现。同时,也需要一个发送忙标志 tx_busy 来指示当前是否正在发送数据,以避免重复发送。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

记忆&碎片

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值