找回密码
 立即注册

QQ登录

只需一步,快速开始

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

[原创]第十届蓝桥杯单片机省赛:电压频率采集装置源程序&题目&源代码

  [复制链接]
跳转到指定楼层
楼主
附件里面有省赛程序题及客观题(客观题无答案)及我自己写的源代码以下是程序设计题题目



以下是单片机主函数,有完整的注释。
  1. #include "STC15F2K60S2.H"
  2. #include "MAIN.H"
  3. #include "HAREWARE.H"
  4. #include "DIG.H"
  5. #include "I2C.H"
  6. #include "DELAY.H"
  7. #include "LED.H"

  8. sbit s4 = P3^3;//按键S4
  9. sbit s5 = P3^2;//按键S5
  10. sbit s6 = P3^1;//按键S6
  11. sbit s7 = P3^0;//按键S7


  12. unsigned int PCF_NUM = 0;//电压值
  13. unsigned char led_mode = 0xff;         //LED灯点亮模式
  14. unsigned int f_num = 0;//频率数值
  15. unsigned char j = 0;//频率测量里面的等待中断标志
  16. unsigned char diya_num = 0;//储存模数转换返回的电压值
  17. unsigned char timer = 0;

  18. bit s4_mode = 1;//1为电压测量模式,0为频率测量模式
  19. bit s5_mode = 0;//1为输出2.0v电压,为0跟随PCF8591三通道电压输出
  20. bit s6_mode = 1;//1为开启LED灯显示,0为关显示
  21. bit s7_mode = 1;//1为开启数码管显示,0为关显示
  22. bit gensui = 0;//0为不跟随电压输出,1为跟随电压输出

  23. unsigned char useg_num[]={0x3e,0,0,0,0,0,0,0};//电压数值数组
  24. unsigned char fseg_num[]={0x71,0,0,0,0,0,0,0};//频率数值数组


  25. void key_scan();//按键扫描函数原型
  26. unsigned char dian_ya_ce_liang(); //电压测量函数原型
  27. void TimerInit();//定时计数初始化函数原型

  28. /************************************************************************************************/
  29. /******************************************函数**************************************************/
  30. /************************************************************************************************/

  31. void main()//主函数
  32. {        
  33.         HAREWARE_init();//关闭外部设备
  34.         DIG_init();//数码管初始化
  35.         LED_init();//LED灯初始化
  36.         TimerInit();//定时器1初始化
  37.         P20 = 1;
  38.         while(1)//等待中断
  39.         {
  40.                 key_scan();//按键扫描

  41.                 if(~s5_mode)//判断是否是电压跟随模式
  42.                 {
  43.                         PCF_DA(103); //没有跟随
  44.                         gensui = 0;  //没有跟随
  45.                 }
  46.                 else
  47.                 {
  48.                         gensui = 1;                  //跟随电压
  49.                 }

  50.                 if(s4_mode)//判断是否为电压测量模式
  51.                 {
  52.                         diya_num = dian_ya_ce_liang();
  53.                         led_mode = 0xfe;//电压测量模式指示灯亮
  54.                         if(((diya_num * 0.01953125 >= 1.5) && (diya_num * 0.01953125 < 2.5)) || (diya_num * 0.01953125 >= 3.5))
  55.                         {
  56.                                 led_mode &= 0xfb;//满足条件第三个指示灯亮
  57.                         }
  58.                         if(gensui)
  59.                         {
  60.                                 led_mode &= 0xef;//电压跟随第五个指示灯亮
  61.                         }
  62.                         PCF_NUM = diya_num * 1.953125;//变成十进制的数字,把小数乘一百
  63.                         useg_num[5]=DIG_CODE[PCF_NUM/100];//百位数字
  64.                         PCF_NUM = PCF_NUM % 100;
  65.                         useg_num[6]=DIG_CODE[PCF_NUM/10];//十位数字
  66.                         PCF_NUM %=10;
  67.                         useg_num[7]=DIG_CODE[PCF_NUM];//个位数字
  68.                         LED_show(led_mode);//LED等显示
  69.                         DIG_show(useg_num);//数码管显示
  70.                         if(gensui)//判断是否是电压跟随模式
  71.                         {
  72.                                 PCF_DA(diya_num); //没有跟随
  73.                         }
  74.                 }
  75.                 else//频率测量模式
  76.                 {
  77.                         TR1 = 1;//开始计时                        
  78.                         TR0 = 1;//开始计数
  79.                         j = 1;//等待中断标志置1
  80.                         while(j);//等待中断
  81.                 }
  82.         }        
  83. }

  84. ////////////////////////////////////////////////////
  85. ////////////////////////////////////////////////////

  86. void TimerInit()//定时计数器初始化函数
  87. {
  88.         AUXR &= 0x3F;//12分频
  89.         TMOD &= 0x00;//TMOD(定时/计数器模式寄存器)清零
  90.         TMOD |= 0x15;//T0设置为模式1,计数;T1设置为模式1,定时
  91.         TH0 = TL0 = 0;//计数器清零
  92.         TL1 = 0xF0;                //设置定时初值
  93.         TH1 = 0xD8;                //设置定时初值
  94.         EA = 1;//开总中断
  95.         ET1 = 1;//开定时器1中断
  96. }

  97. ///////////////////////////////////////////////////////
  98. ///////////////////////////////////////////////////////

  99. unsigned char dian_ya_ce_liang()
  100. {
  101.         return PCF_AD(3);//返回模数转换值         
  102. }

  103. //////////////////////////////////////////////////////
  104. //////////////////////////////////////////////////////

  105. void key_scan()//键盘扫描函数
  106. {
  107.         P3 |= 0x0f;//P3低4位设为全1
  108.         if(~s4)//判断S4按键
  109.         {
  110.                 delay1ms(5);//按键消抖
  111.                 if(~s4)//判断S4按键
  112.                 {
  113.                         s4_mode = ~s4_mode;
  114.                 }
  115.         }

  116.         if(~s5)//判断S5按键
  117.         {
  118.                 delay1ms(5);//按键消抖
  119.                 if(~s5)//判断S5按键
  120.                 {
  121.                         if(s4_mode)//如果在电压测量模式则改变电压跟随标志
  122.                         {
  123.                                  s5_mode = ~s5_mode;//s5_mode取反
  124.                         }
  125.                         
  126.                 }
  127.         }

  128.         if(~s6)//判断S6按键
  129.         {
  130.                 delay1ms(5);//按键消抖
  131.                 if(~s6)//判断S6按键
  132.                 {
  133.                         s6_mode = ~s6_mode;
  134.                         if(~s6_mode)
  135.                         {
  136.                                 LED_init();//关LED灯
  137.                         }
  138.                         
  139.                 }
  140.         }

  141.         if(~s7)//判断S7按键
  142.         {
  143.                 delay1ms(5);//按键消抖
  144.                 if(~s7)//判断S7按键
  145.                 {
  146.                         s7_mode = ~s7_mode;//取反
  147.                         if(~s7_mode)//如果数码管开关标志为0,关数码管显示
  148.                         {
  149.                                 DIG_init();//关数码管
  150.                         }
  151.                         
  152.                 }
  153.         }
  154.         while(~s4||~s5||~s6||~s7)//松手检测
  155.         {
  156.                 if(s4_mode)//如果为电压测量模式,数码管显示电压值,防止出现数码管黑屏现象
  157.                 {
  158.                         DIG_show(useg_num);//数码管显示电压测量值
  159.                         LED_show(led_mode);//LED显示电压测量模式
  160.                 }
  161.                 else//如果为频率测量模式,数码管显示频率值,防止出现数码管黑屏现象
  162.                 {
  163.                         DIG_show(fseg_num);//数码管显示频率测量值
  164.                         LED_show(led_mode);//LED显示频率测量模式
  165.                 }
  166.         }
  167. }
  168. /*//////////////////////////////////////////
  169. ///////////定时器1中断函数/////////////////
  170. //////////////////////////////////////////*/
  171. void T1()interrupt 3//定时器1中断函数
  172. {
  173.         unsigned char i = 0;
  174.         unsigned int f_num2 = 0;
  175.         P20 = ~P20;
  176.         TR0 = 0;//停止计数
  177.         TR1        = 0;//停止定时
  178.         TL1 = 0xF0;//设置定时初值
  179.         TH1 = 0xD8;//设置定时初值
  180.         timer++;//计数器加1
  181.         j = 0;//等待中断标志清零
  182.         if(timer == 20)
  183.         {
  184.                 f_num = (TH0 * 256 + TL0) * 5; //计算频率
  185.                 timer = 0;
  186.                 TL0 = TH0 = 0;//计数器清零
  187.                 for(i=7;i>2;i--)//重新初始化频率数值数组
  188.                 {
  189.                         fseg_num[i] = 0;//除数组的第一位和第二位其他的初始化为0         
  190.                 }
  191.                 if((f_num >= 1000 && f_num < 5000)||(f_num >= 10000))
  192.                 {
  193.                         led_mode = 0XF5;//满足条件led4亮
  194.                 }
  195.                 else
  196.                 {
  197.                         led_mode = 0XFD;
  198.                 }
  199.                 for(i = 7;i>2 && f_num != 0;i--)
  200.                 {
  201.                         fseg_num[i] = DIG_CODE[f_num % 10];
  202.                         f_num /= 10;
  203.                 }
  204.         }
  205.         LED_show(led_mode);
  206.         DIG_show(fseg_num);               
  207. }
