本帖最后由 Amistad 于 2019-5-12 23:29 编辑
这次分享的是蓝桥杯第九届的题目,国赛得题目比省赛的要难很多,主要是考的器件非常的多,怎么去设计代码的结构至关重要,数码管,e2prom,继电器,蜂鸣器,led,这几个器件在国赛是必考项目,DS1302,超声波,和PCF8591考的次数也非常多。大家一定要每个模块都练到位,一定分析一下从第三届到现在每届题目,下面我们给出第九届的题目以上是第九届的题目。
大家看过之后会发现考的器件非常的多,怎么去设计程序的结构非常重要。在我的程序运用了定时器产生轮询标志来调用每个子函数,来符合程序的设计要求。这个方法大家可以借鉴一下(当然高手除外),如果大家有更好的方法欢迎分享,大家一起进步,共同提高。下面给出我单片机程序的main.c文件的内容- #include "main.h"
- #include "Display.H"
- #include "stdio.H"
- #include "KEY.h"
- #include "TIME.h"
- #include "DELAY.h"
- #include "i2c.h"
- #include "onewire.h"
- union flo_to_ch
- {
- f32 f_num;
- u8 u_num[4];//共用内存单元,u_num[4]分别为f32数据f_num的4个字节
- };
- union flo_to_ch temperature_H,Voltage_H,frequency_H,thresh_H;//温度、电压、阈值数据结构
- f32 temperature_P,Voltage_P,thresh_P=1.0;//当前温度、当前电压、当前阈值
- u8 Dis_Buf[10] = {" "}; //数码管显示缓存
- u8 Work_Mode = 0; //’U’回显,其他常规显示。初值0数码管不显示,任意按键后只有回显和其他常规显示。
- u8 Dis_Mode = 0; //数码管显示模式,0常规不显示、‘U’电压显示 ‘F’频率显示 ‘C’温度显示 ‘P’电压阈值设置显示
- bit job1_flag = 0;
- bit job2_flag = 0;
- bit job3_flag = 0;
- bit job4_flag = 0;
- bit job5_flag = 0;
- void job1(void); //数码管动态显示处理,每5ms一次
- void job2(void); //显示模式处理,每100ms一次
- void job3(void); //按键读取与处理,每50ms一次
- void job4(void); //电压与温度测量(频率测量在time.c文件解决),每400ms一次
- void job5(void); //LED亮灯处理,每200ms一次
- void ufv_set(void);//温度、电压、频率存储
- void ufv_read(void);//温度、电压、频率读取
- void thresh_read(void);//阈值读取
- void thresh_set(void);//阈值存储
- void Sys_Init()
- {
- Buzzy_Off;
- Relay_Off;
- Led_Set = 0xff;
- }
- void main()
- {
- Sys_Init();
- Timer0Init();
- Timer1Init();
- Timer2Init();
- init_pcf8591();//初始化
- ufv_read();//读取eeprom数据,温度、电压、频率
- thresh_read();//阈值读取
- while (1)
- {
- if (job1_flag)
- {
- job1(); //数码管动态显示处理,每5ms一次
- job1_flag = 0;
- }
- if (job2_flag)
- {
- job2(); //显示模式处理,每100ms一次
- job2_flag = 0;
- }
- if (job3_flag)
- {
- job3(); //按键读取与处理,每50ms一次
- job3_flag = 0;
- }
- if (job4_flag)
- {
- job4(); //电压与温度测量(频率测量在time.c文件解决),每400ms一次
- job4_flag = 0;
- }
- if (job5_flag)
- {
- job5(); //LED亮灯处理,每200ms一次
- job5_flag = 0;
- }
- }
- }
- void job1(void) //数码管动态显示处理,每5ms一次
- {
- Display(Dis_Buf);
- }
- void job2(void) //显示模式处理,每100ms一次,Work_Mode=’U’回显,其他常规显示
- {
- switch (Dis_Mode) //Dis_Mode=0常规不显示、’U’电压显示 ‘F’频率显示 ‘C’温度显示 ‘P’电压阈值设置显示
- {
- case 0:
- {
- sprintf(Dis_Buf, " ");
- }break;
- case 'P':
- {
- sprintf(Dis_Buf, "P %3.1f", thresh_P);
- }break;
- case 'C':
- {
- if (Work_Mode == 'H')
- {
- sprintf(Dis_Buf, "HC %5.2f", temperature_H.f_num);
- }
- else
- {
- sprintf(Dis_Buf, "C %5.2f", temperature_P);
- }
- }break;
- case 'F':
- {
- if (Work_Mode == 'H')
- {
- sprintf(Dis_Buf, "HF%6.0f", frequency_H.f_num);
- }
- else
- {
- sprintf(Dis_Buf, "F %6.0f", frequency_P);
- }
- }break;
- case 'U':
- {
- if (Work_Mode == 'H')
- {
- sprintf(Dis_Buf, "HU %3.1f", Voltage_H.f_num);
- }
- else
- {
- sprintf(Dis_Buf, "U %3.1f", Voltage_P);
- }
- }
- break;
- }
- }
- void ufv_set(void)//温度、电压、频率存储
- {
- temperature_H.f_num = temperature_P;
- Voltage_H.f_num = Voltage_P;
- frequency_H.f_num = frequency_P;
-
- write_eeprom(0,temperature_H.u_num[0]);i2c_delay(200);i2c_delay(200);
- write_eeprom(1,temperature_H.u_num[1]);i2c_delay(200);i2c_delay(200);
- write_eeprom(2,temperature_H.u_num[2]);i2c_delay(200);i2c_delay(200);
- write_eeprom(3,temperature_H.u_num[3]);i2c_delay(200);i2c_delay(200);
- write_eeprom(4,Voltage_H.u_num[0]);i2c_delay(200);i2c_delay(200);
- write_eeprom(5,Voltage_H.u_num[1]);i2c_delay(200);i2c_delay(200);
- write_eeprom(6,Voltage_H.u_num[2]);i2c_delay(200);i2c_delay(200);
- write_eeprom(7,Voltage_H.u_num[3]);i2c_delay(200);i2c_delay(200);
-
- write_eeprom(8,frequency_H.u_num[0]);i2c_delay(200);i2c_delay(200);
- write_eeprom(9,frequency_H.u_num[1]);i2c_delay(200);i2c_delay(200);
- write_eeprom(10,frequency_H.u_num[2]);i2c_delay(200);i2c_delay(200);
- write_eeprom(11,frequency_H.u_num[3]);i2c_delay(200);i2c_delay(200);
- }
- void ufv_read(void)//温度、电压、频率读取
- {
-
- temperature_H.u_num[0]=read_eeprom(0);i2c_delay(200);i2c_delay(200);
- temperature_H.u_num[1]=read_eeprom(1);i2c_delay(200);i2c_delay(200);
- temperature_H.u_num[2]=read_eeprom(2);i2c_delay(200);i2c_delay(200);
- temperature_H.u_num[3]=read_eeprom(3);i2c_delay(200);i2c_delay(200);
-
- Voltage_H.u_num[0]=read_eeprom(4);i2c_delay(200);i2c_delay(200);
- Voltage_H.u_num[1]=read_eeprom(5);i2c_delay(200);i2c_delay(200);
- Voltage_H.u_num[2]=read_eeprom(6);i2c_delay(200);i2c_delay(200);
- Voltage_H.u_num[3]=read_eeprom(7);i2c_delay(200);i2c_delay(200);
-
- frequency_H.u_num[0]=read_eeprom(8);i2c_delay(200);i2c_delay(200);
- frequency_H.u_num[1]=read_eeprom(9);i2c_delay(200);i2c_delay(200);
- frequency_H.u_num[2]=read_eeprom(10);i2c_delay(200);i2c_delay(200);
- frequency_H.u_num[3]=read_eeprom(11);i2c_delay(200);i2c_delay(200);
- }
- void thresh_read(void)//阈值读取
- {
- thresh_H.u_num[0]=read_eeprom(12);i2c_delay(200);i2c_delay(200);
- thresh_H.u_num[1]=read_eeprom(13);i2c_delay(200);i2c_delay(200);
- thresh_H.u_num[2]=read_eeprom(14);i2c_delay(200);i2c_delay(200);
- thresh_H.u_num[3]=read_eeprom(15);i2c_delay(200);i2c_delay(200);
- thresh_P=thresh_H.f_num;
- }
- void thresh_set(void)//阈值存储
- {
- thresh_H.f_num=thresh_P;
- write_eeprom(12,thresh_H.u_num[0]);i2c_delay(200);i2c_delay(200);
- write_eeprom(13,thresh_H.u_num[1]);i2c_delay(200);i2c_delay(200);
- write_eeprom(14,thresh_H.u_num[2]);i2c_delay(200);i2c_delay(200);
- write_eeprom(15,thresh_H.u_num[3]);i2c_delay(200);i2c_delay(200);
- }
- void job3(void) //按键读取与处理,每50ms一次
- {
- u8 Key_Num = No_Key;
- Key_Num = read_keyboard();
- switch (Key_Num)
- {
- //Work_Mode=’U’回显,其他常规显示;Dis_Mode=0常规不显示、‘U’电压显示 ‘F’频率显示 ‘C’温度显示 ‘P’电压阈值设置显示
- case 'T': //S7 设置 电压阈值用S6加0.1V
- {
- if (Dis_Mode == 'P')
- {
- Work_Mode = 0;
- Dis_Mode = 'U';
- }
- else
- {
- Dis_Mode = 'P';
- // Voltage_threshold.f_num = read_eeprom(8);
- }
- }
- break;
- case '+': //S5 存储 (温度/电压/频率 存储到E2PROM)
- {
- ufv_set();
- }
- break;
- case '-': //S4 切换 数码管显示状态(温度/电压/频率,包括回显)
- {
- if (Dis_Mode == 'C')
- Dis_Mode = 'U';
- else if (Dis_Mode == 'U')
- Dis_Mode = 'F';
- else
- Dis_Mode = 'C';
- }
- break;
- case 'A': //S6 回显 E2PROM中的数据(温度/电压/频率);设置电压阈值用S6加0.1V
- {
- if (Dis_Mode == 'P') //阈值设置thresh_P
- {
- thresh_P = thresh_P + 0.1;
- if (thresh_P > 5.0)
- thresh_P = 0.1;
- thresh_set();
- }
- else //回显
- {
- Work_Mode = 'H';
- ufv_read();
- }
- }
- break;
- }
- }
- void job4(void) //电压与温度测量(频率测量在time.c文件解决),每400ms一次
- {
- Voltage_P = adc_pcf8591();
- Voltage_P = Voltage_P* 5.0 / 255;
- temperature_P = rd_temperature();
- temperature_P = temperature_P * 0.0625;
- }
- void job5(void) //LED亮灯处理,每200ms一次
- {
- static bit led_flash =0;
- static u8 Led_Set_Temp = 0xff;
- led_flash =~led_flash;
- (Dis_Mode == 'C')&&(Work_Mode!='H')?(Led_Set_Temp &= ~0x01):(Led_Set_Temp |= 0x01);
- (Dis_Mode == 'U')&&(Work_Mode!='H')?(Led_Set_Temp &= ~0x02):(Led_Set_Temp |= 0x02);
- (Dis_Mode == 'F')&&(Work_Mode!='H')?(Led_Set_Temp &= ~0x04):(Led_Set_Temp |= 0x04);
- (Voltage_P>thresh_P)&&(!led_flash) ? (Led_Set_Temp &= 0x7f):(Led_Set_Temp|=0x80);
- Led_Set=Led_Set_Temp;
- }
复制代码
全部资料51hei下载地址:
第9届:多功能测量仪表.rar
(808.38 KB, 下载次数: 61)
|