Technology Sharing

51 MCU Basics 10——Serial Port Experiment

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

51 MCU serial port experiment

1. Hardware and software requirements

  • MCU model: STC89C52RC
  • Development environment: KEIL4
  • Burning software Serial communication software: stc-isp

2. Serial port experiment

Realize serial port communication between MCU and PC, and control MCU through PC input commands.

2.1 MCU and PC send characters
2.1.1 Effect

insert image description here

2.1.2 Code
#include "reg52.h"
#include <intrins.h>
sbit testLed = P3^7;
sfr AUXR = 0x8E; // 屏蔽电磁干扰


void UartInit(){
	PCON &= 0x7F; // 不倍速 不倍速甚至可以不用设置
	SCON = 0x40; // REN 不是能
	TMOD &= 0x0F;
	TMOD |= 0x20;	// 8位自动重装
	TL1 = 0xFD;		//设定定时初值
	TH1 = 0xFD;		//设定定时器重装值
	ET1 = 0;  	// 	禁止定时器1溢出申请中断
	EA = 1;
	TR1 = 1;		//启动定时器1
}
void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}
void init(){
	UartInit();
	testLed = 1;
	testLed = 0;
	Delay1000ms();
	
}

void main(){
	char msg = 'a';
	init();
	while(1){
		SBUF = msg; // 写入缓存区
		testLed = !testLed;
		Delay1000ms(); // 延迟用于 为传输数据预留时间

	}
}
  • 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
2.1.3 Optimization

Instead of using the delay method, the flag bit is used to determine whether the transmission is successful, and the character string is sent.

#include "reg52.h"
#include <intrins.h>
sbit testLed = P3^7;
sfr AUXR = 0x8E; // 屏蔽电磁干扰


void UartInit(){
	PCON &= 0x7F; // 不倍速 不倍速甚至可以不用设置
	SCON = 0x40; // REN 不是能
	TMOD &= 0x0F;
	TMOD |= 0x20;	// 8位自动重装
	TL1 = 0xFD;		//设定定时初值
	TH1 = 0xFD;		//设定定时器重装值
	ET1 = 0;  	// 	禁止定时器1溢出申请中断
	EA = 1;
	ES = 1;
	TR1 = 1;		//启动定时器1
}
void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}
void init(){
	UartInit();
	testLed = 1;
	testLed = 0;
	Delay1000ms();
	
}

void sendByte(char msg){
	SBUF = msg;
	while(!TI);
	TI = 0; 
}

void sendString(char *str){
	while(*str!='0'){
		sendByte(*str);
		str++;
	}
}
void main(){
	init();
	while(1){
		sendString("hello worldrn");
		testLed = !testLed;
		Delay1000ms();
	}
}
  • 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
2.3 Serial port receiving data (instruction control microcontroller)
2.3.1 Non-interrupt mode implementation

The main query method is to detect whether the RI flag is set to 1. Note that the software sets it to 0.

#include "reg52.h"
#include <intrins.h>
sbit testLed = P3^7;
sfr AUXR = 0x8E; // 屏蔽电磁干扰
char cmd;

void UartInit(){
	PCON &= 0x7F; // 不倍速 不倍速甚至可以不用设置
	SCON = 0x50;
	TMOD &= 0x0F;
	TMOD |= 0x20;	// 8位自动重装
	TL1 = 0xFD;		//设定定时初值
	TH1 = 0xFD;		//设定定时器重装值
	ET1 = 0;  	// 	禁止定时器1溢出申请中断
	EA = 1;
	ES = 1;
	TR1 = 1;		//启动定时器1
}

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void sendByte(char msg){
	SBUF = msg;
	while(!TI);
	TI = 0; // 只是中断标志 但是没有中断函数 则不会触发中断 有中断函数时需要及时置0 
}

void sendString(char *str){
	while(*str!='0'){
		sendByte(*str);
		str++;
	}
}
void init(){
	UartInit();
	testLed = 0;
	Delay1000ms();
	
}

void main(){
	init();
	while(1){	
		if(RI){
			cmd = SBUF;
			if(cmd == 'o'){
				testLed = 0;
			}
			else if(cmd == 'c'){
				testLed = 1;
			}
			RI= 0;
		}
	}
}
  • 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
2.3.2 Interrupt mode implementation
#include "reg52.h"
#include <intrins.h>
#include <string.h>
#define SIZE 3
sbit testLed = P3^7;
sbit testLed2 = P3^6;
sfr AUXR = 0x8E; // 屏蔽电磁干扰
char cmd[SIZE];

void UartInit(){
	PCON &= 0x7F; // 不倍速 不倍速甚至可以不用设置
	SCON = 0x50;
	TMOD &= 0x0F;
	TMOD |= 0x20;	// 8位自动重装
	TL1 = 0xFD;		//设定定时初值
	TH1 = 0xFD;		//设定定时器重装值
	ET1 = 0;  	// 	禁止定时器1溢出申请中断
	EA = 1;
	ES = 1;
	TR1 = 1;		//启动定时器1
}

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void sendByte(char msg){
	SBUF = msg;
	while(!TI);
	TI = 0; // 只是中断标志 但是没有中断函数 则不会触发中断 有中断函数时需要及时置0 
}

void sendString(char *str){
	while(*str!='0'){
		sendByte(*str);
		str++;
	}
}

void init(){
	UartInit();
	testLed = 0;
	testLed2 = 1;
	Delay1000ms();
	
}

void main(){
	init();
	while(1){	
		sendString("Hello World!rn");
		testLed = !testLed;
		Delay1000ms();
	}
}

void UartHandler() interrupt 4{
	static int i = 0;
	char tmp;
	if(RI){
		RI = 0;
		tmp = SBUF;
		if(tmp == 'o' || tmp == 'c'||i==SIZE){
			i = 0;
		}
		cmd[i++] = tmp;
		
		if(cmd[0] == 'o' && cmd[1] == 'p'){
			testLed2 = 0;
			memset(cmd,'0',SIZE);
		}
		if(cmd[0] == 'c' && cmd[1] == 'l'){
			testLed2 = 1;
			memset(cmd,'0',SIZE);
		}
	}
	if(TI);

}
  • 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
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92