51单片机基础10——串口实验

串口实验

    • 51单片机串口实验
      • [1. 软硬件条件](#1. 软硬件条件)
      • [2. 串口实验](#2. 串口实验)
        • [2.1 单片机与PC 发送字符](#2.1 单片机与PC 发送字符)
          • [2.1.1 效果](#2.1.1 效果)
          • [2.1.2 代码](#2.1.2 代码)
          • [2.1.3 优化](#2.1.3 优化)
        • [2.3 串口接收数据(指令控制单片机)](#2.3 串口接收数据(指令控制单片机))
          • [2.3.1 非中断方式实现](#2.3.1 非中断方式实现)
          • [2.3.2 中断方式实现](#2.3.2 中断方式实现)

51单片机串口实验

1. 软硬件条件

  • 单片机型号:STC89C52RC
  • 开发环境:KEIL4
  • 烧录软件串口通信软件:stc-isp

2. 串口实验

实现单片机与PC 串口通信,能够通过PC 输入指令 控制单片机。

2.1 单片机与PC 发送字符
2.1.1 效果
2.1.2 代码
c 复制代码
#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(); // 延迟用于 为传输数据预留时间

	}
}
2.1.3 优化

不采用延迟方式,采用标志位判断是否发送成功,并且发送字符串。

c 复制代码
#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 world\r\n");
		testLed = !testLed;
		Delay1000ms();
	}
}
2.3 串口接收数据(指令控制单片机)
2.3.1 非中断方式实现

主要时查询法检测RI标志位是否被置1 ,注意软件置0.

c 复制代码
#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;
		}
	}
}
2.3.2 中断方式实现
c 复制代码
#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!\r\n");
		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);

}
相关推荐
梓䈑2 分钟前
【C语言】自定义类型:结构体
c语言·开发语言·windows
PYSpring7 分钟前
数据结构-LRU缓存(C语言实现)
c语言·数据结构·缓存
TANGLONG22229 分钟前
【C语言】数据在内存中的存储(万字解析)
java·c语言·c++·python·考研·面试·蓝桥杯
@qike1 小时前
【C++】—— 日期类的实现
c语言·c++·笔记·算法·学习方法
f狐0狸x2 小时前
C语言指针plus版练习
c语言·指针
江奖蒋犟3 小时前
【初阶数据结构】排序——归并排序
c语言·数据结构·算法
水饺编程3 小时前
【英特尔IA-32架构软件开发者开发手册第3卷:系统编程指南】2001年版翻译,1-2
linux·嵌入式硬件·fpga开发
无限大.3 小时前
c语言实例 -- 循环链表
c语言·开发语言·链表
电子科技圈3 小时前
IAR全面支持国科环宇AS32X系列RISC-V车规MCU
人工智能·嵌入式硬件·mcu·编辑器
Stark、3 小时前
异常处理【C++提升】(基本思想,重要概念,异常处理的函数机制、异常机制,栈解旋......你想要的全都有)
c语言·开发语言·c++·后端·异常处理