本帖最后由 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)
2019-5-10 21:08 上傳
點擊文件名下載附件
|