一、本人在准备过程中遇到的问题:

1、矩阵键盘不稳定的情况:可以看看下面链接的内容,有多种按键的处理方法。

https://blog.csdn.net/qq_43935020/article/details/114108489https://blog.csdn.net/qq_43935020/article/details/114108489

2、串口通信时ISP软件无法接受到信息:

例如stc-isp-15xx-v6.86r,可以将最低波特率和最高波特率调节相同的波特率。

042ce1ef585442acba185d9543babbd6.png

3、使用DS18B20时会读到85℃:在主程序中引用下面的代码,并且加上750ms的延时函数

void ds18b20_init()
{
	unsigned char lsb,msb;
	unsigned int tep;	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	do
	{
		init_ds18b20();
		Write_DS18B20(0xcc);
		Write_DS18B20(0xbe);
		lsb=Read_DS18B20();
		msb=Read_DS18B20();
		tep=msb;
		tep=(msb<<4)|(lsb>>4);
	}while(tep==85);

void Delay750ms()		//@12.000MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 35;
	j = 51;
	k = 182;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void main()
{
    void ds18b20_init();
    void Delay750ms();
    while(1)
    {

    }
}

4、使用DS1302时,时钟停止不动:这是一个小常识

void main()
{
	ds1302_wirte();
	while(1)
	{
		ds1302_read();
	}
}

 

二、比赛准备与学习

蓝桥杯单片机比赛需要用到的知识有:数电知识+模电知识+C语言知识+单片机知识(考试时可用比赛时给的PDF阅读器查看STC手册的知识)。

选择题有15分,10小题,一题1.5分。(选择题的基础,本人学习在参加蓝桥杯之前都已学过,若没有学习过的同学需要多加准备了。)

设计题:应该先把考试会考到的几大模块摸索清楚,这里推荐B站【小蜜蜂笔记】的视频。清楚基本的内容后可以看历年的真题。看到真题时,不要盲目的下手,直接就开始打代码。可以先在草稿纸上,把基础的界面显示,按键功能,LED的亮灭功能,以及参数的设定等等,有大致的了解之后再进行代码的编写。

 

三、主要的学习资源

1、【欧浩源】小蜜蜂老师的基础教程https://www.bilibili.com/video/BV1Bt41187hw/?spm_id_from=333.999.0.0&vd_source=9622193d8b15b12f3f5d7b274ed88882https://www.bilibili.com/video/BV1Bt41187hw/?spm_id_from=333.999.0.0&vd_source=9622193d8b15b12f3f5d7b274ed88882

2、历年选择题答案与解析

小蜜蜂老师的宝藏网站!!!

https://www.xmf393.com/2019/06/11/lqbmcu/https://www.xmf393.com/2019/06/11/lqbmcu/

3、设计题的代码驱动修改 (以14届为例)

https://blog.csdn.net/boybs/article/details/129911996https://blog.csdn.net/boybs/article/details/129911996

4、历年设计https://pan.baidu.com/s/1GNSoH7eSqL-r3zMhZoxTEg 提取码:235u

四、各模块的主要程序(考前模块总结)

下面的内容需要对各模块功能有一定了解。

1、PCF8591        (iic.h)

unsigned char adc_value=0;//采样电压
float adc_volt=0;         //换算电压
unsigned int smg_volt;    //数码管显示电压

void read_adc()//ADC
{
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x43);
	IIC_WaitAck();
	IIC_Stop();
	
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	adc_value=IIC_RecByte();
	IIC_SendAck(1);
	IIC_Stop();
	
	adc_volt=adc_value*(5.0/255);
	smg_volt=adc_volt*100;
}

void read_dac(float dat)//DAC
{
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x03);//0x01为光敏电阻的A/D转换通道,0x03为电位器的A/D转换通道
                     //0x41为光敏电阻的A/D转换通道或者D/A,0x43为电位器的A/D转换通道或者D/A
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}

 

2、24C02        (iic.h)

void write_24c02(unsigned char addr,unsigned char dat)//单字节写入
{
		IIC_Start();
		IIC_SendByte(0xa0);
		IIC_WaitAck();
		IIC_SendByte(addr);//需要存放的地址
		IIC_WaitAck();
		IIC_SendByte(dat);//需要存放的数据
		IIC_WaitAck();
		IIC_Stop();
}

unsigned char read_24c02(unsigned char addr)//单字节读出
{
		unsigned char tmp=0;

        //伪操作
		IIC_Start();
		IIC_SendByte(0xa0);
		IIC_WaitAck();
		IIC_SendByte(addr);
		IIC_WaitAck();

	    IIC_Start();
		IIC_SendByte(0xa1);//读指令
		IIC_WaitAck();
		tmp=IIC_RecByte();//读出数据
		IIC_SendAck(1);
		IIC_Stop();
		
		return tmp;//返回读到的数据
}

 

3、DS18B20        (onewire.h)

