打印
[51单片机]

从业将近十年!手把手教你单片机程序框架(连载)

[复制链接]
楼主: jianhong_wu
手机看帖
扫描二维码
随时随地手机跟帖
321
jianhong_wu|  楼主 | 2014-5-21 13:01 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
cjseng 发表于 2014-5-21 12:29
TI标志位不会出错的,它只是发送完一个字节的标志,发送完一个字节,TI由硬件自动置1.这个出错的几率基本 ...

非常专业,非常细致的解释。佩服。

使用特权

评论回复
322
lmx89| | 2014-5-21 15:25 | 只看该作者
cjseng 发表于 2014-5-21 12:29
TI标志位不会出错的,它只是发送完一个字节的标志,发送完一个字节,TI由硬件自动置1.这个出错的几率基本 ...

非常感谢!

使用特权

评论回复
323
sinuoke9999| | 2014-5-21 17:28 | 只看该作者
好东东,学习了!

使用特权

评论回复
324
sinuoke9999| | 2014-5-22 11:31 | 只看该作者
楼主,问一个小问题:

ucRcregBuf[uiRcregTotal-1]=SBUF;   //将串口接收到的数据缓存到接收缓冲区里

这句好像是SBUF里的数据放到ucRcregBuf[uiRcregTotal-1]里,那么ucRcregBuf[0],ucRcregBuf[1].....ucRcregBuf[uiRcregTotal-1]里面好像并没有存放数据啊?麻烦楼主帮忙解释一下,万分感激 啊!:handshake

使用特权

评论回复
325
jianhong_wu|  楼主 | 2014-5-22 11:36 | 只看该作者
本帖最后由 jianhong_wu 于 2014-5-22 11:38 编辑
sinuoke9999 发表于 2014-5-22 11:31
楼主,问一个小问题:

ucRcregBuf=SBUF;   //将串口接收到的数据缓存到接收缓冲区里

每接收一串数据,uiRcregTotal变量都是从0开始往上累加。请注意,在ucRcregBuf[uiRcregTotal-1]=SBUF;之前有一条语句 ++uiRcregTotal; 所以ucRcregBuf[0],ucRcregBuf[1].....ucRcregBuf[uiRcregTotal-1]都存放了数据。建议你在硬件平台上测试一下。

使用特权

评论回复
326
sinuoke9999| | 2014-5-22 16:42 | 只看该作者
楼主,你好啊!
有个小疑问,请教一下啊:   第68行,  uiVoiceCnt=const_voice_short; //蜂鸣器发出声音,说明数据尾和有效数据都接收正确 。   
                                           1.     这行语句执行完毕之后,是等待T0发生中断吗?
                                           2.     T0中断结束后,程序还会回到这里,如何才能跳出 最内层语句呢(67行的if语句)
   

使用特权

评论回复
327
jianhong_wu|  楼主 | 2014-5-22 16:57 | 只看该作者
sinuoke9999 发表于 2014-5-22 16:42
楼主,你好啊!
有个小疑问,请教一下啊:   第68行,  uiVoiceCnt=const_voice_short; //蜂鸣器发出声音, ...

1.     uiVoiceCnt=const_voice_short这行语句执行完毕之后,是等待T0发生中断吗?
答:   不用刻意等待定时中断,主程序会继续往下执行。因为定时器中断每隔一段很小的时间就会周期性地发生中断,当发生定时中断时,中断函数自然会根据变量uiVoiceCnt是否为0而发出报警声音。
2.     T0中断结束后,程序还会回到这里,如何才能跳出 最内层语句呢(67行的if语句)
答:还是上面那个问题,主函数不会刻意原地等待中断,主函数会继续往下执行,它自然就会跳出 最内层语句呢(67行的if语句)。

使用特权

