《匠人手记》推荐网上购书渠道:
互动出版网(china-pub)购书入口   >>>
当当网(dangdang)购书入口   >>>
卓越亚马逊网 购书入口   >>>
淘宝网(taobao)购书入口   >>>
更多购书渠道……   >>> 

设为首页加入收藏联系匠人管理入口21IC首页21IC博客21IC社区侃单片机回复的贴参与的贴

天气预报
百宝日历
载入中...

百宝专栏

载入中...
最新货色

载入中...

粉丝评论

载入中...

载入中...



百宝信息

载入中...

百宝流量

(2006-07-01开始)


匠人手记

 匠人观点: 好记性不如烂笔头  
 黑色幽默:三鹿门——后世畅想

单片机C语言学习2
pcbomb 发表于 2007-11-12 19:35:00  阅读全文 | 回复(0) | 引用通告 | 编辑

四》其他:
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
    /*禁止中断*/


四》位运算符:
        ━━━━┳━━━━━┳━━━━━┳━━━━━━┳━━━━━━┳━━━━━━
            ~   ┃    &     ┃     |    ┃    ^          ┃     <<     ┃    >>        
        ━━━━╋━━━━━╋━━━━━╋━━━━━━╋━━━━━━╋━━━━━━ 
        按位取反┃  按位与  ┃   按位或 ┃ 按位异或   ┃  左移      ┃     右移
        ━━━━┻━━━━━┻━━━━━┻━━━━━━┻━━━━━━┻━━━━━━

对移位:如<< ,a<<2,即为将二进制的a左移两位,若a=0x8f,即10001111,a=a<<2,将导致a=0x3c(00111100),右边补零。

五》条件运算符:
逻辑表达式? 表达式1:表达式2

六》指针与地址运算符:
*取内容        &取地址

七》强制类型转换:(类型)=表达式
(char *)0xb000

八》sizeof 取数据类型、变量以及表达式的字节数的运算符;

九》continue:中断语句:结束本次循环。


单片机C语言之三_____________________________________________________________________________________
函数:
一》中断服务函数与寄存器组定义:

函数类型 函数名(形式参数表) [interrupt n][using n]
n为中断号,0~31:
━━━━┳━━━━━┳━━━━━
中断编号┃  中断向量┃ 入口地址
━━━━╋━━━━━╋━━━━━
    0   ┃  外中断0 ┃   0003H
━━━━╋━━━━━╋━━━━━
    1   ┃  定时器0 ┃   000BH
━━━━╋━━━━━╋━━━━━
    2   ┃  外中断1 ┃   0013H
━━━━╋━━━━━╋━━━━━
    3   ┃  定时器1 ┃   001BH
━━━━╋━━━━━╋━━━━━
    4   ┃  串行口  ┃   0023H
━━━━┻━━━━━┻━━━━━
后面的n指的是四个工作寄存器组的一个:0~3
对函数目标代码影响如下:
在函数入口处将当前工作寄存器组保护到堆栈中;指定的工作寄存器内容不会改变,函数返回前将被保护的工作寄存器组从堆栈中恢复!
例(定时1ms):

    #i nclude <reg51.h>
    sbit P1_0=P1^0;   

void timer0(void) interrupt 1 using 1{
    P1_0=!P1_0;
    TH0=-(1000/256);
    TL0=-(1000%256);
}
main(){   
    SP=0x60;
    P1_0=0;
    TMOD=0X01;
    TH0=-(1000/256);
    TL0=-(1000%256);
    EA=1;
    ET0=1;
    TR0=1;
    do{}while(1);
}

/*    注意:
    1、如果中断函数中用到浮点运算,必须保存浮点寄存器的状态。(在math.h中保存浮点寄存器函数为pfsave, 恢复浮点寄存器的状态函数为fprestore)
    2、如果在中断函数中调用了其他函数,则被调函数所使用的工作寄存器组与中断函数的一致!
*/


单片机C语言之四_____________________________________________________________________________________
一、 局部变量与全局变量(外部变量):

1、 全局变量若不在开头定义则加extern
2、 全局变量会使代码长,占用内存多

二、 存储方式:
自动变量(auto):缺省,函数调用存在,退出消失。

内部变量 静态变量(static):static int a=5;始终存在,退出不消失,但不能访问。

寄存器变量(register):速度最快。通常只给编译器一个建议,由编译器根
据实际情况确定。(见下)

变量 全局变量(global):
外部变量
静态变量(static):

寄存器变量例:
    #i nclude<stdio.h>
    int_power(m,e)
    int m;
register int e;
{
    register int temp;
    temp=1;
    for(;e;e--)
    temp*=m;
    return(temp);
}
main()
{
    ……
}

三、 函数的参数和局部变量的存储器模式:

三种存储器模式:small,compact,large.
一个函数的存储器模式确定了函数的参数和局部变量在内存中的地址空间
small:内部ram
compact, large:外部RAM
函数类型 函数名(形式参数表)[存储器模式]

