从单片机基础到程序框架(连载)

2020-01-12 17:12发布

本帖最后由 吴坚鸿 于 2016-1-17 11:32 编辑

前言:
前言_pdf文件.pdf (30.44 KB, 下载次数: 729) 2016-1-17 11:30 上传 点击文件名下载附件

      大家好,我叫吴坚鸿,以前一直想写两本书,一本讲单片机入门基础,一本讲单片机程序框架。现在发现,单片机基础和程序框架并没有明显的分水岭,基础中有框架,框架中有基础,应该合二为一,读起来才会连贯舒畅。所以我决定中止当前已写到55节的《从业十年,教你单片机入门基础》连载帖,新开此连载帖。
      再提一下我2014年写的《从业将近十年,手把手教你单片机程序框架》,一方面受到很多网友的好评,另一方面也有一些热心网友提出了宝贵的意见,我今天看来,确实还有一些可待改进的地方。本来计划在2017年重写《……单片机程序框架》那个老帖,现在看来不用那么折腾了,只要把《……单片机程序框架》的内容也整合到此新帖里就可以了,这样对我也比较省事。我的时间计划是,先花4年时间写一个初稿,然后再花2年时间重写一次,最后再花1年时间整理成书,整个过程大概7年时间左右,今年是2016年,估计到2023年左右《从单片机基础到程序框架》的新书就可以出版了。
      感谢各位朋友的支持。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
99条回答
chun_hua82
2020-01-24 14:52
第十四节:二进制与字节单位,以及常用三种变量的取值范围。
第十四节_pdf文件.pdf (81.21 KB, 下载次数: 129) 2016-4-17 09:38 上传 点击文件名下载附件

【14.1   为什么要二进制?】

       为什么要二进制?我们日常生活明明是十进制的,为何数字电子领域偏要选择二进制?这是由数字硬件电路决定的。人有十个手指头,人可以直接发出十种不同声音来命名0,1,2,3...9这些数字,人可以直接用眼睛识别出十种不同状态的信息,但是数字底层基础硬件电路要直接处理和识别十种状态却很难,相对来说,处理和识别两种状态就轻松多了,所以选择二进制。比如,一颗LED灯的亮或灭,一个IO口的输出高电平或低电平,识别某一个点的电压是高电平或低电平,只需要三极管等基础元器件就可把硬件处理电路搭建起来,二进制广泛应用在数字电路的存储,通讯和运算等领域,想学好单片机就必须掌握它。

【14.2   二进制如何表示成千上万的大数值?】

       二进制如何表示成千上万的数值?现在用LED灯的亮和灭来跟大家讲解。

     (1)1个LED灯:
  1.       灭   第0种状态
  2.       亮   第1种状态
复制代码
      合计:共2种状态。

    (2)2个LED灯挨着:
  1.       灭灭   第0种状态
  2.       灭亮   第1种状态
  3.       亮灭   第2种状态
  4.       亮亮   第3种状态
复制代码
      合计:共4种状态。

   (3)3个LED灯挨着:
  1.       灭灭灭   第0种状态
  2.       灭灭亮   第1种状态
  3.       灭亮灭   第2种状态
  4.       灭亮亮   第3种状态
  5.       亮灭灭   第4种状态
  6.       亮灭亮   第5种状态
  7.       亮亮灭   第6种状态
  8.       亮亮亮   第7种状态
复制代码
      合计:共8种状态。

   (4)8个LED灯挨着:
  1.       灭灭灭灭灭灭灭灭   第0种状态
  2.       灭灭灭灭灭灭灭亮   第1种状态
  3.       ......                         第N种状态
  4.       亮亮亮亮亮亮亮灭   第254种状态
  5.       亮亮亮亮亮亮亮亮   第255种状态
复制代码
      合计:共256种状态。

    (5)16个LED灯挨着:
  1.       灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭   第0种状态
  2.       灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭亮   第1种状态
  3.       ......                                                     第N种状态
  4.       亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮灭   第65534种状态
  5.       亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮   第65535种状态
复制代码
      合计:共65536种状态。

    (6)32个LED灯挨着:
  1.       灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭   第0种状态
  2.       灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭亮   第1种状态
  3.       ......                                                               第N种状态
  4.       亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮灭   第4294967294种状态
  5.       亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮   第4294967295种状态
复制代码
      合计:共4294967296种状态。

结论:
       连续挨着的LED灯越多,能表达的数值范围就越大。

【14.3   什么是位?】

       什么是位?以上一个LED灯就代表1位,8个LED灯就代表8位。位的英文名是用bit来表示。一个变量的位数越大就意味着这个变量的取值范围越大。一个单片机的位数越大,就说明这个单片机一次处理的数据范围就越大,意味着运算和处理速度就越快。我们日常所说的8位单片机,32位单片机,就是这个位的概念。为什么32位的单片机比8位单片机的处理和运算能力强,就是这个原因。

【14.4   什么是字节?】

       什么是字节?字节是计算机很重要的一个基本单位,一个字节有8位。8个LED灯挨着能代表多少种状态,就意味着一个字节的数据范围有多大。从上面举的例子中,我们知道8个LED灯挨着,能表示从0到255种状态,所以一个字节的取值范围就是从0到255。