评论回复
328
sinuoke9999| | 2014-5-22 16:58 | 只看该作者
你好,楼主:
还是针对第   第68行,  uiVoiceCnt=const_voice_short; //蜂鸣器发出声音,说明数据尾和有效数据都接收正确 。   
                   1.  直接在 68行后添加蜂鸣器处理语句,不好吗?这个语句执行时间也不长啊!
                   2.  后面加个 break语句跳出最能层的 if 语句 ,如何?
                   3. 你这个程序里没有明确限制:收发数据是分布执行的。如果处理时间比较长,而数据还在不断的接受中,会不会导致数据的丢失?

                    
         
   
   
  

使用特权

评论回复
329
jianhong_wu|  楼主 | 2014-5-22 17:05 | 只看该作者
sinuoke9999 发表于 2014-5-22 16:58
你好,楼主:
还是针对第   第68行,  uiVoiceCnt=const_voice_short; //蜂鸣器发出声音,说明数据尾和有效 ...

1.  直接在 68行后添加蜂鸣器处理语句,不好吗?这个语句执行时间也不长啊!
答:你说的这种方法也可以。但是我不喜欢这样用。如果蜂鸣器的时间很长,就会在那里死等太长时间,影响其它任务。
2.  后面加个 break语句跳出最能层的 if 语句 ,如何?
答:我一直不明白为什么if语句要“跳出”是什么意思,if语句又不是while循环语句,为什么你一直强调“跳出”的动作。
3. 你这个程序里没有明确限制:收发数据是分布执行的。如果处理时间比较长,而数据还在不断的接受中,会不会导致数据的丢失?
答:我这个程序结构是这样的,先等待接受完一串数据后再处理,如果正在接受数据的过程中,它不会进行处理的。另外,绝大多数的串口收发程序都是遵循事先约定的一发一收的应答协议,你不用过多担心。

使用特权

评论回复
330
sinuoke9999| | 2014-5-22 17:10 | 只看该作者
你好啊, 按照你的意思,程序执行完第 68行后,会等待TO发生中断,然后蜂鸣器叫一声,然后结束本次的 T0中断服务函数,现在是不是程序还会继续 停留在 68行后,由于本次的数据处理还没结束,那么67行的 if语句是永远满足条件的,是不是出现了无法结束if语句呢?

使用特权

评论回复
331
jianhong_wu|  楼主 | 2014-5-22 17:55 | 只看该作者
sinuoke9999 发表于 2014-5-22 17:10
你好啊, 按照你的意思,程序执行完第 68行后,会等待TO发生中断,然后蜂鸣器叫一声,然后结束本次的 T0中 ...

你要复习一下C语言的基础知识,仔细看看if语句的语法。if语句不是循环语句,if语句跟while,for这些语句不一样。

使用特权

评论回复
332
sinuoke9999| | 2014-5-22 18:10 | 只看该作者
jianhong_wu 发表于 2014-5-22 17:55
你要复习一下C语言的基础知识,仔细看看if语句的语法。if语句不是循环语句,if语句跟while,for这些语句不 ...

第64行中的 if  语句,你是怎么退出的? 由于条件满足,你还不是使用 break语句 来退出的????

使用特权

评论回复
333
jianhong_wu|  楼主 | 2014-5-22 18:20 | 只看该作者
sinuoke9999 发表于 2014-5-22 18:10
第64行中的 if  语句,你是怎么退出的? 由于条件满足,你还不是使用 break语句 来退出的???? ...

你误会了。此处的break语句是用来立即退出 62行的 while(uiRcMoveIndex>=5) 循环.

使用特权

评论回复
334
电子宜宾| | 2014-5-22 23:19 | 只看该作者
顶一个 顶一个 顶一个 顶一个

使用特权

评论回复
335
dengjinhua1987| | 2014-5-23 10:39 | 只看该作者
收益匪浅啊

使用特权

评论回复
336
zhongfabai| | 2014-5-23 16:14 | 只看该作者
:)写得很不错,赞一个。。。

使用特权

评论回复
337
hww5408| | 2014-5-26 11:09 | 只看该作者
吴总,什么时候更新呀?

使用特权

