UART是一种通用串行数据总线,用于异步通信。该总线双向通信,可以实现全双工传输和接收。
一、串口传输协议
1. 传输方式
串口通信的数据由发送设备通过自身的TXD接口传输到接收设备得RXD接口, 一个字符一个字符地传输,每个字符一位一位地传输,并且传输一个字符时,总是以“起始位”开始,以“停止位”结束,字符之间没有固定的时间间隔要求。
每一个字符的前面都有一位起始位(低电平),字符本身由8位数据位组成,接着字符后面是一位校验位(检验位可以是奇校验、偶校验或无校验位),最后是一位或一位半或二位停止位,停止位后面是不定长的空闲位,停止位和空闲位都规定为高电平。具体如下图所示。
实际传输时每一位的信号宽度与波特率有关,波特率越高,宽度越小,在进行传输之前,双方一定要使用同一个波特率设置。
波特率
波特率:每秒钟传输的数据位数(bit)。
波特率的单位是每秒比特数(bps),串口典型的传输波特率600bps,1200bps,2400bps,4800bps,9600bps,19200bps等。
以波特率9600bps为例:1秒钟传输9600位(bit)数据,所以传输1位(bit)数据需要1000000us/9600=104us。
空闲位
空闲位:处于逻辑“1”状态,高电平,每个字符之间都会有一段空闲位,表示当前线路上没有数据传输。
起始位
起始位:处于逻辑”0”状态,低电平,表示数据传输的开始。
数据位
数据位:一般是8位数据位,传输有效数据。
校验位
校验位:校验方法有奇校验(odd)、偶校验(even)以及无(noparity),用来校验数据传送的正确性。
停止位
停止位:一个字符数据的结束标志,可以是1位、1.5位、2位的高电平,表示数据传输的结束。
二、I/O口模拟串口通信----延时法
这次以波特率9600bps,1位起始位,8位数据位,无校验位,1位停止位的传输方式为例,实现模拟串口通信。
具体程序如下:
Uart1sim.c
#include "Uart1sim.h"
#include "delay.h"
void Uart1sim_GPIO_Config(void) //模拟串口引脚配置初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE); // 使能PD端口时钟
//UART1SIM_TX PB.5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PD端口
GPIO_ResetBits(GPIOB, GPIO_Pin_5);
//UART1SIM_RX PB.6
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PA10
}
/*
功能:模拟串口发送
参数:data---要发送的数据
*/
void Uart1sim_Txout(u8 data) //模拟串口发送
{
unsigned char i;
UART1SIM_TX(1);//空闲---高电平
delay_us(RATE9600);
UART1SIM_TX(0);//起始位---低电平
delay_us(RATE9600);
for(i=0x01;i!=0;i<<=1)//8位数据位
{
if(i&data) UART1SIM_TX(1);
else UART1SIM_TX(0);
delay_us(RATE9600);
}
UART1SIM_TX(1);//停止位---高电平
delay_us(RATE9600);
}
/*
功能:模拟串口接收
参数:*data存储接收到数据的地址
返回值:1---接收,0---未接收
*/
u8 Uart1sim_Rxout(u8* data) //模拟串口接收
{
unsigned char i=0,Rxdata;
if(UART1SIM_RX==0)//起始位
{
delay_us(RATE9600);
for(i=0x01;i!=0;i<<=1)
{
if(UART1SIM_RX==1) Rxdata|=i;
else Rxdata&=~i;
delay_us(RATE9600);
}
*data=Rxdata;
return 1;
}
return 0;
}
Uart1sim.h
#ifndef __UART1SIM_H
#define __UART1SIM_H
#include "stm32f10x.h"
#define RATE9600 (1000000/9600) //1s=1000ms=1000000us
#define UART1SIM_RX GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6)
#define UART1SIM_TX(a) if (a)
GPIO_SetBits(GPIOB,GPIO_Pin_5);
else
GPIO_ResetBits(GPIOB,GPIO_Pin_5)
void Uart1sim_GPIO_Config(void) ;
void Uart1sim_Txout(u8 data);
u8 Uart1sim_Rxout(u8* data);
#endif
注意1: 利用延时的方法模拟串口通信,有一些弊端,当程序的中断时间过长的时候,收发都会有影响。
注意2: 由于接收是引脚的低电平检测触发,当程序的运行周期过长的时候,有可能出现接收不到的现象。
UART是一种通用串行数据总线,用于异步通信。该总线双向通信,可以实现全双工传输和接收。
一、串口传输协议
1. 传输方式
串口通信的数据由发送设备通过自身的TXD接口传输到接收设备得RXD接口, 一个字符一个字符地传输,每个字符一位一位地传输,并且传输一个字符时,总是以“起始位”开始,以“停止位”结束,字符之间没有固定的时间间隔要求。
每一个字符的前面都有一位起始位(低电平),字符本身由8位数据位组成,接着字符后面是一位校验位(检验位可以是奇校验、偶校验或无校验位),最后是一位或一位半或二位停止位,停止位后面是不定长的空闲位,停止位和空闲位都规定为高电平。具体如下图所示。
实际传输时每一位的信号宽度与波特率有关,波特率越高,宽度越小,在进行传输之前,双方一定要使用同一个波特率设置。
波特率
波特率:每秒钟传输的数据位数(bit)。
波特率的单位是每秒比特数(bps),串口典型的传输波特率600bps,1200bps,2400bps,4800bps,9600bps,19200bps等。
以波特率9600bps为例:1秒钟传输9600位(bit)数据,所以传输1位(bit)数据需要1000000us/9600=104us。
空闲位
空闲位:处于逻辑“1”状态,高电平,每个字符之间都会有一段空闲位,表示当前线路上没有数据传输。
起始位
起始位:处于逻辑”0”状态,低电平,表示数据传输的开始。
数据位
数据位:一般是8位数据位,传输有效数据。
校验位
校验位:校验方法有奇校验(odd)、偶校验(even)以及无(noparity),用来校验数据传送的正确性。
停止位
停止位:一个字符数据的结束标志,可以是1位、1.5位、2位的高电平,表示数据传输的结束。
二、I/O口模拟串口通信----延时法
这次以波特率9600bps,1位起始位,8位数据位,无校验位,1位停止位的传输方式为例,实现模拟串口通信。
具体程序如下:
Uart1sim.c
#include "Uart1sim.h"
#include "delay.h"
void Uart1sim_GPIO_Config(void) //模拟串口引脚配置初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE); // 使能PD端口时钟
//UART1SIM_TX PB.5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PD端口
GPIO_ResetBits(GPIOB, GPIO_Pin_5);
//UART1SIM_RX PB.6
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PA10
}
/*
功能:模拟串口发送
参数:data---要发送的数据
*/
void Uart1sim_Txout(u8 data) //模拟串口发送
{
unsigned char i;
UART1SIM_TX(1);//空闲---高电平
delay_us(RATE9600);
UART1SIM_TX(0);//起始位---低电平
delay_us(RATE9600);
for(i=0x01;i!=0;i<<=1)//8位数据位
{
if(i&data) UART1SIM_TX(1);
else UART1SIM_TX(0);
delay_us(RATE9600);
}
UART1SIM_TX(1);//停止位---高电平
delay_us(RATE9600);
}
/*
功能:模拟串口接收
参数:*data存储接收到数据的地址
返回值:1---接收,0---未接收
*/
u8 Uart1sim_Rxout(u8* data) //模拟串口接收
{
unsigned char i=0,Rxdata;
if(UART1SIM_RX==0)//起始位
{
delay_us(RATE9600);
for(i=0x01;i!=0;i<<=1)
{
if(UART1SIM_RX==1) Rxdata|=i;
else Rxdata&=~i;
delay_us(RATE9600);
}
*data=Rxdata;
return 1;
}
return 0;
}
Uart1sim.h
#ifndef __UART1SIM_H
#define __UART1SIM_H
#include "stm32f10x.h"
#define RATE9600 (1000000/9600) //1s=1000ms=1000000us
#define UART1SIM_RX GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6)
#define UART1SIM_TX(a) if (a)
GPIO_SetBits(GPIOB,GPIO_Pin_5);
else
GPIO_ResetBits(GPIOB,GPIO_Pin_5)
void Uart1sim_GPIO_Config(void) ;
void Uart1sim_Txout(u8 data);
u8 Uart1sim_Rxout(u8* data);
#endif
注意1: 利用延时的方法模拟串口通信,有一些弊端,当程序的中断时间过长的时候,收发都会有影响。
注意2: 由于接收是引脚的低电平检测触发,当程序的运行周期过长的时候,有可能出现接收不到的现象。
举报