PIC單片機CCS之C語言(#IF,#ENDIF的用法)

2020-12-15 電子產品世界
#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(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進行驗證

相關焦點

  • PIC單片機CCS之C語言(#BIT的用法)
    BIT語法: #bit id=x.y本文引用地址:http://www.eepw.com.cn/article/201611/315392.htmid是一個有效的C標識符;x是一個常數或是一個C變量;y是一個常數(為0~7)目的:創建一個新的C變量(是一位),放置在存儲區中,對應的是字節x中y位,有益於在C語言中只接存取
  • PIC單片機C語言程序設計(5)
    在《電子製作》2009年第10期,《PIC單片機C語言程序(1)》的延時函數中,我們已用過後綴運算符i++,大家可以從中體會其用法。  (2)邏輯運算符。  邏輯運算符是基本運算符中的一種。邏輯運算符有:與「&&」、或「||" 、非「!」等3三種。  邏輯運算符&&、||為雙目(兩個量)運算符,!為單目運算符。
  • PIC單片機C語言程序實例
    編者按:為了幫助具有PIC單片機彙編語言知識的技術人員或工程師,快速掌握利用C語言編寫PIC單片機程序的方法,本刊特推出《PIC單片機C語言程序設計》系列連載文章。丈中給出的C語言程序實例,均是可執行的,讀者可以放心引用。      一、彙編語言與C語言      早期的單片機程序多採用彙編語言編寫。
  • 單片機教程:PIC單片機C語言程序設計(五)
    接前文:單片機教程:PIC單片機C語言程序設計(四)   九、C語言的運算符   C語言提供了30多個運算符,範圍很大,應用廣。  在《PIC單片機C語言程序(一)》的延時函數中,我們已用過後綴運算符i++,大家可以從中體會其用法。  (2)邏輯運算符。  邏輯運算符是基本運算符中的一種。邏輯運算符有:與「&&」、或「||「 、非「!」等3三種。  邏輯運算符&&、||為雙目(兩個量)運算符,!為單目運算符。
  • PIC單片機C語言程序設計(4)
    2.if語句  if 語句也稱為條件語句,是C 語言中轉移語句之一。在設計C 語言程序時,常常要根據某些條件以決定程序運行的流向,這時就需要if 語句來實現。
  • PIC單片機CCS之C語言(#USE FAST_IO的用法)
    例子:#use fast_io(A)例子文件:ex_cust.c;該文件在前面已經敘述過了
  • PIC單片機asm與C混合編程
    一、如何從彙編轉向PICC首先要求你要有C 語言的基礎。C代碼的頭文件一定要有#include,它是很多頭文件的集合,C 編譯器在pic.h 中根據你的晶片自動載入相應的其它頭文件。這點比彙編好用。載入的頭文件中其實是聲明晶片的寄存器和一些函數。
  • 單片機的C語言中數組的用法
    數組在C51語言的地位舉足輕重,因此深入地了解數組是很有必要的。下面就對數組進行詳細的介紹。(1)一維數組本文引用地址:http://www.eepw.com.cn/article/201611/320327.htm一維數組是最簡單的數組,用來存放類型相同的數據。數據的存放是線性連續的。
  • PIC單片機C語言程序設計(2)
    一個完整的PIC單片機C語言程序,通常由包含文件(即頭文件1,變量定義、變量說明、函數定義、函數體和注釋等六部分等組成。  1.C語言的標識符  所謂標識符,實際上是一些由程序編寫者自定義的名稱,類似於PIC單片機彙編語言中給寄存器(RAM)的命名。
  • PIC單片機CCS之C語言(#USE FIXED_IO的用法)
  • 如何寫出高效優美的單片機C語言代碼?
    (2)、平方運算a=pow(a,2.0);可以改為:a=a*a;說明:在有內置硬體乘法器的單片機中(如51系列),乘法運算比求平方運算快得多,因為浮點數的求平方是通過調用子程序來實現的,在自帶硬體乘法器 的AVR單片機中,如ATMega163中,乘法運算只需2個時鐘周期就可以完成
  • PIC單片機之步進電機
    PIC 單片機的RD0~RD3 為電機脈衝輸出引腳,通過ULN2003 集成晶片來驅動小型步進電機,我們只要將步進電機的插頭,直接插在板子J3 插座處即可。對於單片機軟體的編程,我們使用MPLab IDE軟體來進行C 語言編程,它是我們的編程環境,同時我們可以通過使用ICD2 仿真燒寫器和增強型PIC實驗板連接進行程序的仿真調試和燒寫步驟,具體的操作步驟,我們已經在前幾期做了詳細的說明和介紹
  • 單片機C語言編程心得
    寫這個8*8按鍵程序的過程中,不管是在自己寫還是參考別人程序的過程中,發現自己對C語言有些基本知識點和編程規範有很多不懂的地方,有些是自己以前的編程習慣不好,有些就是基礎知識不紮實的表現,所以總結出來。
  • STM32中C語言知識點:初學者必看,老鳥複習(長文總結)
    C語言書籍,因為C語言基礎比較差,想把C語言重新學一遍,再去學單片機,我以前剛學單片機的時候也有這樣子的想法。其實C語言是可以邊學單片機邊學的,學單片機的一些例程中,遇到不懂的C語言知識,再去查相關的知識點,這樣印象才會深刻些。下面就列出了一些STM32中重要的C語言知識點,初學的小夥伴可以多讀幾遍,其中大多知識點之前都有寫過,這裡重新整理一下,更詳細地分析解釋可以閱讀附帶的連結。
  • 51,AVR,PIC,MSP430,STM32單片機比較
    PIC:我就是學這款單片機入門的,pic的好處就是各個型號的兼容性強,學好了PIC16f877a,16系列的就OK了,別的型號要用的時候拿出2分鐘看看數據手冊就行了。12系列 16系列 18系列也是充分的向下兼容。
  • PIC單片機之I2C總線
    大家好,通過前一期的學習,我們已經對ICD2 仿真燒寫器和增強型PIC 實驗板的使用方法及學習方式有所了解與熟悉,學會了如何用單片機來控制發光管、繼電器、蜂鳴器、按鍵、數碼管、RS232 串口、步進電機、溫度傳感器等資源,體會到了學習板的易用性與易學性,看了前幾期實例,當你實驗成功後一定很興奮,很有成就感吧!
  • PIC單片機 C編程技巧
    (以MPLAB5.7版本為例子)啟動MPLAB.在Project-->Install Language Tool:Language Suite>hi-tech piccTool Name ---->PICC CompilerExecutable ---->c:hi-picinpicc.exe (假如你的PICC是默認安裝的)選Command-line
  • 長文 | 花了兩天時間整理了STM32中的一些C語言知識點,初學者福利!老鳥複習
    說在前面的話 一位初學單片機的小夥伴讓我推薦C語言書籍,因為C語言基礎比較差,想把C語言重新學一遍,再去學單片機,我以前剛學單片機的時候也有這樣子的想法。其實C語言是可以邊學單片機邊學的,學單片機的一些例程中,遇到不懂的C語言知識,再去查相關的知識點,這樣印象才會深刻些。
  • 通俗易懂講PIC單片機:從一竅不通到入門進步
    單片機入門不難-談PIC系列(轉自礦石收音機論壇---嶗山)十年前的老帖子,講得通俗易懂,分享之。本文引用地址:http://www.eepw.com.cn/article/201803/376687.htm  請看圖1
  • 【愛找茬】都是C語言,單片機C語言和普通的C語言究竟有什麼差異呢?
    許多小夥伴在學完C語言後想入門單片機,但學著學著發現明明都是C語言,為什麼單片機C語言和我當初學的C語言有差異呢?今天小編就來梳理我們平時所學的C語言與單片機C語言的有什麼樣的不同。