找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3617|回复: 6
打印 上一主题 下一主题
收起左侧

【原创】第九届蓝桥杯单片机决赛:多功能测量仪表源程序

[复制链接]
跳转到指定楼层
楼主
本帖最后由 Amistad 于 2019-5-12 23:29 编辑

这次分享的是蓝桥杯第九届的题目,国赛得题目比省赛的要难很多,主要是考的器件非常的多,怎么去设计代码的结构至关重要,数码管,e2prom,继电器,蜂鸣器,led,这几个器件在国赛是必考项目,DS1302,超声波,和PCF8591考的次数也非常多。大家一定要每个模块都练到位,一定分析一下从第三届到现在每届题目,下面我们给出第九届的题目以上是第九届的题目。 大家看过之后会发现考的器件非常的多,怎么去设计程序的结构非常重要。在我的程序运用了定时器产生轮询标志来调用每个子函数,来符合程序的设计要求。这个方法大家可以借鉴一下(当然高手除外),如果大家有更好的方法欢迎分享,大家一起进步,共同提高。下面给出我单片机程序的main.c文件的内容
  1. #include "main.h"
  2. #include "Display.H"
  3. #include "stdio.H"
  4. #include "KEY.h"
  5. #include "TIME.h"
  6. #include "DELAY.h"
  7. #include "i2c.h"
  8. #include "onewire.h"
  9. union flo_to_ch
  10. {
  11.         f32 f_num;
  12.         u8 u_num[4];//共用内存单元,u_num[4]分别为f32数据f_num的4个字节
  13. };

  14. union flo_to_ch temperature_H,Voltage_H,frequency_H,thresh_H;//温度、电压、阈值数据结构
  15. f32 temperature_P,Voltage_P,thresh_P=1.0;//当前温度、当前电压、当前阈值

  16. u8 Dis_Buf[10] = {"        "}; //数码管显示缓存

  17. u8 Work_Mode = 0; //’U’回显,其他常规显示。初值0数码管不显示,任意按键后只有回显和其他常规显示。
  18. u8 Dis_Mode = 0;  //数码管显示模式,0常规不显示、‘U’电压显示 ‘F’频率显示 ‘C’温度显示 ‘P’电压阈值设置显示

  19. bit job1_flag = 0;
  20. bit job2_flag = 0;
  21. bit job3_flag = 0;
  22. bit job4_flag = 0;
  23. bit job5_flag = 0;

  24. void job1(void); //数码管动态显示处理,每5ms一次
  25. void job2(void); //显示模式处理,每100ms一次
  26. void job3(void); //按键读取与处理,每50ms一次
  27. void job4(void); //电压与温度测量(频率测量在time.c文件解决),每400ms一次
  28. void job5(void); //LED亮灯处理,每200ms一次
  29. void ufv_set(void);//温度、电压、频率存储
  30. void ufv_read(void);//温度、电压、频率读取
  31. void thresh_read(void);//阈值读取
  32. void thresh_set(void);//阈值存储

  33. void Sys_Init()
  34. {
  35.         Buzzy_Off;
  36.         Relay_Off;
  37.         Led_Set = 0xff;
  38. }

  39. void main()
  40. {
  41.         Sys_Init();
  42.         Timer0Init();
  43.         Timer1Init();
  44.         Timer2Init();
  45.         init_pcf8591();//初始化
  46.           ufv_read();//读取eeprom数据,温度、电压、频率
  47.         thresh_read();//阈值读取
  48.         while (1)
  49.         {
  50.                 if (job1_flag)
  51.                 {
  52.                         job1(); //数码管动态显示处理,每5ms一次
  53.                         job1_flag = 0;
  54.                 }
  55.                 if (job2_flag)
  56.                 {
  57.                         job2(); //显示模式处理,每100ms一次
  58.                         job2_flag = 0;
  59.                 }
  60.                 if (job3_flag)
  61.                 {
  62.                         job3(); //按键读取与处理,每50ms一次
  63.                         job3_flag = 0;
  64.                 }
  65.                 if (job4_flag)
  66.                 {
  67.                         job4(); //电压与温度测量(频率测量在time.c文件解决),每400ms一次
  68.                         job4_flag = 0;
  69.                 }
  70.                 if (job5_flag)
  71.                 {
  72.                         job5(); //LED亮灯处理,每200ms一次
  73.                         job5_flag = 0;
  74.                 }               
  75.         }
  76. }

  77. void job1(void) //数码管动态显示处理,每5ms一次
  78. {
  79.         Display(Dis_Buf);
  80. }

  81. void job2(void) //显示模式处理,每100ms一次,Work_Mode=’U’回显,其他常规显示
  82. {
  83.         switch (Dis_Mode) //Dis_Mode=0常规不显示、’U’电压显示 ‘F’频率显示 ‘C’温度显示 ‘P’电压阈值设置显示
  84.         {
  85.                 case 0:
  86.                 {
  87.                         sprintf(Dis_Buf, "        ");
  88.                 }break;
  89.                 case 'P':
  90.                 {
  91.                         sprintf(Dis_Buf, "P     %3.1f", thresh_P);
  92.                 }break;
  93.                 case 'C':
  94.                 {
  95.                         if (Work_Mode == 'H')
  96.                         {
  97.                                 sprintf(Dis_Buf, "HC  %5.2f", temperature_H.f_num);
  98.                         }        
  99.                         else
  100.                         {
  101.                                 sprintf(Dis_Buf, "C   %5.2f", temperature_P);
  102.                         }
  103.                 }break;
  104.                 case 'F':
  105.                 {
  106.                         if (Work_Mode == 'H')
  107.                         {
  108.                                 sprintf(Dis_Buf, "HF%6.0f", frequency_H.f_num);                        
  109.                         }
  110.                         else
  111.                         {
  112.                                 sprintf(Dis_Buf, "F %6.0f", frequency_P);
  113.                         }
  114.                 }break;
  115.                 case 'U':
  116.                 {
  117.                         if (Work_Mode == 'H')
  118.                         {
  119.                                 sprintf(Dis_Buf, "HU    %3.1f", Voltage_H.f_num);
  120.                         }        
  121.                         else
  122.                         {
  123.                                 sprintf(Dis_Buf, "U     %3.1f", Voltage_P);
  124.                         }
  125.                 }
  126.                 break;
  127.         }
  128. }
  129. void ufv_set(void)//温度、电压、频率存储
  130. {

  131.         temperature_H.f_num = temperature_P;
  132.         Voltage_H.f_num = Voltage_P;
  133.         frequency_H.f_num = frequency_P;
  134.         
  135.         write_eeprom(0,temperature_H.u_num[0]);i2c_delay(200);i2c_delay(200);
  136.         write_eeprom(1,temperature_H.u_num[1]);i2c_delay(200);i2c_delay(200);
  137.         write_eeprom(2,temperature_H.u_num[2]);i2c_delay(200);i2c_delay(200);
  138.         write_eeprom(3,temperature_H.u_num[3]);i2c_delay(200);i2c_delay(200);

  139.         write_eeprom(4,Voltage_H.u_num[0]);i2c_delay(200);i2c_delay(200);
  140.         write_eeprom(5,Voltage_H.u_num[1]);i2c_delay(200);i2c_delay(200);
  141.         write_eeprom(6,Voltage_H.u_num[2]);i2c_delay(200);i2c_delay(200);
  142.         write_eeprom(7,Voltage_H.u_num[3]);i2c_delay(200);i2c_delay(200);
  143.         
  144.         write_eeprom(8,frequency_H.u_num[0]);i2c_delay(200);i2c_delay(200);
  145.         write_eeprom(9,frequency_H.u_num[1]);i2c_delay(200);i2c_delay(200);
  146.         write_eeprom(10,frequency_H.u_num[2]);i2c_delay(200);i2c_delay(200);        
  147.         write_eeprom(11,frequency_H.u_num[3]);i2c_delay(200);i2c_delay(200);

  148. }
  149. void ufv_read(void)//温度、电压、频率读取
  150. {
  151.         
  152.         temperature_H.u_num[0]=read_eeprom(0);i2c_delay(200);i2c_delay(200);
  153.         temperature_H.u_num[1]=read_eeprom(1);i2c_delay(200);i2c_delay(200);
  154.         temperature_H.u_num[2]=read_eeprom(2);i2c_delay(200);i2c_delay(200);
  155.         temperature_H.u_num[3]=read_eeprom(3);i2c_delay(200);i2c_delay(200);
  156.         
  157.         Voltage_H.u_num[0]=read_eeprom(4);i2c_delay(200);i2c_delay(200);
  158.         Voltage_H.u_num[1]=read_eeprom(5);i2c_delay(200);i2c_delay(200);
  159.         Voltage_H.u_num[2]=read_eeprom(6);i2c_delay(200);i2c_delay(200);
  160.         Voltage_H.u_num[3]=read_eeprom(7);i2c_delay(200);i2c_delay(200);
  161.         
  162.         frequency_H.u_num[0]=read_eeprom(8);i2c_delay(200);i2c_delay(200);
  163.         frequency_H.u_num[1]=read_eeprom(9);i2c_delay(200);i2c_delay(200);        
  164.         frequency_H.u_num[2]=read_eeprom(10);i2c_delay(200);i2c_delay(200);        
  165.         frequency_H.u_num[3]=read_eeprom(11);i2c_delay(200);i2c_delay(200);

  166. }
  167. void thresh_read(void)//阈值读取
  168. {
  169.         thresh_H.u_num[0]=read_eeprom(12);i2c_delay(200);i2c_delay(200);
  170.         thresh_H.u_num[1]=read_eeprom(13);i2c_delay(200);i2c_delay(200);        
  171.         thresh_H.u_num[2]=read_eeprom(14);i2c_delay(200);i2c_delay(200);        
  172.         thresh_H.u_num[3]=read_eeprom(15);i2c_delay(200);i2c_delay(200);
  173.         thresh_P=thresh_H.f_num;
  174. }
  175. void thresh_set(void)//阈值存储
  176. {
  177.         thresh_H.f_num=thresh_P;
  178.         write_eeprom(12,thresh_H.u_num[0]);i2c_delay(200);i2c_delay(200);
  179.         write_eeprom(13,thresh_H.u_num[1]);i2c_delay(200);i2c_delay(200);
  180.         write_eeprom(14,thresh_H.u_num[2]);i2c_delay(200);i2c_delay(200);        
  181.         write_eeprom(15,thresh_H.u_num[3]);i2c_delay(200);i2c_delay(200);
  182. }
  183. void job3(void) //按键读取与处理,每50ms一次
  184. {
  185.         u8 Key_Num = No_Key;
  186.         Key_Num = read_keyboard();
  187.         switch (Key_Num)
  188.         {
  189.                 //Work_Mode=’U’回显,其他常规显示;Dis_Mode=0常规不显示、‘U’电压显示 ‘F’频率显示 ‘C’温度显示 ‘P’电压阈值设置显示
  190.         case 'T': //S7 设置 电压阈值用S6加0.1V
  191.         {
  192.                 if (Dis_Mode == 'P')
  193.                 {
  194.                         Work_Mode = 0;
  195.                         Dis_Mode = 'U';
  196.                 }
  197.                 else
  198.                 {
  199.                         Dis_Mode = 'P';
  200.                 //        Voltage_threshold.f_num = read_eeprom(8);
  201.                 }
  202.         }
  203.         break;
  204.         case '+': //S5 存储 (温度/电压/频率 存储到E2PROM)
  205.         {
  206.                 ufv_set();
  207.         }
  208.         break;
  209.         case '-': //S4 切换 数码管显示状态(温度/电压/频率,包括回显)
  210.         {
  211.                 if (Dis_Mode == 'C')
  212.                         Dis_Mode = 'U';
  213.                 else if (Dis_Mode == 'U')
  214.                         Dis_Mode = 'F';
  215.                 else
  216.                         Dis_Mode = 'C';
  217.         }
  218.         break;

  219.         case 'A': //S6 回显 E2PROM中的数据(温度/电压/频率);设置电压阈值用S6加0.1V
  220.         {
  221.                 if (Dis_Mode == 'P') //阈值设置thresh_P
  222.                 {
  223.                         thresh_P = thresh_P + 0.1;
  224.                         if (thresh_P > 5.0)
  225.                                 thresh_P = 0.1;
  226.                         thresh_set();        
  227.                 }
  228.                 else //回显
  229.                 {
  230.                         Work_Mode = 'H';
  231.                         ufv_read();
  232.                 }
  233.         }
  234.         break;
  235.         }
  236. }

  237. void job4(void) //电压与温度测量(频率测量在time.c文件解决),每400ms一次
  238. {
  239.         Voltage_P = adc_pcf8591();
  240.         Voltage_P = Voltage_P* 5.0 / 255;
  241.         temperature_P = rd_temperature();
  242.         temperature_P = temperature_P * 0.0625;
  243. }

  244. void job5(void) //LED亮灯处理,每200ms一次
  245. {
  246.         static bit led_flash =0;
  247.         static u8 Led_Set_Temp = 0xff;
  248.         led_flash =~led_flash;
  249.         (Dis_Mode == 'C')&&(Work_Mode!='H')?(Led_Set_Temp &= ~0x01):(Led_Set_Temp |= 0x01);
  250.         (Dis_Mode == 'U')&&(Work_Mode!='H')?(Led_Set_Temp &= ~0x02):(Led_Set_Temp |= 0x02);
  251.         (Dis_Mode == 'F')&&(Work_Mode!='H')?(Led_Set_Temp &= ~0x04):(Led_Set_Temp |= 0x04);
  252.         (Voltage_P>thresh_P)&&(!led_flash) ? (Led_Set_Temp &= 0x7f):(Led_Set_Temp|=0x80);
  253.         Led_Set=Led_Set_Temp;
  254. }

复制代码

全部资料51hei下载地址:
第9届:多功能测量仪表.rar (808.38 KB, 下载次数: 61)

评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:538905 发表于 2019-5-15 15:08 | 只看该作者
做得非常好,帮助很大
回复

使用道具 举报

板凳
ID:538905 发表于 2019-5-15 15:10 | 只看该作者
非常棒,为楼主点赞!
回复

使用道具 举报

地板
ID:538578 发表于 2019-5-15 16:04 | 只看该作者
我舍友去参加了蓝桥杯,回来跟我们说收获很大
回复

使用道具 举报

5#
ID:540218 发表于 2019-5-16 21:07 | 只看该作者
nice 很不错
回复

使用道具 举报

6#
ID:185815 发表于 2020-3-28 23:30 | 只看该作者
感谢分享,学习一下
回复

使用道具 举报

7#
ID:102702 发表于 2020-3-31 22:26 | 只看该作者
楼主做出实物图了吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表