PIC单片机CCS之C语言(#BYTE的用法)

发布者:Zhenai5201314最新更新时间:2016-09-27 来源: eefocus关键字:PIC单片机  CCS 手机看文章 扫描二维码
随时随地手机看文章
      #BYTE

语法: #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单片机  CCS 引用地址:PIC单片机CCS之C语言(#BYTE的用法)

上一篇:PIC 单片机烧写程序时提示Fuse error 0x2007错误
下一篇:PIC单片机CCS之C语言(#USE I2C)

推荐阅读最新更新时间:2024-03-16 15:12

基于PIC单片机的智能目标跟踪系统设计方案
摘 要: 通过借鉴嵌入式系统在电子技术、信号处理以及计算机等领域应用的成功经验,在分析目标检测与跟踪算法的基础上,将目标检测与跟踪算法与嵌入式技术相结合,设计一种基于嵌入式PIC32单片机的目标检测与跟踪系统,可以实现目标检测跟踪系统的小型化,智能化,并以具体飞行目标为例进行了目标的识别和跟踪。 研究目的 随着现代社会对军用和民用设备需求的不断扩大及要求的不断提高,运动目标的识别和跟踪技术已经迅速发展成为现代信息处理领域中一项非常重要的技术,也是无人机野外战场侦察技术中的重点和难点,并在许多领域内发挥着不可替代的作用。目前,基于PC 机的目标检测与跟踪技术已趋于成熟,但其在嵌入式平台的应用研究还处于初级阶段。由于嵌入式系统具有
[单片机]
基于<font color='red'>PIC单片机</font>的智能目标跟踪系统设计方案
PIC单片机的外接电压检测复位电路举例
  1.设计思路   有许多型号单片机的内部均不具备掉电复位功能,即使对于内部包含该功能的PIC单片机,其复位门槛电压值是固定不可更改的,有时不能满足用户的需求,因此,外加电压检测复位电路也是较常见的设计方案。   对于片内带有掉电复位功能BOR的PIC单片机,在使用外接电压检测复位电路时,就必须将内部BUR功能禁止,方法是将系统配置字的BUDEN位设置为0。   对于内部不带BOR功能的PIC单片机,其电源控制寄存器PCUN没有BOR标志位,无法准确识别由外接电压检测复位电路引起的单片机复位,因此在程序执行过程中在MCLR引脚施加了人工复位信号引起的复位。   与外接电压检测复位电路相关的单片机片内等效电路如图1所示,从
[单片机]
<font color='red'>PIC单片机</font>的外接电压检测复位电路举例
PIC单片机在直流电机无级调速系统的设计
现代工业生产中,电动机是主要的驱动设备,目前在直流电动机拖动系统中已大量采用晶闸管(即可控硅)装置向电动机供电的KZ—D拖动系统,取代了笨重的发电动一电动机的F—D系统,又伴随着电子技术的高度发展,促使直流电机调速逐步从模拟化向数字化转变,特别是单片机技术的应用,使直流电机调速技术又进入到一个新的阶段,智能化、高可靠性已成为它发展的趋势。本调速系统采用PIC16F874单片机作为中心处理器,充分利用了PIC16F874单片机捕捉、比较、模/数转换模块的特点作为触发电路,其优点是:结构简单,能与主电路同步,能平稳移相且有足够的移相范围,控制角调整量可达10000步,能够实现电机的无级平滑控制,脉冲前沿陡且有足够的幅值,脉宽可设定,稳
[单片机]
<font color='red'>PIC单片机</font>在直流电机无级调速系统的设计
PIC单片机学习知识之程序设计(二)
上文中我们讲述了 PIC单片机基础学习之程序设计(一) ,接下来将继续为大家讲解PIC单片机程序设计(二),供大家学习。 PIC单片机的查表程序可以利用子程序带值返回的特点来实现。具体是在主程序中先取表数据地址放入W,接着调用子程序,子程序的第一条指令将W置入PC,则程序跳到数据地址的地方,再由“RETLW”指令将数据放入W返回到主程序。下面程序以F10放表头地址。 MOVLW  TABLE     ;表头地址→F10 MOVWF  10 MOVLW  1        ;1→W,准备取“1”的线段值 ADDWF  10,1      ;F10+W =“1”的数据地址 CALL  CONVERT MOVWF  6        ;
[单片机]
基于PIC单片机的数字可调稳压电源(1.3-25v)PROTEUS仿真+源程序
程序如下: list p=12c672 ; list directive to define processor #include p12c672.inc ; processor specific variable definitions w_temp EQU 0x70 status_temp EQU 0x71 pclath_temp EQU 0x72 reg0 EQU 0x75 reg1 EQU 0x76 advalue EQU 0x77 advflag EQU 0x78 bank
[单片机]
基于<font color='red'>PIC单片机</font>的数字可调稳压电源(1.3-25v)PROTEUS仿真+源程序
PIC单片机驱动LCD模块的设计
偏置电压是通过使用外部梯形电阻网络(电路见下图)而产生。因为梯形电阻网络连接在VDD和Vss之间,所以会有电流通过梯形电阻网络,电流大小与电阻成反比。也就是说,电阻越大,通过梯形电阻网络的电流就越小。如果使用10kΩ电阻,且VDD=5V,则梯形电阻网络将不断消耗166μA的电流。这对于一些使用电池供电的应用来说是很大的电流。 如何最大程度增大电阻,而又不会对显示质量产生负面影响?一些基本的电路分析可以帮助确定梯形网络中电阻增大的程度。 LCD模块实际上就是一个模拟多路开关,它交替地将LCD电压连接到各个段和公共引脚(段电极和公共电极交叉于每一个LCD像素点)。LCD像素可用电容进行模拟。梯形电阻网络中的每个分接点可以用戴维
[单片机]
<font color='red'>PIC单片机</font>驱动LCD模块的设计
PIC单片机驱动步进电机先正转后反转
//************************************************** //实验目的: //熟悉PIC单片机驱动步进电机,先正转后反转 //************************************************** //************************************************** //硬件设置: //1、把步进电机接在J10位置上 //2、5脚是5V电源脚,1-4接步进电机线圈 //************************************************** //*********************
[单片机]
PIC单片机通用同步异步收发器的编程应用
0 引言 PIC18Fxx8单片机是美国微芯公司推出的16位RISC指令集的高级产品,由于芯片内含有A/D、内部E2PROM存储器、I2C和SPI接口、CAN接口、同步/异步串行通信(USART)接口等强大的功能,具有很好的应用前景。但是,目前介绍其应用和以C语言编程的中文参考资料很少。本文将探讨该型单片机异步串行通信的编程应用,程序用HI-TECH PICC-18 C语言编写,并在重庆大学-美国微芯公司PIC单片机实验室的PIC18F458实验板上通过。 1 PIC18FXX8单片机同步/异步收发器(USART) 通用同步/异步收发器(USART)模块是由PIC18FXX8内的三个串行I/O模块组成的器件之
[单片机]
<font color='red'>PIC单片机</font>通用同步异步收发器的编程应用
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved