打印
[51单片机]

从业十年,教你单片机入门基础。(连载)

[复制链接]
楼主: jianhong_wu
手机看帖
扫描二维码
随时随地手机跟帖
101
ghl137| | 2015-6-26 21:50 | 只看该作者 回帖奖励 |倒序浏览
先收藏再慢慢读,学习学习

使用特权

评论回复
102
oldzhang| | 2015-6-27 12:03 | 只看该作者
其实C语言是入门者的一个难关。学C语言首先要清楚:数和变量;运算符;四条语句;函数。深入点再学结构体;指针;。。。
数和变量按位数分为8位,16位,32位。。。;整数,浮点数,无符号数,二进制,8进制,16进制数。。。;数组。。。
运算符:加减乘除,逻辑运算,比较,单目,双目,3目。。。
四条语句:for,if,while,switch-case语句
函数:带()的,分内函数和自己编写的函数

使用特权

评论回复
103
jianhong_wu|  楼主 | 2015-6-28 10:35 | 只看该作者
第二十四节:乘法运算的5种常见格式。
      请先看以下的乘法语法格式:
       “保存变量”=“被乘数1”*“乘数2”*... *“乘数N”;
        含义是:右边的“被乘数”与各“乘数”相乘,并且把最终的运算结果赋值给左边的“保存变量”。注意,这里的符号“=”不是等于号的意思,而是赋值的意思。左边的“保存变量”必须是变量,不能是常量,否则编译时会报错。右边的“被乘数”和“乘数”既可以是变量,也可以是常量,也可以是“保存变量”本身自己。多说一句,何谓变量和常量?变量是可以在程序中被更改的,是被分配的一个RAM空间。常量往往是数字,或者是被分配在ROM空间的一个具体数值。下面根据右边“被乘数”与“乘数”的不同组合,列出了乘法运算的5种常见格式。
      第1种:“被乘数1”是常量,“乘数2”是常量。比如:
unsigned char a;
a=15*3;

数字“15”和“3”都是常量。执行上述语句后,保存变量a变成了45。

      第2种:“被乘数1”是变量,“乘数2”是常量。比如:
unsigned char b;
unsigned char x=15;
b=x*10;

x是变量,“10”是常量。由于原来x变量里面的数值是15,执行上述语句后,保存变量b变成了150。而变量x则保持不变,x还是15。

      第3种:“被乘数1”是变量,“乘数2”是变量。比如:
unsigned char c;
unsigned char x=15;
unsigned char y=6;
c=x*y;

x是变量,y也是变量。由于原来x变量里面的数值是15,y变量里面的数值是6,执行上述语句后,保存变量c变成了90。而变量x和y则保持不变,x还是15,y还是6。

      第4种:“被乘数1”是保存变量本身,“乘数2”是常量。比如:
unsigned char d=18;
d=d*2;
d=d*7;

d是保存变量,“2”和“7”都是常量。这类语句有一个特点,具备了自乘功能,可以更改自己本身自己的数值。比如原来保存变量d的数值是18,执行“d=d*2;”语句后,d变成了36,接着再执行完“d=d*7;”语句后,d最后变成了252。

      第5种:“被乘数1”是保存变量本身,“乘数2”是变量。比如:
unsigned char e=2;
unsigned char x=15;
unsigned char y=6;
e=e*x;
e=e*y;

e是保存变量,x与y都是变量。这类语句有一个特点,具备了自乘功能,可以更改自己本身自己的数值。比如原来保存变量e的数值是2,执行“e=e*x;”语句后,e变成了30,接着再执行完“e=e*y;”语句后,e最后变成了180。

       现在编写一个程序来练习上述5种格式的乘法语句,最后把程序编译后下载到坚鸿51学习板观察结果。请直接复制第十节模板程序,修改的main程序代码如下:
