• 今天做了一下第七届的决赛题,逻辑比初赛复杂的多,但是原理都相同,主要是时间不够。 简单总结一下一些荣翻译忘记的地方: (1)矩阵键盘中:P36 replaced by P44,P37 replaced by P42,写的时候注意在ISP文件中...

    今天做了一下第七届的决赛题,逻辑比初赛复杂的多,但是原理都相同,主要是时间不够。

    简单总结一下一些荣翻译忘记的地方:

    (1)矩阵键盘中:P36 replaced by P44,P37 replaced by P42,写的时候注意在ISP文件中添加P4有关的定义。

    (2)今天脑子抽了,居然用P0 = 0X00;来消影,记住是P0 = 0XFF

    (3)关于DS1302,在写时间的时候需要取消写保护,写完数据记得上写保护(具体参照datasheet)。

    (4)读完一次时间后记得Ds1302_Single_Byte_Write(0x00, 0x00);!!!!

    (5)iic协议在使用的时候,对于PSF8591与AT24C02的读过程是不同的,请比赛的时候一定参照datasheet写。

    附图:

    PCF8591读数据过程


    AT24C02读数据过程(注意需要开启两次iic协议)


    (6)iic协议第一步写地址字的时候记得读与写的区别(0与1

    ----------------------------------------------------------------------------------------------------------------------------------

    (7)该onewire.c中的延时函数的时候不要改错了,是在while(t--)内加12次减运算

    (8)超声波中的RX TX需要自己定义,参照原理图定义:RX(连接在N_B1上,是CX20106A的输出,P11),TX(连接在N_A1上,连接驱动电路,由P10驱动)

    (9)判断是否收到的时候,当RX == 0是收到了,程序里应该写为:while(RX == 1 && timeflag >= 2);

    (10)超声波波速计算的时候是332 + temper * 0.607 

    (11)ISP自动生成串口配置的时候记得ES = 1允许中断

    (12)使用规范的锁存器使用方法:

    	P2 = (P2&0x1f)|0Xa0;
    	P0 |= 0x40;
    	P2 &= 0X1f;
    先清空高三位再赋值,使用完锁存器后直接选中Y0,Y0无外接元件。

    (13)温度的命令常量如果头文件没有,就去datasheet找一下

     


    -----------------------------------------------------------------------------------------------------------------------------------

    做个标记:明天需要做的事情:

    1、今天测频率出了点问题,具体看一下

    2、写一个测温度的练练手 //done

    3、写一个超声波的练练手 //done

    4、看看外部中断的配置

    5、看看串口的例程 //done

    6、看一下模电中关于放大器的题目(包括电压放大、电流量转换成电压量即:ad原理) //done

    7、看一下理论题 //done

    展开全文
  • 第七届蓝桥杯单片机决赛试题
  • 蓝桥杯 单片机设计 历年决赛真题及答案 在学习蓝桥杯编程时很好的参考,要沉下心分析很精华!
  • 省赛顺利通过,可是决赛只拿了一个国三。想想要总结一下这次的得失,可是感觉我应该从头分析一下自己的编程经历了,做一个短期的总结吧(大致是七个月)。 作为一个农村的娃子(之所以说自己是娃子,因为我希望自己...

    这次比赛,成绩并不是太理想,虽然我是一个渣二本(河南农业大学,一听,种地的还学编程???),却金刚不可夺其志,毅然决然的报了A组C,学院不支持,最后倔着脾气自费报名了。省赛顺利通过,可是决赛只拿了一个国三。想想要总结一下这次的得失,可是感觉我应该从头分析一下自己的编程经历了,做一个短期的总结吧(大致是七个月)。

    作为一个农村的娃子(之所以说自己是娃子,因为我希望自己始终保持着一颗童心),和千千万万农村的娃子一样,大学前,不知道啥是编程,更别提算法了。

    大学后,我只是感觉自己对计算机充满了兴趣,可是并不是对他有太多的了解。只是停留在打打LOL,玩玩魔兽,对战一下红警,PK一下火影:究极风暴(我可是火影粉丝哦),另外经常光顾一下4399小游戏……我始终是一个初出茅庐的小孩子,啥也不懂。

    我开始接触编程,起初并不感兴趣,并且认定我不会好好学习,所以一开学并没有学,加之我的苹果刚到第一天,我就花了五分钟把它KO.了,我那叫一个郁闷,自己开始琢磨如何装系统,因为不问不知道,一问吓一跳,重装双系统需要四百大洋,一向不抠门儿的我这次抠门儿了,毕竟想想自己五分钟就怼了四百,心里疼。

    可是,我这是第一次接触IOS,一丁点都不懂,于是我问学长,学长给我了三个字,“找百度”,所以,我整整查阅资料花了两个星期,各种方案都试了,却没有一个方法真的可行(可能是网上的教程有些老了吧),没有办法,可是没有办法我也真得不舍得花钱去装。

    陷入了僵局,我该咋办?继续查资料呗,终于,我又经过两天的查找,成功的做成了一个启动盘,并装好了IOS系统(接着又装好了win),当时,我那叫一个开心(毕竟啥也没见过,这芝麻大的事那时候就让我很开心了)。

    这时大致是15年十月中旬吧,然后,开始学编程吧,学校都已经讲了两周编程课了,我却一节都没听,都睡过去了,怎么破呢?只好自学。

    学编程,我首先要考虑的事是我用啥写?用啥运行?也就是我该用啥IDE,这可难坏我了,于是我加了一些技术群和苹果群,请教了一些人,他们都清一色的推荐我用Xcode,我也就听从了他们的建议,然而,不知为何,我的苹果商店下载Xcode一直失败,我也感觉自己很失败(后来知道是因为服务器在美国,在国内下载时需要好一些的网速,而我这坑爹的校园网,也有一些其他的原因),依然是请教一个技术群里的大神(如果有兴趣可以来这个群里看看,牛人挺多的,群号:367556880,当然这不是专门的算法群,但是可以拓宽自己的眼界),然后他们告诉我,可以去开发者中心下载,于是我又折腾了几天,才算是下载好,可是下载好后,我彻底蒙逼了,全洋宴,顿时我想换了……

    我自幼英语极差,看着全洋的编译器,我怂。于是我用win系统尝试用VC6++写,可是我一用,我立马心凉了半截…我的心在滴血(现在看来,这个编译器虽然低级,但是对我们初学者有好处,我就因为没用过低级编译器,在比赛中吃亏了),这下,我又耽搁这了。

    这时已经十月下旬了。

    然后我一个朋友给我分享了一个我感觉是改变了我的方向的一个视频,为什么呢?那时候我都想放弃编程,开始学PS了,想走平面设计(后来事实证明这不是我的菜,没有艺术细胞),然后他给我了一个以Xcode为IDE的教学C的视频,我开始第一次真正意义上的学习C,这时候十月结束了,也就是这个时候,我开始爱上编程了,爱上Xcode了。

    这时候,很多学长都说一句话:编程的精髓是算法。于是,我这么爱装逼的人,一定要学精髓,(后来发现,学长们都是说说而已,因为我们学校没有深入学习算法的),于是我就一步错步步错,走上了算法的不归路了。

    用了一个月,我自学完了C语言基础,当然是仅限于算法层的,那些偏向应用层的部分我没有学习,然后自己开始接触算法训练题。和很多新手一样,一开始啥都不会,但是我可以很自豪的说,我在学C语言第二周就挑战鸡兔同笼以及39级台阶问题(现在看来特别水的题,那时候着实费了一番功夫才做出来),那时候,我只学到了循环语句而已。

    然后我通过这两道题发现,自己的编程代码写出来既费时又一团糟,于是我注意到了两个问题:
    1、编程习惯,命名规范问题;
    2、遇见一丁点思路都没有的题,我该怎么办?苦思?还是……

    这时候,我想,习惯都是从小养成最好,我不应该等自己养成坏习惯后再改,于是一开始我就查找各种命名规范,查到了匈牙利命名法和驼峰式命名法以及帕斯卡命名法,当时傻逼了,一看驼峰,好low的名字,不用;一看帕斯卡,英文名字,不感冒,不用;于是用起了匈牙利命名法,但是后来我又转成了驼峰式命名法,倒不是说匈牙利的不好,只是没有驼峰式优势大,事实证明,驼峰式的确使用率越来越高了(了解命名规范的简要规范:http://blog.csdn.net/f_zyj/article/details/51510085)。

    至于第二个问题,我最后用一句话来说服了自己:学而不思则罔,思而不学则怠!那么什么方法学最快呢?我感觉就是在自己练题时,遇见不会的,多去看看别人写的博客还代码,这样子可以快速学到很多东西。

    这时,我感觉,我是真正的开始要学算法了,此时十一月初。

    然后,经过几天的边看边练,我发现,网上很多题都是用C++或者Java写的,C++居多,于是为了可以看懂别人的代码,我又花了半个月的空闲时间,学习了C++的语法基础,学到了多态。

    接着又经过了一段时间的学习,沿袭着自己的方法搞,感觉挺好的。到了十一月中旬时,学校举行了蓝桥杯的校赛,为了给省赛选出选手,我信心满满的参加了(我们这一届虽然有几个有编程基础的人,但是那时我已经远远超过他们了),最后也顺利过了。

    学校说,会学院出钱给我们参加省赛(300大洋呢),我们报名时,我发现,蓝桥杯分为A,B,C三组,我们学校我的专业对应的最低组别是B组,学校说让我们都报B组,我内心不服,为啥我们注定只能报B组?于是我想方设法找老师,申请报A组,然而老师不同意,于是又一个学长说,“你就这么看不起B组?…最好报B组,别不自量力,但是如果你真的想报A组,自己去跟团委老师说”。

    于是,我就跟团委老师申请,然后因为老师不同意,我只好退一步说,我自费可以吗?然后老师就同意了,因为我态度十分坚决,金刚不可夺其志。

    因为是自费,我连指导老师都没有(其实有没有都一样,因为老师并没有指导,只是挂个名字而已,但是也的确受到一些不错的老师的帮助和指引)。

    这时,我已经开始了为省赛而奋斗,我要让他们看看,我不虚,我要刚起来。

    接着,就到了寒假,我们学校有一个工作室在家属院那里租有房子,他们觉得我努力学习,我也想留校,于是我决定一方面学习PHP,以后为他们做一些后台的东西,一方面准备省赛(回到家里真的学不成),于是,我整个寒假,放假后,我在那个工作室宅了两周,然后25回家,初二就又来了郑州,寒假休息了七天,终于在一个月学完了PHP(只是学,没有实战经验,但是学习过程中,我对后台框架等等有了新的认识,提高了自己的认知)和数据结构,这时候我已经认识到,编程的精髓是算法+数据结构,算法也是每天坚持做题。

    开学后(这学期我们主修课是Java,我不是太想学Java,但是为了增加见识和期末考好,我还是学了些许,学到了多态继承等等),大概是二月末,离省赛还有一个月,我狠狠突袭了一个月,到了三月二十号,终于在省赛中无惊无险的晋级了。

    学院也不再质疑我的能力(其实我真的很水,只是学校太弱鸡了),学校一共晋级了五个,就我一个大一,然后学校又把培训的任务交给了我,让我带着他们准备国赛(我们学校到现在还没有一个正儿八经的算法学习的环境,培训都是临时申请的教室,还时不时被占,学院真得没有支持太多,一切革命靠自己,这时,我深切的认为,我们需要一个算法学习的环境,于是打起了今年国赛后申请实验室的想法),然后紧张无序的准备了两个月。

    很快,到了五月底,我们由一个研究生带队去北京参加比赛。说实话,挺紧张的,因为A组的都是重点学校的人,像我这样的只学了七个月的二本渣渣应该不多吧。本来就是想着第一年我参加省赛试试水,为来年准备经验,的确,这次经验倒是有了很多。

    五月二十八日,也就是昨天,不对,现在都凌晨了,应该是昨天的昨天,下午一点,我们到了北科大,那是我们的考场,貌似我们那里又是几乎就我一个A组,和省赛一样,因为考场是按学校分的,在北科大参加竞赛的差不多都是二本吧,就我一个A组,那叫一个无奈,就我一个神经病吧。

    两点,准时入场,开始考试,我一上来就出岔子,我报告老师,无法解压试题,后来老师笑笑说,区分大小写(解压有一个密码,对大小写敏感),然后就正式开始了,打开第一题时,已经过了十分钟吧。这时,老师开示发面包和水还有一个瓶奶,我当时还高兴,这个比赛服务真好,后来我发现,其实这也是一个素质的考验吧。

    由于我一开始昨天就出岔子,所以有些紧张,于是打开了矿泉水,三两分钟喝完了,然后控制不住自己,又喝了一瓶奶,这时我后悔啦,可是后悔也来不及了,规定一个小时内不准上厕所,然后就开始……你懂得。

    此时的状态不好,刚好加上第一题题意不是太清楚,后来组委会又专门补充说明了,但是我已经在上边乱了心神,(憋得慌),所以用了一种特别多余的方法去解,最后还错了,于是我心慌了,感觉这次要挂,然后一到三点,我立马去了厕所,但是因为时间已经过去了一个小时,我却卡在了第一题,我着急,麻溜的方便完(绅士的说法,其实我还是更喜欢说尿完),又回去做题了,这时刚好组委会进行了A组第一题补充说明,然后我用了五分钟重新写,成功得到了答案。

    接着看第二题,简直不像话,搞这么简单的题,我又用了三分钟轻松拿下,此时已经三点十一了,我心里稍微缓和了些,开始做第三题,代码填空,这个题也很简单,用了十分钟分析检验,做了出来。

    然后开始搞第四题,因为这次考试波折太多,我情绪不是很稳定,长时间的失眠导致我注意力很难集中,第四题我想岔了方法,最开始想着暴力遍历,写到一半想起来这是程序大题,有时间限制,于是我改成了dfs,写到一半,我想会不会超时啊,于是又改成了bfs,然而当我写完了,一看要输出路径,差点吐血,只好又改成了dfs,这一来回折腾,修改代码,都知道,修改代码是一个灾难,于是我在比赛时碰见了这个灾难,我出了BUG了……

    我想deBug,可是这个编译器我第二次用(第一次是省赛,那时写得很顺,没有任何bug出现,所以就没有把这个当回事,自己学编程七个月,几乎没有用过低级编译器,结果坑死在这里了),根本不知道怎么用,找到了deBug按钮,但是不知道具体怎么搞,在这个上面,整整折腾了四十五分钟,我一行一行的自己手动模拟运行,最终在剩余了一个小时二十分钟时搞出来了。

    然后一看时间不够了,只能写一道题,然后就同时看了第五题和第六题,二选一,我选择的第五题,因为第五题是KMP,而第六题我拿不准,可能是链表吧,毕竟数据结构我只是学了一遍,并没有深入研究,原本打算暑假留校学数据结构和算法的。七个月的时间是不足以我深入学习这些高深的东西的。如果是链表,那我就真的选对了,因为C语言实现链表挺乏力的。

    第五题我感觉自己应该是可以过的,可是跟据我自己的比赛成绩来看,想必是被KO.了,应该是只过了部分数据吧。

    最后,时间无情的被用完了,我也放弃了挣扎了,想挣扎服务器也不给面子啊。

    昨天下午,成绩出来了,A组别C/C++国三,不是很好,比赛时状况频发,一共去了四趟厕所……哎,诱惑也是一种考验啊,对于我这种把事物只分为能吃的和不能吃的人而言,比赛发水和奶已经是极大的诱惑了,竟然还发面包,我想静静。

    总的来说,这次比赛给了我很多经验。

    就算法准备方面,我感觉应该着重放在dfs和bfs上,因为这个每次都要考,兴许还是好几道,然后一定要学学KMP和Manacher算法,因为铁定会考一道字符串处理的问题,而字符串处理问题你把这两个算法搞定,那其他的就不在话下,考试时只要看懂题就能过,其他的基础的算法,都要会。难度最大的压轴题嘛,我感觉以后会越来越难的,链表、树、图什么的,如果你想多拿分,那就都看看吧。

    另外,其他的方面的经验,最是宝贵了。
    一,控制住嘴,尽量不要吃喝提供的那些东西,这也是一个考验;
    二,控制住眼,不要过早的看后边的题,以免乱了思绪;
    三,控制住手,不要帮助眼去看后边的题。

    最后,最最最重要的是,一定要在竞赛前多熟悉竞赛提供的IDE,这个一旦出现问题,可以把你急死,不要问我为什么这么强调,我就是被急死了的那个人。

    抱着枕头准备森!!!(希望这个可以对下一届参加蓝桥杯的新人提供一些帮助,我是个渣渣,但是渣渣也有一颗不安分的心,我要报A组!!!金刚不可夺其志,A组,继续刚,咱不怂!)

    展开全文
  • 题目要求太多了就不放了; 1 #include "stc15.h" 2 #include "intrins.h" 3 #include "stdio.h" 4 #include "key.h" 5 #include "iic.h" 6 #include "ds1302.h" ... 8 #define ...

    题目要求太多了就不放了;

     

      1 #include "stc15.h"
      2 #include "intrins.h"
      3 #include "stdio.h"
      4 #include "key.h"
      5 #include "iic.h"
      6 #include "ds1302.h"
      7 #include "intrins.h"
      8 #define uchar unsigned char
      9 #define uint  unsigned int
     10 
     11 #define KEYS4   4
     12 #define KEYS5   5
     13 #define KEYS6   6
     14 #define KEYS7   7   
     15 #define KEYS8   8
     16 #define KEYS9   9
     17 #define KEYS10  10
     18 #define KEYS11  11
     19 
     20 uchar code smg_dis[]    = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0x40};
     21 uchar code Store_add[]  = {0x05,0x06,0x07,0x08};//地址索引
     22 uchar code Time_Init[]  = {23,59,10};
     23 uchar code TIme_Limit[] = {23,59,59};
     24 
     25 uchar Smg_Buf[8]={10,10,10,10,10,10,10,10};//显存
     26 uchar Time_rd_Buf[3] = {0};//时间读
     27 uchar Time_wr_Buf[3]= {0};//时间写
     28 uchar Event[4]= {0};//事件存储
     29 uint  Limit[2]= {2000,1000};//电压阈值
     30 
     31 bit KeyFlag  = 0;//案件扫描
     32 bit MeasFlag = 0;//扫描
     33 
     34 bit SetFlag  = 0;//闪烁使能
     35 bit Blink    = 0;//1s闪烁
     36 bit TimeSet  = 0;//时间设置
     37 bit LimitSet = 0;//阈值设置
     38 
     39 uchar AT_Read(uchar add);
     40 void AT_Write(uchar add ,uchar dat);
     41 void Delay2ms(void);
     42 void Time_Set(uchar *arr);
     43 void Time_Read(uchar *arr);
     44 void Time_Show(uchar *arr);
     45 uint Fre_Read (void);//采集频率
     46 uint ADC_Read(uchar add);//采集电压
     47 void UartInit(void);
     48 void Timer0Init(void);
     49 
     50 uchar Value_Dispose (uchar sum , uchar val ,uchar max , uchar min);
     51 
     52 //功能处理 
     53 void Key_Dispose1 (uchar val);
     54 void Key_Dispose2 (uchar val);
     55 void Key_Dispose3 (uchar val);
     56 void Key_Dispose4 (uchar val);
     57 
     58 void VoltMeasure (void);//后台电压扫描
     59 
     60 void EEPROM_Init (void);//初始化EEPROM中的阈值
     61 void EEPROM_Read(void);//初始化读取EEPROM保存
     62 void EEPROM_Write(uchar *arr);//事件保存
     63 
     64 /* 
     65 EEPROM 存储格式:
     66 
     67     0x01~0x02 电压上限
     68     0x03~0x04 电压下限
     69     0x05 时 [0]
     70     0x06 分 [1]
     71     0x07 秒    [2]
     72     0x08 事件类型[3]
     73     0x10 0xAA  校验位
     74     
     75 */
     76 
     77 uint FreTemp = 0;//频率
     78 uchar ShowMode = 0;
     79 //0 --> 时间
     80 //1 --> 电压
     81 //2 --> 频率
     82 //3 --> 查询
     83 
     84 void main ()
     85 {
     86     KeyStruct KeyVal;//按键结构体
     87     P0 = ~0X00;P2=0X80;P2=0X00;
     88     P0 =  0X00;P2=0Xa0;P2=0X00;
     89     Timer0Init();
     90     Time_Set(Time_Init);
     91 //    UartInit();
     92 //    AT_Write(0x10,0x23);//test
     93     EA = 0;
     94     EEPROM_Init();
     95     EA = 1;
     96     while(1)
     97     {
     98         if(KeyFlag)
     99         {
    100             KeyFlag = 0;
    101             KeyVal = KeyRead();
    102             Key_Dispose1(KeyVal.knew);//入参键值
    103             Key_Dispose2(KeyVal.knew);
    104             Key_Dispose3(KeyVal.knew);
    105             Key_Dispose4(KeyVal.knew);
    106         }
    107         if(MeasFlag)
    108         {
    109             MeasFlag = 0;
    110             if(ShowMode == 2) 
    111             {
    112                 FreTemp = Fre_Read();
    113             }
    114             Time_Read(Time_rd_Buf);
    115             VoltMeasure();//后台采集电压
    116             if(ShowMode == 0 && !SetFlag) Time_Show(Time_rd_Buf);//仅在显示状态下
    117         }    
    118     }
    119 }
    120 
    121 void VoltMeasure (void)
    122 {
    123     uint temp;
    124     temp = ADC_Read(0x03);
    125     if(temp>=Limit[0])//100ms 一次电压采集 
    126     {
    127         Event[3] = 1;//大于上限
    128         Event[2] = Time_rd_Buf[2];
    129         Event[1] = Time_rd_Buf[1];
    130         Event[0] = Time_rd_Buf[0];
    131         EEPROM_Write(Event);
    132     }
    133     else if(temp<=Limit[1]) 
    134     {
    135         Event[3] = 0;//小于下限
    136         Event[2] = Time_rd_Buf[2];
    137         Event[1] = Time_rd_Buf[1];
    138         Event[0] = Time_rd_Buf[0];
    139         EEPROM_Write(Event);
    140     }
    141     if(ShowMode == 1 && !SetFlag) 
    142     {
    143         Smg_Buf[0] = 11;
    144         Smg_Buf[1] = 1;
    145         Smg_Buf[2] = 11;
    146         Smg_Buf[3] = 10;
    147         Smg_Buf[4] = temp/1000;
    148         Smg_Buf[5] = temp/100%10;
    149         Smg_Buf[6] = temp/10%10;
    150         Smg_Buf[7] = temp%10;
    151     }    
    152 }
    153 
    154 
    155 void TIME0 (void) interrupt 1
    156 {
    157     static uchar SmgCount  = 0;
    158     static uchar KeyCount  = 0;
    159     static uchar MeasCount = 0;
    160     static uchar SmgLen    = 0;
    161     static uint  count = 0;
    162     if(SetFlag)
    163     {
    164         if(++ count > 999)
    165         {
    166             count = 0;
    167             Blink = ~Blink;
    168         }
    169     }
    170     else
    171     {
    172         count = 0;
    173         Blink = 0;
    174     }
    175      
    176     if( ++SmgCount > 1)//数码管
    177     {
    178         SmgCount = 0;
    179         P0=~smg_dis[Smg_Buf[SmgLen]];
    180         P2=0xe0;P2=0X00;
    181         P0=1<<SmgLen;P2=0xc0;P2=0X00;
    182         if(++SmgLen > 7) SmgLen=0;
    183     }
    184     
    185     if(++MeasCount > 80)//采集间隔
    186     {
    187         MeasCount = 0;
    188         MeasFlag = 1;
    189     }
    190         
    191     if( ++KeyCount > 10)//按键
    192     {
    193         KeyCount=0;
    194         KeyFlag=1;
    195     }
    196 }
    197 
    198 void Timer0Init(void)        //1ms@11.0592MHz
    199 {
    200     AUXR |= 0x80;
    201     TMOD &= 0xF0;
    202     TL0 = 0xCD;
    203     TH0 = 0xD4;
    204     TF0 = 0;
    205     TR0 = 1;
    206     ET0 = 1;
    207     PT0 = 0;
    208     EA = 1;
    209 }
    210 
    211 uint Fre_Read (void)
    212 {
    213     uint temp;
    214     TH1 = 0;
    215     TL1 = 0;
    216 //    EA = 0;
    217     while(P34);
    218     while(!P34);
    219     TR1 = 1;
    220     while(P34);
    221     while(!P34);
    222     TR1 = 0;
    223     temp = TH1<<8|TL1;
    224 //    EA = 1;
    225     return 1000000/temp*0.93;// hz
    226 }
    227 
    228 uint ADC_Read(uchar add)
    229 {
    230     uchar temp;
    231     IIC_Start();
    232     IIC_SendByte(0x90);
    233     IIC_WaitAck();
    234     IIC_SendByte(add);
    235     IIC_WaitAck();
    236     IIC_Start();
    237     IIC_SendByte(0x91);
    238     IIC_WaitAck();
    239     temp = IIC_RecByte();
    240     IIC_WaitAck();
    241     IIC_Stop();
    242     return temp *5.0/256*1000;// mv
    243 }
    244 
    245 void Time_Read(uchar *arr)
    246 {
    247     arr[2] = Read_Ds1302(0x81);
    248     arr[1] = Read_Ds1302(0x83);
    249     arr[0] = Read_Ds1302(0x85);//
    250     arr[0] = arr[0]/16*10 + arr[0]%16; 
    251     arr[1] = arr[1]/16*10 + arr[1]%16; 
    252     arr[2] = arr[2]/16*10 + arr[2]%16; 
    253 }
    254 
    255 void Time_Show (uchar *arr)
    256 {
    257     Smg_Buf[0] = arr[0]/10;
    258     Smg_Buf[1] = arr[0]%10;
    259     Smg_Buf[2] = 11;
    260     Smg_Buf[3] = arr[1]/10;
    261     Smg_Buf[4] = arr[1]%10;
    262     Smg_Buf[5] = 11;
    263     Smg_Buf[6] = arr[2]/10;
    264     Smg_Buf[7] = arr[2]%10;
    265 }
    266 
    267 void Time_Set(uchar *arr)
    268 {
    269     Write_Ds1302(0x8e,0x00);
    270     Write_Ds1302(0x80,arr[2]/10*16+arr[2]%10);//
    271     Write_Ds1302(0x82,arr[1]/10*16+arr[1]%10);
    272     Write_Ds1302(0x84,arr[0]/10*16+arr[0]%10);
    273     Write_Ds1302(0x8e,0x80);
    274 }
    275 
    276 uchar AT_Read(uchar add)
    277 {
    278     uchar temp;
    279     IIC_Start();
    280     IIC_SendByte(0xa0);
    281     IIC_WaitAck();
    282     IIC_SendByte(add);
    283     IIC_WaitAck();
    284     IIC_Start();
    285     IIC_SendByte(0xa1);
    286     IIC_WaitAck();
    287     temp=IIC_RecByte();
    288     IIC_WaitAck();
    289     IIC_Stop();
    290     Delay2ms();
    291     return temp;    
    292 }
    293 
    294 void AT_Write(uchar add ,uchar dat)
    295 {
    296     IIC_Start();
    297     IIC_SendByte(0xa0);
    298     IIC_WaitAck();
    299     IIC_SendByte(add);
    300     IIC_WaitAck();
    301     IIC_SendByte(dat);
    302     IIC_WaitAck();
    303     IIC_Stop();
    304     Delay2ms();    
    305 }
    306 
    307 void EEPROM_Write(uchar *arr)//保存事件时间
    308 {
    309     uchar i = 0;
    310     for(;i<4;i++)
    311     {
    312         AT_Write(Store_add[i],arr[i]);
    313     }
    314 }
    315 
    316 void EEPROM_Init (void)
    317 {
    318     //初始化EEPROM中的阈值
    319     //高位在后
    320     if( AT_Read(0x10)== 0xaa)//判断校验位
    321     {
    322         EEPROM_Read();
    323         P0 = ~0X01;P2=0X80;P2=0X00;
    324     }
    325     else
    326     {
    327         AT_Write(0x10,0xaa);//写入校验位
    328         AT_Write(0x01,Limit[0]);
    329         AT_Write(0x02,Limit[0]>>8);
    330         AT_Write(0x03,Limit[1]);
    331         AT_Write(0x04,Limit[1]>>8);    
    332         P0 = ~0X02;P2=0X80;P2=0X00;
    333     } 
    334 }
    335 
    336 void EEPROM_Read(void)//初始化读取EEPROM保存
    337 {
    338     uchar i = 0;
    339     Limit[0] = AT_Read(0x02) << 8 | AT_Read(0x01);
    340     Limit[1] = AT_Read(0x04) << 8 | AT_Read(0x03);//读取阈值
    341     for(;i<4;i++)//读取事件
    342     {
    343         Event[i] = AT_Read(Store_add[i]);    
    344     }
    345 }
    346 
    347 void UartInit(void)//Uart1 9600bps 11.0592Mhz time2
    348 {
    349     SCON = 0x50;        
    350     AUXR |= 0x01;        
    351     AUXR |= 0x04;        
    352     T2L = 0xE0;        
    353     T2H = 0xFE;        
    354     AUXR |= 0x10;
    355 }
    356 
    357 void Delay2ms(void)        //@11.0592MHz
    358 {
    359     unsigned char i, j;
    360 
    361     _nop_();
    362     _nop_();
    363     i = 22;
    364     j = 128;
    365     do
    366     {
    367         while (--j);
    368     } while (--i);
    369 }
    370 
    371 void Key_Dispose1 (uchar val)//功能处理 1 时间设置
    372 {
    373     static uchar mode = 0;
    374     static uchar len = 0;
    375     static uchar temp[3];
    376     if( !LimitSet && val == KEYS7 )
    377     {
    378         if(ShowMode == 0)mode++;
    379         else 
    380         {
    381             ShowMode = 0;
    382         }
    383         if(mode == 1)
    384         {
    385             SetFlag  = 1;//进入时间设置
    386             TimeSet  = 1;
    387             ShowMode = 0;
    388             Time_wr_Buf[0] = Time_rd_Buf[0];
    389             Time_wr_Buf[1] = Time_rd_Buf[1];
    390             Time_wr_Buf[2] = Time_rd_Buf[2];
    391             temp[0]=Time_wr_Buf[0];
    392             temp[1]=Time_wr_Buf[1];
    393             temp[2]=Time_wr_Buf[2];
    394             mode++;
    395         }
    396         else if(mode == 3)
    397         {
    398             SetFlag  = 0; 
    399             TimeSet  = 0;
    400             if(temp[0]!=Time_wr_Buf[0]||temp[1]!=Time_wr_Buf[1]||temp[2]!=Time_wr_Buf[2])
    401                 Time_Set(Time_wr_Buf);
    402             mode = 0;
    403         }
    404     }
    405     if( TimeSet )//时间调整
    406     {
    407         Time_Show(Time_wr_Buf);
    408         if(val==KEYS4)
    409         {
    410             if(++len > 2 )len = 0;
    411         }
    412         if(Blink)
    413         {
    414             Smg_Buf[len*3]   = 10;
    415             Smg_Buf[len*3+1] = 10;
    416         }
    417         Time_wr_Buf[len] = Value_Dispose(Time_wr_Buf[len],val,TIme_Limit[len],0);
    418     }
    419     else
    420     {
    421         len = 0;
    422     }
    423 }
    424 
    425 void Key_Dispose2 (uchar val)//电压
    426 {
    427     static uchar mode = 0;
    428     static uchar len = 0;
    429     if( !TimeSet && val == KEYS6 )
    430     {
    431         mode++;
    432         if(mode==1)
    433         {
    434             ShowMode = 1;
    435         }
    436         else if(mode==2)
    437         {
    438             SetFlag  = 1;//开闪烁
    439             LimitSet = 1;
    440         }
    441         else
    442         {
    443             SetFlag  = 0;
    444             LimitSet = 0;
    445             mode = 1;
    446             AT_Write(0x01,Limit[0]);
    447             AT_Write(0x02,Limit[0]>>8);    
    448             AT_Write(0x03,Limit[1]);
    449             AT_Write(0x04,Limit[1]>>8);    
    450         }
    451     } 
    452     if(ShowMode!=1 ) mode = 0;//直接退出到时间显示后清0
    453     if( LimitSet )
    454     {
    455         Smg_Buf[0] = Limit[0]/1000;
    456         Smg_Buf[1] = Limit[0]/100%10;
    457         Smg_Buf[2] = Limit[0]/10%10;
    458         Smg_Buf[3] = Limit[0]%10;
    459         
    460         Smg_Buf[4] = Limit[1]/1000;
    461         Smg_Buf[5] = Limit[1]/100%10;
    462         Smg_Buf[6] = Limit[1]/10%10;
    463         Smg_Buf[7] = Limit[1]%10;
    464         
    465         if(val==KEYS4)
    466         {
    467             if(++len > 1 )len = 0;
    468         }
    469         if(Blink)
    470         {
    471             Smg_Buf[len*4]   = 10;
    472             Smg_Buf[len*4+1] = 10;
    473             Smg_Buf[len*4+2] = 10;
    474             Smg_Buf[len*4+3] = 10;
    475         }
    476         Limit[len] = Value_Dispose(Limit[len]/500,val,10,0)*500;//步进500
    477     }
    478     else
    479     {
    480         len = 0;
    481     }       
    482 }
    483 
    484 void Key_Dispose3 (uchar val)//频率
    485 {
    486     static uchar mode = 0;
    487     static uchar len = 0;
    488     uint temp;
    489     if( !TimeSet && !LimitSet && val == KEYS5 )
    490     {
    491         mode++;
    492         if(mode==1)
    493         {
    494             ShowMode = 2;
    495         }
    496         else if(mode==2)
    497         {
    498             ShowMode = 0;
    499         }
    500     } 
    501     if(ShowMode != 2) mode = 0;//直接退出到时间显示后清0
    502     if( ShowMode == 2 )
    503     {
    504         Smg_Buf[0] = 11;
    505         Smg_Buf[1] = 2;
    506         Smg_Buf[2] = 11;
    507         if(val==KEYS4)
    508         {
    509             if(++len > 1 )len = 0;
    510         }
    511         if(len==0)
    512         {
    513             Smg_Buf[3] = FreTemp/10000;
    514             Smg_Buf[4] = FreTemp/1000%10;
    515             Smg_Buf[5] = FreTemp/100%10;
    516             Smg_Buf[6] = FreTemp/10%10;
    517             Smg_Buf[7] = FreTemp%10;
    518         }
    519         else
    520         {
    521             temp = 100000/FreTemp;
    522             Smg_Buf[3] = temp/10000;
    523             Smg_Buf[4] = temp/1000%10;
    524             Smg_Buf[5] = temp/100%10;
    525             Smg_Buf[6] = temp/10%10;
    526             Smg_Buf[7] = temp%10;
    527         }  
    528     }
    529     else
    530     {
    531         len = 0;
    532     }       
    533 }
    534 
    535 void Key_Dispose4 (uchar val)//查询
    536 {
    537     static uchar mode = 0;
    538     static uchar len = 0;
    539     if( !TimeSet && !LimitSet && val == KEYS9 )
    540     {
    541         mode++;
    542         if(mode==1)
    543         {
    544             ShowMode = 3; 
    545         }
    546         else if(mode==2)
    547         {
    548              ShowMode = 0; 
    549         }
    550     } 
    551     if(ShowMode != 3) mode = 0;//直接退出到时间显示后清0
    552     if( ShowMode == 3 )
    553     {
    554         if(val==KEYS4)
    555         {
    556             if(++len > 1 )len = 0;
    557         }
    558         if(len==0)
    559         {
    560             Smg_Buf[0] = 10;
    561             Smg_Buf[1] = 10;
    562             Smg_Buf[2] = 10;
    563             Smg_Buf[3] = 10;
    564             Smg_Buf[4] = 10;
    565             Smg_Buf[5] = 10;
    566             Smg_Buf[6] = 10;
    567             Smg_Buf[7] = Event[3];
    568         }
    569         else
    570         {
    571             Time_Show(Event);
    572         } 
    573     }
    574     else
    575     {
    576         len = 0;
    577     }       
    578 }
    579 
    580 uchar Value_Dispose (uchar sum , uchar val ,uchar max , uchar min)
    581 {
    582     char temp;
    583     temp = sum;
    584     if(val == KEYS11) 
    585     {
    586         if(++temp >= max) temp = max;
    587     }
    588     else if(val == KEYS10) 
    589     {
    590         if(--temp <= min) temp = min;
    591     }
    592     return temp;  
    593 }

     

    转载于:https://www.cnblogs.com/nsss/p/10886566.html

    展开全文
  • 现在的蓝桥杯单片机组已经不考电路设计了,所以这个题的编程部分就比较简单,一般来说在DS18B20驱动写好的情况下,两个多小时就可以写好。 1、题目 一看题目,这个题需要用到DS18B20测温度,数码管和LED显示,以及...

    现在的蓝桥杯单片机组已经不考电路设计了,所以这个题的编程部分就比较简单,一般来说在DS18B20驱动写好的情况下,两个多小时就可以写好。

    1、题目

    一看题目,这个题需要用到DS18B20测温度,数码管和LED显示,以及独立按键进行设置等等。

    有难度的一点在PWM输出,要求PWM频率在1Kz,由于我们在DS18B20的程序中有关中断的操作,所以想要完美的输出相应占空比的PWM,需要更改DS18B20中的开关总中断的位置。

    2、代码

    代码下载链接:https://download.csdn.net/download/xiaomo_haa/11002294

    在第一次调试的时候,我是将DS18B20中的关中断 EA = 0 改为了禁止定时器0中断 ET0 = 0。这时使用逻辑分析仪观察波形,输出完美PWM波,但是我改为控制 EA 后,观察占空比20%时候的波形,有的部分占空比不是20%。

    附上占空比为20%时候的波形图

    控制ET0

    控制EA

    可以看到这个时候由于关总中断的影响,造成这个高电平时间减少,占空比小于20%

    main.c 

    #include <stc15.h>
    #include "sys.h"
    
    bit flag_2ms = 0, flag_500ms = 0;
    bit flag_fan = 0, flag_temper = 0;
    u8 mode = 1, modebackup = 1;
    signed char min = 2, sec = 0;		//time
    int temper_int = 0;				//temperture
    
    void main(void)
    {
    	int temper = 0;
    	bit res;
    	
    	AllInit();
    	Timer0Init();
    	Start18B20();
    	EA = 1;
    	while(1)
    	{
    		TubeShow();
    		KeyPress();
    		
        	if((sec == 0) && (min == 0))
    			flag_fan = 0;
    		else
    			flag_fan = 1;
    
    		if(flag_2ms)
    		{
    			flag_2ms = 0;
    			KeyScan();
    		}
    		
    		if(flag_500ms)		//show temperture
    		{
    			flag_500ms = 0;
    			res = Get18B20Temp(&temper);
    			if(res)
    			{
    				temper >>= 4;
    				if((temper > 0) && (temper < 75))
    					temper_int = temper;
    			}
    			Start18B20();
    		}
    	}
    }
    

    sys.c

    #include "sys.h"
    
    void AllInit(void)
    {
    	P2 = (P2 & 0x1f) | 0x80;	//open Y4C
    	P0 = 0xff;
    	P2 = (P2 & 0x1f) | 0xc0;	//open Y6C
    	P0 = 0x00;
    	P2 = (P2 & 0x1f) | 0xa0;	//open Y5C
    	P0 = 0x00;
    	P2 = P2 & 0x1f;
    }
    
    void Timer0Init(void)		//100微秒@11.0592MHz
    {
    	AUXR |= 0x80;		//定时器时钟1T模式
    	TMOD &= 0xF0;		//设置定时器模式
    	TL0 = 0xAE;		//设置定时初值
    	TH0 = 0xFB;		//设置定时初值
    	TF0 = 0;		//清除TF0标志
    	TR0 = 1;		//定时器0开始计时
    	ET0 = 1;
    }
    
    void Timer0(void) interrupt 1
    {
    	static u8 T0count1 = 0, T0count3 = 0;
    	static u16 T0count2 = 0, T0count4 = 0;
    	u8 temp;
    	
    	T0count1 ++;
    	
    	if(flag_temper)
    		T0count4 ++;
    	else
    		T0count4 = 0;
    	
    	if(flag_fan)
    	{
    		T0count2 ++;
    		T0count3 ++;
    	}
    		
    	if(T0count1 >= 20)		//2ms
    	{
    		T0count1 = 0;
    		flag_2ms = 1;
    	}
    	
    	if(T0count4 >= 2000)	//500ms	show temperture
    	{
    		T0count4 = 0;
    		flag_500ms = 1;
    	}
    	
    	if(flag_fan)
    	{
    		switch(modebackup)
    		{
    			case 1: temp = 2; break;
    			case 2: temp = 3; break;
    			case 3: temp = 7; break;
    		}
    		
    		if(T0count3 <= temp)
    			PWM = 1;
    		else
    		{
    			PWM = 0;
    			if(T0count3 >= 10)
    				T0count3 = 0;
    		}
    	}
    	else
    		T0count3 = 0;
    	
    	if(T0count2 >= 10000)								//1s
    	{
    		T0count2 = 0;
    		sec --;
    		if(sec < 0)				//sec
    		{
    			sec = 59;
    			min --;
    			if(min < 0)			//min
    			{
    				min = 0;			//stop
    				min = 0;			//stop
    				flag_fan = 0;
    			}
    		}
    	}
    	LEDWork();
    	TubeScan();
    }
    

    sys.h

    #ifndef _SYS_H_
    #define _SYS_H_
    
    #include <stc15.h>
    #include <intrins.h>
    #include "ds18B20.h"
    
    typedef unsigned char u8;
    typedef unsigned int u16;
    typedef unsigned long u32;
    
    //External variables
    extern bit flag_2ms, flag_500ms;
    extern bit flag_fan, flag_temper;
    extern u8 mode, modebackup;
    extern signed char min, sec;
    extern int temper_int;
    
    //Pin
    sbit S7 = P3^0;
    sbit S6 = P3^1;
    sbit S5 = P3^2;
    sbit S4 = P3^3;
    
    sbit PWM = P3^4;
    
    //Function
    void AllInit(void);
    void Timer0Init(void);
    
    void TubeScan(void);
    void TubeShow(void);
    void LEDWork(void);
    
    void KeyScan(void);
    void KeyAction(unsigned char key);
    void KeyPress(void);
    
    #endif
    
    

    display.c

    #include "sys.h"
    
    unsigned char code table[]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 
                                0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e,
    														0xff, 0xbf};
    u8 TubeBuff[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
    u8 smg1, smg2, smg3, smg4, smg5, smg6, smg7, smg8;
    
    void TubeScan(void)
    {
    	static u8 index = 0;
    	
    	P2 = (P2 & 0x1f) | 0xe0;
    	P0 = 0xff;
    	
    	P2 = (P2 & 0x1f) | 0xc0;
    	P0 = 0x01 << index;
    	
    	P2 = (P2 & 0x1f) | 0xe0;
    	P0 = TubeBuff[index];
    	
    	P2 = P2 & 0x1f;
    	
    	index ++;
    	index &= 0x07;
    }
    
    void TubeShow(void)
    {
    	if((mode >= 1) && (mode <= 3))
    	{
    		smg1 = smg3 = 17;		//-
    		smg2 = mode;
    		smg4 = 16;					//shut down
    		smg5 = min / 10;		//min
    		smg6 = min % 10;
    		smg7 = sec / 10;				//sec
    		smg8 = sec % 10;
    	}
    	else if(mode == 4)
    	{
    		smg1 = smg3 = 17;		//-
    		smg2 = mode;
    		smg4 = smg5 = 16;		//shut down
    		smg6 = temper_int / 10;
    		smg7 = temper_int % 10;
    		smg8 = 12;					//c
    	}
    	
    	TubeBuff[0] = table[smg1];
    	TubeBuff[1] = table[smg2];
    	TubeBuff[2] = table[smg3];
    	TubeBuff[3] = table[smg4];
    	TubeBuff[4] = table[smg5];
    	TubeBuff[5] = table[smg6];
    	if(mode != 4)
    		TubeBuff[5] &= 0x7f;
    
    	TubeBuff[6] = table[smg7];
    	TubeBuff[7] = table[smg8];
    }
    
    
    void LEDWork(void)
    {
    	u8 dat;
    	
    	dat = _crol_(0x7f, modebackup);
    	P0 = 0xff;
    	P2 = (P2 & 0x1f) | 0x80;
    	if((sec != 0) || (min != 0))
    		P0 = dat;
    
    	P2 = P2 & 0x1f;
    }
    

    key.c

    #include "sys.h"
    
    u8 KeySta[] = {1, 1, 1, 1};
    u8 KeyBackup[] = {1, 1, 1, 1};
    u8 KeyBuff[] = {0xff, 0xff, 0xff, 0xff};
    
    void KeyScan(void)
    {
    	u8 i;
    	
    	KeyBuff[0] = (KeyBuff[0] << 1) | S7;
    	KeyBuff[1] = (KeyBuff[1] << 1) | S6;
    	KeyBuff[2] = (KeyBuff[2] << 1) | S5;
    	KeyBuff[3] = (KeyBuff[3] << 1) | S4;
    	
    	for(i = 0; i < 4; i ++)
    	{
    		if(KeyBuff[i] == 0xff)				//Key release
    			KeySta[i] = 1;
    		else if(KeyBuff[i] == 0x00)		//Key press
    			KeySta[i] = 0;
    		else
    		{}
    	}
    }
    
    void KeyAction(unsigned char key)
    {
    	if(key == 0)					//S7 temperture
    	{		
    		if(mode != 4)
    		{
    			mode = 4;
    			flag_500ms = 1;
    			flag_temper = 1;
    		}
    		else
    		{
    			flag_temper = 0;
    			mode = modebackup;
    		}
    	}
    	else if(key == 1)			//S6 stop
    	{
    		sec = 0;
    		min = 0;
    		flag_fan = 0;
    	}
    	else if(key == 2)			//S5 minter plus
    	{
    		min ++;
    		if(min > 99)
    			min = 99;
    	}
    	else if(key == 3)			//S4	mode change
    	{
    		if(mode == 4)
    		{
    			modebackup ++;
    			if(modebackup == 4)
    				modebackup = 1;
    		}
    		else
    		{
    			mode ++;
    			if(mode == 4)
    				mode = 1;
    			modebackup = mode;	//backup mode
    		}
    	}
    }
    
    void KeyPress(void)
    {
    	u8 i;
    	
    	for(i = 0; i < 4; i ++)
    	{
    		if(KeySta[i] != KeyBackup[i])
    		{
    			if(KeySta[i] == 0)					//action when key press
    				KeyAction(i);
    			KeyBackup[i] = KeySta[i];
    		}
    	}
    }
    
    

    ds18b20.c

     #include "sys.h"
    
    sbit DS18B20_IO = P1^4;
    
    /*******************************************************************************
    * 函数名	:Delayus
    * 输入值	:unsigned int us
    * 返回值	:none
    * 作者		:小默haa
    * 时间		:2019年2月17日
    * 功能描述:1T单片机延时指定us
    * 备注		:最大形参65535,即最大延时65ms
    *******************************************************************************/
    void Delayus(unsigned int us)
    {
    	do{
    		_nop_();
    		_nop_();
    		_nop_();
    		_nop_();
    		_nop_();
    		_nop_();
    		_nop_();
    		_nop_();
    	}while(--us);
    }
    
    /*******************************************************************************
    * 函数名	:Get18B20Ack
    * 输入值	:none
    * 返回值	:none
    * 作者		:小默haa
    * 时间		:2019年2月27日
    * 功能描述:复位总线,获取18B20存在脉冲,以启动一次读写操作
    * 备注		:
    *******************************************************************************/
    bit Get18B20Ack(void)
    {
    	bit ack;
    	
    	DS18B20_IO = 0;			//产生500us的复位脉冲
    	Delayus(500);
    	DS18B20_IO = 1;			//延时60us
    //	EA = 0;							//禁止总中断
    	ET0 = 0;
    	Delayus(60);
    	ack = DS18B20_IO;		//读取存在脉冲
    	while(!DS18B20_IO);	//等待存在脉冲结束
    	
    //	EA = 1;							//重新使能总中断
    	ET0 = 1;
    	
    	return ack; 	
    }
    
    /*******************************************************************************
    * 函数名	:DS18B20Write
    * 输入值	:unsigned char dat
    * 返回值	:none
    * 作者		:小默haa
    * 时间		:2019年2月27日
    * 功能描述:向18B20写入一个字节
    * 备注		:dat为待写入字节
    *******************************************************************************/
    void DS18B20Write(unsigned char dat)
    {
     	unsigned char mask;
    						
    	for(mask = 0x01; mask != 0; mask <<= 1)	//低位在先,依次移出8个bit
    	{
    //		EA = 0;
    		ET0 = 0;
    		DS18B20_IO = 0;				//产生2us低电平脉冲
    		Delayus(2);
    	 	if(dat & mask)				//输出该bit值
    		 	DS18B20_IO = 1;
    		else
    		 	DS18B20_IO = 0;
    //		EA = 1;
    		ET0 = 1;
    		Delayus(60);					//延时60us
    		DS18B20_IO = 1;				//拉高通信引脚
    	}
    }
    
    /*******************************************************************************
    * 函数名	:DS18B20Read
    * 输入值	:none
    * 返回值	:unsigend char dat
    * 作者		:小默haa
    * 时间		:2019年2月27日
    * 功能描述:从18B20读取一个字节
    * 备注		:返回值为读取到的字节
    *******************************************************************************/
    unsigned char DS18B20Read(void)
    {
     	unsigned char mask, dat = 0;
    	
    	for(mask = 0x01; mask != 0; mask <<= 1)	//低位在先,依次采集8个bit
    	{
    //		EA = 0;
    		ET0 = 0;
    		DS18B20_IO = 0;				//产生2us低电平脉冲
    		Delayus(2);
    		DS18B20_IO = 1;				//结束低电平脉冲,等待18B20输出数据
    		Delayus(2);						//延时2us
    
    	 	if(DS18B20_IO)				//读取通信引脚上的值
    		 	dat |= mask;
    //		EA = 1;
    		ET0 = 1;
    		Delayus(60);					//再延时60us
    	}
    	
    	return dat;	
    }
    
    /*******************************************************************************
    * 函数名	:Start18B20
    * 输入值	:none
    * 返回值	:bit ~ack
    * 作者		:小默haa
    * 时间		:2019年2月27日
    * 功能描述:启动一次18B20温度转换
    * 备注		:返回值为是否启动成功
    *******************************************************************************/
    bit Start18B20()
    {
     	bit ack;
    	static bit flag = 1;
    
    	ack = Get18B20Ack();		//执行总线复位,并获取18B20应答
    	if(ack == 0)						//如18B20正确应答,则启动一次转换
    	{
    		DS18B20Write(0xCC);		//跳过ROM操作
    		
    		if(flag)
    		{
    			flag = 0;
    			DS18B20Write(0x4e);			//写暂存器指令4E
    			DS18B20Write(0x4b);			//写高速缓存器TH高温限值75度
    			DS18B20Write(0x00);			//写高速缓存器TL低温限值0度
    			DS18B20Write(0x1f);			//写配置寄存器4
    															//0x1f : 0.5000°C  转换时间93.75ms
    															//0x3f : 0.2000°C  转换时间187.5ms
    															//0x5f : 0.1250°C  转换时间375ms
    															//0x7f : 0.0625°C  转换时间750ms
    		}
    		
    		ack = Get18B20Ack();		//执行总线复位,并获取18B20应答
    		if(ack == 0)						//如18B20正确应答,则启动一次转换
    		{
    			DS18B20Write(0xCC);		//跳过ROM操作
    			DS18B20Write(0x44);		//启动一次温度转换
    		}
    	}
    
    	return ~ack;						//ack == 0 表示操作成功,所以返回值对其取反
    }
    
    /*******************************************************************************
    * 函数名	:Get18B20Temp
    * 输入值	:int *temp
    * 返回值	:bit ~ack
    * 作者		:小默haa
    * 时间		:2019年2月27日
    * 功能描述:读取18B20转换的温度值
    * 备注		:返回值为是否读取成功
    *******************************************************************************/
    bit Get18B20Temp(int *temp)
    {
     	bit ack;
    	unsigned char LSB, MSB;			//16bit温度值的低字节和高字节
    
    	ack = Get18B20Ack();				//执行总线复位,并获取18B20应答
    	if(ack == 0)								//如18B20正确应答,则读取温度值
    	{
    	 	DS18B20Write(0xCC);				//跳过ROM操作
    		DS18B20Write(0xBE);				//发送读命令
    		LSB = DS18B20Read();			//读温度值的低字节
    		MSB = DS18B20Read();			//读温度值的高字节
    		*temp = ( MSB << 8) + LSB;	//合成16bit的整数
    	}
    
    	return ~ack;								//ack == 0 表示操作应答,所以返回值为1其取反值
    } 
    
    

    ds18b20.h

    #ifndef __DS18B20_H
    #define __DS18B20_H
    
    
    //单总线延时函数
    void Delayus(unsigned int us);
    bit Get18B20Ack(void);
    void DS18B20Write(unsigned char dat);
    unsigned char DS18B20Read(void);
    bit Start18B20();
    bit Get18B20Temp(int *temp);
    
    
    #endif
    

     

    展开全文
  • 第七届 蓝桥杯省赛试题 单片机 pdf格式。
  • 蓝桥杯电子类单片机第五届决赛(多功能事件记录器)参考程序
  • 第一题: 标题:换零钞 x星球的钞票的面额只有:100元,5元,2元,1元,共4种。 小明去x星旅游,他手里只有2张100元的x星币,太不方便,恰好路过x星银行就去换零钱。 小明有点强迫症,他坚持要求200元换出的零钞...

    第一题:
    标题:换零钞

    x星球的钞票的面额只有:100元,5元,2元,1元,共4种。
    小明去x星旅游,他手里只有2张100元的x星币,太不方便,恰好路过x星银行就去换零钱。
    小明有点强迫症,他坚持要求200元换出的零钞中2元的张数刚好是1元的张数的10倍,
    剩下的当然都是5元面额的。

    银行的工作人员有点为难,你能帮助算出:在满足小明要求的前提下,最少要换给他多少张钞票吗?
    (5元,2元,1元面额的必须都有,不能是0)

    思路:2元的10个10个地加,直到满足条件为止.(还是手算吧T^T)

    答案:74

    第二题:
    标题:激光样式

    x星球的盛大节日为增加气氛,用30台机光器一字排开,向太空中打出光柱。
    安装调试的时候才发现,不知什么原因,相邻的两台激光器不能同时打开!
    国王很想知道,在目前这种bug存在的情况下,一共能打出多少种激光效果?

    显然,如果只有3台机器,一共可以成5种样式,即:
    全都关上(sorry, 此时无声胜有声,这也算一种)
    开一台,共3种
    开两台,只1种

    30台就不好算了,国王只好请你帮忙了。

    要求提交一个整数,表示30台激光器能形成的样式种数。

    思路:dfs深搜

    代码:

    #include<cstdio>
    #include<iostream>
    using namespace std;
    
    int a[40],ans=0;
    
    void dfs(int i){
    	if(i==31)
    	{
    		ans++;
    //		cout<<a[1]<<" "<<a[2]<<" "<<a[3]<<endl;
    		return ;
    	}
    	a[i]=0;
    	dfs(i+1);
    		
    	a[i]=1;
    	if(a[i]==1&&a[i-1]==1)
    		return ;
    	dfs(i+1);	
    	return ;
    }
    
    int main(){
    //	memset(a,0,sizeof(a));
    	dfs(1);
    	cout<<ans<<endl;
    	
    	return 0;
    }
    

    第三题:
    标题:格雷码

    格雷码是以n位的二进制来表示数。
    与普通的二进制表示不同的是,它要求相邻两个数字只能有1个数位不同。
    首尾两个数字也要求只有1位之差。

    有很多算法来生成格雷码。以下是较常见的一种:
    从编码全0开始生成。
    当产生第奇数个数时,只把当前数字最末位改变(0变1,1变0)
    当产生第偶数个数时,先找到最右边的一个1,把它左边的数字改变。
    用这个规则产生的4位格雷码序列如下:
    0000
    0001
    0011
    0010
    0110
    0111
    0101
    0100
    1100
    1101
    1111
    1110
    1010
    1011
    1001
    1000

    以下是实现代码,仔细分析其中逻辑,并填写划线部分缺少的代码。

    #include <stdio.h>
    void show(int a,int n)
    {
    int i;
    int msk = 1;
    for(i=0; i<n-1; i++) msk = msk << 1;
    for(i=0; i<n; i++){
    printf((a & msk)? “1” : “0”);
    msk = msk >> 1;
    }
    printf("\n");
    }

    void f(int n)
    {
    int i;
    int num = 1;
    for(i=0; i<n; i++) num = num<<1;

    int a = 0;
    for(i=0; i<num; i++){
    	show(a,n);
    	
    	if(i%2==0){
    		a = a ^ 1;
    	}
    	else{
    		a = _________________________ ; //填空
    	}
    }
    

    }

    int main()
    {
    f(4);
    return 0;
    }

    答案:
    a=a^((a&(~a+1))<<1);
    或 a=a^((a&(-a))<<1);
    更多的戳这里:https://blog.csdn.net/nka_kun/article/details/80487810

    展开全文
  • 省赛时候水到了一个省一,然后我们学校的决赛地点在北大,所以就可以愉快的去北京(旅游)参加比赛了。 坐高铁到北京南站,然后换乘地铁去北大附近,排队买票的人贼多,然后被强制安装注册了zfb。。。。。到了旅馆才...
  • 2017年蓝桥杯单片机比赛经验分享 我的蓝桥杯单片机获得江苏省二等奖,大约是江苏省130名(江苏省一等奖103个)。比赛失利的主要原因还是当时比较的单纯,只知道一味的死练。 这也是我感觉死的最莫名其妙的比赛,抱...
  • 蓝桥杯单片机第七届决赛(电压频率采集设备)参考程序
  • 蓝桥杯单片机记录2019

    2018-12-25 21:22:58
    蓝桥杯单片机省赛记录2019 省赛必考模块 1. LED 2. 数码管显示 3. DS18B20 4. DS1302 5. IIC、AD转换 省赛历年必做真题 1. 第四届(模拟智能农田灌溉系统) 2. 第五届(温度检测与控制装置) 时钟 IIC AD 独立按键 ...
  • 第十届蓝桥杯 单片机设计与开发项目省赛-程序设计试题
  • 第十届蓝桥杯省赛程序设计试题+客观题题目
  • 这是一篇介绍蓝桥杯板子方波N555模块的博客 我自己的理解是将定时器0设置为计数模式,定时器1设置为计时模式来定1S的时间,然后定时器0记录的次数就是频率。 怎么设置呢只需要将TMOD设置为TMOD=0x04即可 寄存器...
  • 第十届C/C++B组的蓝桥杯决赛在2019-05-25下午已经结束了,可是我现在才想来总结下自己的收获。可能收获也谈不上吧,就是说说自己的北京三日游。 行程: 24日早上从学校出发,高铁赶向北京,挤地铁,挤公交,我们...
  • 蓝桥杯电子类单片机第六届决赛(智能物料传送系统)参考程序
  • 第十届蓝桥杯单片机设计与开发的试题,分为客观题和编程部分。
  • 蓝桥杯单片机01】从历年决赛真题中寻找单片机常见的考点 广东职业技术学院 欧浩源 【第三届:门禁系统】 1、功能简述 “门禁系统”主要有两种工作模式: 模式1:7:00~22:00为自动门状态,该状态下门的开...
1 2 3 4 5
收藏数 92
精华内容 36