//DS18B20 温度的读出与显示
void read_display_ds18b20()
{
	unsigned char LSB,MSB;
	unsigned int temp;
	
	init_ds18b20();
	Write_DS18B20(0xcc);//忽略ROM操作
	Write_DS18B20(0x44);//启动温度转换
	smg_dispalay();//延时
	
	init_ds18b20();
	Write_DS18B20(0xcc);//忽略ROM操作
	Write_DS18B20(0xbe);//读出内部存储器
	LSB=Read_DS18B20();//第0字节,温度的低8位
	MSB=Read_DS18B20();//第1字节,温度的高8位
	init_ds18b20();
	
	temp=MSB;
	temp=(temp<<8)|LSB;
	if((temp&0xf800)==0x0000)//判断是否为正温度
	{
		temp_ds18b20=temp*0.0625;//计算实际温度
	}
	smg_ds18b20=temp_ds18b20;//若要保留一位小数点则temp_ds18b20*10,                                   
                              //保留两位则 temp_ds18b20*100;
	smg_dispalay();
}

 

4、DS1302        (ds1302.h)

void DS1302_W()
{
	char i;
	Write_Ds1302_Byte( 0x8e,0x00);//允许写入	
	for(i=0;i<7;i++)
	{
	Write_Ds1302_Byte( Write_DS1302_add[i],Timer[i]);
	}
	Write_Ds1302_Byte( 0x8e,0x80);//禁止写入
}

void DS1302_R()
{
	char i;
	
	for(i=0;i<7;i++)
	{
	Timer[i]=Read_Ds1302_Byte( Read_DS1302_add[i] );//将时钟读出
	}
}

 

5、PWM信号

unsigned char count=0;//计数
unsigned char pwm_duty=0;//脉冲宽度,占空比

void Init_Timer0()//定时100us
{
	TMOD = 0x01;
	TH0=(65535-100)/256;
	TL0=(65535-100)%256;
	
	ET0=1;
	EA=1;
}

void ServiceTimer0() interrupt 1
{
	TH0=(65535-100)/256;
	TL0=(65535-100)%256;
	
	count++;
	if(count==pwm_duty)
	{
		L1=1;
	}
	else if(count==100)//count==100,宽度为10ms
	{
		L1=0;
		count=0;
	}
}

 

6、NE555频率发生器

 unsigned int count_t=0;    //时间计数
 unsigned int dat_f=0;      //得到的实际频率
 unsigned char count_f;     //频率计数

void Init_Timer()           //T0计数,模式二。T1定时,模式一。
{
	TH0=0xff;
	TL0=0xff;
	
	TH1=(65535 - 50000 +1)/256;
	TL1=(65535 - 50000 +1)%256;
	
	TMOD=0x16;//0001 0110
	
	ET0=1;
	ET1=1;
	EA=1;
	
	TR0=1;
	TR1=1;
}

void Service_T0() interrupt 1
{
	count_f++;                //频率计数
	
}

void Service_T1() interrupt 3
{
	TH1=(65535 - 50000 +1)/256;
	TL1=(65535 - 50000 +1)%256;
	
	count_t++;
	if(count_t==20)           //当定时50ms*20=1s,
	{
		dat_f=count_f;        //得到实际频率
		count_f=0;            //重新测频率,先清零
		count_t=0;            //定时计数重新开始,先清零
	}
}

 

7、超声波

sfr AUXR=0x8e;

sbit TX=P1^0;
sbit RX=P1^1;

void Delay13ms()		//@12.000MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 1;
	j = 152;
	k = 187;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}



void send_wave()                //产生8个40KHZ的信号
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		TX=0;                   //发送
		Delay13us();
		TX=1;
		Delay13us();
	}
}

unsigned int get_distance()    //得到测量距离
{
	unsigned long distant;

    AUXR |=0x80;                
	TL0=0x00;
	TH0=0x00;
	
	send_wave();
	TR0=1;                    //打开定时器
	while((RX==1)&&(TF0==0)); //等待超声波返回,或者等待测量距离超出范围
	TR0=0;                    //关闭定时器
	
	if(TF0==0)                //在正常的距离范围
	{
		distant=TH0*256+TL0;
		distant=(distant*170)/110592;
	}
	else                       //不正常的距离范围
	{
		TF0=0;
		distant=999;
	}
	return distant;
}

 

8、串口通信

void InitUart()
{
	TMOD=0x20;
	TH1=0xfd;
	TL1=0xfd;
	TR1=1;
	
	SCON=0x50;
	AUXR=0x00;
	
	ES=1;
	EA=1;
}

unsigned char command=0x00;//上位机内容

void ServiceUart() interrupt 4    //接受完成用中断
{
	if(RI==1)
	{
		command=SBUF;              //接受完成则将内容传给上位机
		RI=0;;
	}
}

void SendByte(unsigned char dat)    //发送完成用查询
{
	SBUF=dat;
	while(TI==0);
	TI=0;
}

void SendString(unsigned char *s)    //发送字符串
{
	while(*s!='\0')
	{
	SendByte(*s++);
	}
}

 

注:以上内容大多数都是小蜜蜂老师的内容,可能存在部分的问题,希望大家给予指正。

 

 

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