void main() //主程序
{
/*---C语言学习区域的开始---------------------------------------------------------------------------*/
        
  unsigned char a;       //定义一个变量a,并且分配了1个字节的RAM空间。
  unsigned char b;       //定义一个变量b,并且分配了1个字节的RAM空间。
  unsigned char c;       //定义一个变量c,并且分配了1个字节的RAM空间。
  unsigned char d=18;       //定义一个变量d,并且分配了1个字节的RAM空间。初始化默认为18.
  unsigned char e=2;       //定义一个变量e,并且分配了1个字节的RAM空间。初始化默认为2.
        
  unsigned char x=15;    //定义一个变量x,并且分配了1个字节的RAM空间。初始化默认为15.
  unsigned char y=6;     //定义一个变量y,并且分配了1个字节的RAM空间。初始化默认为6.        

  //第1种:“被乘数1”是常量,“乘数2”是常量。
  a=15*3;
        
        
  //第2种:“被乘数1”是变量,“乘数2”是常量。
  b=x*10;
        
  //第3种:“被乘数1”是变量,“乘数2”是变量。
  c=x*y;
        
        
  //第4种:“被乘数1”是保存变量本身,“乘数2”是常量。
  d=d*2;
  d=d*7;
        
        
  //第5种:“被乘数1”是保存变量本身,“乘数2”是变量。
  e=e*x;
  e=e*y;


  GuiWdData0=a;   //把变量a这个数值放到窗口变量0里面显示
  GuiWdData1=b;   //把变量b这个数值放到窗口变量1里面显示
  GuiWdData2=c;   //把变量c这个数值放到窗口变量2里面显示
  GuiWdData3=d;   //把变量d这个数值放到窗口变量3里面显示
  GuiWdData4=e;   //把变量e这个数值放到窗口变量4里面显示

        
/*---C语言学习区域的结束---------------------------------------------------------------------------*/
   while(1)  
   {
      initial();
      key_service();
      display_service();
   }

}


        如何在坚鸿51学习板上观察a,b,c,d,e这5个变量?按下S1或者S5按键即可切换显示不同的窗口,从而显示不同的变量。上坚鸿51学习板观察程序执行的结果如下:
变量a为45。
变量b为150。
变量c为90。
变量d为252。
变量e为180。

     下节预告:乘法连写的简写。
(未完待续)

使用特权

评论回复
104
czdo| | 2015-6-30 09:22 | 只看该作者
我也来预订一本书

使用特权

评论回复
105
dianzijiangren| | 2015-6-30 17:57 | 只看该作者
搞了十年,还做单片机,哥们你也是让我醉了

使用特权

评论回复
106
神奇号| | 2015-7-1 20:24 | 只看该作者
学习了,

使用特权

评论回复
107
NoTCsmile| | 2015-7-2 14:00 | 只看该作者
原来 只是卖开发板的。。。。再说 就是十年也算不得高手吧。。。

使用特权

评论回复
108
弥勒开怀笑| | 2015-7-2 15:12 | 只看该作者

使用特权

评论回复
109
fmzhangpei241| | 2015-7-4 09:29 | 只看该作者
mark

使用特权

评论回复
110
jianhong_wu|  楼主 | 2015-7-6 10:16 | 只看该作者
第二十五节:连乘以及自乘运算的简写。
       上一节我列举的乘法例子中,右边的参与运算的数据都是两个。实际上,C语言规则没有限制数据个数,它的通用格式如下:
       “保存变量”=“被乘数1”*“乘数2”...*“乘数N”;
       当右边的乘数个数超过两个的时候,就是我所说的“连乘”,每个乘数的属性没有限定,可以是常量,也可以是变量。比如:
 a=2*5*3;  //被乘数和乘数全部是常量。a的结果为30。
  b=k*x*y;  //被乘数和乘数全部是变量。b的结果为36。
  c=x*5*y;  //被乘数和乘数,有的是常量,有的是变量。c的结果为90。

        连乘的运行顺序是,赋值符号“=”右边的乘数挨个相乘,把每一次的运算结果放在一个临时的隐蔽变量里,这个隐蔽的变量我们看不到,是单片机系统内部参与运算时的专用寄存器,等右边所有的乘数连乘的计算结果出来后,再把这个隐蔽变量所保存的计算结果赋值给左边的“保存变量”。
        讲完了连乘的格式,接着讲自乘的简写。何谓自乘?当右边的被乘数是“保存变量”本身时,这种情况就是我所说的“自乘”。比如:
“保存变量”=“保存变量”*“乘数1”;
“保存变量”=“保存变量”*“乘数1”*“乘数2”...*“乘数N”;
        上述自加计算式可以简写成如下格式:
“保存变量”*=“乘数1”;       
“保存变量”*=“乘数1”*“乘数2”...*“乘数N”;
        这种格式就是我所说的自乘简写。现在举几个例子如下:
  
