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 }
View Code

 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 }
View Code

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 }
View Code

记录下,发现串口还有些不理解的地方~

posted on 2023-04-19 20:15  Ivan2023  阅读(144)  评论(0)    收藏  举报