| 单片机C语言 |
| 类别:单片机/DSP |
|                    一》宏定义:1、不带参数:      #define 标识符 常量表达式      /*#define是宏定义命令,宏名(标识符)好习惯用大写*/      #define NIL 0x80 2、带参数:/*相当于小函数*/      #define 宏名(参数表) 字符串      /*不仅要时行字任串替换还要进行参数的替换,在宏定义时,宏名与带参数的括弧之间不应该加空格,否则将空格以后的字符串都作为替代字符串的一部分,这可是很容易出错的*/      如:#define SQ(a,b) a*b      使用:x=12;y=10;area=SQ(x,y);/*则area=12*10=120*/二》文件包含:#include 或#include "文件名"      /*在C中用双引用形式更保险,在C51中常用物是尖括弧形式*/三》条件编译:      /*一般源程序中的所有程序行都参加编译,但有时希望对其中一部分内容只在满足一定条件下才进行编译,也就是对一部分内容指定编译的条件。*/#if、#elif、 #else、#endif、#ifdef、#ifndef      /*选择不同的编译范围,产生不同的代码,提供通用性。*/      /*如对8051在6MHZ与12MHZ下有*/      #ifdef cpu==8051      #define FREQ 6 /*程序段*/      #else      #define FREQ 12/*程序段*/      #endif      /*这样下面的原程序不用做任何修改便可以使用于两种时钟频率的单片机系统*/四》其他:      1、#error:捕捉不可预料的编译条件      #if (myv!=0&&myv!=1)/*假定其值必为0或1*/      #error myv must be 1 or 0/*出错时显示*/      #endif      2、#pragma:用于在程序中向编译器传送各种编译控制命令      #pragma 编译命令序列      /*例:想按如下命令编译ex.c c51 ex.c debug cod large可用:*/      #pragma DB CD LA      #pragma disable      /*禁止中断*/      单片机C语言之二_____________________________________________________________________________________      一》数据类型:      char int long      1:unsinged 0~255 0~65535 0~4294967295      2:signed -128~127 -32768~32767 -2147483648~2147483647指针:* 3字节位标量: sbit      特殊功能寄存器:sfr      16位特殊功能寄存器:sfr16 占2个内存单元,0~65535      可寻址位:sbit利用他可访问51单片机的内部RAM中的可寻址位或特殊功能寄存器中的可寻址位      sfr P0=0x80;      sbit P0_1=P0^1;      /*将P0口的口地址定义为80H,将P0.1位定义为P1_1*/二》数据存贮类型      表1. C51数据存贮类型      ━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━      数据存贮类型 ┃ 与存贮空间的对应关系      ━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━      data ┃ 直接寻址片内数据存贮区,访速度快      bdata ┃ 可位寻址片内数据存贮区,允许位与字节混合访问      idata ┃ 间接寻址片内数据存贮区,可访问片内全部RAM地址空间      pdata ┃ 分页寻址片外数据存贮区(256字节)由MOVX @R0访问      xdata ┃ 片外数据存贮区(64K),由MOVX @DPTR访问      code ┃ 代码存贮区(64K),由MOVC @DPTR访问      ━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━      变量的存贮类型定义:      char data var      /*字符变量var被定义为data存贮类型,C51编译器将把该变量定位在51单片机片内数据区存贮区中*/      bit bdata flag      /*位变量flag被定义为bdata存贮类型,C51编译器将把该变量定位在51单片机片内数据区存贮区(RAM)中的位寻址区:20H--2FH*/      三》typedef:重新定义数据类型typedef 已有数据类型 新的数据类型      typedef int word;      /*将word定义为整型*/      word i,j;      /*将i,j定义为整型*/四》位运算符:      ━━━━┳━━━━━┳━━━━━┳━━━━━━┳━━━━━━┳━━━━━━      ~ ┃ & ┃ | ┃ ^ ┃ 初始化数组:      unsigned char a[5]={0x11,0x22,0x33,0x44,0x55}      或      unsigned char a[ ] ={0x11,0x22,0x33,0x44,0x55,0x66}3>数组作为函数的参数:不但可以由变量作为函数的参数外,还可以用数组名作为函数的参数。一个数组数组名表示该数组的首地址。用一个数组名作为函数的参数时,在执行函数调用的过程中参数传递方式采用的是地址传递。将实际参数数组首地址传递给被调函数中的形式参数数组,这样一来两个数组就占有同一段内存单元。见下图:a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9]起始地址1000b[0] b[1] b[2] b[3] b[4] b[5] b[6] b[7] b[8] b[9]      用数组名作为函数的参数,应该在主调函数和被调函数中分别进行数组定义而不能只在一方定义数组。而且在两个函数中定义的数组类型必须一致,如果类型不一致将导致编译出错。实参数组和型参数组的长度可以一致可以不一致,编译器对形参数组的长度不做检查,直只是将实参数组的首地址传递给行参数组。如果希望行参数组能得到实参数组的全部元素,则应使两个数组的长度一致。定义型参数组时可以不指定长度,只在数组名后面跟一个方括号[]。这时为了在被调函数中处理数组元素的需要,应另外设置一个参数来传递数组元素的个数。      例:用数组作为函数的参数,计算两个不同长度的数组中所有元素的平均值 #includefloat average(array,n)      int n;      float array[ ];      {      int I;      float aver,sum=array[0];      for(I=1;I      sum=sum+array[I];      aver=sum/n;      return(aver);      }      main()      {      float pot_1[2]={99.9,88.8};      float pot_2[3]={11,22,33.3};      average(pot_1,2);      average(pot_1,3);      }单片机C语言之六_____________________________________________________________________________________      软件法去干扰:      工程上我们在采集数据时一般要求精度达到5%%,大于这个值将认为无效。我在实际应用中采用8535对32路数据进行采集(8535带10位AD,带看门狗),发现数据跳动有时达7%%,这是由于各种干扰造成的。主要来自于随机干扰,下面就各种干扰的方法给出简单的去除方法: 1、白噪声:最重要的统计特性为平均值为0,可采取每路数据采集几次求平均的方法; 2、随机干扰:该点明显高于或低于附近正常采样值,故采取中值滤波法,即对被测信号连续采样M次,进行大小排序,取大小居中的1/3个采样值进行算术平均; 3、电源干扰:特点是有固定周期,故可采用定时采样求平均的方法。      由于各种排序与求平均算法用C易于实现,故C常常用于采集系统中软件去干扰。至于排序算法可参考上一篇文章,有一个经典的程序。      在实际中我们采用每路猜9个值,排序,取中间3个,求平均。然后。。,每路数据几乎不动!      单片机C语言之七_____________________________________________________________________________________      指针:可对内存地址直接操作      基于存贮器的指以贮器类为参量,它在编译时才被确定。因此为指针选择存贮器的方法可以省掉,以这些指针的长度可为1个字节(idata *,data *,pdata *)或2个这节(code *,xdata *)。      char xdata *address; ADC0809具有8个模拟量输入通道,采用中断方式,在中断函数中读取8个通道的A/D转换值,分别存储在外部RAM的1000H~1007H单元。ADC0809端口地址为00F0H。 程序定义了两个指针变量* ADC和* ADCdata,分别指向ADC0809端口地址(00F0H)和外部RAM单元地址(1000H~1007H)      由*ADC=I送入通道数,启动ADC0809进行A/D转换,转换结束时产生INT1中断。在中断服务函数int1()中通过temp=*ADC和*ADCdata=temp;读取A/D转换结果并存到外部RAM中。 #include      unsigned int xdata *ADC; /*定义ADC0809端口指针*/      unsigned int xdata *ADCdata; /*定义ADC0809数据缓冲器指针*/      unsigned char I;      void main( )      {      ADC=0x00f0; /*定义端口地址和数据缓冲器地址*/      ADCdata=0x1000;      I=8; /* ADC0809有8个模拟输入通道*/      EA=1; EX1=1;IT1=1; /*开中断*/      *ADC=I; /*启动ADC0809*/      WHILE(I); /*等待8个通道A/D转换完*/      }      void int1() interrupt 2      {      unsigned char tmp;      temp=*ADC; /*读取A/D转换结果*/      *ADCdata=temp; /*结果值存到数据缓冲区*/      ADCdata++; /*数据缓冲区地址加1*/      i—;      *ADC=I; /*启动下一个模拟输入通道A/D转换*/      }除了用指针变量来实现对内存地址的直接操作外,c51编译器还提供一组宏,该宏定义文件为:“absacc.h”,利用它可十分方便地实现对任何内存空间的直接操作,改写上面的程序:      #include      #include /*包含绝对地址操作预定义头文件*/      #define ADC 0x00f0; /*定义ADC0809端口地址*/      #define ADCdata 0X1000 /*定义数据缓冲器地址*/      unsigned char I;      void main( )      {      I=8; / *ADC0809有8个模拟输入通道*/      EA=1;ex1=1;it1=1; / *开中断*/      XBYTE[ADC]=I; /*启动0809 */      While(i); /*等待8个通道转换完毕*/      }void int1() interrupt2 {      unsigned char tmp;      tmp=XBYTE[ADC]; /*读取A/D转换结果*/      i--;      XBYTE[ADCdata+I]=tmp; /**结果值存储到数据缓冲器*/      XBYTE[ADC]=I; /*启动下一个模拟输入通道A/D转换*/      }两指针相减-----计算字符串的长度      #include      main() {      char *s=”abcdef”;      int strlen(char *s);      printf(“\n length of ‘%%s’=%%d\n”,s,strlen(s));      }int strlen(char *s) {      char *p=s;      while(*p!=’\0’)p++;      return(p-s);      }结果为:length of ‘abcdef’=6注:不允许指针之间进行加,乘,除,移位,或屏蔽运算,也不允许用float类型数据与指针做加,减运算!抽象型指针:      ANSI新标准增加了一种“void * ”的指针类型,这是一种抽象型指针,即可以定义一个指针变量,但不指定该指针是指向哪种类型的数据的。在赋值时需进行强制类型转换:      Char *p1;      Void *p2;      P1=(char*)p2;      抽象型指针可以用来在每个存储区内访问任意绝对地址或者用来产生绝对调用;-----------------------------7d224e10f40      Content-Disposition: form-data; name="submit1"上传------------------------------      来源:不详      作者:不详           |
- pic16单片机应..
- 2008-1-9
- 基于单片机的某车型..
- 2008-1-7
- 基于ARM的FPG..
- 2008-1-7
- 基于单片机的电热水..
- 2007-11-15
- 一种基于单片机的汽..
- 2007-11-15
- 基于单片机的电子导..
- 2007-11-8
- 51单片机边沿触发..
- 2007-11-8
- 如何选择细纱机主电..
- 2007-11-5
- 单片机编程技巧
- 2007-9-14
- 空压机变频改造技术..
- 2007-9-3
- 运用定点DSP实现..
- 2007-8-7
- 基于TMS320C..
- 2007-8-9
- 一种用于图像认证的..
- 2007-7-29
- TMS320F20..
- 2007-8-9
- 多DSP系统互连方..
- 2007-8-9
- C5402 DSP..
- 2007-8-9
- 具有高可靠性的高速..
- 2007-8-9
- 基于DSP的实时M..
- 2007-8-7
- 带ARM核的双CP..
- 2007-8-9
- 基于TMS320V..
- 2007-8-9



