06:串口通信
串口通信
- 1、基础知识
- 1.1、通信
- 2.1、数据帧格式
- 2.3、波特率
- 2、串口UART
- 2.1、寄存器简介
- 2.2、串口内部基本结构
- 2.3、工作方式和波特率
- 3、实验
- 3.1、串口发送
- 3.1.1、实验①
- 3.1.2、实验②
- 3.1.3、实验③
- 3.2、串口接收
- 3.2.1、实验①
- 3.2.2、实验②
1、基础知识
1.1、通信
2.1、数据帧格式
2.3、波特率
2、串口UART
2.1、寄存器简介
2.2、串口内部基本结构
2.3、工作方式和波特率
综上:若想将串口在方式1的波特率配置为9600,则应该如何设置?
3、实验
3.1、串口发送
3.1.1、实验①
实验:使用轮询方式让单片机通过串口向外发送一个字节的数据
①UART.c文件的代码如下:
#include "UART.h"
/**
* 串口初始化
* 参数:波特率
*/
void UART_Init(unsigned int Baud)
{
/* 串口寄存器的配置 */
PCON &= 0x3F; //PCON = 00xx xxxx
SCON &= 0x0F;
SCON |= 0x50; //SCON = 0101 xxxx
/* 配置T1的寄存器 */
TMOD &= 0x0F;
TMOD |= 0x20; //TOMD = 0010 xxxx
TH1 = 256 - (28800/Baud);//配置波特率
TL1 = 256 - (28800/Baud);//配置波特率
ET1 = 0; //关闭T1溢出中断
TR1 = 1; //使能T1
}
②UART.h文件的代码如下:
#ifndef __UART_H
#define __UART_H
#include <reg51.h> //包含51头文件,里面全是寄存器地址
void UART_Init(unsigned int Baud);//串口初始化
#endif
③mian.c文件的代码如下:
#include "UART.h"
#include "Delay.h"
void main(void)
{
UART_Init(9600);//9600波特率
while(1)
{
SBUF = 0x88;//给SBUF写入一个字节数据0x88
while(!TI); //等待数据发送完成(未完成TI = 0,完成TI = 1)
TI = 0; //手动清0
Delayms(500);
}
}
3.1.2、实验②
实验:
①使用轮询方式让单片机通过串口向外发送一个字节的数据
②使用轮询方式让单片机通过串口向外发送多个字节的数据
③使用轮询方式让单片机通过串口向外发送字符串
①UART.c文件的代码如下:
#include "UART.h"
/**
* 串口初始化
* 参数:波特率
*/
void UART_Init(unsigned int Baud)
{
/* 串口寄存器的配置 */
PCON &= 0x3F; //PCON = 00xx xxxx
SCON &= 0x0F;
SCON |= 0x50; //SCON = 0101 xxxx
/* 配置T1的寄存器 */
TMOD &= 0x0F;
TMOD |= 0x20; //TOMD = 0010 xxxx
TH1 = 256 - (28800/Baud);//配置波特率
TL1 = 256 - (28800/Baud);//配置波特率
ET1 = 0; //关闭T1溢出中断
TR1 = 1; //使能T1
}
/**
* 发送一个字节的数据
*/
void Send_Char(unsigned char ch)
{
SBUF = ch; //给SBUF写入一个字节数据
while(!TI); //等待数据发送完成(未完成TI = 0,完成TI = 1)
TI = 0; //手动清0
}
/**
* 发送多个字节的数据
*/
void Send_Array(unsigned char* Array,unsigned char Len)
{
unsigned char i;
for(i = 0; i<Len; i++)
{
Send_Char(*(Array+i));
}
}
/**
* 发送字符串
*/
void Send_String(unsigned char* str)
{
while(*str != '\0')
{
Send_Char(*str++);
}
}
②UART.h文件的代码如下:
#ifndef __UART_H
#define __UART_H
#include <reg51.h> //包含51头文件,里面全是寄存器地址
void UART_Init(unsigned int Baud);//串口初始化
void Send_Char(unsigned char ch);//发送一个字节的数据
void Send_Array(unsigned char* Array,unsigned char Len);//发送多个字节的数据
void Send_String(unsigned char* str);//发送字符串
#endif
③mian.c文件的代码如下:
#include "UART.h"
#include "Delay.h"
void main(void)
{
UART_Init(9600);//9600波特率
while(1)
{
Send_Char(0xAA);//发送一个字节数据AA
Delayms(500);
Send_Array(Arr,5);//发送多个字节数据
Delayms(500);
}
}
3.1.3、实验③
实验:
printf函数的重定向
#include <stdio.h>
void mian(void)
{
char a = 1;
int b = 12365;
long c = 0x7FFFFFFF;
unsigned char x = 'A';
unsigned int y = 54321;
unsigned long z = 0x4A6F6E00;
float f = 10.0;
float g = 22.95;
char buf [] = "Test String";
char *p = buf;
printf ("char %bd int %d long %ld\n",a,b,c);
printf ("Uchar %bu Uint %u Ulong %lu\n",x,y,z);
printf ("xchar %bx xint %x xlong %lx\n",x,y,z);
printf ("String %s is at address %p\n",buf,p);
printf ("%f != %g\n", f, g);
printf ("%*f != %*g\n", (int)8, f, (int)8, g);
}
①UART.c文件的代码如下:
#include "UART.h"
/**
* 串口初始化
* 参数:波特率
*/
void UART_Init(unsigned int Baud)
{
/* 串口寄存器的配置 */
PCON &= 0x3F; //PCON = 00xx xxxx
SCON &= 0x0F;
SCON |= 0x50; //SCON = 0101 xxxx
/* 配置T1的寄存器 */
TMOD &= 0x0F;
TMOD |= 0x20; //TOMD = 0010 xxxx
TH1 = 256 - (28800/Baud);//配置波特率
TL1 = 256 - (28800/Baud);//配置波特率
ET1 = 0; //关闭T1溢出中断
TR1 = 1; //使能T1
}
/**
* 发送一个字节的数据
*/
void Send_Char(unsigned char ch)
{
SBUF = ch; //给SBUF写入一个字节数据
while(!TI); //等待数据发送完成(未完成TI = 0,完成TI = 1)
TI = 0; //手动清0
}
/**
* 对printf函数进行重定向
*/
char putchar(char ch)
{
Send_Char(ch);
return ch;
}
②UART.h文件的代码如下:
#ifndef __UART_H
#define __UART_H
#include <reg51.h> //包含51头文件,里面全是寄存器地址
void UART_Init(unsigned int Baud);//串口初始化
void Send_Char(unsigned char ch);//发送一个字节的数据
char putchar(char ch);//printf()重定向
#endif
③mian.c文件的代码如下:
#include "UART.h"
#include "Delay.h"
void main(void)
{
UART_Init(9600);//9600波特率
while(1)
{
printf("nihao\r\n");
printf("%bd\r\n",88);
printf("%d\r\n",12365);
printf("%f\r\n",3.14);
Delayms(500);
}
}
3.2、串口接收
使用VSPD软件模拟串口,软件安装包:链接: link
电路连接和串口的配置如下图所示:
3.2.1、实验①
实验:
使用轮询方式接收一个字节的数据
①UART.c文件的代码如下:
#include "UART.h"
/**
* 串口初始化
* 参数:波特率
*/
void UART_Init(unsigned int Baud)
{
/* 串口寄存器的配置 */
PCON &= 0x3F; //PCON = 00xx xxxx
SCON &= 0x0F;
SCON |= 0x50; //SCON = 0101 xxxx
/* 配置T1的寄存器 */
TMOD &= 0x0F;
TMOD |= 0x20; //TOMD = 0010 xxxx
TH1 = 256 - (28800/Baud);//配置波特率
TL1 = 256 - (28800/Baud);//配置波特率
ET1 = 0; //关闭T1溢出中断
TR1 = 1; //使能T1
}
/**
* 发送一个字节的数据
*/
void Send_Char(unsigned char ch)
{
SBUF = ch; //给SBUF写入一个字节数据
while(!TI); //等待数据发送完成(未完成TI = 0,完成TI = 1)
TI = 0; //手动清0
}
/**
* 对printf函数进行重定向
*/
char putchar(char ch)
{
Send_Char(ch);
return ch;
}
②UART.h文件的代码如下:
#ifndef __UART_H
#define __UART_H
#include <reg51.h> //包含51头文件,里面全是寄存器地址
void UART_Init(unsigned int Baud);//串口初始化
void Send_Char(unsigned char ch);//发送一个字节的数据
char putchar(char ch);//printf()重定向
#endif
③mian.c文件的代码如下:
#include "UART.h"
#include "Delay.h"
void main(void)
{
unsigned char Data = 0; //一个字节的数据缓冲区
UART_Init(9600); //9600波特率
while(1)
{
if(RI) //RI = 1,SBUF里面接收到数据
{
Data = SBUF; //对数据进行处理
RI = 0;
Send_Char(Data); //将数据发送出去
}
}
}
3.2.2、实验②
实验:
使用中断方式接收一个字节数据
①UART.c文件的代码如下:
#include "UART.h"
/**
* 串口初始化,且开启中断
* 参数:波特率
*/
void UART_It_Init(unsigned int Baud)
{
/* 串口寄存器的配置 */
PCON &= 0x3F; //PCON = 00xx xxxx
SCON &= 0x0F;
SCON |= 0x50; //SCON = 0101 xxxx
/* 配置T1的寄存器 */
TMOD &= 0x0F;
TMOD |= 0x20; //TOMD = 0010 xxxx
TH1 = 256 - (28800/Baud);//配置波特率
TL1 = 256 - (28800/Baud);//配置波特率
ET1 = 0; //关闭T1溢出中断
TR1 = 1; //使能T1
/* 使能串口中断 */
ES = 1; //使能串口中断
EA = 1; //使能中断总开关
}
/***********中断服务函数*************/
/**
* 中断服务函数
*/
unsigned char Data2 = 0;
unsigned char Flag2 = 0;
void UART_Routine(void) interrupt 4
{
/* 若是发送完成中断:TI = 1*/
if(TI)
{
//一般情况下不使用你中断进行发送数据
}
/* 若接收数据完成中断 RI = 1*/
if(RI)
{
RI = 0;
Data2 = SBUF;//对数据进行处理
Flag2 = 1; //标志位置1
}
}
②UART.h文件的代码如下:
#ifndef __UART_H
#define __UART_H
#include <reg51.h> //包含51头文件,里面全是寄存器地址
#include <stdio.h>
void UART_Init(unsigned int Baud);//串口初始化
void Send_Char(unsigned char ch);//发送一个字节的数据
void Send_Array(unsigned char* Array,unsigned char Len);//发送多个字节的数据
void Send_String(unsigned char* str);//发送字符串
char putchar(char ch);//printf()重定向
void UART_It_Init(unsigned int Baud);//串口初始化(使能中断)
extern unsigned char Data2;
extern unsigned char Flag2;
#endif
③mian.c文件的代码如下:
#include "UART.h"
void main(void)
{
UART_It_Init(9600); //9600波特率
while(1)
{
if(Flag2) //Flag = 1,数据处理完成
{
Flag2 = 0;
Send_Char(Data2);//将数据发送出去
}
}
}