【蓝桥杯单片机】

蓝桥杯单片机总结(只拿了国三,不写了)

*以下是根据我个人国赛复习顺序而列 *

S1 串口

S1-1 串口初始化

串口1选择定时器2,原因后续再提。
直接用STC-ISP自动生成即可,仅需额外加两行代码。
在这里插入图片描述
再加上开启总中断和串口中断。

void UartInit(void)		//9600bps@12.000MHz
{
	SCON = 0x50;	//8位数据,可变波特率
	AUXR |= 0x01;	//串口1选择定时器2为波特率发生器
	AUXR |= 0x04;	//定时器2时钟为Fosc,即1T
	T2L = 0xC7;		//设定定时初值
	T2H = 0xFE;		//设定定时初值
	AUXR |= 0x10;	//启动定时器2
	ES = 1;			//串口中断
	EA = 1;			//总中断
}

好,串口的初始化已经完成了,为了方便串口发送,我们还需要重定向一下串口,原因可自行搜索。

char putchar(char c)
{
	ES=0;
	SBUF=c;
	while(!TI);
	TI=0;
	ES=1;
	return 0;
}

串口初始化,以及重定向后,就可以用printf进行输出了,大家死去的C语言记忆是不是开始攻击自己呢?

printf("A");printf("\r\n");
printf("123456\r\n");
printf("串口\r\n");

结果:
在这里插入图片描述

S1-2 串口发送与接收

S1-2-1 串口发送

注意!!!
使用printf时需要加上库函数stdio.h
数据定义:

unsigned char  a=123;
char  b=-123;
unsigned short c=12345;
short d=-12345;
unsigned int   e=12345;
int   f=-12345;
unsigned long  g=99999999;
long  h=-9999999;
float i=8888.6666;

发送:

	printf("a=%bu\r\n",a);//实测,正数也可以用%bd
	printf("b=%bd\r\n",b);
	printf("c=%hu\r\n",c);//实测,正数也可以用%hd
	printf("d=%hd\r\n",d);
	printf("e=%hu\r\n",e);//实测,正数也可以用%hd
	printf("f=%hd\r\n",f);
	printf("g=%lu\r\n",g);//实测,正数也可以用%ld
	printf("h=%ld\r\n",h);
	printf("i=%.0f\r\n",i);
	printf("i=%.1f\r\n",i);
	printf("i=%.2f\r\n",i);
	printf("i=%.3f\r\n",i);
	printf("i=%.4f\r\n",i);
	printf("i=%.5f\r\n",i);

结果:
在这里插入图片描述
在这篇帖子学到的
51单片机重定向printf函数 打印数值不正确问题

S1-2-2 串口接收

注意!!!
比较时需要加上库函数string.h
定义:

u8 urdat;
u8 xdata buf[10];  //接收到的数据
u8 index = 0;  //buf数组索引
bit Uart_Ref = 0;  //接收完成标志 1:接收完成

中断:

void Uart1_Isr(void) interrupt 4
{
	if(RI)
	{
		RI = 0;
		urdat = SBUF;
		if(urdat == 'n')
		{
			Uart_Ref = 1;
			buf[index] = 'n';
			buf[index+1] = '\0';
			index = 0;
		}
		else
		{
			buf[index++] = urdat; //接收的数据暂时存到数组里
		}
	}
}

执行:

if(Uart_Ref == 1)  //接收完成
{
	Uart_Ref = 0;
	if(strcmp(buf,"Return") == 0)
	{
		printf("Noises:%hu\r\n",Freq);
	}
}

这也是在C站上学来的,已经忘了原链接在哪

S2 频率

测频率使用定时器0,此时需要将开发版右侧P34与SIGNAL用跳线帽短接起来。
警告:测频率时会与矩阵按键发生冲突,使用时应当注意。

S2-1 初始化

定时器1初始化1ms:

void Timer1_Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x40;			//定时器时钟1T模式
	TMOD &= 0x0F;			//设置定时器模式
	TL1 = 0x20;				//设置定时初始值
	TH1 = 0xD1;				//设置定时初始值
	TF1 = 0;				//清除TF1标志
	TR1 = 1;				//定时器1开始计时
	ET1 = 1;				//使能定时器1中断
	EA=1;
}

定时器0初始化:

void Timer0_Init(void)		//1毫秒@12.000MHz
{
	TMOD |= 0x06;			//设置定时器模式
	TL0 = 0xff;				//设置定时初始值
	TH0 = 0xff;				//设置定时初始值
	TR0 = 1;				//定时器0开始计时
	ET0 = 1;				//使能定时器0中断
	EA = 1;
}

数据定义:

u16 Freq=0,Count=0,t=0;

S2-2 定时器中断

定时器中断执行:

//定时器1:
void Timer1_Isr(void) interrupt 3
{
	t++;
	if(t>=1000)
	{
		Freq=Count;
		Count=0;
		t=0;
	}
	
}
//定时器0:
void Timer0_Isr(void) interrupt 1
{
	Count++;
}

S2-3 结果

输出:

while(1)
{
	Delay1000ms();
	printf("Freq=%hu",Freq);
}

结果:
在这里插入图片描述

S3 超声波

S3-1 超声波初始化

初始化:
原理可自行百度

void Delay13us(void)	//@12.000MHz
{
	unsigned char data i;

	_nop_();
	_nop_();
	i = 36;
	while (--i);
}

void Send_Sonic()
{
	u8 i = 8;
	while(i--)
	{
		Sonic_TX=1;
		Delay13us();
		Sonic_TX=0;
		Delay13us();
	}
}

u16 GetDist()
{
	u16 dist;
	Send_Sonic();
	CR=1;
	while((Sonic_RX)&&(!CF));
	CR=0;
	if(CF==1)
	{
		CF=0;
		return 999;
	}
	else
	{
		dist=CH*256+CL;
		dist*=0.017;
	}
	CH=0;
	CL=0;
	
	return dist;
}

直接在main函数中调用即可
GetDist()返回值是单位为cm的数
Delay13us()中的i=36可微调

S4 温度ds18b20

话不多说,直接上代码

unsigned long GetTemp()
{
	unsigned long Dat;
	u8 high,low;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	Delay_OneWire(200);
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	low=Read_DS18B20();
	high=Read_DS18B20();
	Dat=0x0f&high;
	Dat<<=8;
	Dat|=low;
	Dat*=625;
	
	return Dat;
}

返回值很长

DigBuf[6]=TEMP_Value%1000000/100000;
DigBuf[7]=TEMP_Value%100000/10000;

显示个位和百位

S5 时间ds1302

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

略不世出

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值