×
单片机 > 单片机程序设计 > 详情

PIC单片机CCS之C语言(#IF,#ENDIF的用法)

发布时间:2020-06-08 发布时间:
|
 #IF expr

#ELSE

#ELIF

#ENDIF

语法: #if expr

code

#elif expr

code

#else

code

#endif

expr是一个常数表达式,标准算子或预处理器标识符;

Code是任意的标准C源程序.

目的: 预处理器求出常数表达式的值,如果这个值是非0值,就处理可选项#ELSE或#ENDIF的上面的所有行.

注意:你不可在#IF里使用C变量,只有预处理器通过#define创造的才可使用.

若id被定义了,则预处理器表达式DEFINED(id)可用来返回1,若没有定义id,则DEFINED(id)返回的值为0.

例子:#if MAX_VALUE>255

long value;     //若MAX_VALUE>255,则将value定义为长整型变量

#else

int value;      //若MAX_VALUE不大于255, 则将value定义为整型变量

#endif

例子文件:ex_extee.c

文件: ex_extee.c如下:

#if defined(__PCB__)  //若使用了PCB编译器,则defined( __PCB__)返回值为1

#include <16c56.h>    //包含16c56.h头文件

#fuses HS, NOWDT, NOPROTECT  //HS:高速晶振/谐振器, NOWDT:不使用WDT

                               // NOPROTECT:程序存储器代码不保护

#use delay(clock=20000000)        //使能内置函数的功能:delay_ms()和delay_us()

                               //#USE DELAY()必须在#use rs232()使用之前出现.

#use rs232(baud=9600, xmit=PIN_A3, rcv=PIN_A2)

//使用波特率为9600,

//发送脚为PIN_A3

//接收脚为PIN_A2

//使能内置函数:GETC,PUTC和PRINTF, kbhit();

#elif defined(__PCM__)

#include <16F877.h>

#fuses HS,NOWDT,NOPROTECT,NOLVP

#use delay(clock=20000000)

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)  // Jumpers: 8 to 11, 7 to 12

#elif defined(__PCH__)

#include <18F452.h>

#fuses HS,NOWDT,NOPROTECT,NOLVP

#use delay(clock=20000000)

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)  // Jumpers: 8 to 11, 7 to 12

#endif    //结束if定义

#include   //包含input.c头文件

#include <2416.c>  //包含2416.c头文件

void main() {

   BYTE value, cmd;  //声明字节型变量value,  cmd

   EEPROM_ADDRESS address;  //用EEPROM_ADDRESS代替long int,为16位

   init_ext_eeprom();  //初始化连接到eeprom的I/O脚

   do {

      do {

         printf("\r\nRead or Write: ");

         cmd=getc();  //从RS232口读一个字节

         cmd=toupper(cmd);  //将cmd中的小写字母转换成大写字母送给cmd

         putc(cmd);

      } while ( (cmd!='R') && (cmd!='W') );  //直到输入R或W为止

printf("\n\rLocation: ");

 

#if sizeof(EEPROM_ADDRESS)==1 

//若定义EEPROM_ADDRESS是1个字节,则sizeof(EEPROM_ADDRESS)==1返回1

      address = gethex();

#else  //若定义EEPROM_ADDRESS是大于1个字节

#if EEPROM_SIZE>0xfff

      address = gethex();

#else  // EEPROM_SIZE小于0xfff

      address = gethex1();   //从RS232口读一个字节,为eeprom存储高字节地址

#endif    //结束if定义

      address = (address<<8)+gethex(); //从RS232口读2个字节,为eeprom存储低字节地址

#endif    //结束if定义

      if(cmd=='R')  //若输入R,则执行下面

         printf("\r\nValue: %X\r\n",READ_EXT_EEPROM( address ) );

      if(cmd=='W') {

         printf("\r\nNew value: ");

         value = gethex();  //从RS232输入,为写入eeprom的值做准备

         printf("\n\r");

         WRITE_EXT_EEPROM( address, value );

      }

   } while (TRUE);

}

 

 

文件: input.c如下:

#include    //包含CTYPE.H头文件

BYTE gethex1() {

   char digit;  //声明字节型变量digit

   digit = getc();  //从RS232口读一个字节

   putc(digit);    //向RS232口写一个字节

   if(digit<='9')   //将读到的字节以16进制返回

     return(digit-'0');  //若读到的ascii码小于或等于39,则将其减30,以16进制返回

   else

     return((toupper(digit)-'A')+10); //若读到的ascii码大于39,则将其减41,再加10返回

}

 

BYTE gethex() {

   int lo, hi;  //声明整型变量lo, hi

   hi = gethex1();  //从RS232口读一个字节,存储到hi中

   lo = gethex1();  //从RS232口读一个字节,存储到lo中

   if(lo==0xdd)

     return(hi);

   else

     return( hi*16+lo );

}

 

void get_string(char* s, int max) {

   int len;   //声明整型变量len

   char c;   //声明字节型变量c

   --max;   //初始化max值

   len=0;   //初始化len值

   do {

     c=getc();   //从RS232口读一个字节,存储到c中

     if(c==8) {  // Backspace若是空格键

        if(len>0) {

          len--;

          putc(c);  //向RS232写c

          putc(' ');

          putc(c);

        }

     } else if ((c>=' ')&&(c<='~'))

       if(len

         s[len++]=c;

         putc(c);

       }

   } while(c!=13);

   s[len]=0;

}

 