【14.5   三种常用变量的取值范围是什么?】

       前面章节曾提到三种常用的变量:unsigned char,unsigned int ,unsigned long。现在有了二进制和字节的基础知识,就可以跟大家讲讲这三种变量的取值范围,而且很重要,这是我们写单片机程序必备的概念。
       unsigned char的变量占用1个字节RAM,共8位,根据前面LED灯的例子,取值范围是从0到255。
       unsigned int的变量占用2个字节RAM,共16位,根据前面LED灯的例子,取值范围是从0到65535。多说一句,对于51内核的单片机,unsigned int的变量是占用2个字节。如果是在32位的stm32单片机,unsigned int的变量是占用4个字节的,所以不同的单片机不同的编译器是会有一些差异的。
       unsigned long的变量占用4个字节RAM,共32位,根据前面LED灯的例子,取值范围是从0到4294967295。

【14.6   例程练习和分析。】

       现在我们编写一个程序来验证unsigned char,unsigned int,unsigned long的取值范围。
       定义两个unsigned char变量a和b,a赋值255,b赋值256,255和256恰好处于unsigned char的取值边界。
       再定义两个unsigned int变量c和d,c赋值65535,d赋值65536,65535和65536恰好处于unsigned int的取值边界。
       最后定义两个unsigned long变量e和f,e赋值4294967295,f赋值4294967296,4294967295和4294967296恰好处于unsigned long的取值边界。
       程序代码如下:


  1. /*---C语言学习区域的开始。-----------------------------------------------*/

  2. void main() //主函数
  3. {
  4.         unsigned char a;   //定义一个变量a,并且分配了1个字节的RAM空间。
  5.         unsigned char b;   //定义一个变量b,并且分配了1个字节的RAM空间。
  6.         unsigned int c;    //定义一个变量c,并且分配了2个字节的RAM空间。
  7.         unsigned int d;    //定义一个变量d,并且分配了2个字节的RAM空间。
  8.         unsigned long e;   //定义一个变量e,并且分配了4个字节的RAM空间。
  9.         unsigned long f;   //定义一个变量f,并且分配了4个字节的RAM空间。

  10.         a=255;         //把255赋值给变量a,a此时会是什么数?会超范围溢出吗?
  11.         b=256;         //把256赋值给变量b,b此时会是什么数?会超范围溢出吗?
  12.         c=65535;       //把65535赋值给变量c,c此时会是什么数?会超范围溢出吗?
  13.         d=65536;       //把65536赋值给变量d,d此时会是什么数?会超范围溢出吗?
  14.         e=4294967295;  //把4294967295赋值给变量e,e此时会是什么数?会超范围溢出吗?
  15.         f=4294967296;  //把4294967296赋值给变量f,f此时会是什么数?会超范围溢出吗?

  16.         View(a);   //把第1个数a发送到电脑端的串口助手软件上观察。
  17.     View(b);   //把第2个数b发送到电脑端的串口助手软件上观察。
  18.         View(c);   //把第3个数c发送到电脑端的串口助手软件上观察。
  19.     View(d);   //把第4个数d发送到电脑端的串口助手软件上观察。
  20.         View(e);   //把第5个数e发送到电脑端的串口助手软件上观察。
  21.     View(f);   //把第6个数f发送到电脑端的串口助手软件上观察。

  22.     while(1)  
  23.     {
  24.     }
  25. }

  26. /*---C语言学习区域的结束。-----------------------------------------------*/
复制代码

在电脑串口助手软件上观察到的程序执行现象如下:

  1. 开始...

  2. 第1个数
  3. 十进制:255
  4. 十六进制:FF
  5. 二进制:11111111

  6. 第2个数
  7. 十进制:0
  8. 十六进制:0
  9. 二进制:0

  10. 第3个数
  11. 十进制:65535
  12. 十六进制:FFFF
  13. 二进制:1111111111111111

  14. 第4个数
  15. 十进制:0
  16. 十六进制:0
  17. 二进制:0

  18. 第5个数
  19. 十进制:4294967295
  20. 十六进制:FFFFFFFF
  21. 二进制:11111111111111111111111111111111

  22. 第6个数
  23. 十进制:0
  24. 十六进制:0
  25. 二进制:0
复制代码

分析:        
        通过实验结果,我们知道unsigned char变量最大能取值到255,如果非要赋值256就会超出范围溢出后变成了0。unsigned int变量最大能取值到65535,如果非要赋值65536就会超出范围溢出后变成了0。unsigned long变量最大能取值到4294967295,如果非要赋值4294967296就会超出范围溢出后变成了0。

【14.7   如何在单片机上练习本章节C语言程序?】

        直接复制前面章节中第十一节的模板程序,练习代码时只需要更改“C语言学习区域”的代码就可以了,其它部分的代码不要动。编译后,把程序下载进带串口的51学习板,通过电脑端的串口助手软件就可以观察到不同的变量数值,详细方法请看第十一节内容。

一周热门 更多>