语法: #byte id=x
id是一个有效的C标识符;
x是一个常数或是一个C变量;
目的:如果id是一个已知C的变量,那么它将定位在地址x处,在这种情况下,变量类型的最初定义不会被改变.若id不是已知的C变量,则利用#byte id=x就可创建一个新的C变量,且放在地址x处,类型为整型(8位).
主意:在两个不同的存储区里,x不是唯一对应这个变量(id)的地址.其它变量可能和它拥有相同的地址.实际上,当x是一个变量时,那么id和x就共享有相同的地址存储单元.
例子:
#byte status=3 //定义status的地址为3
#byte b_port=6 //定义b_port的地址为6
struct{
short int r_w; //定义位变量
short int c_d; //定义位变量
int unused :2; //保留两位
int data :4; //保留4位
}a_port //将a_port定义为结构变量, r_w对应a_port.0, c_d对应a_port.1
#byte a_port=5 //定义a_port的地址为5,即端口RA口
…
a_port.c_d=1;
例子文件: ex_glint.c
#DEFINE
语法: #define id text
or
#define id(x,y…) text
id是一个预处理器标识符;text是任意字符文字;x,y等是被定位于预处理器中的标识符,在这中形式下,有一个或更多的标识符被逗号隔开.
目的:利用简单的字符来规定代替id,这个所给的字符来自于程序指针.
在第二种形式下,原来的标识符要同text中的那个简单的标识符相匹配,用text代替原来的标识符;
如果text包含#idx形式的字符,那么赋值后的结果是参数id和字符x连接;
如果text包含idx##idy形式的字符,那么参数idx就和参数idy连接形成一个新的标识符;
例子: #define BITS 8 //用BITS代替8
a=a+BITS; //相当于a=a+8
#define hi(x) (x<<4) //将(x<<4) 用hi(x) 代替
a=hi(a); //相当于a=(a<<4)
例子文件:ex_stwt.c, ex_macro.c
文件:ex_stwt.c如下:
#if defined(__PCM__) //若使用了PCM编译器,则defined(__PCM__)返回值为1
#include <16F877.h> //包含16F877.h头文件
#fuses HS, NOWDT, NOPROTECT, NOLVP //HS:高速晶振/谐振器, NOWDT:不使用WDT
// NOPROTECT:程序存储器代码不保护
#use delay(clock=20000000) //使能内置函数的功能:delay_ms()和delay_us()
//#USE DELAY()必须在#use rs232()使用之前出现.
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) //使用波特率为9600,
//发送脚为PIN_C6
//接收脚为PIN_C7
//使能内置函数:GETC,PUTC和PRINTF;
#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
#define INTS_PER_SECOND 76 // (20000000/(4*256*256)) 用INTS_PER_SECOND代替76
BYTE seconds; //秒计数器,1秒=(4/20000000)*256*256* INTS_PER_SECOND
BYTE int_count; // 在1秒未到之前,还要经过多少次中断,才够1秒;
#int_rtcc //Timer0(RTCC)溢出, 指定下面的函数是一个中断服务函数
void clock_isr() { // the RTCC (timer0) overflows (255->0),For this program this is apx 76 times
if(--int_count==0) { // per second.
++seconds; //1秒到, seconds加1;
int_count=INTS_PER_SECOND; ////给int_count赋初值
}
}
void main() {
BYTE start;
int_count=INTS_PER_SECOND; //给int_count赋初值
set_timer0(0); //设定实时时钟/计数器的计数初值
setup_counters( RTCC_INTERNAL, RTCC_DIV_256 | RTCC_8_BIT);
//设置Timer0的时钟源为内部时钟源
//每隔256个脉冲,TMR0计数1次
//在PIC18XXXX中,RTCC_8_BIT设置Timer0为8位定时器方式;
enable_interrupts(INT_RTCC); //允许Timer0(RTCC)溢出,建立中断标志位
enable_interrupts(GLOBAL); //使能总中断
do {
printf("Press any key to begin.\n\r");
getc(); //从RS232口读入1个字符
start=seconds;
printf("Press any key to stop.\n\r");
getc(); //从RS232口读入1个字符
printf("%u seconds.\n\r",seconds-start);
} while (TRUE);
}
上面的文件是利用Timer0采用内部指令周期作为时钟源,再256分频,构成1秒发生齐器.
文件: ex_macro.c如下:
#define BUFFERSIZE 10 //用BUFFERSIZE代替10
#define BUFFER_EMPTY (next_in==next_out)
//用BUFFER_EMPTY代替表达式(next_in==next_out)
#define min(x,y) ((x #define max(x,y) ((x>y)?x:y) //用max(x,y)代替表达式((x>y)?x:y) ,若x>y,则返回x #define forever while(1); //用forever代替表达式while(1) #define MHZ(x) x##000000 //用MHZ(x)代替x##000000 #ifndef __PCB__ //若没有定义__PCB__,则执行下面的语句; #define NORMAL_RS232 baud=9600, xmit=PIN_C6, rcv=PIN_C7 // #else //若有定义__PCB__,则执行下面的语句; #define NORMAL_RS232 baud=9600, xmit=PIN_B1, rcv=PIN_B0 #endif //结束if定义 #define set_options(value) {#ASM \ MOVLW value \ OPTION \ #ENDASM} #define debug(x) printf("%s variable value is %d\r\n",#x,x); //用debug(x)代替printf("%s variable value is %d\r\n",#x,x);; #define TOSTRING(s) #s //用TOSTRING(s)代替#s #define DEVICE_FILE_FOR(chip) TOSTRING(chip##.h) #ifdef __pcb__ //若有定义__PCB__,则执行下面的语句; #define IDLE {if(kbhit()) isr();} //用IDLE代替{if(kbhit()) isr();} //若getc()读到数据,则kbhit()返回1,否则, kbhit()返回0 #else //若没有定义__PCB__,则执行下面的语句; #define IDLE ; //用IDLE代替; ; #endif //结束if定义 #include DEVICE_FILE_FOR(16C74) //包含16C74.h头文件 #fuses HS,NOPROTECT //HS:高速晶振/谐振器, NOPROTECT:程序存储器代码不保护 #use delay(clock=MHZ(20)) //使能内置函数的功能:delay_ms()和delay_us() //#USE DELAY()必须在#use rs232()使用之前出现. #use RS232(NORMAL_RS232) //使用波特率为9600, //发送脚为PIN_C6 //接收脚为PIN_C7 //使能内置函数:GETC,PUTC和PRINTF, kbhit(); int buffer[BUFFERSIZE]; //声明buffer[10]数组 int next_in, next_out; //声明整型变量next_in和next_out #ifndef __pcb__ //若没有定义__PCB__,则执行下面的语句; #int_rda //RS232接收到的数据有用,指定下面的函数是一个中断函数 #endif //结束if定义 void isr() { buffer[next_in]=getc(); //从RS232口读数据 next_in=(next_in+1)%BUFFERSIZE; //将next_in加1后,除以10,将商赋给next_in } void main() { int x, largest; //声明整型变量x和largest set_options(0x34); //用汇编设置option寄存器,将预分频器留给Timer0使用 //分频比为1:32, Timer0的时钟源选择外部时钟; // Timer0在下降沿递增计数;INT脚电平下降沿触发中断 //使能GPIO上拉 #ifndef __pcb__ //若没有定义__PCB__,则执行下面的语句; enable_interrupts(INT_RDA); //使能UART接收中断 enable_interrupts(GLOBAL); //使能总中断 #endif //结束if定义 next_in=next_out=0; //初始化变量next_in 和next_out largest=0; //初始化变量largest do { while(BUFFER_EMPTY) //当next_in=next_out时 IDLE; //若定义__PCB__,则用IDLE代替{if(kbhit()) isr();} //若getc()读到数据,则kbhit()返回1,否则, kbhit()返回0 //若没有定义__PCB__,则用IDLE代替; x=buffer[next_out]; next_in=(next_out+1)%BUFFERSIZE; //将next_out加1后,除以10,将商赋给next_in largest = max(largest,x); //求最大值 debug(next_in); //用debug(x)代替printf("%s variable value is %d\r\n",#x,x);; debug(next_out) //用debug(x)代替printf("%s variable value is %d\r\n",#x,x);; } forever; //用forever代替表达式while(1) }上面的例子是通过UART接收10个数据,求其最大值
上一篇:PIC 单片机烧写程序时提示Fuse error 0x2007错误
下一篇:PIC单片机CCS之C语言(#USE I2C)
推荐阅读最新更新时间:2024-03-16 15:12
设计资源 培训 开发板 精华推荐
- 安世半导体&世平集团 Nexperia 在5G基础架构的应用 下载赢好礼!
- EE团--TI 原装DK-LM3S9B96开发板 348元(包邮)!
- Follow me第3期来袭,与得捷一起解锁Seeed Studio XIAO ESP32C3!
- 免费申请 | ST多款开发板返场测评
- EEWORLD社区7月明星人物出炉
- 看是德科技X8711A 物联网设备功能测试解决方案,答题赢好礼
- 有奖直播|多款MSP430™片上Sigma-Delta ADC助力高精度信号检测应用 报名中
- Follow me第3期来袭,与得捷一起解锁Seeed Studio XIAO ESP32C3!
- 有奖直播|TI MSP430™民用超声波水表开发指南及其智能模拟组合模块在传感器检测中的应用
- 看视频瓜分红包:面向高效高密度开关电源的先进功率 MOSFET 技术及应用