12_单片机_串行口通信_UART
1. 串行接口:简称串口(通常指COM接口),英文名Serial interface。将数据一位一位地顺序传送。缺点速度慢。
接口划分标准:同步串行接口(SSI)和异步串行接口(UART)。UART是并行输入成为串行输出,分为TTL电平和RS232电平

2. STC89C51RC系列单片机内部集成一个全双工串行通信口,与传统8051单片机的串口完全兼容。
设有2个互相独立的接收、发送缓冲器,可以同时发送和接收数据。发送缓冲器只能写入但不能读出;接收缓冲器只能读出但不能写入。
所以两个缓冲器共用一个地址码(99H),这两个缓冲器统称为 串行通信特殊功能寄存器SBUF。
3. 串行通信有4种工作方式(如下图右):方式0、方式1、方式2、方式3。两种工作方式的波特率可变,另外两种的波特率不变。通常使用方式1。
波特率是由内部定时器/计数器产生的,使用软件设置不同的波特率和选择不同的工作方式。

4. 方式1,波特率计算方式

5. 使用”方式1“实现串口数据发送,如下代码,实现每隔100ms,单片机通过串口发送字符 'F'
1 #include <reg51.h> 2 3 /****************************************************** 4 * 初始化串口 5 ** 1. 定时器1设置为8位自动重载定时器 6 ** 1. 设置波特率是否加倍;是否启用帧错误检测 PCON 7 ** 2. 设置串行通信的工作方式; 是否允许串行接收 SCON 8 ** 3. 波特率是内部定时器/计数器产生,计算波特率 9 设置波特率4800,定时器1 10 4800 = (2/32)*(12000000/(12*(256-TH1))) 11 TH1 ≈ 243 12 ** 4. 开启串口中断 13 ** 5. 开启总中断 14 ** 6. 启动定时器1 15 ******************************************************/ 16 17 void delay100ms(void) 18 { 19 unsigned char a,b,c; 20 for(c=7;c>0;c--) 21 for(b=74;b>0;b--) 22 for(a=95;a>0;a--); 23 } 24 25 void Init_uart(void) 26 { 27 TMOD = 0x20; // 定时器1的工作模式 28 PCON = 0x80; // 波特率加倍 29 SCON = 0x50; // 工作方式1,且允许串行接收 30 31 TH1 = 243; // 0xF3 32 TL1 = 243; 33 34 ES = 1; // 开启串口中断 35 EA = 1; // 开启总中断 36 TR1 = 1; // 启动Timer1 37 } 38 39 void uart_isr(void) interrupt 4 using 1 40 { 41 } 42 43 void uart_send_bit(unsigned char c) 44 { 45 SBUF = c; 46 while(!TI); 47 TI = 0; 48 } 49 50 void main(void) 51 { 52 Init_uart(); 53 54 while(1) 55 { 56 uart_send_bit('F'); 57 delay100ms(); 58 } 59 }
6. 向串口发送1bit数据,单片机再从串口发出来
1 #include <reg51.h> 2 3 4 unsigned char tmp; 5 6 void delay100ms(void) 7 { 8 unsigned char a,b,c; 9 for(c=7;c>0;c--) 10 for(b=74;b>0;b--) 11 for(a=95;a>0;a--); 12 } 13 14 void Init_uart(void) 15 { 16 TMOD = 0x20; // 定时器1的工作模式 17 PCON = 0x80; // 波特率加倍 18 SCON = 0x50; // 工作方式1,且允许串行接收 19 20 TH1 = 243; // 0xF3 21 TL1 = 243; 22 23 ES = 1; // 开启串口中断 24 EA = 1; // 开启总中断 25 TR1 = 1; // 启动Timer1 26 } 27 28 void uart_send_bit(unsigned char c) 29 { 30 SBUF = c; 31 while(!TI); 32 TI = 0; 33 } 34 35 void uart_isr(void) interrupt 4 using 1 36 { 37 if(RI) 38 { 39 RI = 0; 40 tmp = SBUF; 41 uart_send_bit(tmp); 42 } 43 } 44 45 void main(void) 46 { 47 Init_uart(); 48 while(1); 49 }
7. 串口发送字符串,每隔100ms
1 #include <reg51.h> 2 3 4 unsigned char tmp; 5 6 void delay100ms(void) 7 { 8 unsigned char a,b,c; 9 for(c=7;c>0;c--) 10 for(b=74;b>0;b--) 11 for(a=95;a>0;a--); 12 } 13 14 void Init_uart(void) 15 { 16 TMOD = 0x20; // 定时器1的工作模式 17 PCON = 0x80; // 波特率加倍 18 SCON = 0x50; // 工作方式1,且允许串行接收 19 20 TH1 = 243; // 0xF3 21 TL1 = 243; 22 23 ES = 1; // 开启串口中断 24 EA = 1; // 开启总中断 25 TR1 = 1; // 启动Timer1 26 } 27 28 void uart_send_bit(unsigned char c) 29 { 30 SBUF = c; 31 while(!TI); 32 TI = 0; 33 } 34 35 void uart_send_string(unsigned char *str) 36 { 37 while(*str != '\0') 38 { 39 uart_send_bit(*str); 40 str++; 41 } 42 } 43 44 void uart_isr(void) interrupt 4 using 1 45 { 46 47 } 48 49 void main(void) 50 { 51 Init_uart(); 52 while(1) 53 { 54 uart_send_string("abcdqwer!@ "); 55 delay100ms(); 56 } 57 }
记录下,发现串口还有些不理解的地方~
浙公网安备 33010602011771号