#IF expr
#ELSE本文引用地址:http://www.eepw.com.cn/article/201611/315395.htm
#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(lens[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进行验证