例:
#pragma large /*默认存储器模式为large*/
extern int calc(char I,int b)small; /*指定small模式*/
extern int func(int I,float f) large; /*指定large模式*/
int large_te(int I,int k) /*未指定,按默认的large模式处理*/
{
return(mtest(I,k)+2);
}

利用存储器混合模式编程,充分利用有限的存储空间,还可加快程序的执行速度!


单片机C语言之五_____________________________________________________________________________________
        数组

1>初始化数组:
    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]

起始地址1000

b[0] b[1] b[2] b[3] b[4] b[5] b[6] b[7] b[8] b[9]
用数组名作为函数的参数,应该在主调函数和被调函数中分别进行数组定义而不能只在一方定义数组。而且在两个函数中定义的数组类型必须一致,如果类型不一致将导致编译出错。实参数组和型参数组的长度可以一致可以不一致,编译器对形参数组的长度不做检查,直只是将实参数组的首地址传递给行参数组。如果希望行参数组能得到实参数组的全部元素,则应使两个数组的长度一致。定义型参数组时可以不指定长度,只在数组名后面跟一个方括号[]。这时为了在被调函数中处理数组元素的需要,应另外设置一个参数来传递数组元素的个数。
例:用数组作为函数的参数,计算两个不同长度的数组中所有元素的平均值

    #i nclude<stdio.h>

float average(array,n)
    int n;
    float array[ ];
{
    int I;
    float aver,sum=array[0];
    for(I=1;I<n;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中。

    #i nclude<reg51.h>
    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”,利用它可十分方便地实现对任何内存空间的直接操作,改写上面的程序:
    #i nclude<reg51.h>
    #i nclude<absacc.h> /*包含绝对地址操作预定义头文件*/
    #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转换*/
}

两指针相减-----计算字符串的长度
    #i nclude<stdio.h>
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;
抽象型指针可以用来在每个存储区内访问任意绝对地址或者用来产生绝对调用。

看《匠人手记》,与匠人同行!北航出版,正在热卖!

发表评论:
载入中...

芯片专题

器件专题

软件专题

硬件专题

综合专题

项目专题

原创专题

器件检测
LCD LED
按键 触摸键
E2PROM
电池 电机
电阻 电容 电感

指令系统
软件算法
编程规范
滤波算法
串行通讯

PCB设计
I2C PWM
红外遥控
充电技术
中断 ADC 

匠人手记
匠人夜话
网络心路
一周热点串烧
从零开始玩PIC
DIY旋转时钟

广告5号位 [投放]


学习板、开发板、编程器、下载器、仿真器(查看详情……)

广告3号位 [投放]

站内搜索


站外搜索


百度  google
mp3  歌词 
图片  FLASH 
知道  文档
新闻  词典 
地图  mp3 
软件  天网 
雅虎  爱问 
搜狗  讯雷 
网讯  华军 
天空 

21IC器件搜索
百宝箱分站
  • 《匠人的百宝箱》21IC站
  • 《匠人的百宝箱》21IC笔记团队
  • 《匠人手记》21IC书友会
  • 《匠人的百宝箱》MCUBLOG站
  • 《匠人的百宝箱》MCUBLOG笔记团队
  • 《匠人的百宝箱》EDN站
  • 《匠人手记》EDN书友会
  • 《匠人的百宝箱》与非网站
  • 《匠人的百宝箱》新浪站
  • 《匠人的百宝箱》百度站
  • 《匠人的百宝箱》网易126站
  • 《匠人的百宝箱》网易163站
  • 《匠人的百宝箱》互动出版网站
  • 广告4号位 [投放]

     
     

    匠人原创

    往日酷贴

     
     
     

    大千八卦

    友情连接

    新浪新闻:
    新浪财经:
    AK58新闻:
    新浪股票:
    新浪股票:
    证券之星:

     [更多酷站连接]

     

     

    [欢迎交换连接]

    [百宝箱之与非门分舵]

    [电脑圈圈的家当]

    [IC921的博客]

    [柔月阁]

    [八楼的呼吸]

    [hotpower 的水潭]

    [xwj的文君阁]

    [所长的BLOG]

    [阿摆手记]

    [电子伙伴]

    [unaided的笔记]

    [小飞的笔记]

    [单片机开发联盟]

    [网址之家]

    [好东西网址大全]

    [美萍中文精选]

    [数字电视之家]

    [SMARTCODE电子书斋]

    [软件开发之窗]

    [Armoric]

    [我爱研发网]

    [infernal的笔记]

    [雄鹰的空中加油站]

    [SunK]

    [逍遥电子]

    [ningpanda的博客]

    [C-Design]

    [一网见天下]

    [海边淘沙]

    [嵌入式365]

    [水牛的仓库]

    [股剩是怎样炼成的]

    [PIC论坛]

    [ICC AVR开发网]

    [中国高校自动化网]

     

     

     

    MCU博客-中国电子工程师博客网 

    大学生电子网 

     

     

     

     

     

    !!! 《匠人的百宝箱》 !!!