这个程序实现了PC与单片机的简单交互,从键盘读取一个定长为4的字符串,通过PC串口发送给单片机,再由单片机通过串口程序将该字符串返回给PC。一般串口通信程序均可按此模板进行编程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <REG51.h>
#include <stdio.h>
 
unsigned char c[5] = {0};  //缓冲区为4字节。一次从PC接收4个字符,
                        //之所以要分配5个字节,是为了下面的SendString()例程考虑。
int ready; //信号量,当ready为0,表示缓冲区尚未准备好,主程序阻塞。
int length = 0; //记录单片机当前已接收字符串长度。
 
//串口初始化例程。
void init_uart()
{
	SCON = 0x50;	//SCON: mode 1, 8-bit UART, enable rcvr
	TMOD = 0x20;	//TMOD: timer 1, mode 2, 8-bit reload
	TH1 = 0xFD;	//TH1:  reload value for 9600@11.0592MHz
	TCON = 0x69;
	TR1 = 1;	//启动定时器1
	ES = 1;	//允许串口中断位
	EA = 1;	//允许总中断位
}
 
//从串口发送一个字符
void SendOneChar(char c)
{
	ES=0; //发送数据时关串口中断
	TI=0; //清TI位
 
	SBUF = c; //将待发送字符放入串口数据缓冲寄存器,并开始传输。
 
	while(!TI); //等待传送结束。当字符发送结束后由硬件置位请求中断,
             //此时while循环结束,而串口中断处理函数需等到ES重新置1后才可能响应。
	TI=0; //软件清TI位,亦可在中断处理函数中清0
	ES = 1; //开串口中断
}
 
//向串口发送字符串
void SendString(char *st)
{
	while(*st)
	{
		SendOneChar(*st++);
	}
}
 
//串口中断服务程序。每执行1次,从串口接收1个字符。
void uart_interrupt() interrupt 4
{
	ready = 0; //当本中断服务程序接收到所需长度字符串后置ready为1,
	          //使主程序往下执行。
 
	if(RI) //当SBUF接收到1个字符,硬件置RI为1。
	{
		RI = 0; //清RI
		if(length < 4) //将接收到的字符缓存在c数组里。
		{
			c[length++] = SBUF;
		}
		if(length >= 4) //如果数组已满,表示已经接收到指定长度字符串。
		{
			ready = 1; //置ready
			length = 0; //清length
		}
	}
	if(TI) //当SBUF发送完1个字符后,由硬件置TI为1。
	{
		//字符发送中断处理,本例中没有涉及。
	}
}
 
void main()
{
	int i;
 
	init_uart();
	while(1)
	{
		ready = 0;
		while(!ready);//阻塞,等待串口接收4个字节的字符串。
		for(i = 0; i < 4000; i++);//延迟一小段时间
		SendString(c);//发送字符串到PC
	}
}

版权声明:本文为fdggg原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/fdggg/articles/2966451.html