复制代码
全部的程序请到附件里面下载


全部资料51hei下载地址:
2019年第10届.rar (760.55 KB, 下载次数: 212)

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:425226 发表于 2019-10-26 18:43 | 只看该作者
国赛的单片机的题目有吗
回复

使用道具 举报

板凳
ID:411550 发表于 2020-2-8 15:50 | 只看该作者
很好,帮助很大 这一年考的不是很寻常
回复

使用道具 举报

地板
ID:699675 发表于 2020-2-28 15:45 | 只看该作者
厉害啊
回复

使用道具 举报

5#
ID:411236 发表于 2020-4-21 16:25 | 只看该作者
烧录进去LED全是亮的,数码管没有显示,独立按键按下也没有任何反应。。。
回复

使用道具 举报

6#
ID:830957 发表于 2020-10-17 11:22 | 只看该作者
DAC输出电压是测量板子上哪里的电压啊  比如 Rb2上?
回复

使用道具 举报

7#
ID:331814 发表于 2020-11-12 20:35 | 只看该作者
本帖最后由 Amistad 于 2020-11-12 20:36 编辑
oiwgceowicqoeu 发表于 2020-4-21 16:25
烧录进去LED全是亮的,数码管没有显示,独立按键按下也没有任何反应。。。

看没看程序是IO模式还是MM模式,就说不行,还有可能是你板子坏了
回复

使用道具 举报

8#
ID:942202 发表于 2021-6-30 22:15 来自手机 | 只看该作者
所有程序都要写上去吗
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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