蓝桥第十二届单片机心得

自己的心得

蓝桥杯单片机难吗,不是很难,但注重细心。一分付出,一分收获。今年我参加了第十二届的比赛,但因为自己操作不当,美化代码的过程中删了定时器,没在主函数删了调用函数,导致已经完成的大厦轰然倒塌,自己也很难受,但没办法,希望看到文章的你们不要犯这种低级问题。
emmmm,不过后来拿了省一,挺意外的。

新手上路

基础部分的内容,推荐大家去看小蜜蜂老师的视频,讲的很好,网址: https://www.xmf393.com/2019/06/11/2019061103.

学习思路

以下是我的学习思路
首先:先学会LED、蜂鸣器、继电器、按键、数码管、数码管位选、串口等基本操作。
其次:ds1302,ds18b20,eeprom(24C02),PCF8591等。
然后:PWM呼吸灯,DA(因为我刚开始一直没找到)、超声波。
最关键的是一定要做省赛题!实操很重要!

赛题链接:https://pan.baidu.com/s/1ULZzd9nSA8l21VQQiDYvuQ .
提取码:1234

一些需要注意的点!!

LED

首先要说的是LED灯,比如第10届省赛题目中,如果单独点亮LED,会出现原先没有定义的灯跟着一起亮,我的解决方法如下

void led()
{
	unsigned char key1,key2,key3,key4;
	if(s4_stat == 0)										key1 = 0x01;
	else if(s4_stat == 1)									key1 = 0x02;
	if((dat_sz>=0&&dat_sz<150)||(dat_sz>=250&&dat_sz<350))	key2 = 0x04;
	else													key2 = 0x00;
	if(dat_f>=0&&dat_f<1000||dat_f>=5000&&dat_f<10000)		key3 = 0x08;
	else													key3 = 0x00;
	if(DA_dy == 103)										key4 = 0x10;
	else													key4 = 0x00;
	P2 = (P2 & 0x1f) | 0x80;P0 = ~(key1|key2|key3|key4);P2 = 0x00;
}

延迟delay

本来不想单独拿出来讲的,实在是初学者这里出问题的太多了。

//这个t是0-255
void delay(unsigned char t)
{
	while(t--)}

//这个t是0-65536
void delay(unsigned int t)
{
	while(t--)}

//这个不影响数码管显示
void delay(unsigned char t)
{
	while(t--)
	{数码管显示}
}

按键消抖

有时候题目会让你只加1,但你按了按键会出现加的好多,这里推荐一种解决方法

if(key == 0)
{
	delay(100);
	if(key == 0)
	{
		相关操作;
		while(key == 0){数码管操作;}
	}
}

矩阵按键

我参考的B站一位UP主,写的很好,这里用的是reg52

sbit P42 = P4^2;
sbit P44 = P4^4;
unsigned char key_value;
void scan_key()
{
	P3 = 0x0f;P42 = 0;P44 = 0;
	if(P3 != 0x0f)
	{
		delay(100);
		if(P3 != 0x0f)
		{
		switch(P3)
		{
			case 0x0e:key_value = 0;break;
			case 0x0d:key_value = 4;break;
			case 0x0b:key_value = 8;break;
			case 0x07:key_value = 12;break;
		}
		P3 = 0xf0;P42 = 1;P44 = 1;
		switch(P3)
		{
			case 0xe0:key_value += 3;break;
			case 0xd0:key_value += 2;break;
		}
		if(P42 == 0)
		{
			key_value += 1;
		}
	//	!!这里可以根据key_value的值做其他的按键操作!!
		while(P3 != 0xf0);
		while(P42 != 1);
		while(P44 != 1);
		}
	}
}

DS13B20

关于ds13b20读取温度,onewire里面的延迟都要增大10-12倍。特别注意的就是,蜜蜂老师那的temp是16位的,LSB、MSB是8位的,还有就是老师那的delay(700)是unsigned int的而不是unsigned char,要特别注意一下。两位小数的读法我建议大家去找找相关内容看看,以免考到。

IIC

IIC这一块除了DA输出,其他没啥可说的,DA输出参考代码如下(只需要这样然后主函数调用就行,接着你去拿万用表测J3的D/A与GND两个位置就可以得到差不多的数值):

void write_DA()
{
	IIC_Start(); 
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x40);		//0100 0000 这里的第二位置为1为DA,0为AD
	IIC_WaitAck();
	IIC_SendByte(DA_dy1);	//DA_dy1的值是0-255,换算5V电压
	IIC_WaitAck();			//你只需要乘以500/255.0f = 1.96可到就行
	IIC_Stop(); 
}

还有一个点就是应答和非应答。

IIC_SendAck(x);	//0的话值0-128,1的话值是0-255.

PWM

有些小伙伴可能学了很久都没搞懂PWM是怎么搞的,我举个例子。

unsigned char count,time,pwm_duty,led_light;
void Init()				//定时器
{
	TMOD = 0x01;
	TH0 = (65536 - 100) / 256;
	TL0 = (65536 - 100) % 256;
	TR0 = 1;
	ET0 = 1;
	EA = 1;
}

void 函数名() interrupt 1
{
	TH0 = (65536 - 100) / 256;
	TL0 = (65536 - 100) % 256;
	count++;
	if(count <= pwm_duty)
	{P2 = (P2 & 0x1f) | 0x80;P0 = 0xfe;P2 = 0x00;}
	else if(count < 10)
	{P2 = (P2 & 0x1f) | 0x80;P0 = 0xff;P2 = 0x00;}
	else
	{count = 0;time++;P2 = (P2 & 0x1f) | 0x80;P0 = 0xfe;P2 = 0x00;}
}
void pwm()
{
	if(time == 5)
	{
		time = 0;
		if(led_light == 0) //0是亮、1是暗
		if(pwm_duty == 10)	pwm_duty = 10,led_light = 1;	else	pwm_duty++;
		else if(led_light == 1)
		if(pwm_duty == 0)   pwm_duty = 0,led_light = 0;		else 	pwm_duty--;	
	}
}

首先我们要的是小灯缓慢亮0.5s,缓慢灭0.5s,先定义一个100us的定时器,先经过count走了10次后,time++了,五次后也就是count加了50次(换算也就是50ms),然后led灯会变一次pwm_duty,也就是小灯的亮度,总共要变10次,也就是0.5s,达到效果。

IO和MM模式

省赛我还没看到要求用MM模式的,大多数都是要求IO模式,最好都学一下,MM模式比IO模式多用一个absacc.h的头文件。

结尾

希望看到这篇文章的你,不会和我刚考完一样,感觉自己的付出和回报不成正比,自己的心态很受打击。当我知道没删那个的时候,我当时人直接懵了,手机也摔地上碎屏了,自己付出了很多,和老师与陪自己一起走过来经常交流的赛友们学到了很多,但最后因为一个很小的问题导致这样,自己真的完全接受不了。不过人生总有得有失吧,唉,大家国赛加油!
最后记得根据题目意思交压缩包,而不是只交了一份hex文件!!!

最后,青山不改,碧水长流

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值