// stdlib.h is required for the ato_ conversions

// in the following functions

#ifdef  _STDLIB   //若定义_STDLIB,则执行下面

signed int get_int() {

  char s[5];   //声明字符型数组s[5]

  signed int i;  //声明有符号整型变量i

  get_string(s, 5);  //从RS232口读5个字节,存储到s数组中

  i=atoi(s);  //将数组s[]的字符串转换成整型数送给i

  return(i);

}

 

signed long get_long() {

  char s[7];     //声明字符型数组s[7]

  signed long l;  //声明有符号长整型变量l

  get_string(s, 7); //从RS232口读7个字节,存储到s数组中

  l=atol(s);  //将数组s[]的字符串转换成长整型数送给l

  return(l);

}

 

float get_float() {

  char s[20];     //声明字符型数组s[7]

  float f;        //声明符点型变量l

  get_string(s, 20); //从RS232口读20个字节,存储到s数组中

  f = atof(s);  //将数组s[]的字符串转换成符点数送给f

  return(f);

}

#endif    //结束if定义

 

文件: 2416.c如下:

////   Library for a MicroChip 24LC16B                         ////

////   init_ext_eeprom();    Call before the other functions are used   ////

////   write_ext_eeprom(a, d);  Write the byte d to the address a      ////

////   d = read_ext_eeprom(a);  Read the byte d from the address a    ////

////   b = ext_eeprom_ready();  Returns TRUE if the eeprom is ready  ////

////                            to receive opcodes              ////

////   The main program may define EEPROM_SDA                ////

////   and EEPROM_SCL to override the defaults below.             ////

////                            Pin Layout                    ////

////   -----------------------------------------------------------               ////

////   |                                                        |   ////

////   | 1: NC   Not Connected   | 8: VCC   +5V                   |   ////

////   | 2: NC   Not Connected   | 7: WP    GND                   |  ////

////   | 3: NC   Not Connected   | 6: SCL   EEPROM_SCL and Pull-Up |   ////

////   | 4: VSS  GND           | 5: SDA   EEPROM_SDA and Pull-Up |  ////

////   -----------------------------------------------------------     ////

#ifndef EEPROM_SDA  //若没有定义EEPROM_SDA,则执行下面

#define EEPROM_SDA  PIN_C4   //用EEPROM_SDA代替PIN_C4

#define EEPROM_SCL  PIN_C3   //用EEPROM_SCL代替PIN_C3

#endif    //结束if定义

#use i2c(master, sda=EEPROM_SDA, scl=EEPROM_SCL)

     // master设置成主机方式

     //除非指定了FORCE_HW,否则会产生模拟I2C的软件函数.

//使能I2C_START,  I2C_STOP直到下一个#USE  I2C的出现为止.

//使能I2C_READ,  I2C_WRITE直到下一个#USE  I2C的出现为止.

//使能I2C_POLL直到下一个#USE  I2C的出现为止.

     //指定sda脚为EEPROM_SDA, 指定scl脚为EEPROM_SCL

#define EEPROM_ADDRESS  long int   //用EEPROM_ADDRESS代替long int

#define EEPROM_SIZE    2048        //用EEPROM_SIZE代替2048

void init_ext_eeprom() {

   output_float(EEPROM_SCL);  //将EEPROM_SCL引脚设为输入,开集电极连接

   output_float(EEPROM_SDA);  //将EEPROM_SDA引脚设为输入,开集电极连接

}

 

BOOLEAN ext_eeprom_ready() {

   int1 ack;             //声明位变量ack

   i2c_start();           //发送启动条件

   ack = i2c_write(0xa0);  //发送从机地址0xa0;若ack=0,表示从机应答(ACK);

//若ack=1,表示从机不应答(NO ACK);

   i2c_stop();           //发送停止条件

   return !ack;

} // ext_eeprom_ready()函数,若返回1,表示从机准备好; 若返回0,表示从机忙或eeprom坏了

 

void write_ext_eeprom(long int address, BYTE data) {

   while(!ext_eeprom_ready());  //若从机忙,则主机等待

   i2c_start();   //发送启动条件

   i2c_write( (0xa0|(BYTE)(address>>7))&0xfe);  //发送命令字的高字节(发送写命令)

   i2c_write(address);  //发送命令字的低字节

   i2c_write(data);     //发送数据

   i2c_stop();         //发送停止条件

}

 

BYTE read_ext_eeprom(long int address) {

   BYTE data;               //声明字节变量data

   while(!ext_eeprom_ready());  //先发器件地址,若从机忙,则主机等待

   i2c_start();   //在此处是:发送重新启动条件

   i2c_write( (0xa0|(BYTE)(address>>7))&0xfe);  //发送命令字的高字节(发送写命令)

   i2c_write(address);  //发送命令字的低字节

   i2c_start();   //发送启动条件

   i2c_write( (0xa0|(BYTE)(address>>7))|1);  //发送命令字的高字节(发送读命令)

   data=i2c_read(0);  //读I2C数据,然后发送ack=0(不用从机应答)

   i2c_stop();        //发送停止条件

   return(data);      //返回所读到的I2C数据

}

上面的例子主要用来读写24C16,通过PC机RS232进行验证




『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
STM32中断向量表的位置.重定向