蓝桥杯51单片机设计

发布于:2025-07-11 ⋅ 阅读:(54) ⋅ 点赞:(0)

目录

#串口通信#

①通信基础知识

上下位机通信

上下位机通信设置

补充知识点

②代码思路

③代码注意点:

①TXD与RXD连接

②通信速率确定——单片机中定时器决定

④串口程序设计

1.初始工作

2.代码参考

3.运行代码

⑤数据接收信号并文字显示(竞赛内容)

uart.c编写

uart.h编写

main.c编写(串口有关内容)


#串口通信#

①通信基础知识

信息交换

可以同时进行的信息交换(说跟听可以同时进行)——全双工串口通信

只有其中一个可以进行信息交换(说跟听只有一个可以进行)——半双工串口通信

只有一个信道通信(一一对应的信息交换,只有一个嘴巴一个耳朵)——串行通信

有很多信道通信(有很多嘴巴很多耳朵)——并行通信

可以自己适应语速但有bug——异步通信

波特率:一秒传输多少位

比特率:一秒发多少字节

数据格式:起始位+八个数据位+奇偶校验位+停止位

上下位机通信

上下位机通信设置

补充知识点

②代码思路

先配SCOM:SM0和SM1置01;REN=1;TI和RI置0;再配AUXR:选择定时器2为波特率发生器,并为1T:装初值TH2和TL2;最后ES=1和EA=1

③代码注意点:

①TXD与RXD连接

②通信速率确定——单片机中定时器决定

串口1一般是定时器2为波特率发生器来计时

定时器溢出一次的时间就是串口发一次数据时间t1

波特率设为x

④串口程序设计

1.初始工作

在模块里添加SYS文件夹中UART文件夹(与sys和delay统一等级)

新建俩个文件uart.c和uart.

在魔法棒里,C51添加文件路径

再将文件添加到工程中

.代码参考

void Uart1_Init(void)	//9600bps@12.000MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x01;		//串口1选择定时器2为波特率发生器
	AUXR |= 0x04;		//定时器时钟1T模式
	T2L = 0xC7;			//设置定时初始值
	T2H = 0xFE;			//设置定时初始值
	AUXR |= 0x10;		//定时器2开始计时
	ES = 1;				//使能串口1中断
}

//EA在主函数打开

代码源头可查找ISP

在主函数定义发送数组

发送函数编写

void Uart_send(uchar *Str)
{
		while(++Str !="\0")
		{
			SBUF = *Str;//发送数组内容
			while(TI==0);//发送完成TI=1
			TI=0;
			Str++;
		}
}

在串口接收数据之前要加一个中断服务函数,因为串口接收是通过触发中断实现的

若接收数据完成,会触发中断服务函数

void Uart1_Isr(void) interrupt 4
{
	if (RI)				//检测串口1接收中断
		//RI=1,说明数据接收完成,响应中断后,RI=0清零
	{
		Uart_buf[++index]=SBUF;//将SBUF内容给数组
		RI = 0;			//清除串口1接收中断请求位
	}
}

主函数代码编写

将“你好”转换到Uart_Txbuf

这种写法有缺点,每次打印东西,都要将内容赋值到数组中

数组定义很大,就浪费空间

3.运行代码

.点击运行

.串口助手,清空接收区,串口comSTC保持一致,波特率与文件内容保持一致,打开串口

优化代码

用printf来打印内容,用putchar来引用,#include<studio.h>

接收函数编写

char putchar(char ch)
{
	SBUF=ch;
	while(TI==0);//等待发送完成
	TI=0;//发送完成标志位置0
	return ch;
}
void main()
{
	Uart1_Init();
	EA=1;
	printf("Distance: %ucm",2025);//因为有putchar函数,所以可以直接使用printf函数

}

注意printf函数在keil中的使用

⑤数据接收信号并文字显示(竞赛内容)

14届模拟题二(有关串口内容成功显示)

uart.c编写

#include "uart.h"

//若串口接收,就需要增加中断
void Uart1_Isr(void) interrupt 4
{
	if (RI)				//检测串口1接收中断
	{
		uart_flag=1;//接受标志位
		uart_systick=0;//接收时间置零
		rec_buf[index++]=SBUF;
		RI = 0;			//清除串口1接收中断请求位
		if(index>2)index=0;//接收信号0 1
	}
}

void Uart1_Init(void)	//9600bps@12.000MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x40;		//定时器时钟1T模式
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0xC7;			//设置定时初始值
	TH1 = 0xFE;			//设置定时初始值
	ET1 = 0;			//禁止定时器中断
	TR1 = 1;			//定时器1开始计时
	ES = 1;				//使能串口1中断
	EA=1;
}

char putchar(char ch)
{
	SBUF=ch;
	while(TI==0);
	TI=0;
	return ch;
}

uart.h编写

#ifndef __UART_H_
#define __UART_H_
#include "sys.h"
void Uart1_Init(void);	//9600bps@12.000MHz
char putchar(char ch);
extern	uchar rec_buf[5];
extern	uchar index;
extern uchar uart_systick;
extern bit uart_flag;

#endif

main.c编写(串口有关内容)

bit flag_send;//每次发送当前数码管显示数据
uchar uart_systick;//接收数据的时间
bit uart_flag;//接收数据标志位,0未接收 1接收
//if(uart_flag==1) uart_stick++;

void Timer0_Isr(void) interrupt 1
{
	//***********************
	if(uart_flag==1)uart_systick++;//接收数据后,开始计时
	//**************************
}

void collect()
{
	if(collect_dly<500)return;
	collect_dly=0;
    temp=temperature(1);//3位onewire温度
	Vol=(read_ADDA(0x03)/51.0)*100;//电压显示
//////////////////////////////////////////////////////////
	if(flag_send==1)//S12按下发送数据
	{
		if(state_display==0)//温度显示界面
		{	
		  printf("TEMP:%.1f℃",temp/10.0);
		}//1位小数点,温度位三位数
		else if(state_display==1)
		{
		  printf("Voltage:%.2fV",Vol/100.0);
		}			//2位小数
		flag_send=0;//停止发送数据
	}
}
///////////////////////////////////////////////////////
void uart_pro()
{	
	if(index==0)return;//接收信号的帧头,失败
	if(uart_systick>=10)//接收信号超过十毫秒
	{
		uart_flag=uart_systick=0;//时间重置,标志位置零,接收成功
		if(index>0)//接收到帧头,并且由连续接受下去的趋势
		{
			if(index==1)//接收到信号
			{
				if(rec_buf[0]=="A"&&uart_state==1)//接收到信号并且是在解锁界面
				{
					state_display=0;
					display();
				}
				else if(rec_buf[0]=='B'&&uart_state==1)
				{
					state_display=1;//电压显示界面
					display();
				}
			}
		}
		index=0;//接收完数据,重新读取信号
	}
}


网站公告

今日签到

点亮在社区的每一天
去签到