赞
踩
一、本人在准备过程中遇到的问题:
1、矩阵键盘不稳定的情况:可以看看下面链接的内容,有多种按键的处理方法。
2、串口通信时ISP软件无法接受到信息:
例如stc-isp-15xx-v6.86r,可以将最低波特率和最高波特率调节相同的波特率。
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的亮灭功能,以及参数的设定等等,有大致的了解之后再进行代码的编写。
三、主要的学习资源
2、历年选择题答案与解析
小蜜蜂老师的宝藏网站!!!
https://www.xmf393.com/2019/06/11/lqbmcu/https://www.xmf393.com/2019/06/11/lqbmcu/
3、设计题的代码驱动修改 (以14届为例)
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++);
- }
- }
注:以上内容大多数都是小蜜蜂老师的内容,可能存在部分的问题,希望大家给予指正。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。