评论回复
338
jianhong_wu|  楼主 | 2014-5-26 12:45 | 只看该作者
hww5408 发表于 2014-5-26 11:09
吴总,什么时候更新呀?

这两天会更新的。

使用特权

评论回复
339
jianhong_wu|  楼主 | 2014-5-28 11:46 | 只看该作者
第四十九节:利用DS18B20做一个温控器  。

开场白:
      DS18B20是一款常用的温度传感器芯片,它只占用单片机一根IO口,使用起来也特别方便。需要特别注意的是,正因为它只用一根IO口跟单片机通讯,因此读取一次温度值的通讯时间比较长,而且时序要求严格,在通讯期间不允许被单片机其它的中断干扰,因此在实际项目中,系统一旦选用了这款传感器芯片,就千万不要选用动态扫描数码管的显示方式。否则在关闭中断读取温度的时候,数码管的显示会有略微的“闪烁”现象。
      DS18B20的测温范围是-55度至125度。在-10度至85度的温度范围内误差是+-0.5度,能满足大部分常用的测温要求。
这一节要教会大家三个知识点:
第一个:大概了解一下DS18B20的驱动程序。
第二个:做温控设备的时候,为了避免继电器在临界温度附近频繁跳动切换,应该设置一个缓冲温差。本程序的缓冲温差是2度。
第三个:继续加深了解按键,显示,传感器它们三者是如何紧密关联起来的程序框架。

具体内容,请看源代码讲解。

(1)        硬件平台.
基于朱兆祺51单片机学习板。

(2)实现功能:
     本程序只有1个窗口。这个窗口有2个局部显示。
第1个局部是第7,6,5位数码管,显示设定的温度。
第2个局部是第4,3,2,1位数码管,显示实际环境温度。其中第4位数码管显示正负符号位。
S1按键是加键,S5按键是减键。通过它们可以直接设置“设定温度”。
一个LED灯用来模拟工控的继电器。
当实际温度低于或者等于设定温度2度以下时,模拟继电器的LED灯亮。
当实际温度等于或者大于设定温度时,模拟继电器的LED灯灭。
当实际温度处于设定温度和设定温度减去2度的范围内,模拟继电器的LED维持现状,这个2度范围用来做缓冲温差,避免继电器在临界温度附近频繁跳动切换。

(3)源代码讲解如下:
第四十九节源代码讲解.rar (4.69 KB)
总结陈词:
下一节开始讲单片机采集模拟信号的内容,欲知详情,请听下回分解-----利用ADC0832采集电压的模拟信号。

(未完待续,下节更精彩,不要走开哦)

使用特权

评论回复
340
longcomeon| | 2014-5-30 10:56 | 只看该作者
  if(key_sr1==1)//IO是高电平,说明两个按键没有全部被按下,这时要及时清零一些标志位
  {
      ucKeyLock1=0; //按键自锁标志清零
      uiKeyTimeCnt1=0;//按键去抖动延时计数器清零,此行非常巧妙,是我实战中摸索出来的。   
            if(ucShortTouchFlag1==1)  //短按触发标志
          {
             ucShortTouchFlag1=0;
                 ucKeySec=1;    //触发一号键的短按
          }
  }
  else if(ucKeyLock1==0)//有按键按下,且是第一次被按下
  {
     uiKeyTimeCnt1++; //累加定时中断次数
     if(uiKeyTimeCnt1>const_key_time_short1)
     {
            ucShortTouchFlag1=1;   //激活按键短按的有效标志  
     }

     if(uiKeyTimeCnt1>const_key_time_long1)
     {
            ucShortTouchFlag1=0;  //清除按键短按的有效标志

        uiKeyTimeCnt1=0;
        ucKeyLock1=1;  //自锁按键置位,避免一直触发

        ucKeySec=2;    //触发1号键的长按
              
     }

  }
大师,请问下 if(key_sr1==1)//IO是高电平,按键没按下,怎么进入这if里面的if语句判断if(ucShortTouchFlag1==1)  //短按触发标志,谢谢

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则