d*=6;     //相当于d=d*6;最后d的结果为30。
  e*=x;     //相当于e=e*x;最后e的结果为15。
  f*=2*y*k; //相当于f=f*(2*y*k);最后f的结果为120。

     我之前在讲加法的自加和减法的自减运算时,还给大家介绍了它们另外一种特殊的简写方式。比如减法运算,当右边只有2减数,当一个减数是“保存变量”,另一个是常数1时,格式如下:
“保存变量”=“保存变量”-1;       
        这时候,可以把上述格式简写成如下两种格式:
“保存变量”--;
--“保存变量”;
        这两种格式也是俗称的“自减1”操作。比如:
g--;  //相当于g=g-1或者g-=1;
--h;  //相当于h=h-1或者h-=1;

         那么,本节所讲的自乘运算,有没有这种特殊写法“g**”或者“**h”?答案很明显,没有。因为任何一个数“自乘1”还是等于它本身,所以研究这种特殊写法就没有任何意义。
         现在编写一个程序来练习刚才讲到的内容,最后把程序编译后下载到坚鸿51学习板观察结果。请直接复制第十节模板程序,修改的main程序代码如下:


void main() //主程序
{
/*---C语言学习区域的开始---------------------------------------------------------------------------*/
        
  unsigned char a;       //定义一个变量a,并且分配了1个字节的RAM空间。
  unsigned char b;       //定义一个变量b,并且分配了1个字节的RAM空间。
  unsigned char c;       //定义一个变量c,并且分配了1个字节的RAM空间。
  unsigned char d=5;       //定义一个变量d,并且分配了1个字节的RAM空间。初始化默认为5.
  unsigned char e=5;       //定义一个变量e,并且分配了1个字节的RAM空间。初始化默认为5.
  unsigned char f=5;       //定义一个变量f,并且分配了1个字节的RAM空间。初始化默认为5.
   
  unsigned char x=3;    //定义一个变量x,并且分配了1个字节的RAM空间。初始化默认为3.
  unsigned char y=6;     //定义一个变量y,并且分配了1个字节的RAM空间。初始化默认为6.        
  unsigned char k=2;     //定义一个变量k,并且分配了1个字节的RAM空间。初始化默认为2.
        
        
            //第1个知识点:连乘。
  a=2*5*3;  //被乘数和乘数全部是常量。a的结果为30。
  b=k*x*y;  //被乘数和乘数全部是变量。b的结果为36。
  c=x*5*y;  //被乘数和乘数,有的是常量,有的是变量。c的结果为90。

            //第2个知识点:自乘的简写。
  d*=6;     //相当于d=d*6;最后d的结果为30。
  e*=x;     //相当于e=e*x;最后e的结果为15。
  f*=2*y*k; //相当于f=f*(2*y*k);最后f的结果为120。
         
         


   GuiWdData0=a;   //把变量a这个数值放到窗口变量0里面显示
   GuiWdData1=b;   //把变量b这个数值放到窗口变量1里面显示
   GuiWdData2=c;   //把变量c这个数值放到窗口变量2里面显示
   GuiWdData3=d;   //把变量d这个数值放到窗口变量3里面显示
   GuiWdData4=e;   //把变量e这个数值放到窗口变量4里面显示
   GuiWdData5=f;   //把变量f这个数值放到窗口变量5里面显示


        
/*---C语言学习区域的结束---------------------------------------------------------------------------*/
   while(1)  
   {
      initial();
      key_service();
      display_service();
   }

}

        如何在坚鸿51学习板上观察a,b,c,d,e,f这6个变量?按下S1或者S5按键即可切换显示不同的窗口,从而显示不同的变量。上坚鸿51学习板观察程序执行的结果如下:
变量a为30。
变量b为36。
变量c为90。
变量d为30。
变量e为15。
变量f为120。
     下节预告:乘法运算的溢出。
(未完待续)

使用特权

评论回复
111
cccsssc| | 2015-7-6 10:59 | 只看该作者
要是真能仔细看完其实收获还是非常可观的!

使用特权

评论回复
112
shenxfs| | 2015-7-7 07:55 | 只看该作者
初看教程感觉还可以,但仔细阅读还是有些不对,误人子弟之嫌。
首先main函数书写就有问题:void main(),函数的形参为空,返回值也是空。LZ搞了单片机十年,嵌入式c语言编码规范是否知道,规范要求main函数必须明确返回值和形参的类型,写成int main(void)或int main(int argc.char **argv)。void main()在keil不会告警,可在其它编译器会出错。

