单片机c语言中if_单片机c语言if使用 - CSDN
  • 先说结论,if语句多加一对小括号即可。具体调试过程如下: 我用的编译器版本是MPLAB X IDE v4.15,单片机型号是PIC16F1938; 想用6位数码管实现时钟功能,结果写出来的代码,片选顺序有问题,而且时分秒累加及...

    先说结论,if语句中多加一对小括号即可。具体调试过程如下:

    我用的编译器版本是MPLAB X IDE v4.15,单片机型号是PIC16F1938;

    想用6位数码管实现时钟功能,结果写出来的代码,片选顺序有问题,而且时分秒累加及进位都有问题。

    拿单步跟踪了老半天,发现是if语句进不去。if语句如下:

     unsigned char Buffer[3] = {0};
     if(Buffer[0]&0x0F < 0x09){   
         Buffer[0]++;
     }
     else{
         Buffer[0] &= 0xF0;
     }

    我是左看右看,上看下看,还请同事帮我看,都没看出来什么问题。首先为了确认,我还特意复习了一下C语言运算符的优先级顺序 —— & 运算的优先级高于 < 运算。那实在没辙了,于是,在Disassembly窗口中(Debuging时,在Window—>Debuging选项中可以打开该窗口),看了一下这条if语句对应的汇编指令,如下图,

     

    可以看出来,if语句根本没有对应的汇编指令。 那就只能尝试了,于是我在 & 运算符两侧加上了括号,改正后的代码如下:

     unsigned char Buffer[3] = {0};
     if((Buffer[0]&0x0F) < 0x09){   
         Buffer[0]++;
     }
     else{
         Buffer[0] &= 0xF0;
     }

    再重新编译,奇迹般地,代码正常运行了!再看一下修改过后的if语句对应的汇编指令,如下图,

     

    可以 看出来,汇编指令也正常了。于是,误打误撞,if语句不执行的问题被一对括号解决了。

    那么问题来了,在if( (Buffer[0]&0x0F) < 0x09 ) {...}这条语句中,这对红色的小括号到底有什么用呢?

    这个时候,就体现出“师父”这种生物的重要性了。。。根据我师父所讲,在没有加这对红色的小括号之前,if语句最终会变成下边这样

    if( Buffer[0] < 0x09 ) {...}

    也就是说,没有括号的话 ,Buffer[0]&0x0F 这个 & 操作的结果就不会保存,最后就变成了Buffer[0] 里的数据与 0x09 作比较。

    若要再深入了解,可以查一下“C语言中小括号的作用”,或“C语言中左值与右值”。

    展开全文
  • 一,C语言中if语句的可注意点: if(flag_moshi==0) if(0==flag_moshi) if(flag_moshi=0) if(0=flag_moshi) 首先,毫无疑问的是 :这四个if语句,前三个均是正确的!第四个错在:赋值运算符“=”的作用是将...

    一,C语言中if语句的可注意点:
                    if(flag_moshi==0)

                    if(0==flag_moshi)
                    if(flag_moshi=0)
                    if(0=flag_moshi)
       首先,毫无疑问的是 :这四个if语句中,前三个均是正确的!第四个错在:赋值运算符“=”的作用是将右侧的常量或表达式计算所得的值赋给左边的变量;

      对于第一个和第二个if语句中:if语句的使用均是正确的,相比较而言,更优先选用第二种,因为由于数学符号的思维定势;我们普遍的会将数学符号的等于”=“与C语言中的赋值”=“相混淆,而我们进行判断是否相等时,第一种方法误写成
    if(flag_moshi=0)时,编译环境是不会报错的,但是如果误写成 if(0=flag_moshi)时,编译环境是会报错的,再优秀的编程高手都有可能犯错,所以,我们可以利用这一点,尽量推荐使用if(0==flag_moshi),由于赋值语句只有一种合法的格式,故使用
     if(flag_moshi=0)
    二:DS1302驱动的修改:

    第一种修改:
    #ifndef __DS1302_H
    #define __DS1302_H

    /*
      程序说明: DS1302驱动程序
      软件环境: Keil uVision 4.10
      硬件环境: CT107单片机综合实训平台 8051,12MHz
      日    期: 2011-8-9
    */
    #include <intrins.h>
    sbit SCK=P1^7;  
    sbit SDA=P2^3;  
    sbit RST = P1^3;   // DS1302复位   

    void Write_Ds1302_Byte(unsigned  char temp);
    void Write_Ds1302( unsigned char address,unsigned char dat );
    unsigned char Read_Ds1302 ( unsigned char address );
    void ds1302init();
    void ds1302get();
    u8 str[]={59,50,11,07,05,01,18};
    u8 shijian[7];
    void Write_Ds1302_Byte(unsigned  char temp)
    {
     unsigned char i;
     for (i=0;i<8;i++)      
     {
      SCK=0;
      SDA=temp&0x01;
      temp>>=1;
      SCK=1;
     }
    }  
    void Write_Ds1302( unsigned char address,unsigned char dat )    
    {
      RST=0;
     _nop_();
      SCK=0;
     _nop_();
      RST=1; 
        _nop_(); 
      Write_Ds1302_Byte(address); 
      Write_Ds1302_Byte(dat/10<<4|(dat%10));            //十进制转BCD码
      RST=0;
    }
    unsigned char Read_Ds1302 ( unsigned char address )
    {
      unsigned char i,temp=0x00,dat1,dat2;
      RST=0;
     _nop_();
      SCK=0;
     _nop_();
      RST=1;
     _nop_();
      Write_Ds1302_Byte(address);
      for (i=0;i<8;i++)  
      {  
      SCK=0;
      temp>>=1; 
       if(SDA)
       temp|=0x80; 
       SCK=1;
     }
      RST=0;
     _nop_();
      RST=0;
     SCK=0;
     _nop_();
     SCK=1;
     _nop_();
     SDA=0;
     _nop_();
     SDA=1;
     _nop_();
     dat1=temp/16;                        //取十位
     dat2=temp%16;                      //取个位
     temp=dat1*10+dat2;             //BCD码转十进制
     
     return (temp);   
    }
    void ds1302init()
    {
     u8 i,adr;
     adr=0X80;
     Write_Ds1302(0X8E,0X00);
     for(i=0;i<7;i++)
     {
      Write_Ds1302(adr,str[i]);
      adr=adr+2;
     }
     Write_Ds1302(0X8E,0X80);
    }
    void ds1302get()
    {
     u8 i,adr;
     adr=0X81;
     for(i=0;i<7;i++)
     {
        shijian[i]=Read_Ds1302 (adr);
      adr=adr+2;
     }
    }

    #endif
    此种方法使用BCD码转十进制,以及十进制转BCD码,修改驱动程序较为繁琐,多了四行的修改。,但是,其意更大:相比较当您使用计数时,比如19,在往上加的话就是20,但如果利用的十六进制时,便是1A;这不利于数码管的显示!尤其在写真题的时候,毕竟十进制我们一直使用,更为亲近一些,方便使用一些吧!

    第二种修改:
    #ifndef __DS1302_H
    #define __DS1302_H

    /*
      程序说明: DS1302驱动程序
      软件环境: Keil uVision 4.10
      硬件环境: CT107单片机综合实训平台 8051,12MHz
      日    期: 2011-8-9
    */
    #include <intrins.h>
    sbit SCK=P1^7;  
    sbit SDA=P2^3;  
    sbit RST = P1^3;   // DS1302复位
    u8 str[]={0X50,0X59,0X23,0X27,0X04,0X05,0X18};
    u8 shijian[7];
    void Write_Ds1302_Byte(unsigned  char temp);
    void Write_Ds1302( unsigned char address,unsigned char dat );
    unsigned char Read_Ds1302 ( unsigned char address );
    void ds1302init();
    void ds1302get();
    void Write_Ds1302_Byte(unsigned  char temp)
    {
     unsigned char i;
     for (i=0;i<8;i++)      
     {
      SCK=0;
      SDA=temp&0x01;
      temp>>=1;
      SCK=1;
     }
    }  
    void Write_Ds1302( unsigned char address,unsigned char dat )    
    {
      RST=0;
     _nop_();
      SCK=0;
     _nop_();
      RST=1; 
        _nop_(); 
      Write_Ds1302_Byte(address); 
      Write_Ds1302_Byte(dat);  
      RST=0;
    }
    unsigned char Read_Ds1302 ( unsigned char address )
    {
      unsigned char i,temp=0x00;
      RST=0;
     _nop_();
      SCK=0;
     _nop_();
      RST=1;
     _nop_();
      Write_Ds1302_Byte(address);
      for (i=0;i<8;i++)  
      {  
      SCK=0;
      temp>>=1; 
       if(SDA)
       temp|=0x80; 
       SCK=1;
     }
      RST=0;
     _nop_();
      RST=0;
     SCK=0;
     _nop_();
     SCK=1;
     _nop_();
     SDA=0;
     _nop_();
     SDA=1;
     _nop_();
     return (temp);   
    }
    void ds1302init()
    {
     u8 i,adr;
     adr=0X80;
     Write_Ds1302(0X8E,0X00);
     for(i=0;i<7;i++)
     {
       Write_Ds1302(adr,str[i]);
        adr=adr+2;   
     }
     Write_Ds1302(0X8E,0X80);
    }
    void ds1302get()
    {
     u8 i,adr;
     adr=0X81;
     for(i=0;i<7;i++)
     {
        shijian[i]=Read_Ds1302 (adr);
        adr=adr+2;   
     }
    }
    #endif


    展开全文
  • 单片机C语言 if与#if

    千次阅读 2016-03-05 21:41:51
    #ifif都是C和C++的指令,但是二者区别很大。 1)#if属于条件编译技术,用于给编译器提供信息,控制有些代码变成机器语言; 2)if属于程序判断,在程序运行时控制语句是否被执行; 3)#if在程序编译前执行,if...
    #if和if都是C和C++中的指令,但是二者区别很大。
    1)#if属于条件编译技术,用于给编译器提供信息,控制有些代码变成机器语言;
    2)if属于程序判断,在程序运行时控制语句是否被执行;
    3)#if在程序编译前执行,if在程序运行时执行;
    4)#if后面不能写变量,if后面可以写变量。
    展开全文
  • 单片机C语言中while(1)的问题

    千次阅读 2018-07-26 16:23:48
    单片机C语言中while(1)的问题   单片机C语言的主程序,通常要用一个while(1)语句来让程序进入一个无限循环,目的是为了让程序一直保持在我们需要运行的情况下。  虽然这种做法毋庸置疑,在网上还是有不少朋友...

    单片机C语言中while(1)的问题

     

    单片机C语言的主程序,通常要用一个while(1)语句来让程序进入一个无限循环,目的是为了让程序一直保持在我们需要运行的情况下。
      虽然这种做法毋庸置疑,在网上还是有不少朋友有疑问,如果程序不加while(1)会出现什么情况,对于这种好学精神,还是值得赞扬的,做学问就需要有追根问底的精神。
      首先,大家要理解一件事情,我们编写的C语言程序,最终下载到单片机当中去,在我们单片机的程序存储空间FLASH当中存储的全部是2进制数字代码。比如0x00,0x01,一直到0xff。而我们编写的C代码,依靠的是编译软件,比如keil软件,首先将C语言编译成为汇编语言,最终汇编语言变成2进制代码,也就是我们的HEX文件当中的数据,下载到单片机当中去。
      因此,查找这个问题,首先从源头来找,首先是C语言,然后,我们再看一下软件给我们编译的汇编语言是什么样子。用KEIL软件编写一个程序,然后simulator的方式进行仿真,进入仿真环境后,在View窗口下有个Disassembly window,打开,里边就会出现刚才我们的C语言所对应的汇编语言了(KEIL软件会自动将C编译成汇编),找到里边的主函数,找到你最后一行的程序所对应的汇编,找到后,会发现在最后一行程序结束后,KEIL这个软件还会自动给加入几行汇编代码这几行代码就是(1)MOV R0, #0x7F;(2)CLR A; (3)MOV @R0, A; (4) DJNZ R0, (3); (5)MOV SP, #0x0C;(6) LJMP main;这几条语句,前4条,是将我们单片机的内存的前128个地址清零,第5条,是定义堆栈,第6条,是将程序重新跳转到main函数的首行进行执行。
      从这里我们可以看出,最终下载到单片机运行的程序包含两部分,一部分是我们编写的程序代码,另外一部分是编译器自动生成的代码,因此,用KEIL软件编写的程序在没有while(1)的情况下运行到最后一行,会自动跳转到main函数第一行运行。
      本着严谨的态度,笔者又查找PIC单片机的编译开发环境MAPLAB IDE,找到其中的汇编程序,在Disassembly window汇编程序中没有发现跳转到主函数的语句或者是复位语句。笔者不甘心,于是继续查找,打开了Promgram Memory,这也是最终下载到单片机当中的程序,通过仔细查看笔者在其后边,发现了在main函数的最后,有一条“reset”语句,这是一条PIC单片机的复位语句,也就是说PIC单片机在进行程序编译的过程中,如果没有while(1)语句,最后则会直接执行复位,这MAPLAB隐藏的可够深的。
      我在论坛上看到一个发帖者提出他下载进AVR单片机的没有while(1)的程序,但是单片机却没有复位,这点我没有再去验证,因为我们的程序通常都是要加while(1)这个循环,因此呢,问题到了这里,单片机程序没有while(1)会出现什么情况,这一点已经不重要了。但是有一点已经可以确认了,一部分单片机在没有while(1)的情况下,运行到最后一行出现的情况受到编译开发环境的影响。
      当然了,一个严谨的开发环境,就应该像KEIL和MAPLAB这样,在程序员编译程序可能出现漏洞的地方给与防护,避免程序跑飞程序员无法查找程序问题。

     

    深有体会。刚学单片机不久,参考别人的程序写了LCD驱动,在买来的实验板上运行时,显示正常。在自己用面包板上搭建的系统运行时,只能显示几秒钟,之后一片空白,当时怀疑面包板供电不稳定,或者信号线干扰,折腾几小时后,在程序末尾加一句“while(1);”,显示完全正常。

     

    不加不稳定,有时候会在main()里面循环,有时候会乱码。

     

     

    这里的while(1)并不是防止程序“跑飞”的,而是防止main()返回。
    ①    在嵌入式中main是不能返回的。不同的C语言实现的单片机初始化代码会有不同的表现,有的是在call _main后jmp,而有的是jmp  0,等等这些会导致不可预料的结果。
    ②    在我们写的C语言后转换成汇编,再观察单片机的代码区,你会发现没有写程序的部分例如全1或者全0区域,程序运行到这里,就会有可能造成意料不到的结果。若无while(1)循环,程序全部执行后,跳转至程序起始处重新执行。
    
    展开全文
  • 单片机C语言中加入NOP指令

    千次阅读 2009-03-02 15:25:00
    单片机C语言中加入NOP指令标准的C语言没有空语句。但在单片机的C语言编程,经常需要用几个空指令产生短延时的效果。这在汇编语言很容易实现,写几个nop就行了。在AVR-GCC,我用如下方法嵌入汇编指令:asm ...
  • 51单片机C语言程序100例

    万次阅读 多人点赞 2018-04-13 13:08:30
    目录目录................................................................................................................................1函数的使用和熟悉********************************/.................
  • [quote] 本源程序是每一个MCS-51系列单片机C语言程序的必备内容,包括程序开始处的说明信息、头文件、SFR定义、子函数、主函数和C语言常用的5大语句(if,while,do while,for,switch)模板。可将其模板下载到本地硬盘...
  • 单片机C语言编程,所有心得都在这里了...

    万次阅读 多人点赞 2018-03-31 10:50:01
    这个8*8按键程序的过程,不管是在自己写还是参考别人程序的过程,发现自己对C语言有些基本知识点和编程规范有很多不懂的地方,有些是自己以前的编程习惯不好,有些就是基础知识不扎实的表现,所以总结出来。...
  • 单片机C语言代码优化

    2016-08-14 17:06:32
     能够使用条件编译(ifdef)的地方就使用条件编译而不使用if 语句,有利于减少编译生成的代码的长度。   2.如果果需要缩短代码的长度,可以将程序一些公共的程序段定义为函数,在Keil 的高级别优化就是这样的...
  • 单片机c语言应用100例

    2020-07-30 23:32:14
    第4章单片机C语言开发基础 4.1C语言源程序的结构特点 4.2标志符与关键字 4.3C语言的数据类型与运算符 4.3.1数据类型 4.3.2运算符 4.3.3实例8:用不同数据类型的数据控制1ED的闪烁 4.3.4实例9:用P0口、P1口分别显示...
  • 在整理代码的过程经常能看到#if的用法: if (opt_.mode!=PMODE_SINGLE) { /* for precise positioning */ #if 0 opt_.sateph =EPHOPT_BRDC; #endif opt_.ionoopt=IONOOPT_BRDC; opt_.tropopt=TROPOPT_SAAS; ...
  • 单片机C语言编程心得

    2018-08-24 09:22:35
    写这个8*8按键程序的过程,不管是在自己写还是参考别人程序的过程,发现自己对C语言有些基本知识点和编程规范有很多不懂的地方,有些是自己以前的编程习惯不好,有些就是基础知识不扎实的表现,所以总结出来。...
  • 单片机C语言实现数码管控制

    万次阅读 2017-06-13 10:20:20
    本文分析了数码管的工作原理,并尝试用C51单片机去控制数码管的显示。希望更加深入理解单片机的内部工作原理和C语言的特性。
  • C语言 if语句详解

    千次阅读 2014-12-04 19:05:30
    C语言if语句有三种基本形式。 语句的三种形式 1) 第一种形式为基本形式:if  if(表达式) 语句 其语义是:如果表达式的值为真,则执行其后的语句,否则不执行该语句。其过程可表示为下图。 【例5-3】 ...
  • 该文档是松翰官网上基于C语言的SN8单片机程序设计指导说明手册,从SN8 C程序结构、Real Time的C程序、SN8 C的Bit操作 、Debugger使用操作几方面做详细介绍
  • // IO初始化 pa口8个口输出低电平 _papu=0;//上拉失能 _pac=0;//方向寄存器0:输出;1:输入 _pa=0;
  • 本系列文章讲述了基于proteus仿真的51单片机学习,内容全面,不仅讲解电路原理,还讲解了单片机c语言,实例丰富,内容全面。
  • 一、程序风格: 1、严格采用阶梯层次组织程序代码: ... 在程序需要给出的提示字符串,为了支持多种语言的开发,除了一些给调试用的临时信息外,其他所有的提示信息必须定义在资源。 3、对变
  • 今天我们要说的不是stm32是关于单片机开发所应用到的C语言基础的,如果文字看不下去可以看文章尾部视频,主要是在要写这一篇文章开始我也是头疼的,原因就是有点长,当然也有借鉴的地方!!嘿嘿  C是单片机开发的...
  • 32单片机C语言相关知识以及寄存器地址名称映射分析
1 2 3 4 5 ... 20
收藏数 7,506
精华内容 3,002
关键字:

单片机c语言中if