使用特权

评论回复
113
风继续吹AQA| | 2015-7-8 10:51 | 只看该作者
太赞了!

使用特权

评论回复
114
Aidon_Zhang| | 2015-7-8 16:27 | 只看该作者
感谢

使用特权

评论回复
115
jianhong_wu|  楼主 | 2015-7-12 07:26 | 只看该作者
第二十六节:乘法运算的溢出。
     乘法的溢出规律跟加法的溢出规律是一样的。举一个例子如下:
   unsigned char k=30;
   unsigned char n=10;
   unsigned char a;
   a=k*n;  

分析:
kn相乘,相当于30乘以10,运算结果是300(十六进制是0x012c保存在一个隐藏中间变量,根据前面加法运算的规律,我猜测这个隐藏中间变量可能是unsigned int类型,然后再把这个中间变量赋值给单字节变量a,a只能接收十六进制的低8位字节0x2c,所以运算后a的数值由于溢出变成了十六进制的0x2c(十进制是44)。
由于乘法的溢出规律跟加法的溢出规律是一样的,所以不再多举例子。在实际项目中,为了避免一不小心就溢出的问题,我强烈建议,不管加减乘除,凡是参与运算的变量全部都要转化成unsigned long变量,转化的方法也跟加减运算的转换方法一致,不再详细解决这方面的内容。
现在编写一个程序来练习刚才讲到的内容,最后把程序编译后下载到坚鸿51学习板观察结果。请直接复制第十节模板程序,修改的main程序代码如下:
void main() //主程序
{
/*---C语言学习区域的开始-----------------------------------------------------------------

----------*/
      
   unsigned char k=30;
   unsigned char n=10;
   unsigned char a;

   a=k*n;  

   GuiWdData0=a;   //把变量a这个数值放到窗口变量0里面显示



        
/*---C语言学习区域的结束-----------------------------------------------------------------

----------*/
   while(1)  
   {
      initial();
      key_service();
      display_service();
   }

}

    查看运算结果的方法。如何在坚鸿51学习板上观察变量?按下S1或者S5按键即可切换显示不同的窗口,从而显示不同的变量。按下S9按键不松手就可以切换到十六进制的显示界面,松开手后会自动切换到十进制的界面。上坚鸿51学习板观察程序执行的结果如下:
       变量a为0x2c(十进制是44)。
     下节预告:除法运算的常见格式。
(未完待续)

使用特权

评论回复
116
zjglizhen| | 2015-7-13 16:21 | 只看该作者
赞,太棒了

使用特权

评论回复
117
multisensor| | 2015-7-13 20:21 | 只看该作者
万丈高原平地起...

使用特权

评论回复
118
tianjian002| | 2015-7-14 22:31 | 只看该作者
:P关注航太电子单片机开发板

使用特权

评论回复
119
风去| | 2015-7-14 22:33 | 只看该作者

使用特权

评论回复
120
jianhong_wu|  楼主 | 2015-7-18 07:13 | 只看该作者
第二十七节:整除求商的运算。
C语言中,乘法符号不是“×”而是“*”,除法求商的符号不是“÷”而是“/”。乘除法符号跟我们日常用的数学符号有点不一样,我个人猜测C语言这样规定的原因是因为“×”容易跟大写字母“X”搞混,而“÷”这个符号在电脑键盘上不方便直接输入,故分别用“*”和“/”替代。
何谓“整除”?请看以下两个对比例子:
10除以4,商等于2.5------(带小数点)
10除以4,商等于2,余数是2------(这就叫做整除)
什么时候带小数点,什么时候是整除?取决于参与运算的变量类型。标准的C语言中,其实远远不止我前面所说的unsigned char ,unsigned int ,unsigned long这三种类型,还有一种叫浮点数的float类型,当参与运算的变量涉及float类型时,就可能存在小数点。这是题外话,大家大概知道有这么一回事即可,暂时不用深入研究float等其它类型的数据,因为在单片机项目中,只要用我所述的三种常用类型就绝对够用了,单片机不用涉及float类型,如果项目涉及小数点的显示和处理,我们完全可以用那三种类型去处理它,这些处理方法我后续会讲到,暂时不用管。而unsigned char ,unsigned int ,unsigned long这三种类型的除法都是整除,我后续所讲的所有章节内容也都是整除。
整除的通用格式:
“保存变量”=“被除数” /  “除数1/  “除数2... /  “除数N;
跟之前讲的加减运算一样,左边的“保存变量”必须是变量,右边的可以是变量和常量的任意组合。如果右边只有两个参与运算的数据,就是整除的常见格式。
整除的常见格式:
“保存变量”=“被除数” /  “除数” ;       
现在从整除常见格式的6个方面来分析它的规律。
(1)当“除数”等于0时。我们都知道,数**算除数是不允许等于0的,如果在单片机中非要让除数为0,商会出现什么结果?我试过,发现有一个规律:如果“除数”是变量的0,那么商等于十进制的255(十六进制是0xff)。如果“除数”是常量的0,那么商等于十进制的1。比如:
a=23 /y;  //假设除数变量y里面是0,那么a的结果是255(十六进制的0xff)。
b=23 /0;  //除数是常量0,那么b的结果是1。

(2)当被除数小于“除数”时。商等于0。比如:
c=7 / 10;  //c的结果是0。

(3)当被除数等于“除数”时。商等于1。比如:
d=10/ 10;  //d的结果是1。

(4)当被除数大于“除数”时。商大于0
比如:
e=10/ 4;  //e的结果是2。
f=10/ 3;  //f的结果是3。

(5)自除运算的简写。跟前面加减法一样,当“被除数”是“保存变量”时,存在自除运算的简写。
“保存变量”=“保存变量” /  “除数” ;
上述自除运算的简写如下:
“保存变量” / =“除数” ;
比如:
g/=5;  //相当于g=g/5;

加减法有自加1++g”和自减1g--”的特殊写法,但是除法不存在这种自除1的特殊写法,因为一个数除以1还是等于它本身,所以自除1没有任何意义,因此C语言语法中没有这种写法。
   (6)除法的溢出规律跟加法的溢出规律是一样的,所以不再多举例子。在实际项目中,为了避免一不小心就溢出的问题,我强烈建议,不管加减乘除,凡是参与运算的变量全部都要转化成unsigned long变量,转化的方法也跟加减运算的转换方法一致,不再详细讲解这方面的内容。
现在编写一个程序来练习刚才讲到的内容,最后把程序编译后下载到坚鸿51学习板观察结果。请直接复制第十节模板程序,修改的main程序代码如下:

void main() //主程序
{
/*---C语言学习区域的开始---------------------------------------------------------------------------*/
        
  unsigned char a;
  unsigned char b;
  unsigned char c;
  unsigned char d;
  unsigned char e;
  unsigned char f;
        unsigned char g=10;  //初始化为10
        unsigned char y=0; //除数变量初始化为0。
        a=23/y;
        b=23/0;
        c=7/10;
        d=10/10;
        e=10/4;
        f=10/3;
        g/=5;  //相当于g=g/5;
       
  GuiWdData0=a;   //把a这个变量放到窗口变量0里面显示
  GuiWdData1=b;   //把b这个变量放到窗口变量1里面显示
  GuiWdData2=c;   //把c这个变量放到窗口变量2里面显示
  GuiWdData3=d;   //把d这个变量放到窗口变量3里面显示
  GuiWdData4=e;   //把e这个变量放到窗口变量4里面显示
  GuiWdData5=f;   //把f这个变量放到窗口变量5里面显示
  GuiWdData6=g;   //把g这个变量放到窗口变量5里面显示
        
/*---C语言学习区域的结束---------------------------------------------------------------------------*/
   while(1)  
   {
                  initial();
      key_service();
      display_service();
   }

}

    查看运算结果的方法。如何在坚鸿51学习板上观察变量?按下S1或者S5按键即可切换显示不同的窗口,从而显示不同的变量。按下S9按键不松手就可以切换到十六进制的显示界面,松开手后会自动切换到十进制的界面。上坚鸿51学习板观察程序执行的结果如下:
     变量a为255(十六进制是0xff)。
     变量b为1。
     变量c为0。
     变量d为1。
    变量e为2。
    变量f为3。
    变量g为2。
     下节预告:整除求余的运算。
(未完待续)

使用特权

评论回复
发新帖 本帖赏金 10.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则