注意:访问本站需要Cookie和JavaScript支持!请设置您的浏览器! 打开购物车 查看留言付款方式联系我们
初中电子 单片机教材一 单片机教材二
搜索上次看见的商品或文章:
商品名、介绍 文章名、内容
首页 电子入门 学单片机 免费资源 下载中心 商品列表 象棋在线 在线绘图 加盟五一 加入收藏 设为首页
本站推荐:
1.红外遥控噐软件解码及其应用
文章长度[79335] 加入时间[2006/8/20] 更新时间[2024/12/5 13:15:49] 级别[3] [评论] [收藏]

MCS-51系列MCU对TC9012红外遥控噐软件解码实例清单如下:

;==============================================
;遥控器软件解码子程序,入口标号:TKEY
;影响4BH、4CH单元;4BH为循环计数器。
;位地址00H为读键标志:“1”为成功,“0”为读
;键无效, 若成功, 键值在4C单元中。
;位地址04H为键值类型标志:
;“1” 实际值,“0” 映射值。
;以下2个参数是红外遥控信号的软件解
;码参数,视CPU时钟频率而定,若晶振为6M,则
;==============================================
#HW EQU #08H ;引导脉冲特征宽度
#PW EQU  #02H ;信号脉冲特征宽度
#ZGZQ EQU #90H;主工作区高位地址;
TKE2: LJMP TKE;接力跳转;
TKEY: PUSH A ;子程序入口
  PUSH PSW
  PUSH DPH
  PUSH DPL
  PUSH 00H
  PUSH 01H
  MOV TMOD,#01H
  MOV PSW, #00H
  MOV P2, #ZGZQ
  MOV R0, #70H
  MOV R1, #21H ;有效脉冲只有33个
  CLR 00H
TK3:  MOV TH0,#0
  MOV TL0,#0AH;测低电平宽度
  SETB TR0
TK4:  JB TF0, TKE2;超时无效转结束
  JNB P3.3, TK4
  CLR TR0
  MOV A, TH0
  MOVX @R0, A
  INC R0
  MOV A, TL0
  MOVX @R0, A
  INC R0
  MOV TH0, #00H
  MOV TL0, #0AH;测高电平宽度
  SETB TR0
TK5:  JB TF0, TKE2;超时无效转结束
  JB P3.3, TK5
  CLR TR0
  MOV A, TH0
  MOVX @R0, A
  INC R0
  MOV A, TL0
  MOVX @R0, A
  INC R0
  DJNZ R1, TK3;循环
;
;分析脉冲流
;脉冲波形数据存放在70H开始的连续84H个单元内,
;每个脉冲由一个低电平脉宽和高电平脉宽组成
;每个脉宽数据占两个字节,前一个字节为高8位
;后一个字节为低8位
;
;判引导脉冲是否有效
  MOV R0, #70H
  MOVX A, @R0
  CLR C
  SUBB A, #HW
  JC TKE  ;低电平引导脉冲无效转结束
  INC R0
  INC R0
  MOVX A, @R0
  SUBB A, #HW
  JC TKE  ;高电平引导脉冲无效转结束
;分析键码
;键码值在片内4CH单元 !
;判9012遥控芯片特征码是否有效,
;特征码是连续两个字节的0EH
;首先译码第1个特征码,并判断是否为“0EH”
  MOV 4BH, #8
  MOV 4CH, #0
  INC R0
  INC R0
TK6:  INC R0
  INC R0
  MOVX A, @R0
  CLR C
  SUBB A, #PW
  MOV A, 4CH
  RRC A
  MOV 4CH, A
  INC R0
  INC R0
  DJNZ 4BH, TK6 ;循环
  MOV A, 4CH
  CPL A
  CJNE A, #0EH, TK7
  MOV A, R0 ;是9012芯片的特征码
  ADD A, #20H;跳过后一个特征码的
  MOV R0, A ;判断,去译码键值-----
  LJMP TK9 ;--转TK9
;第1个特征码无效
;再译码第2个特征码,并判断是否为“0EH”
TK7:  MOV 4BH, #8
  MOV 4CH, #0
TK8:  INC R0
  INC R0
  MOVX A, @R0
  CLR C
  SUBB A, #PW
  MOV A, 4CH
  RRC A
  MOV 4CH, A
  INC R0
  INC R0
  DJNZ 4BH, TK8
  MOV A, 4CH
  CPL A
  CJNE A, #0EH, TKE;无效退出;
; 特征码有效,进行键值译码
TK9:  MOV 4BH, #8
  MOV 4CH, #0
TK10: INC R0
  INC R0
  MOVX A, @R0
  CLR C
  SUBB A, #PW
  MOV A, 4CH
  RRC A
  MOV 4CH, A
  INC R0
  INC R0
  DJNZ 4BH, TK10
  MOV A, 4CH;
  CPL A ;得键码
  JB 04H, TKE1
  MOV DPTR, #TAB ;键码到键值
  MOVC A, @A+DPTR;的查表映射
TKE1: MOV 4CH, A;或4CH中
  SETB 00H ;置读键有效标志
TKE:  POP 01H
  POP 00H
POP DPL  ;返回
  POP DPH
  POP PSW
  POP A
  MOV P2, #0FFH
  RET
;以下是针对某一具体应用的“重定义按键”映射表
TAB:  DB 01H,02H,03H,04H,05H,06H,07H,08H
  DB 09H,00H,20H,20H,20H,20H,20H,20H
  DB 0EH,11H,14H,13H,0AH,0BH,0FH,20H
  DB 0CH,0DH,15H,20H,10H,12H,0FH,20H
  DB 20H,20H,20H,20H,20H,20H,20H,20H
;
以上是软件译码的子程序。调用该子程序,必须首先检测是否有遥控信号的到来,并进行同步。具体方法可以采用查询方式,也可采用中断方式。以下给出查询方式的子程序:
;==============================================
;测试是否有遥控信号到来,子程序返回时
;位标志00H置“1”时有遥控信号到来,
;位标志置“0”时无遥控信号到来.
;==============================================
DKEY: SETB 00H
  MOV 2FH,#00H
DK1:  JNB P3.3,DKE
  NOP
  NOP
  NOP
  JNB P3.3,DKE
  NOP
  NOP
  NOP
  DJNZ 2FH,DK1
  CLR 00H
DKE:  RET


2.一种8位I/O口的单片机显示器和键盘接口
LED显示和键盘查询软件汇编的子程序如下:
DISP为LED显示子程序,其功能是使P1.7=1,把显示缓冲区(首址为DISB)中的数据依次送至P1.0~P1.3即U1/CD4511的输入端,同时,P1.4~P1.6输出对应各LED管位的BCD码,每个LED管的显示时间为1ms。
入口参数:DISB显示缓冲区首址;
出口参数:无;
使用寄存器:A,R0,R2,R3,R4。
DISP:   MOV   R3,#04H ;LED数码管个数
MOV  R0,DISB ;显示缓冲区首址
MOV  R2,#08H ;输出码初值,使P1.7=1
DSP0:   MOV   A,R2       ;取初值
SWAP A      ;高4位和低4位交换
ANL   A,#0F0H ;屏蔽低4位
ORL   A,@R0      ;与欲显示数码合成为输出码
MOV  P1,A       ;输出至P1口
MOV  R4,#0FAH   ;延时计数器初值
DLP:    DJNZ   R4,DLP     ;延时1ms
INC   R0     ;显示缓冲器地址+1  
INC   R2     ;LED位地址+1
DJNZ  R3,DSP0 ;共显示4个LED
RET
下面是键盘查询子程序KSB。其功能是,使LED熄灭(P1.7=0),置P1.0~P1.3为输入方式,P1.4~P1.6依次输出数字“0~3”所对应的BCD码,同时测量P1.0~P1.3是否有低电平;若有低电平即为有键按下,延时消键抖动,计算键值,测键是否被释放,若释放,延时退出。此时置累加器A=1,键值在寄存器R2中。若无键,则累加器A=0。
入口参数:无;
出口参数:A有无键标志:A=0时无键,A=1则有键;
R2键位值(0~1FH);
使用寄存器:A,R0,R2,R3,R4。
KBS:    MOV   R3,#0F0H    ;P1初值,P1.0~P1.3输入,P1.4~P1.6=0,P1.7=0
MOV  R4,#04H ;列计数器初值
MOV  R2,#00H ;键位的初值
KS1:    MOV   A,R3       ;取输出初值
SWAP A      ;高低四位交换,形成输出码
MOV  P1,A       ;输出至P1口
NOP
MOV  A,P1       ;测输入
ANL   A,#0FH     ;屏蔽掉高四位
XRL   A,#0F      ;测是否有键
JNZ   KSP    ;有键,转计算键值
INC   R3     ;无键,输出值+1
MOV  A,R2       ;取键值
ADD  A,#04H     ;键值+4(因每列4键)
MOV  R2,A       ;赋键值
DJNZ R4,KS1      ;4列扫完否
KSE0:   CLR A      ;无键,A清零
SJMP  KSE    ;退出
KSP:    ACALL  D20MS     ;有键,延时20ms消键抖动
ORL   P1,#0FH ;再测有键否
NOP
MOV  A,P1
ANL   A,#0FH
XRL   A,#0FH
JZ KSE0       ;无键退出
KSP0:   RRC    A      ;循环右移
JC WAIT       ;此位有键,转等待
INC   R2     ;无键,键值+1
SJMP  KSP0       ;循环测键位,计算键值
WAIT:   ORL    P1,#0FH ;测键是否释放
NOP
MOV  A,P1
ANL   A,#0FH
XRL   A,#0FH
JNZ   WAIT       ;键未释放,等待
ACALL D20MS     ;键释放,延时20ms
INC   A      ;有键,A=1
KSE:    RET
D20MS是延时20ms子程序。
入口参数:无;
出口参数:无;
使用寄存器:R6,R7。
D20MS: MOV R7,#14H
DL1:    MOV   R6,#0F9H
DL2:    DJNZ   R6,DL2
DJNZ   R7,DL1
RET


3.如何在MCS-51系统中使用IDE硬盘
MCS-51程序主要部分如下:
主要部分MCS51程序:
/*  以下是关于8255的一些定义: */
#define  IDE_8255_LSB      0x2000  /* 低8位             */
#define  IDE_8255_MSB      0x2001  /* 高8位             */
#define  IDE_8255_CTL      0x2002
#define  CFG_8255          0x2003
#define  RD_IDE_8255       0x92    /*10010010b, 8255输入      */
#define  WR_IDE_8255       0x80    /*10000000b, 8255输出      */

/*  8255和IDE接口连接     */
#define  IDE_A0    0x01       /* 8255和IDE接口直接相连     */
#define  IDE_A1    0x02       /* 8255和IDE接口直接相连     */
#define  IDE_A2    0x04       /* 8255和IDE接口直接相连     */
#define  IDE_CS0   0x08       /* 8255和IDE接口通过74LS04反相后相连 */
#define  IDE_CS1   0x10       /* 8255和IDE接口通过74LS04反相后相连 */
#define  IDE_WR   0x20       /* 8255和IDE接口通过74LS04反相后相连 */
#define  IDE_RD    0x40       /* 8255和IDE接口通过74LS04反相后相连 */
#define  IDE_RST    0x80       /* 8255和IDE接口通过74LS04反相后相连 */

#define  IDE_DATA          IDE_CS0
#define  IDE_ERR           IDE_CS0 + IDE_A0
#define  IDE_SECCNT       IDE_CS0 + IDE_A1
#define  IDE_SECTOR           IDE_CS0 + IDE_A1 + IDE_A0
#define  IDE_LSB        IDE_CS0 + IDE_A2
#define  IDE_MSB           IDE_CS0 + IDE_A2 + IDE_A0
#define  IDE_HEAD          IDE_CS0 + IDE_A2 + IDE_A1
#define  IDE_COMMAND     IDE_CS0 + IDE_A2 + IDE_A1 + IDE_A0
#define  IDE_STATUS        IDE_CS0 + IDE_A2 + IDE_A1 + IDE_A0
#define  IDE_CONTROL      IDE_CS1 + IDE_A2 + IDE_A1
#define  IDE_ASTATUS       IDE_CS1 + IDE_A2 + IDE_A1 + IDE_A0

/*  IDE命令:*/
#define  IDE_CMD_RECAL      0x10
#define  IDE_CMD_READ        0x20
#define  IDE_CMD_WRITE       0x30
#define  IDE_CMD_INIT         0x91
#define  IDE_CMD_ID           0xEC
#define  IDE_CMD_SPINDOWN   0xE0
#define  IDE_CMD_SPINUP       0xE1


/*  IDE初始化  */
int IDE_Init()
{
    int status, i=0;

    IDE_Write(IDE_HEAD, 0xA0);
    status = IDE_Read(IDE_STATUS);

    while(!(status&0x40)) { /*等待RDY为”1”*/
       delay(1);
       if(i++>5000){
           printf("Time out, device error!\n");
           exit(1);
       }
    }  
    i = 0;
    while(status&0x80) { /*等待BSY为”0”*/
       delay(1);
       if(i++>5000){
           printf("Time out, device error!\n");
           exit(1);
       }
    }  
    IDE_Write(IDE_HEAD, 0x20);
    IDE_Write(IDE_SECCNT, 64);

    IDE_Write(IDE_COMMAND, IDE_CMD_INIT);

    if(IDE_Busy()==-1){
       printf("Time out,device error!\n");
       exit(1);
    }
    IDE_Write(IDE_COMMAND, IDE_CMD_RECAL);
    if(IDE_Busy()==-1){
       printf("Time out,device error!\n");
       exit(1);
    }
}

/* 从硬盘读取一个扇区,放入到形参指定的内存中 */
int ReadSector(short *addr, long int LBA)
{
    IDE_Busy();  /* 等待硬盘空闲 */
    WriteLBA(LBA);
    IDE_Write(IDE_COMMAND,IDE_CMD_READ);
    IDE_DRQ();
    ReadData(addr);  
}


/* 向硬盘写一个扇区,返回零表示成功,否则失败。*/
int WriteSector(short * Buffer, long int LBA)
{
    IDE_Busy();
    WriteLBA(LBA);
    IDE_Write(IDE_COMMAND,IDE_CMD_WRITE);
    IDE_DRQ();
    Wirte_Data(Buffer);
    IDE_Busy();
}

/* 取得错误号   */
short GetError()
{
    int res;
    res = IDE_Read(IDE_ERR);
    return res;
}


/* 读取硬盘的标识。  */
void GetDriverId(short * Buffer)
{
    IDE_Busy();
    IDE_Write(IDE_COMMAND,IDE_CMD_ID);
    IDE_DRQ();
    ReadData(Buffer); 
}

/* 激活硬盘(转动)。  */
void SpinUP()
{
    IDE_Write(IDE_COMMAND,IDE_CMD_SPINUP);
    IDE_Busy();
}

/* 让硬盘休眠(停转)。    */
void SpinDown()
{
    IDE_Busy();
    IDE_Write(IDE_COMMAND,IDE_CMD_SPINDOWN);
    IDE_Busy();
}



/* 从硬盘读取512个字节。   */

int ReadData(short * Buffer)
{
    int i;
   
    for(i = 0; i < 256; i ++)
    {
       *(Buffer ++) = IDE_Read(IDE_DATA);
    }  
    return 0; 
}


/* 向硬盘写入512个字节。 */
void WriteData(short * Buffer)
{
    int i;
   
    for(i = 0; i < 256; i ++)
    {
       IDE_Write(IDE_DATA, *(Buffer++));
    }  
}



/* 向设备寄存器写入逻辑块地址   */
void WriteLBA(long int LBA)
{
    short data = 0;
   
    data |= ((LBA&0xFF000000) >> 24);
    data &= 0x0F;
    data |= 0xE0;
    IDE_Write(IDE_HEAD, data);
   
    data = 0;
    data |= ((LBA&0xFF0000) >> 16);
    IDE_Write(IDE_MSB, data);
   
    data = 0;
    data |= ((LBA&0xFF00) >> 8);
    IDE_Write(IDE_LSB, data);
   
    data = 0;
    data |= (LBA&0xFF);
    IDE_Write(IDE_SECTOR, data);

    IDE_Write(IDE_SECCNT, 1);

}


/* 等待IDE设备空闲,返回设备的状态. */
int IDE_Busy()
{
    int res,i = 0;
    do
    {
       res = IDE_Read(IDE_STATUS);
       delay(1);        /* 等待 1ms        */
       if(i++>5000) return -1;     /* 重试5000次,如果失败,返回错误*/
    }while(res&0x80);

    return res;
}

/* 等待设备空闲直到可以传送数据,返回设备的状态 */
int IDE_Ready()
{
    int i = 0, res;

    do
    {
       res = IDE_Read(IDE_STATUS);
       delay(1);        /* 等待 1ms        */
       if(i++>5000) return -1;
    }while((res&0x80)&&(!(res&0x08)));

    return res;
}

/* 通过8255读取硬盘数据(一个16位的字)。 */
short IDE_Read(unsigned char reg)
{
    short res = 0;
    unsigned char MSB, LSB;
   
    *((char *)CFG_8255) = RD_IDE_8255;   /* 8255为输入模式,读硬盘。 */
    *((char *)IDE_8255_CTL) = reg;
    MSB = *((char *)IDE_MSB);
    LSB = *((char *)IDE_LSB);
    *((char *)IDE_8255_CTL) = 0x00;       /* 清除控制寄存器。    */
    res = (MSB << 8)|LSB;
   
    return res;
}


/* 通过8255向硬盘写入一个字。 */
void IDE_Write(unsigned char reg, short data)
{
    unsigned char outdata = 0;

    *((char *)CFG_8255) = WR_IDE_8255;   /* 8255为输出模式,写硬盘。  */
    outdata |= (data & 0x00ff);
    *((char *)IDE_8255_LSB) = outdata;  /* 首先写LSB。        */
    outdata = 0;
    outdata |= (data >> 8);
    *((char *)IDE_8255_MSB) = outdata; /* 写MSB。           */  
    *((char *)IDE_8255_CTL) = reg;
    reg |= IDE_WR;
    *((char *)IDE_8255_CTL) = reg;
    *((char *)IDE_8255_CTL) = 0x00;       /* 清除控制寄存器。     */
    *((char *)CFG_8255) = RD_IDE_8255;   /* 8255为输入模式,读硬盘。  */
}


/* 硬盘复位操作,当初始化结束后需要复位。 */
void IDE_Reset()
{
    *((char *)CFG_8255) = WR_IDE_8255;   /* 8255为输出模式,写硬盘。 */
    *((char *)IDE_8255_CTL) = IDE_RST;
    delay(3);
    *((char *)IDE_8255_CTL) = 0x00;       /* 清除控制寄存器。     */
}


4.移动电话便携通话装置的按键扫描设计
原程序清单如下:
Remote_Key.h文件代码如下:
#define REM_YES    0x1000  //接听键YES
#define REM_NO    0x2000  //拒接键NO
#define REM_UP     0x4000  /音量增大键UP
#define REM_DOWN   0x8000  //音量减低键DOWN
/*以下决定每个按键对应的比特位置*/
#define _REM_YES    12
#define _REM_NO    13
#define _REM_UP    14
#define _REM_DOWN  15
/* 以下为函数声明*/
void Key_IOINIT(void);

Remote_Key.c文件代码如下:
#include
#include "macro.h"
#include "Remote_Key.h"
#include "SCI.h"     /*SCI串行通信模块*/

unsigned int Remote_Keys;
unsigned char RecByte;
unsigned char* csAdd;

void Key_IOINIT(void)
{
    /*将P5.2从普通I/O引脚功能切换为外部中断引脚3*/
P5C2R &= 0xfd; 
    P5C2R |= 0x04; 
    P5C1R |= 0x06;
    P5C0R |= 0x06;
   
    Disable_Interrupts();
    spp(EXINT_PG);     /*切换到外部中断页寄存器*/
    /*外部中断触发寄存器设置*/
    EITR = 0;        /*设置成信号下降沿触发中断*/
    /*外部中断标志寄存器设置*/
    EIPR = 0;        /*清空所有标志位*/
    /*外部中断使能寄存器设置*/
    EIMR |= EIm_ib1m|   /*使能第3号外部中断*/
   /*外部中断优先级寄存器设置*/
    EIPLR |= 0x2d;     /*设置第3号外部中断优先级*/            
  EIPLR &= 0xeb;     /* INT3(INT.B1 101:5) */
  /*外部中断向量寄存器*/
    EIVR = 0x40 ;     /*设置外部中断向量*/
    Enable_Interrupts();
}

#pragma interrupt (EXT_INT_3)   
void EXT_INT_3(void)
{
    SAVE_PAGE;       /*当前页压栈*/
   spp(EXINT_PG);
   EIPR &= ~EIm_ipb1m;   /*清空第3号外部中断发生标志位*/
   /*片选MCP3201使其工作*/
  csAdd=0x8001;
   *csAdd &= 0xef;    
/*通过SCI串行通信方式从MCP3201获得数据*/   
   SCI_Receive_Buffer(&RecByte, 1);     
   if (RecByte>=0xf0 && RecByte<=0xff) /*接听键(YES)处理*/
   {
      Remote_Keys = REM_YES;
      /*这里添加接听键(YES)处理代码......*/
      ClrBit(Remote_Keys,_REM_YES);
   }
   if (RecByte>=0xcb && RecByte<=0xd7) /*拒接键(NO)处理*/
   {
      Remote_Keys = REM_NO;
      /*这里添加拒接键(NO)处理代码......*/
      ClrBit(Remote_Keys,_REM_NO);
    }
    if (RecByte>=0xc2 && RecByte<=0xc6) /*音量增大键(UP)处理*/
    {
       Remote_Keys = REM_UP;
      /*这里添加音量增大键(UP)处理代码......*/
      ClrBit(Remote_Keys,_REM_UP);
    }
    if (RecByte>=0x8d && RecByte<=0x96) /*音量减低键(DOWN)处理*/
    {
       Remote_Keys = REM_DOWN;
      /*这里添加音量减低键(DOWN)处理代码......*/
      ClrBit(Remote_Keys,_REM_DOWN);
    }
    /*通过将片选信号设置为高电平停止MCP3201工作*/
    *csAdd |= 0x10;    
    /*当前页出栈*/
   RESTORE_PAGE;       
}


5.亿恒C166系列单片机IIC总线的软件模拟
测试原程序如下:
3.1 延时子程序
延时子程序Delay用于产生时钟和数据信号的延时,延时时间为400ns×count。程序清单如下:
void Delay(unsigned int count)
{ while (count--);
}
3.2 SCL线检查子程序
SCL线检查子程序Check_SCL用于向串行时钟线输出高电平。该子程序将等待从设备释放SCL,等待的时限为10ms,如果时钟和数据线无误,则返回值为0,否则为1。程序清单如下:
unsigned char Check_SCL()
{   time_out = period;
   DSCL = 0;         /*设置SCL为输入*/
    while (time_out--)
    { if (SCL)        /* 等待从设备释放SCL*/
     { SCL = 1;     /* 置时钟线为高电平 */
    DSCL = 1;      /*设置SCL为输出*/
     return (0);
     }
     }
    return (1);         /*出错*/
}
3.3 初始化子程序
初始化子程序I2CInit用于主定时器T3和辅助定时器T2的设置,并检查时钟和数据线的错误,如SDL/SCL上无上拉电阻或者被从设备拉低。如时钟和数据线无误则返回值为0,否则为1。程序清单如下:
unsigned char I2cInit()
{   T3CON = 0x0080;    /*定时器模式;分辨率为400ns;向下计时*/
    T2CON = 0x0027;    /*重载模式;输入为T3OTL的正负跳变*/
    T2 = 0x0018;       /*T2的重载值为24*/
    T3 = 0x0018;       /*T3的初值*/
    T2IC = 0x0004;      /*设置T2的中断优先级*/
    DSDA = 0;        /*设置SDA和SCL为输入*/
    DSCL = 0;
    if (!SDA)        /*检查时钟和数据线*/
     if (I2cStop())
       return (1);
      if (!SCL)
     if (I2cStop())
       return (1);
    return (0);
}
3.4 起动子程序
起动子程序I2Cstart用于在I2C总线上产生起始位。程序清单如下:
void I2cStart()
{   SDA = 1;    /*确认SDA和SCL均为高电平*/
    SCL = 1;
    DSDA = 1;     /*设置SDA和SCL为输出*/
    DSCL = 1;
  Delay(5);
    SDA = 0;
    Delay(10);
    SCL = 0;
}
3.5 主设备写子程序
主设备写子程序I2CMasterWrite用于向从设备写一个字节的数据,在写数据前先检查等待情况。传送给从设备的数据为该子程序的参数。程序清单如下:
void I2cMasterWrite(unsigned char input_byte)
{  input_data = input_byte;    /*在中断子程序中使用*/
   COM_ON = 1;             /*置通信标志位*/
  TX_RX = 0;             /*发送模式标志*/
  mask = 0x80;            /*先传送MSB位*/
    DSDA = 1;              /*设置SDA为输出*/
    bit_count = 0;             /*时钟脉冲计数器*/
  if (mask & input_data)       /*发送数据的第一位*/
     SDA = 1;       
else SDA = 0;
   mask = mask >> 1;        /*发送数据右移一位*/
    Check_SCL();         /*发送前检查等待状态*/
    T2IE = 1;                 /*T2中断使能*/
  T3R = 1;              /*定时器开始计时*/
}
3.6 主设备读子程序
主设备读子程序I2CmasterRead用于从从设备读取一个字节的数据,在读数据前先检查等待情况。当该子程序的参数为0时,主设备在接收到一个字节的数据后输出低电平,当参数为1时,输出高电平。程序清单如下:
void I2cMasterRead(unsigned char ack)
{  Ackge = ack;       /*在中断服务程序中使用*/
    rec_data = 0;
    COM_ON = 1;           /*置通信标志位*/
    TX_RX = 1;           /*设置接收标志*/
    mask = 0x80;
    DSDA = 0;            /*设置SDA为输入*/ 
    bit_count = 0;           /*时钟脉冲计数器*/
    Check_SCL();       /*接收前检查等待情况*/
  T2IE = 1;               /* T2中断使能*/
    T3R = 1;            /*定时器开始计时*/
}
3.7 停止子程序
停止子程序I2CStop用于产生I2C总线上的停止位。此外,该子程序还用于产生时钟脉冲直至从设备释放SDA。当SDA正常时,I2Cstop的返回值为0,如果SDA被拉低的时间超过10ms,返回值为1。程序清单如下:
unsigned char I2cStop()
{   time_out = period;
    DSDA =0;             /*设置SDA为输入*/
    while (time_out --)
    {if (!SDA)          /*检查SDA线*/
     {    SCL = 1;         /*如果SDA拉低则产生时钟脉冲*/
       Delay(6);
      SCL = 0;
      Delay(6);
     }    else            /*检查SCL*/
     {SDA = 0;
      DSDA = 1;        /*设置SDA为输出*/
     if (Check_SCL())      /*产生停止位*/
       return (1);        /*错误*/
     Delay(10);
       SDA = 1;
       return (0);
     }
    }
    return (1);          /*错误*/
}
3.8 T2中断服务程序
T2中断服务程序int_timer2_handler用于发送、接受数据,每次中断发送或接受一位数据。程序清单如下:
void int_timer2_handler(void) interrupt 0x22 
{ if (TX_RX)
    {/*接收模式*/
    SCL = 1;
     bit_count++;
     if (bit_count <= 8)
     { if (SDA)
       rec_data |= mask;        /*接收字节存于变量rec_data中*/
      else              
       { time_out = period;        /*用于延时*/
         SCL = 1;
       }
       mask = mask >> 1;
       SCL = 0;            
     if (bit_count == 8)
       { DSDA = 1;               /*设置SDA为输出*/
         if (Ackge)             /*置应答位*/
         SDA = 1;
        else SDA = 0;
        }
      }
        else if (bit_count == 9)
        {/*一个字节接收结束*/
         if (bit_count == 9)         /*延时*/
         { SCL = 1;
          SCL = 1;
          SCL = 1;
         T2IE = 0;         /*中断复位*/
          T3IE = 0;
          T2IR = 0;
          T3R = 0;
          COM_ON = 0;         /*通信结束*/
          SCL = 0;
          }
        }
    }
/*发送模式*/
    else
    { SCL = 1;
      bit_count++;
      if (bit_count <= 8)
        { temp_SDA = 0;
       if (mask & input_data)    /*准备下一位*/
           temp_SDA = 1;
       mask = mask >> 1;     
         SCL = 0;
       if (bit_count != 8)
         SDA = temp_SDA;    /*当时钟为低时发送一位数据 */
        else DSDA = 0;      /*释放SDA以接收ack位*/
      }
      else if (bit_count == 9)   
           { RecAck = SDA;      /*在第9个时钟周期读应答位*/
         if (bit_count == 9)     /*延时*/
             { SCL = 1;           /*1字节发送结束*/
              T2IE = 0;
              T3IE = 0;
              T2IR = 0;
          T3R = 0;
          COM_ON = 0;         /*通信结束*/ 
          SCL = 0;
          }
        }
    }                  /*发送结束*/
}                                
虚拟软件包见文件:I2c_hw。



6.MCS-51四字节浮点库及其使用说明
浮点库程序清单如下:
程序清单:
(1) 标号: BTOF 功能:浮点BCD码转换成格式化浮点数
入口条件:浮点BCD码操作数在[R0]中。
出口信息:转换成的格式化浮点数仍在[R0]中。
BTOF: INC R0
INC R0
inc r0;read L
MOV 07h,@R0
DEC R0
MOV 06h,@R0
DEC R0
mov 05h,@r0
;r5r6r7=0.hml(dec)
dec r0 ;;r0 to jie_ma
mov a,r7
ORL A,R6
orl a,r5
jnz btf0 ;jb r5r6r7=0
MOV @R0,#41H
RET
BTF0: MOV A,@R0
MOV C,ACC.7
MOV 1DH,C
CLR 1FH
MOV C,ACC.6
MOV ACC.7,C
MOV @R0,A
JNC BTF1
ADD A,#19
JC BTF2
MOV @R0,#41H
INC R0
MOV @R0,#0
INC R0
MOV @R0,#0
inc r0
MOV @R0,#0
DEC R0
DEC R0
dec r0
RET
BTF1: SUBB A,#19
JC BTF2
MOV A,#3FH
MOV C,1DH
MOV ACC.7,C
MOV @R0,A
INC R0
MOV @R0,#0FFH
INC R0
MOV @R0,#0FFH
inc r0
MOV @R0,#0FFH
dec r0
DEC R0
DEC R0
RET
BTF2: CLR A ;use r1.r2r3r4
MOV R4,A
MOV R3,A
MOV R2,a
mov r1,#24 ;3byte =3*8=24
BTF3: MOV A,R7
ADD A,R7
DA A
MOV R7,A
MOV A,R6
ADDC A,R6
DA A
MOV R6,A
mov a,r5
addc a,r5
da a
mov r5,a;r5r6r7*2
MOV A,R4
RLC A
MOV R4,A
MOV A,R3
RLC A
MOV R3,A
mov a,r2
rlc a
mov r2,a ;count .r5r6r7(10)=>.r2r3r4(2)
DEC R1
JNB ACC.7,BTF3
MOV A,R5
ADD A,#0B0H
CLR A
ADDC A,R4
MOV R4,A
CLR A
ADDC A,R3
MOV R3,A
CLR A
ADDC A,R2
MOV R2,A
JNC BTF4
MOV R2,#80H
INC R1
BTF4:
MOV DPTR,#BTFL
MOV A,@R0
ADD A,#19
MOV B,#4 ;4 byte
MUL AB
ADD A,DPL
MOV DPL,A
JNC BTF5
INC DPH
BTF5: CLR A
MOVC A,@A+DPTR
MOV C,ACC.6
MOV ACC.7,C
MOV 0ch,A ;r4"=0ch
MOV A,#1
MOVC A,@A+DPTR
MOV 0dh,A
MOV A,#2
MOVC A,@A+DPTR
MOV 0eh,A
MOV A,#3
MOVC A,@A+DPTR
MOV 0fh,A
LCALL MUL1
MOV C,1DH
MOV 1FH,C
LJMP MOV0

(2) 标号: FTOB 功能:格式化浮点数转换成浮点BCD码
入口条件:格式化浮点操作数在[R0]中。
出口信息:转换成的浮点BCD码仍在[R0]中。
FTOB: INC R0
MOV A,@R0 ;h
INC R0
ORL A,@R0 ;m
inc r0
orl a,@r0 ;l
dec r0
DEC R0
DEC R0
JNZ FTB0
MOV @R0,#41H
RET
FTB0: MOV A,@R0
MOV C,ACC.7
MOV 1DH,C
CLR ACC.7
MOV @R0,A
LCALL MVR0
MOV DPTR,#BFL0
MOV B,#0
MOV A,R2
JNB ACC.7,FTB1
MOV DPTR,#BTFL
MOV B,#0EDH
ADD A,#16
JNC FTB1
MOV DPTR,#BFLN
MOV B,#0FAH
FTB1: CLR A
MOVC A,@A+DPTR
MOV C,ACC.6
MOV ACC.7,C
MOV 0ch,A ;r4"
MOV A,#1
MOVC A,@A+DPTR
MOV 0dh,A
MOV A,#2
MOVC A,@A+DPTR
MOV 0eh,A
MOV A,#3
MOVC A,@A+DPTR
MOV 0fh,A
MOV A,0ch ;r4" jie_ma
CLR C
SUBB A,R2
JB ACC.7,FTB2
JNZ FTB3
MOV A,0dh ;0.r5"r6"r7"-0.r3r4r5
CLR C
SUBB A,R3
JC FTB2
JNZ FTB3
MOV A,0eh;r6"-r4;;;2002.6.18
CLR C
SUBB A,r4
JC FTB2
JNZ FTB3
MOV 0ah,B
INC 0ah
MOV 0dh,#10h;0.100000
MOV r6,#0
MOV r7,#0
SJMP FTB6
FTB2: INC DPTR
INC DPTR
INC DPTR
inc dptr  ;4byte
INC B
SJMP FTB1 
FTB3: PUSH B
CALL DIV3
FTB4: MOV A,r2
JZ FTB5
CLR C
LCALL RR1
SJMP FTB4
FTB5:
POP 0ah
LCALL HB2
MOV 0dh,A;r5"
LCALL HB2
MOV R6,A
LCALL HB2
MOV R7,A
MOV A,R3
RLC A
CLR A
ADDC A,R7
DA A
MOV R7,A
CLR A
ADDC A,R6
DA A
MOV R6,A
JNC FTB6
MOV R6,#10H
INC 0dh
FTB6:
INC R0
INC R0
inc r0
MOV A,R7
MOV @R0,A
DEC R0
MOV A,R6
MOV @R0,A
DEC R0
MOV A,0dh
mov @r0,a
dec r0
mov a,0ah
MOV C,1DH
MOV ACC.7,C
MOV @R0,A
RET
;[r3r4r5*100]\10=>bcd1,2
HB2:
MOV A,R5
MOV B,#100
MUL AB
MOV R5,A
MOV A,B
XCH A,R4
MOV B,#100
MUL AB
ADD A,R4
MOV R4,A
;JNC HB21
mov a,B
addc a,#0
xch a ,r3
mov b,#100
mul ab
add a,r3
mov r3,a
mov a,b
addc a,#0
HB21: ;MOV A,B
MOV B,#10
DIV AB
SWAP A
ORL A,B
RET
BTFL: DB 41H,0ECH,1EH ,4ah;10e-19
DB 45H,93H,92H,0efh;10e-18  
DB 48H,0B8H,77H,0aah;10e-17
DB 4BH,0E6H,95H,95h;10e-16
DB 4FH,90H,1DH ,7dh;10e-15
DB 52H,0B4H,24H,0dch;10e-14
DB 55H,0E1H,2EH,13h;10e-13
DB 59H,8CH,0BcH,0cch;10e-12
DB 5CH,0AFH,0EbH,0ffh;10e-11
DB 5FH,0DBH,0E6H,0ffh;10e-10
DB 63H,89H,70H ,5fh;10e-9
DB 66H,0ABH,0CCH,77h;10e-8
DB 69H,0D6H,0bfH,95h;10e-7
BFLN: DB 6DH,86H,37H ,0bdh;10e-6
DB 70H,0A7H,0C5H,0ach;10e-5
DB 73H,0D1H,0B7H,17h;10e-4
DB 77H,83H,12H ,6fh;10e-3
DB 7AH,0A3H,0D7H,0ah;10e-2
DB 7DH,0CCH,0CcH,0cdh;10e-1
BFL0: DB 1,80H,00H ,00h;10e0
DB 4,0A0H,00H,00h;10e1
DB 7,0C8H,00H,00h;10e2
DB 0AH,0FAH,00H,00h;10e3
DB 0EH,9CH,40H,00h;10e4
DB 11H,0C3H,50H,00;10e5
DB 14H,0F4H,24H,00h;10e6
DB 18H,98H,96H,80h;10e7
DB 1BH,0BEH,0BCH,20h;10e8
DB 1EH,0EEH,6BH,28h;10e9
DB 22H,95H,02H,0f9h;10e10
DB 25H,0BAH,43H,0b7h;10e11
DB 28H,0E8H,0D4h,0a5h;10e12
DB 2CH,91H,84H,0e7h;10e13
DB 2FH,0B5H,0E6H,20h;10e14
DB 32H,0E3H,5fH,0a9h;10e15
DB 36H,8EH,1bH,0cah;10e16
DB 39H,0c1H,0A2H,0cdh;10e17
DB 3CH,0DEH,0BH,5bh;10e18
DB 40H,8AH,0d7H,23h;10e19
(3) 标号: FMUL 功能:浮点数乘法
入口条件:被乘数在[R0]中,乘数在[R1]中。
出口信息:OV=0时,积仍在[R0]中,OV=1时,溢出。
FMUL: LCALL MVR0
MOV A,@R0
XRL A,@R1
RLC A
MOV 1FH,C
LCALL MUL0
LJMP MOV0
MUL0: LCALL MVR1
mov 01h,02h
mov 02h,03h
mov 03h,04h
mov 04h,05h
;;**************8
MUL1:
;***********
MOV A,R2 ;;第一尾数为零否?
ORL A,R3
orl a,r4
JZ MUL6
MOV A,0dh ;;第二尾数为零否?
ORL A,0eh
orl a,0fh
JZ MUL5;计算r2R3R4×r5R6R7-→r2R3R4
;************
mov 08h,r0;jie_ma piont
mov 09h,r1;jie_ma
mov 01h,r2
mov 02h,r3
mov 03h,r4
;************
MOV R0,#25;右移相加25次
CLR A
MOV R6,A
MOV R7,A;ACC,R6,R7为部分积累加器
CLR C
LOOP1:JNC M2
CALL ADD0
ADDC A,R1;乘数移出位等于1 ,被乘数往部分积里加1次
M2:CALL SRA1
XCH A,R5
CPL RS0
CALL SRA
CPL RS0;部分积带进位位整体右移1位
DJNZ R0,LOOP1
MOV R5,A
JB ACC.7,M3;查积最高位
MOV A,0DH
RLC A
CALL H0;积最高位为0,积整体算术左移1位
JNB ACC.7,Mul3
CALL INC3;尾数截去部分四舍五入
SJMP mul3
M3:
MOV A,0DH
JNB ACC.7,mul3;2002
CALL INC3;尾数截去部分四舍五入
;sjmp mul3

;***************
MUL3:
;***********
mov r0,08h
mov 03h,r5
mov 04h,r6
mov 05h,r7
;*************
MOV A,09h
ADD A,0ch
MD: MOV r2,A
JB ACC.7,MUL4
JNB ACC.6,MUL6
MOV r2,#3FH
SETB OV
RET
MUL4: JB ACC.6,MUL6
MUL5:
CLR A
mov r5,a   ;out r2.r3r4r5=fu(2)
MOV R3,A
MOV R4,A
MOV R2,#41H
MUL6: CLR OV
RET
(4) 标号: FDIV 功能:浮点数除法
入口条件:被除数在[R0]中,除数在[R1]中。
出口信息:OV=0时,商仍在[R0]中,OV=1时,溢出。
FDIV:
INC R0
MOV A,@R0
INC R0
ORL A,@R0
inc r0
orl a,@r0
dec r0
DEC R0
DEC R0
JNZ DIV1
MOV @R0,#41H
CLR OV
RET
DIV1: INC R1
MOV A,@R1
INC R1
ORL A,@R1
inc r1
orl a,@r1
dec r1
DEC R1
DEC R1
JNZ DIV2
SETB OV
RET
DIV2: LCALL MVR0
MOV A,@R0
XRL A,@R1
RLC A
MOV 1FH,C
LCALL MVR1
LCALL DIV3
LJMP MOV0
DIV3: CLR C ;r3r4r5-r5"r6"r7"
MOV A,R5  ;ASUBB A,0fh
mov a,r4
subb a,0eh
mov a,r3
subb a,0dh
JC DIV4
CALL RR1
SJMP DIV3
DIV4:
mov 08h,r0
mov 09h,r1
mov 0ah,r2
CLR A
mov r0,a
mov r1,a
mov r2,a
MOV B,#24   ;r3r4r5/r5"r6"r7"=>r0r1r2
DIV5: CLR C
mov a,r2
rlc a
mov r2,a
MOV A,R1
RLC A
MOV R1,A
MOV A,R0
RLC A
MOV R0,A
MOV A,R5
RLC A
MOV R5,A
XCH A,R4
RLC A
XCH A,R4
XCH A,R3
RLC A
XCH A,R3
MOV F0,C
CLR C
SUBB A,0fh;r7"
MOV r7,A ;r7 temp
MOV A,R4
SUBB A,0eh
MOV r6,A 
MOV A,R3
SUBB A,0dh
ANL C,/F0
JC DIV6
MOV R3,A
MOV 05h,07h;r7
mov 04h,06h
INC R2
DIV6: DJNZ B,DIV5
MOV A,0dh
CLR C
RRC A
SUBB A,R3
CLR A
ADDC A,R2
MOV R5,A
CLR A
ADDC A,R1
MOV R4,A
CLR A
ADDC A,R0
MOV R3,A
mov r0,08h
mov r1,09h
mov r2,0ah
MOV A,R2
CLR C
SUBB A,0ch
LCALL MD
LJMP RLN
(5) 标号: FMOV 功能:浮点数传送
入口条件:源操作数在[R1]中,目标地址为[R0]。
出口信息:[R0]=[R1],[R1]不变。
FMOV: INC R0
INC R0
inc r0
INC R1
INC R1
inc r1
MOV A,@R1
MOV @R0,A
DEC R0
DEC R1
MOV A,@R1
MOV @R0,A
DEC R0
DEC R1
MOV A,@R1
MOV @R0,A
DEC R0
DEC R1
MOV A,@R1
MOV @R0,A
RET
(6) 标号: FCMP 功能:浮点数代数值比较(不影响待比较操作数)
入口条件:待比较操作数分别在[R0]和[R1]中。
出口信息:若CY=1,则[R0] < [R1],若CY=0且A=0则 [R0] = [R1],否则[R0] > [R1]。
FCMP: MOV A,@R0
XRL A,@R1
JNB ACC.7,CMP2
MOV A,@R0
RLC A
MOV A,#0FFH
RET
CMP2: MOV A,@R1
MOV C,ACC.6
MOV ACC.7,C
MOV B,A
MOV A,@R0
MOV C,ACC.7
MOV F0,C
MOV C,ACC.6
MOV ACC.7,C
CLR C
SUBB A,B
JZ CMP6
RLC A
JNB F0,CMP5
CPL C
CMP5: MOV A,#0FFH
RET
;************
CMP6:
INC R0
INC R0
inc r0
inc r1
INC R1
INC R1
CLR C
MOV A,@R0
SUBB A,@R1
MOV B,A
DEC R0
DEC R1
MOV A,@R0
SUBB A,@R1
DEC R0
DEC R1
;***********
mov 0fh,a;r7"
MOV A,@R0
SUBB A,@R1
dec r0
dec r1
ORL A,0fh
orl a,b
JZ CMP7
JNB F0,CMP7
CPL C
CMP7: RET
(7) 标号: FADD 功能:浮点数加法
入口条件:被加数在[R0]中,加数在[R1]中。
出口信息:OV=0时,和仍在[R0]中,OV=1时,溢出。
FADD: CLR F0 ;设立加法标志
SJMP AS ;计算代数和
FADD: CLR F0
SJMP AS
(8) 标号: FSUB 功能:浮点数减法
入口条件:被减数在[R0]中,减数在[R1]中。
出口信息:OV=0时,差仍在[R0]中,OV=1时,溢出。
FSUB: SETB F0
AS: LCALL MVR1
MOV C,F0
RRC A
XRL A,@R1
MOV C,ACC.7
ASN: MOV 1EH,C
XRL A,@R0
RLC A
MOV F0,C
LCALL MVR0
LCALL AS1
MOV0:
INC R0
INC R0
inc r0
mov a,r5
mov @r0,a
dec r0
MOV A,R4
MOV @R0,A
DEC R0
MOV A,R3
MOV @R0,A
DEC R0
MOV A,R2
MOV C,1FH
MOV ACC.7,C
MOV @R0,A
CLR ACC.7
CLR OV
CJnE A,#3FH,MV01
SETB OV
MV01: MOV A,@R0
RET
MVR0: MOV A,@R0
MOV C,ACC.7
MOV 1FH,C
MOV C,ACC.6
MOV ACC.7,C
MOV R2,A
INC R0
MOV A,@R0
MOV R3,A
INC R0
MOV A,@R0
MOV R4,A
inc r0
mov a,@r0
mov r5,a
dec r0
DEC R0
DEC R0
RET
MVR1: MOV A,@R1
MOV C,ACC.7
MOV 1EH,C
MOV C,ACC.6
MOV ACC.7,C
MOV 0ch,A ;r4"
INC R1
MOV A,@R1
MOV 0dh,A
INC R1
MOV A,@R1
MOV 0eh,A
INC R1
MOV A,@R1
MOV 0fh,A
dec r1
DEC R1
DEC R1
RET
AS1:
MOV A,0dh
ORL A,0eh
orl a,0fh
JZ AS2
MOV A,R3
ORL A,R4
orl a,r5
JNZ EQ1
mov r3,0dh
mov r4,0eh
mov r5,0fh ;a2=>a1
;************
MOV r2,0ch
;************
MOV C,1EH
MOV 1FH,C
AS2: RET
EQ1: MOV A,R2
XRL A,0ch ;jie_ma
JZ AS4
JB ACC.7,EQ3
MOV A,R2
CLR C
SUBB A,0ch
JC EQ4
EQ2: CLR C
MOV A,0dh
RRC A
MOV 0dh,A
MOV A,0eh
RRC A
MOV 0eh,A
MOV A,0fh
RRC A
MOV 0fh,A
;**********
INC 0ch
;**********
ORL A,0eh
orl a,0dh
JNZ EQ1
MOV A,R2
MOV 0ch,A ;r4"
SJMP AS4
EQ3: MOV A,R2
JNB ACC.7,EQ2
EQ4: CLR C
LCALL RR1
;*************8
orl a,r4
ORL A,R3
JNZ EQ1
MOV A,0ch
MOV R2,A
AS4: JB F0,AS5
;****************
MOV A,R5
ADD A,0fh
MOV R5,A
MOV A,R4
ADDC A,0eh
MOV R4,A

MOV A,R3
ADDC A,0dh
MOV R3,A

JNC AS2
LJMP RR1
AS5: CLR C
MOV A,R5
SUBB A,0fh
MOV B,A
;************
MOV A,R4
SUBB A,0eh
mov r6,a;*****temp
MOV A,R3
SUBB A,0dh
JC AS6
MOV R5,B
MOV R3,A
mov r4,06h
LJMP RLN
AS6: CPL 1FH
CLR C
MOV A,0fh
SUBB A,R5
MOV R5,A
MOV A,0eh
SUBB A,R4
MOV R4,A
MOV A,0dh
SUBB A,R3
MOV R3,A
RLN: MOV A,R3
ORL A,R4
orl a,r5;****2002.6.18
JNZ RLN1
MOV R2,#0C1H
RET
RLN1: MOV A,R3
JB ACC.7,RLN2
CLR C
LCALL RL1
SJMP RLN
RLN2: CLR OV
RET
;*****************
RL1:
MOV A,R5
RLC A
MOV R5,a
;*******
MOV A,R4
RLC A
MOV R4,A
MOV A,R3
RLC A
MOV R3,A
DEC R2
CJNE R2,#0C0H,RL1E
CLR A
MOV R3,A
MOV R4,A
MOV R5,A
MOV R2,#0C1H
RL1E: CLR OV
RET
RR1: MOV A,R3
RRC A
MOV R3,A
MOV A,R4
RRC A
MOV R4,A
;*********
MOV A,R5
RRC A
MOV R5,A
;***********
INC R2
CLR OV
CJNE R2,#40H,RR1E
MOV R2,#3FH
SETB OV
RR1E: RET
(9)标号: DTOF 功能:三字节十六进制定点数转换成格式化浮点数
入口条件:三字节定点数的绝对值在[R0]中,数符在位1FH中,整数部分的位数在A中。
出口信息:转换成格式化浮点数在[R0]中(四字节)。
DTOF:
MOV R2,A ;;按整数的位数初始化阶码
MOV 03h,@R0 ;;将定点数作尾数
INC R0
MOV 04h,@R0
inc r0
mov 05h,@r0
dec r0
DEC R0
LCALL RLN ;;进行规格化
LJMP MOV0 ;;传送结果到[R0]中
(10) 标号: FINT 功能:浮点取整函数
入口条件:操作数在[R0]中。
出口信息:结果仍在[R0]中。
FINT: LCALL MVR0
LCALL INT
LJMP MOV0
;****************
INT:
MOV A,R3
ORL A,R4
orl a,r5
JNZ INTA
CLR 1FH
MOV R2,#41H
RET
INTA: MOV A,R2
JZ INTB
JB ACC.7,INTB
CLR C
SUBB A,#24 ;;24 wei
JC INTD
RET
INTB: CLR A
MOV R5,A
MOV R4,A
MOV C,1FH
rrc a
MOV R3,A
Rl A  ;2002.6.20!!!!!!!!!!
MOV R2,A
JNZ INTC
MOV R2,#41H
INTC: RET
INTD: CLR F0
INTE: CLR C
LCALL RR1
ORL C,F0
MOV F0,C
CJNE R2,#24,INTE
JNB F0,INTF
JNB 1FH,INTF
INC R5
MOV A,R5
JNZ INTF
mov a,r4
add a,#01;;;;in
mov a,r3
addc a,#00
INTF: LJMP RLN
ADD0:CLR C;双精度加法子程序
ADC0:XCH A,R7;双精度带进位位加法子程序
ADDC A,R3
XCH  A,R7
XCH  A,R6
ADDC A,R2
XCH  A,R6
RET
SRA0:CLR C;尾数逻辑右移1位子程序
SRA:XCH A,R5;尾数带进位位右移1位
SRA1:RRC A;A R6 R7带进位位右移1位,结果在R5 R6 R7中
XCH A,R5
XCH A,R6
RRC A
XCH A,R6
XCH A,R7
RRC A
XCH A,R7
RET
INC3:
mov a,r7
add a,#1
mov r7,a
mov a,r6
addc a,#0
mov r6,a
mov a,r5
addc a,#0
jnz inc321
mov a,#80h
inc321:
mov r5,a
mov a,09h
addc a,#0;2002.6.18
mov 09h,a
RET0:RET
H0:
XCH A,R7;尾数带进位左移1位
RLC A
XCH A,R7
XCH A,R6
RLC A
XCH A,R6
XCH A,R5
RLC A
XCH A,R5
push a
dec 09h
mov a,09h
CJNE a,#0C0H,RL1E11
MOV R5,#0
MOV R6,#0
mov r7,#0
MOV 09h,#0C1H
RL1E11:
pop a
CLR OV
RET
(11)标号: FSGN 功能:浮点符号函数
入口条件:操作数在[R0]中。
出口信息:累加器 A=1 时为正数,A=0FFH时为负数,A=0 时为零。
FSGN: INC R0 ;;读尾数
MOV A,@R0
INC R0
ORL A,@R0
INC R0
ORL A,@R0
dec r0
DEC R0
DEC R0
JNZ SGN
RET ;;尾数为零,结束
SGN: MOV A,@R0 ;;读取操作数的阶码
RLC A ;;取数符
MOV A,#1 ;;按正数初始化
JNC SGN1 ;;是正数,结束
MOV A,#0FFH ;;是负数,改变标志
SGN1: RET
(12) 标号: FCLR 功能:浮点数清零
入口条件:操作数在[R0]中。
出口信息:操作数被清零。
FCLR:
INC R0
INC R0
inc r0
CLR A
MOV @R0,A
DEC R0
MOV @R0,A
DEC R0
MOV @R0,A
DEC R0
MOV @R0,#41H
RET
(13) 标号: FZER 功能:浮点数判零
入口条件:操作数在[R0]中。
出口信息:若累加器A为零,则操作数[R0]为零,否则不为零。
FZER:
INC R0
mov a,@r0
INC R0
orl A,@R0
inc r0
orl a,@r0
dec r0
DEC R0
DEC R0
JNZ ZERO
MOV @R0,#41H
ZERO: RET
(14) 标号: FPUSH 功能:浮点数压栈
入口条件:操作数在[R0]中。
出口信息:操作数压入栈顶。
FPUSH: POP ACC ;将返回地址保存在R2R3r4中
MOV R2,A
POP ACC
MOV R3,A
pop acc
mov r4,a
;*******
MOV A,@R0 ;将操作数压入堆栈
PUSH ACC
INC R0
MOV A,@R0
PUSH ACC
INC R0
MOV A,@R0
PUSH ACC
inc r0
mov a,@r0
push a
dec r0
DEC R0
DEC R0
mov a,r4
push a
MOV A,R3 ;将返回地址压入堆栈
PUSH ACC
MOV A,R2
PUSH ACC
RET
;***************
(15) 标号: FPOP 功能:浮点数出栈
入口条件:操作数处于栈顶。
出口信息:操作数弹至[R0]中。
FPOP: POP ACC ;将返回地址保存在R2R3r4中
MOV R2,A
POP ACC
MOV R3,A
pop a
mov r4,a
;**********
INC R0
INC R0
inc r0
POP ACC ;将操作数弹出堆栈,传送到[R0]中
MOV @R0,A
DEC R0
POP ACC
MOV @R0,A
DEC R0
POP ACC
MOV @R0,A
dec r0
pop a
mov @R0,A
MOV A,R4
PUSH A
MOV A,R3 ;将返回地址压入堆栈
PUSH ACC
MOV A,R2
PUSH ACC
RET
(16) 标号: FTOD 功能:格式化浮点数转换成双字节定点数
入口条件:格式化浮点操作数在[R0]中。
出口信息:OV=1时溢出,OV=0时转换成功:定点数的绝对值在[R0]中(双字节),数符
在位1FH中,F0=1 时为整数,CY=1时为一字节整数一字节小数,否则为纯小数。
FTOD: LCALL MVR0 ;;将[R0]传送到第一工作区
MOV A,R2
JZ FTD4 ;;阶码为零,纯小数
JB ACC.7,FTD4;;阶码为负,纯小数
SETB C
SUBB A,#10H
JC FTD1
SETB OV ;;阶码大于16,溢出
RET
FTD1: SETB C
MOV A,R2
SUBB A,#8 ;;阶码大于8否?
JC FTD3
FTD2: MOV B,#10H ;;阶码大于8,按双字节整数转换
LCALL FTD8
SETB F0 ;;设立双字节整数标志
CLR C
CLR OV
RET
FTD3: MOV B,#8 ;;按一字节整数一字节小数转换
LCALL FTD8
SETB C ;;设立一字节整数一字节小数标志
CLR F0
CLR OV
RET
FTD4: MOV B,#0 ;;按纯小数转换
LCALL FTD8
CLR OV ;;设立纯小数标志
CLR F0
CLR C
RET
FTD8: MOV A,R2 ;;按规定的整数位数进行右规
CJNE A,B,FTD9
MOV A,R3 ;;将双字节结果传送到[R0]中
MOV @R0,A
INC R0
MOV A,R4
MOV @R0,A
inc r0
MOV A,R5
MOV @R0,A
DEC R0
dec r0
RET
FTD9: CLR C
LCALL RR1 ;右规一次
SJMP FTD8

7.uClinux上的应用程序设计
在Project目录下的Makefile文件如下:
###########################################################
#
# Makefile – Whole Project makefile.
#
# Copyright (c) 2001-2002, Tsinghua MAC
#
###########################################################
#
# Get the core stuff worked out
#

ROOT_DIR = $(shell pwd)
SRC_DIR = $(ROOT_DIR)/src
CONFIG_DIR = $(ROOT_DIR)/config
SCRIPTS_DIR = $(ROOT_DIR)/scripts

CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
     else if [ -x /bin/bash ]; then echo /bin/bash; \
     else echo sh; fi ; fi)
TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi)

HPATH    = $(TOPDIR)/include
FINDHPATH  = $(HPATH)/asm $(HPATH)/linux $(HPATH)/scsi $(HPATH)/net

export ROOT_DIR SRC_DIR CONFIG_DIR SCRIPTS_DIR HPATH FINDHPATH

###########################################################
# normal make targets
#
#
.PHONY: all
all:
    $(MAKE) -C $(SRC_DIR) all
###########################################################

#
# Config stuff, we recall ourselves to load the new config.arch before
# running the kernel and other config scripts
#
.PHONY: config
config: $(CONFIG_DIR)/config.in
    cd $(CONFIG_DIR); $(CONFIG_SHELL) $(SCRIPTS_DIR)/Configure $(CONFIG_DIR)/config.in
    @rm -f $(SRC_DIR)/arch.config
    @if egrep "^CONFIG_DEFAULTS_INTEL_I386" $(CONFIG_DIR)/.config > /dev/null; then \
       ln -s "$(CONFIG_DIR)/arch.i386" $(SRC_DIR)/arch.config; \
    fi
    @if egrep "^CONFIG_DEFAULTS_MOTOROLA_M5272C3" $(CONFIG_DIR)/.config > /dev/null; then \
       ln -s "$(CONFIG_DIR)/arch.m68k" $(SRC_DIR)/arch.config; \
    fi
    @echo "#This dir.config file is automaticly generated by make config!" > $(SRC_DIR)/dir.config
    @echo "ROOT_DIR="$(ROOT_DIR) >> $(SRC_DIR)/dir.config
    @echo "CONFIG_DIR="$(CONFIG_DIR) >> $(SRC_DIR)/dir.config
    @echo "SRC_DIR="$(SRC_DIR) >> $(SRC_DIR)/dir.config
    @echo "SCRIPTS_DIR="$(SCRIPTS_DIR) >> $(SRC_DIR)/dir.config
    @echo "HPATH="$(HPATH) >> $(SRC_DIR)/dir.config
    @echo "FINDPATH="$(FINDPATH) >> $(SRC_DIR)/dir.config

###########################################################
#
# normal make dependancy
#
#
.PHONY: dep
dep:
    $(MAKE) -C $(SRC_DIR) dep

# This one removes all executables from the tree and forces their relinking
clean:
    $(MAKE) -C $(SRC_DIR) clean
   
test:
    $(MAKE) -C $(SRC_DIR) test

run:
    $(MAKE) -C $(SRC_DIR) run

config_error:
    @echo "*************************************************"
    @echo "You have not run make config."
    @echo "The build sequence for this source tree is:"
    @echo "1. "make config" or "make xconfig""
    @echo "2. "make dep""
    @echo "3. "make""
    @echo "*************************************************"
    @exit 1
###########################################################

src目录下的Makefile文件,如下:

VERSION = 2
PATCHLEVEL = 0
SUBLEVEL = 39
UCRELEASE = uc2

.EXPORT_ALL_VARIABLES:

CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
     else if [ -x /bin/bash ]; then echo /bin/bash; \
     else echo sh; fi ; fi)
TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi)

TARGET = ESGateway

all:  $(TARGET)

# Include the make variables (CC, etc...)
#

SUBDIRS       = public serial packet cal xml fifo main interface

$(TARGET):
    @set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i all_targets; done

linuxsubdirs: dummy
    set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i; done

clean:  
    @set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i clean; done

dep:   
    @set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i fastdep; done

.PHONY: test
test:
    @set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i test; done

run:   
#   @set -e; for i in $(SUBDIRS); do $(MAKE) -i -C $$i run; read junk; done
    make -C main run

src目录下的Rules.make文件给出了编译的一些规则,如下:
#
# This file contains rules which are shared between multiple Makefiles.
#

#
# False targets.
#
.PHONY: dummy

#
# Special variables which should not be exported
#
unexport EXTRA_ASFLAGS
unexport EXTRA_CFLAGS
ifneq "$(ARCH)" "h8300"
unexport EXTRA_LDFLAGS
endif
unexport EXTRA_ARFLAGS
unexport SUBDIRS
unexport SUB_DIRS
unexport ALL_SUB_DIRS
unexport MOD_SUB_DIRS
unexport O_TARGET
unexport O_OBJS
unexport L_OBJS
unexport M_OBJS
unexport MI_OBJS
unexport ALL_MOBJS
# objects that export symbol tables
unexport OX_OBJS
unexport LX_OBJS
unexport MX_OBJS
unexport MIX_OBJS
unexport SYMTAB_OBJS

unexport MOD_LIST_NAME

include ../dir.config
include $(SRC_DIR)/arch.config

#
# Get things started.
#
first_rule: sub_dirs
    $(MAKE) all_targets

#
# Common rules
#
INC_DIR = -I$(SRC_DIR)/cal -I$(SRC_DIR)/xml -I$(SRC_DIR)/serial -I$(SRC_DIR)/packet -I$(SRC_DIR)/fifo -I$(SRC_DIR)/ping -I$(SRC_DIR)/interface -I$(SRC_DIR)/public

%.o: %.c
    @echo "Compiling..."
    @echo "$<"
    $(CXX) $(INC_DIR) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
   
%.o: %.cpp
    @echo "Compiling..."
    @echo "$<" 
    $(CXX) $(INC_DIR) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
   
# Rule to compile a set of .o files into one .o file
#

ifeq (.depend,$(wildcard .depend))
include .depend
else
.depend:    fastdep 
endif

ifneq ($(O_TARGET),$(O_OBJS))
$(O_TARGET): .depend $(O_OBJS)
    @echo "Linking..."
    @echo $(O_OBJS) " --> " $@
    @$(LD) $(EXTRA_LDFLAGS) -r -o $@ $(O_OBJS)
else
$(O_TARGET): .depend
endif
#
#
#

all:  $(O_OBJS)
    echo all

all_targets: $(O_OBJS) $(O_TARGET)

#

#
# Rule to compile a set of .o files into one .a file
#
ifdef L_TARGET
$(L_TARGET): $(LX_OBJS) $(L_OBJS)
    rm -f $@
    $(AR) $(EXTRA_ARFLAGS) rcs $@ $(LX_OBJS) $(L_OBJS)
endif

#
# This make dependencies quickly
#
fastdep: dummy
    @echo "make fastdep"
    if [ -n "$(wildcard *.[chS])" ]; then \
    $(SCRIPTS_DIR)/mkdep *.[chS] > .depend; fi
    if [ -n "$(wildcard *.cpp)" ]; then \
    $(SCRIPTS_DIR)/mkdep *.cpp >> .depend; fi

#
# A rule to make subdirectories
#
sub_dirs: dummy
ifdef SUB_DIRS
    set -e; for i in $(SUB_DIRS); do $(MAKE) -C $$i; done
endif
#
# A rule to do nothing
#
dummy:

config:
    cd $(ROOT_DIR); make config

c clean:
    rm -f *.o
    rm -f *.gdb
    rm -f .depend
    rm -f test
    rm -f core
    rm -f *.elf
    rm -f *.elf2flt 

#
# This is useful for testing
#
script:
    $(SCRIPT)

run: test
    @echo ... running ...
    @echo `pwd`/test
    @./test
   
#
# This sets version suffixes on exported symbols
# Uses SYMTAB_OBJS
# Separate the object into "normal" objects and "exporting" objects
# Exporting objects are: all objects that define symbol tables
#


$(MX_OBJS):
    $(CC) $(CFLAGS) -DEXPORT_SYMTAB -c $(@:.o=.c)

$(LX_OBJS) $(OX_OBJS):
    $(CC) $(CFLAGS) -DMODVERSIONS -DEXPORT_SYMTAB -c $(@:.o=.c)

$(M_OBJS):
ifdef MAKING_MODULES
$(O_OBJS) $(L_OBJS):
endif


在config 目录下,编写两个和架构有关的文件,对于x86平台,是arch.i386,如下:
.EXPORT_ALL_VARIABLES:
###################################################################
#
# Vendor specific settings
#

CONSOLE_BAUD_RATE = 19200

###################################################################
#
# The makefiles need to know how to do things in different contexts
# To save some pain we put it all here
#
# First settings we always want for all build
#

# ARCH = kernel, TARGET_ARCH = uClibc

MACHINE    = i386
ARCH     = i386
CROSS_COMPILE =
CROSS     = $(CROSS_COMPILE)

# We"ve used -m5307 here because the bulk of the 5272 instruction timings
# happen to be closer to the 5307 than the 5200 series. Luckily, the
# actual instructions on the two processors are essentially identical.
# This should be fixed at some stage.
CPUFLAGS =
CC    = $(CROSS_COMPILE)gcc
AS    = $(CROSS_COMPILE)as
CXX    = $(CROSS_COMPILE)g++
AR    = $(CROSS_COMPILE)ar
LD    = $(CROSS_COMPILE)ld
OBJCOPY  = $(CROSS_COMPILE)objcopy
RANLIB  = $(CROSS_COMPILE)ranlib

STRIPTOOL = $(CROSS_COMPILE)strip
STRIP   = $(STRIPTOOL)

UCLINUX_BUILD_SET = 0               # have we set a special config below

###################################################################
#
# General purpose lib building rules, uClibc.config uses these when
# possible
#


###################################################################
# Settings for building user apps
#
    CFLAGS = -Wall -Wstrict-prototypes -O2 -g
    #CFLAGS = -Wstrict-prototypes -g
    LDFLAGS = -m elf_i386
###################################################################
# fall through, do other config options perhaps
#
ifeq ($(UCLINUX_BUILD_SET),1)
endif
###################################################################

在config 目录下,对于嵌入式平台,是arch.m68k,如下:

.EXPORT_ALL_VARIABLES:
###################################################################
#
# Vendor specific settings
#
CONSOLE_BAUD_RATE = 19200
###################################################################
#
# The makefiles need to know how to do things in different contexts
# To save some pain we put it all here
#
# First settings we always want for all build
#
# ARCH = kernel, TARGET_ARCH = uClibc

MACHINE    = m68k
ARCH     = m68knommu
CROSS_COMPILE = m68k-elf-
CROSS     = $(CROSS_COMPILE)

# We"ve used -m5307 here because the bulk of the 5272 instruction timings
# happen to be closer to the 5307 than the 5200 series. Luckily, the
# actual instructions on the two processors are essentially identical.
# This should be fixed at some stage.
CPUFLAGS = -m5200
CC    = $(CROSS_COMPILE)gcc
AS    = $(CROSS_COMPILE)as
CXX    = $(CROSS_COMPILE)g++
AR    = $(CROSS_COMPILE)ar
LD    = $(CROSS_COMPILE)ld
OBJCOPY  = $(CROSS_COMPILE)objcopy
RANLIB  = $(CROSS_COMPILE)ranlib
ELF2FLT  = elf2flt
STRIPTOOL = $(CROSS_COMPILE)strip
STRIP   = $(STRIPTOOL)

UCLINUX_BUILD_SET = 0               # have we set a special config below


###################################################################
#
# Settings for building user apps
#
#CFLAGS = -m5200 -msep-data -g
CFLAGS = -m5200 -msep-data
LDFLAGS = -Wl,-elf2flt
SYSLIBS = -lc -lstdc++ -lgcc
###################################################################
#
# fall through, do other config options perhaps
#

ifeq ($(UCLINUX_BUILD_SET),1)
endif
###################################################################

在config 目录下的config.in文件如下:

mainmenu_name "uClinux Configuration"
mainmenu_option next_comment
comment "Target Platform Selection"
comment "Choose a Vendor/Product combination."
choice "Vendor/Product [Intel/i386 | Motorola/M5307C3] " "1 CONFIG_DEFAULTS_INTEL_I386 \
2 CONFIG_DEFAULTS_MOTOROLA_M5307C3 \
" Intel/i386
endmenubsp;     /*产生停止位*/
       return (1);        /*错误*/
     Delay(10);
       SDA = 1;
       return (0);
     }
    }
    return (1);          /*错误*/
}
3.8 T2中断服务程序
T2中断服务程序int_timer2_handler用于发送、接受数据,每次中断发送或接受一位数据。程序清单如下:
void int_timer2_handler(void) interrupt 0x22 
{ if (TX_RX)
    {/*接收模式*/
    SCL = 1;
     bit_count++;
     if (bit_count <= 8)
     { if (SDA)
       rec_data |= mask;        /*接收字节存于变量rec_data中*/
      else              
       { time_out = period;        /*用于延时*/
         SCL = 1;
       }
       mask = mask >> 1;
       SCL = 0;            
     if (bit_count == 8)
       { DSDA = 1;               /*设置SDA为输出*/
         if (Ackge)             /*置应答位*/
         SDA = 1;
        else SDA = 0;
        }
      }
        else if (bit_count == 9)
        {/*一个字节接收结束*/
         if (bit_count == 9)         /*延时*/
         { SCL = 1;
          SCL = 1;
          SCL = 1;
         T2IE = 0;         /*中断复位*/
          T3IE = 0;
          T2IR = 0;
          T3R = 0;
          COM_ON = 0;         /*通信结束*/
          SCL = 0;
          }
        }
    }
/*发送模式*/
    else
    { SCL = 1;
      bit_count++;
      if (bit_count <= 8)
        { temp_SDA = 0;
       if (mask & input_data)    /*准备下一位*/
           temp_SDA = 1;
       mask = mask >> 1;     
         SCL = 0;
       if (bit_count != 8)
         SDA = temp_SDA;    /*当时钟为低时发送一位数据 */
        else DSDA = 0;      /*释放SDA以接收ack位*/
      }
      else if (bit_count == 9)   
           { RecAck = SDA;      /*在第9个时钟周期读应答位*/
         if (bit_count == 9)     /*延时*/
             { SCL = 1;           /*1字节发送结束*/
              T2IE = 0;
              T3IE = 0;
              T2IR = 0;
          T3R = 0;
          COM_ON = 0;         /*通信结束*/ 
          SCL = 0;
          }
        }
    }                  /*发送结束*/
}                                
虚拟软件包见文件:I2c_hw。



6.MCS-51四字节浮点库及其使用说明
浮点库程序清单如下:
程序清单:
(1) 标号: BTOF 功能:浮点BCD码转换成格式化浮点数
入口条件:浮点BCD码操作数在[R0]中。
出口信息:转换成的格式化浮点数仍在[R0]中。
BTOF: INC R0
INC R0
inc r0;read L
MOV 07h,@R0
DEC R0
MOV 06h,@R0
DEC R0
mov 05h,@r0
;r5r6r7=0.hml(dec)
dec r0 ;;r0 to jie_ma
mov a,r7
ORL A,R6
orl a,r5
jnz btf0 ;jb r5r6r7=0
MOV @R0,#41H
RET
BTF0: MOV A,@R0
MOV C,ACC.7
MOV 1DH,C
CLR 1FH
MOV C,ACC.6
MOV ACC.7,C
MOV @R0,A
JNC BTF1
ADD A,#19
JC BTF2
MOV @R0,#41H
INC R0
MOV @R0,#0
INC R0
MOV @R0,#0
inc r0
MOV @R0,#0
DEC R0
DEC R0
dec r0
RET
BTF1: SUBB A,#19
JC BTF2
MOV A,#3FH
MOV C,1DH
MOV ACC.7,C
MOV @R0,A
INC R0
MOV @R0,#0FFH
INC R0
MOV @R0,#0FFH
inc r0
MOV @R0,#0FFH
dec r0
DEC R0
DEC R0
RET
BTF2: CLR A ;use r1.r2r3r4
MOV R4,A
MOV R3,A
MOV R2,a
mov r1,#24 ;3byte =3*8=24
BTF3: MOV A,R7
ADD A,R7
DA A
MOV R7,A
MOV A,R6
ADDC A,R6
DA A
MOV R6,A
mov a,r5
addc a,r5
da a
mov r5,a;r5r6r7*2
MOV A,R4
RLC A
MOV R4,A
MOV A,R3
RLC A
MOV R3,A
mov a,r2
rlc a
mov r2,a ;count .r5r6r7(10)=>.r2r3r4(2)
DEC R1
JNB ACC.7,BTF3
MOV A,R5
ADD A,#0B0H
CLR A
ADDC A,R4
MOV R4,A
CLR A
ADDC A,R3
MOV R3,A
CLR A
ADDC A,R2
MOV R2,A
JNC BTF4
MOV R2,#80H
INC R1
BTF4:
MOV DPTR,#BTFL
MOV A,@R0
ADD A,#19
MOV B,#4 ;4 byte
MUL AB
ADD A,DPL
MOV DPL,A
JNC BTF5
INC DPH
BTF5: CLR A
MOVC A,@A+DPTR
MOV C,ACC.6
MOV ACC.7,C
MOV 0ch,A ;r4"=0ch
MOV A,#1
MOVC A,@A+DPTR
MOV 0dh,A
MOV A,#2
MOVC A,@A+DPTR
MOV 0eh,A
MOV A,#3
MOVC A,@A+DPTR
MOV 0fh,A
LCALL MUL1
MOV C,1DH
MOV 1FH,C
LJMP MOV0

(2) 标号: FTOB 功能:格式化浮点数转换成浮点BCD码
入口条件:格式化浮点操作数在[R0]中。
出口信息:转换成的浮点BCD码仍在[R0]中。
FTOB: INC R0
MOV A,@R0 ;h
INC R0
ORL A,@R0 ;m
inc r0
orl a,@r0 ;l
dec r0
DEC R0
DEC R0
JNZ FTB0
MOV @R0,#41H
RET
FTB0: MOV A,@R0
MOV C,ACC.7
MOV 1DH,C
CLR ACC.7
MOV @R0,A
LCALL MVR0
MOV DPTR,#BFL0
MOV B,#0
MOV A,R2
JNB ACC.7,FTB1
MOV DPTR,#BTFL
MOV B,#0EDH
ADD A,#16
JNC FTB1
MOV DPTR,#BFLN
MOV B,#0FAH
FTB1: CLR A
MOVC A,@A+DPTR
MOV C,ACC.6
MOV ACC.7,C
MOV 0ch,A ;r4"
MOV A,#1
MOVC A,@A+DPTR
MOV 0dh,A
MOV A,#2
MOVC A,@A+DPTR
MOV 0eh,A
MOV A,#3
MOVC A,@A+DPTR
MOV 0fh,A
MOV A,0ch ;r4" jie_ma
CLR C
SUBB A,R2
JB ACC.7,FTB2
JNZ FTB3
MOV A,0dh ;0.r5"r6"r7"-0.r3r4r5
CLR C
SUBB A,R3
JC FTB2
JNZ FTB3
MOV A,0eh;r6"-r4;;;2002.6.18
CLR C
SUBB A,r4
JC FTB2
JNZ FTB3
MOV 0ah,B
INC 0ah
MOV 0dh,#10h;0.100000
MOV r6,#0
MOV r7,#0
SJMP FTB6
FTB2: INC DPTR
INC DPTR
INC DPTR
inc dptr  ;4byte
INC B
SJMP FTB1 
FTB3: PUSH B
CALL DIV3
FTB4: MOV A,r2
JZ FTB5
CLR C
LCALL RR1
SJMP FTB4
FTB5:
POP 0ah
LCALL HB2
MOV 0dh,A;r5"
LCALL HB2
MOV R6,A
LCALL HB2
MOV R7,A
MOV A,R3
RLC A
CLR A
ADDC A,R7
DA A
MOV R7,A
CLR A
ADDC A,R6
DA A
MOV R6,A
JNC FTB6
MOV R6,#10H
INC 0dh
FTB6:
INC R0
INC R0
inc r0
MOV A,R7
MOV @R0,A
DEC R0
MOV A,R6
MOV @R0,A
DEC R0
MOV A,0dh
mov @r0,a
dec r0
mov a,0ah
MOV C,1DH
MOV ACC.7,C
MOV @R0,A
RET
;[r3r4r5*100]\10=>bcd1,2
HB2:
MOV A,R5
MOV B,#100
MUL AB
MOV R5,A
MOV A,B
XCH A,R4
MOV B,#100
MUL AB
ADD A,R4
MOV R4,A
;JNC HB21
mov a,B
addc a,#0
xch a ,r3
mov b,#100
mul ab
add a,r3
mov r3,a
mov a,b
addc a,#0
HB21: ;MOV A,B
MOV B,#10
DIV AB
SWAP A
ORL A,B
RET
BTFL: DB 41H,0ECH,1EH ,4ah;10e-19
DB 45H,93H,92H,0efh;10e-18  
DB 48H,0B8H,77H,0aah;10e-17
DB 4BH,0E6H,95H,95h;10e-16
DB 4FH,90H,1DH ,7dh;10e-15
DB 52H,0B4H,24H,0dch;10e-14
DB 55H,0E1H,2EH,13h;10e-13
DB 59H,8CH,0BcH,0cch;10e-12
DB 5CH,0AFH,0EbH,0ffh;10e-11
DB 5FH,0DBH,0E6H,0ffh;10e-10
DB 63H,89H,70H ,5fh;10e-9
DB 66H,0ABH,0CCH,77h;10e-8
DB 69H,0D6H,0bfH,95h;10e-7
BFLN: DB 6DH,86H,37H ,0bdh;10e-6
DB 70H,0A7H,0C5H,0ach;10e-5
DB 73H,0D1H,0B7H,17h;10e-4
DB 77H,83H,12H ,6fh;10e-3
DB 7AH,0A3H,0D7H,0ah;10e-2
DB 7DH,0CCH,0CcH,0cdh;10e-1
BFL0: DB 1,80H,00H ,00h;10e0
DB 4,0A0H,00H,00h;10e1
DB 7,0C8H,00H,00h;10e2
DB 0AH,0FAH,00H,00h;10e3
DB 0EH,9CH,40H,00h;10e4
DB 11H,0C3H,50H,00;10e5
DB 14H,0F4H,24H,00h;10e6
DB 18H,98H,96H,80h;10e7
DB 1BH,0BEH,0BCH,20h;10e8
DB 1EH,0EEH,6BH,28h;10e9
DB 22H,95H,02H,0f9h;10e10
DB 25H,0BAH,43H,0b7h;10e11
DB 28H,0E8H,0D4h,0a5h;10e12
DB 2CH,91H,84H,0e7h;10e13
DB 2FH,0B5H,0E6H,20h;10e14
DB 32H,0E3H,5fH,0a9h;10e15
DB 36H,8EH,1bH,0cah;10e16
DB 39H,0c1H,0A2H,0cdh;10e17
DB 3CH,0DEH,0BH,5bh;10e18
DB 40H,8AH,0d7H,23h;10e19
(3) 标号: FMUL 功能:浮点数乘法
入口条件:被乘数在[R0]中,乘数在[R1]中。
出口信息:OV=0时,积仍在[R0]中,OV=1时,溢出。
FMUL: LCALL MVR0
MOV A,@R0
XRL A,@R1
RLC A
MOV 1FH,C
LCALL MUL0
LJMP MOV0
MUL0: LCALL MVR1
mov 01h,02h
mov 02h,03h
mov 03h,04h
mov 04h,05h
;;**************8
MUL1:
;***********
MOV A,R2 ;;第一尾数为零否?
ORL A,R3
orl a,r4
JZ MUL6
MOV A,0dh ;;第二尾数为零否?
ORL A,0eh
orl a,0fh
JZ MUL5;计算r2R3R4×r5R6R7-→r2R3R4
;************
mov 08h,r0;jie_ma piont
mov 09h,r1;jie_ma
mov 01h,r2
mov 02h,r3
mov 03h,r4
;************
MOV R0,#25;右移相加25次
CLR A
MOV R6,A
MOV R7,A;ACC,R6,R7为部分积累加器
CLR C
LOOP1:JNC M2
CALL ADD0
ADDC A,R1;乘数移出位等于1 ,被乘数往部分积里加1次
M2:CALL SRA1
XCH A,R5
CPL RS0
CALL SRA
CPL RS0;部分积带进位位整体右移1位
DJNZ R0,LOOP1
MOV R5,A
JB ACC.7,M3;查积最高位
MOV A,0DH
RLC A
CALL H0;积最高位为0,积整体算术左移1位
JNB ACC.7,Mul3
CALL INC3;尾数截去部分四舍五入
SJMP mul3
M3:
MOV A,0DH
JNB ACC.7,mul3;2002
CALL INC3;尾数截去部分四舍五入
;sjmp mul3

;***************
MUL3:
;***********
mov r0,08h
mov 03h,r5
mov 04h,r6
mov 05h,r7
;*************
MOV A,09h
ADD A,0ch
MD: MOV r2,A
JB ACC.7,MUL4
JNB ACC.6,MUL6
MOV r2,#3FH
SETB OV
RET
MUL4: JB ACC.6,MUL6
MUL5:
CLR A
mov r5,a   ;out r2.r3r4r5=fu(2)
MOV R3,A
MOV R4,A
MOV R2,#41H
MUL6: CLR OV
RET
(4) 标号: FDIV 功能:浮点数除法
入口条件:被除数在[R0]中,除数在[R1]中。
出口信息:OV=0时,商仍在[R0]中,OV=1时,溢出。
FDIV:
INC R0
MOV A,@R0
INC R0
ORL A,@R0
inc r0
orl a,@r0
dec r0
DEC R0
DEC R0
JNZ DIV1
MOV @R0,#41H
CLR OV
RET
DIV1: INC R1
MOV A,@R1
INC R1
ORL A,@R1
inc r1
orl a,@r1
dec r1
DEC R1
DEC R1
JNZ DIV2
SETB OV
RET
DIV2: LCALL MVR0
MOV A,@R0
XRL A,@R1
RLC A
MOV 1FH,C
LCALL MVR1
LCALL DIV3
LJMP MOV0
DIV3: CLR C ;r3r4r5-r5"r6"r7"
MOV A,R5  ;ASUBB A,0fh
mov a,r4
subb a,0eh
mov a,r3
subb a,0dh
JC DIV4
CALL RR1
SJMP DIV3
DIV4:
mov 08h,r0
mov 09h,r1
mov 0ah,r2
CLR A
mov r0,a
mov r1,a
mov r2,a
MOV B,#24   ;r3r4r5/r5"r6"r7"=>r0r1r2
DIV5: CLR C
mov a,r2
rlc a
mov r2,a
MOV A,R1
RLC A
MOV R1,A
MOV A,R0
RLC A
MOV R0,A
MOV A,R5
RLC A
MOV R5,A
XCH A,R4
RLC A
XCH A,R4
XCH A,R3
RLC A
XCH A,R3
MOV F0,C
CLR C
SUBB A,0fh;r7"
MOV r7,A ;r7 temp
MOV A,R4
SUBB A,0eh
MOV r6,A 
MOV A,R3
SUBB A,0dh
ANL C,/F0
JC DIV6
MOV R3,A
MOV 05h,07h;r7
mov 04h,06h
INC R2
DIV6: DJNZ B,DIV5
MOV A,0dh
CLR C
RRC A
SUBB A,R3
CLR A
ADDC A,R2
MOV R5,A
CLR A
ADDC A,R1
MOV R4,A
CLR A
ADDC A,R0
MOV R3,A
mov r0,08h
mov r1,09h
mov r2,0ah
MOV A,R2
CLR C
SUBB A,0ch
LCALL MD
LJMP RLN
(5) 标号: FMOV 功能:浮点数传送
入口条件:源操作数在[R1]中,目标地址为[R0]。
出口信息:[R0]=[R1],[R1]不变。
FMOV: INC R0
INC R0
inc r0
INC R1
INC R1
inc r1
MOV A,@R1
MOV @R0,A
DEC R0
DEC R1
MOV A,@R1
MOV @R0,A
DEC R0
DEC R1
MOV A,@R1
MOV @R0,A
DEC R0
DEC R1
MOV A,@R1
MOV @R0,A
RET
(6) 标号: FCMP 功能:浮点数代数值比较(不影响待比较操作数)
入口条件:待比较操作数分别在[R0]和[R1]中。
出口信息:若CY=1,则[R0] < [R1],若CY=0且A=0则 [R0] = [R1],否则[R0] > [R1]。
FCMP: MOV A,@R0
XRL A,@R1
JNB ACC.7,CMP2
MOV A,@R0
RLC A
MOV A,#0FFH
RET
CMP2: MOV A,@R1
MOV C,ACC.6
MOV ACC.7,C
MOV B,A
MOV A,@R0
MOV C,ACC.7
MOV F0,C
MOV C,ACC.6
MOV ACC.7,C
CLR C
SUBB A,B
JZ CMP6
RLC A
JNB F0,CMP5
CPL C
CMP5: MOV A,#0FFH
RET
;************
CMP6:
INC R0
INC R0
inc r0
inc r1
INC R1
INC R1
CLR C
MOV A,@R0
SUBB A,@R1
MOV B,A
DEC R0
DEC R1
MOV A,@R0
SUBB A,@R1
DEC R0
DEC R1
;***********
mov 0fh,a;r7"
MOV A,@R0
SUBB A,@R1
dec r0
dec r1
ORL A,0fh
orl a,b
JZ CMP7
JNB F0,CMP7
CPL C
CMP7: RET
(7) 标号: FADD 功能:浮点数加法
入口条件:被加数在[R0]中,加数在[R1]中。
出口信息:OV=0时,和仍在[R0]中,OV=1时,溢出。
FADD: CLR F0 ;设立加法标志
SJMP AS ;计算代数和
FADD: CLR F0
SJMP AS
(8) 标号: FSUB 功能:浮点数减法
入口条件:被减数在[R0]中,减数在[R1]中。
出口信息:OV=0时,差仍在[R0]中,OV=1时,溢出。
FSUB: SETB F0
AS: LCALL MVR1
MOV C,F0
RRC A
XRL A,@R1
MOV C,ACC.7
ASN: MOV 1EH,C
XRL A,@R0
RLC A
MOV F0,C
LCALL MVR0
LCALL AS1
MOV0:
INC R0
INC R0
inc r0
mov a,r5
mov @r0,a
dec r0
MOV A,R4
MOV @R0,A
DEC R0
MOV A,R3
MOV @R0,A
DEC R0
MOV A,R2
MOV C,1FH
MOV ACC.7,C
MOV @R0,A
CLR ACC.7
CLR OV
CJnE A,#3FH,MV01
SETB OV
MV01: MOV A,@R0
RET
MVR0: MOV A,@R0
MOV C,ACC.7
MOV 1FH,C
MOV C,ACC.6
MOV ACC.7,C
MOV R2,A
INC R0
MOV A,@R0
MOV R3,A
INC R0
MOV A,@R0
MOV R4,A
inc r0
mov a,@r0
mov r5,a
dec r0
DEC R0
DEC R0
RET
MVR1: MOV A,@R1
MOV C,ACC.7
MOV 1EH,C
MOV C,ACC.6
MOV ACC.7,C
MOV 0ch,A ;r4"
INC R1
MOV A,@R1
MOV 0dh,A
INC R1
MOV A,@R1
MOV 0eh,A
INC R1
MOV A,@R1
MOV 0fh,A
dec r1
DEC R1
DEC R1
RET
AS1:
MOV A,0dh
ORL A,0eh
orl a,0fh
JZ AS2
MOV A,R3
ORL A,R4
orl a,r5
JNZ EQ1
mov r3,0dh
mov r4,0eh
mov r5,0fh ;a2=>a1
;************
MOV r2,0ch
;************
MOV C,1EH
MOV 1FH,C
AS2: RET
EQ1: MOV A,R2
XRL A,0ch ;jie_ma
JZ AS4
JB ACC.7,EQ3
MOV A,R2
CLR C
SUBB A,0ch
JC EQ4
EQ2: CLR C
MOV A,0dh
RRC A
MOV 0dh,A
MOV A,0eh
RRC A
MOV 0eh,A
MOV A,0fh
RRC A
MOV 0fh,A
;**********
INC 0ch
;**********
ORL A,0eh
orl a,0dh
JNZ EQ1
MOV A,R2
MOV 0ch,A ;r4"
SJMP AS4
EQ3: MOV A,R2
JNB ACC.7,EQ2
EQ4: CLR C
LCALL RR1
;*************8
orl a,r4
ORL A,R3
JNZ EQ1
MOV A,0ch
MOV R2,A
AS4: JB F0,AS5
;****************
MOV A,R5
ADD A,0fh
MOV R5,A
MOV A,R4
ADDC A,0eh
MOV R4,A

MOV A,R3
ADDC A,0dh
MOV R3,A

JNC AS2
LJMP RR1
AS5: CLR C
MOV A,R5
SUBB A,0fh
MOV B,A
;************
MOV A,R4
SUBB A,0eh
mov r6,a;*****temp
MOV A,R3
SUBB A,0dh
JC AS6
MOV R5,B
MOV R3,A
mov r4,06h
LJMP RLN
AS6: CPL 1FH
CLR C
MOV A,0fh
SUBB A,R5
MOV R5,A
MOV A,0eh
SUBB A,R4
MOV R4,A
MOV A,0dh
SUBB A,R3
MOV R3,A
RLN: MOV A,R3
ORL A,R4
orl a,r5;****2002.6.18
JNZ RLN1
MOV R2,#0C1H
RET
RLN1: MOV A,R3
JB ACC.7,RLN2
CLR C
LCALL RL1
SJMP RLN
RLN2: CLR OV
RET
;*****************
RL1:
MOV A,R5
RLC A
MOV R5,a
;*******
MOV A,R4
RLC A
MOV R4,A
MOV A,R3
RLC A
MOV R3,A
DEC R2
CJNE R2,#0C0H,RL1E
CLR A
MOV R3,A
MOV R4,A
MOV R5,A
MOV R2,#0C1H
RL1E: CLR OV
RET
RR1: MOV A,R3
RRC A
MOV R3,A
MOV A,R4
RRC A
MOV R4,A
;*********
MOV A,R5
RRC A
MOV R5,A
;***********
INC R2
CLR OV
CJNE R2,#40H,RR1E
MOV R2,#3FH
SETB OV
RR1E: RET
(9)标号: DTOF 功能:三字节十六进制定点数转换成格式化浮点数
入口条件:三字节定点数的绝对值在[R0]中,数符在位1FH中,整数部分的位数在A中。
出口信息:转换成格式化浮点数在[R0]中(四字节)。
DTOF:
MOV R2,A ;;按整数的位数初始化阶码
MOV 03h,@R0 ;;将定点数作尾数
INC R0
MOV 04h,@R0
inc r0
mov 05h,@r0
dec r0
DEC R0
LCALL RLN ;;进行规格化
LJMP MOV0 ;;传送结果到[R0]中
(10) 标号: FINT 功能:浮点取整函数
入口条件:操作数在[R0]中。
出口信息:结果仍在[R0]中。
FINT: LCALL MVR0
LCALL INT
LJMP MOV0
;****************
INT:
MOV A,R3
ORL A,R4
orl a,r5
JNZ INTA
CLR 1FH
MOV R2,#41H
RET
INTA: MOV A,R2
JZ INTB
JB ACC.7,INTB
CLR C
SUBB A,#24 ;;24 wei
JC INTD
RET
INTB: CLR A
MOV R5,A
MOV R4,A
MOV C,1FH
rrc a
MOV R3,A
Rl A  ;2002.6.20!!!!!!!!!!
MOV R2,A
JNZ INTC
MOV R2,#41H
INTC: RET
INTD: CLR F0
INTE: CLR C
LCALL RR1
ORL C,F0
MOV F0,C
CJNE R2,#24,INTE
JNB F0,INTF
JNB 1FH,INTF
INC R5
MOV A,R5
JNZ INTF
mov a,r4
add a,#01;;;;in
mov a,r3
addc a,#00
INTF: LJMP RLN
ADD0:CLR C;双精度加法子程序
ADC0:XCH A,R7;双精度带进位位加法子程序
ADDC A,R3
XCH  A,R7
XCH  A,R6
ADDC A,R2
XCH  A,R6
RET
SRA0:CLR C;尾数逻辑右移1位子程序
SRA:XCH A,R5;尾数带进位位右移1位
SRA1:RRC A;A R6 R7带进位位右移1位,结果在R5 R6 R7中
XCH A,R5
XCH A,R6
RRC A
XCH A,R6
XCH A,R7
RRC A
XCH A,R7
RET
INC3:
mov a,r7
add a,#1
mov r7,a
mov a,r6
addc a,#0
mov r6,a
mov a,r5
addc a,#0
jnz inc321
mov a,#80h
inc321:
mov r5,a
mov a,09h
addc a,#0;2002.6.18
mov 09h,a
RET0:RET
H0:
XCH A,R7;尾数带进位左移1位
RLC A
XCH A,R7
XCH A,R6
RLC A
XCH A,R6
XCH A,R5
RLC A
XCH A,R5
push a
dec 09h
mov a,09h
CJNE a,#0C0H,RL1E11
MOV R5,#0
MOV R6,#0
mov r7,#0
MOV 09h,#0C1H
RL1E11:
pop a
CLR OV
RET
(11)标号: FSGN 功能:浮点符号函数
入口条件:操作数在[R0]中。
出口信息:累加器 A=1 时为正数,A=0FFH时为负数,A=0 时为零。
FSGN: INC R0 ;;读尾数
MOV A,@R0
INC R0
ORL A,@R0
INC R0
ORL A,@R0
dec r0
DEC R0
DEC R0
JNZ SGN
RET ;;尾数为零,结束
SGN: MOV A,@R0 ;;读取操作数的阶码
RLC A ;;取数符
MOV A,#1 ;;按正数初始化
JNC SGN1 ;;是正数,结束
MOV A,#0FFH ;;是负数,改变标志
SGN1: RET
(12) 标号: FCLR 功能:浮点数清零
入口条件:操作数在[R0]中。
出口信息:操作数被清零。
FCLR:
INC R0
INC R0
inc r0
CLR A
MOV @R0,A
DEC R0
MOV @R0,A
DEC R0
MOV @R0,A
DEC R0
MOV @R0,#41H
RET
(13) 标号: FZER 功能:浮点数判零
入口条件:操作数在[R0]中。
出口信息:若累加器A为零,则操作数[R0]为零,否则不为零。
FZER:
INC R0
mov a,@r0
INC R0
orl A,@R0
inc r0
orl a,@r0
dec r0
DEC R0
DEC R0
JNZ ZERO
MOV @R0,#41H
ZERO: RET
(14) 标号: FPUSH 功能:浮点数压栈
入口条件:操作数在[R0]中。
出口信息:操作数压入栈顶。
FPUSH: POP ACC ;将返回地址保存在R2R3r4中
MOV R2,A
POP ACC
MOV R3,A
pop acc
mov r4,a
;*******
MOV A,@R0 ;将操作数压入堆栈
PUSH ACC
INC R0
MOV A,@R0
PUSH ACC
INC R0
MOV A,@R0
PUSH ACC
inc r0
mov a,@r0
push a
dec r0
DEC R0
DEC R0
mov a,r4
push a
MOV A,R3 ;将返回地址压入堆栈
PUSH ACC
MOV A,R2
PUSH ACC
RET
;***************
(15) 标号: FPOP 功能:浮点数出栈
入口条件:操作数处于栈顶。
出口信息:操作数弹至[R0]中。
FPOP: POP ACC ;将返回地址保存在R2R3r4中
MOV R2,A
POP ACC
MOV R3,A
pop a
mov r4,a
;**********
INC R0
INC R0
inc r0
POP ACC ;将操作数弹出堆栈,传送到[R0]中
MOV @R0,A
DEC R0
POP ACC
MOV @R0,A
DEC R0
POP ACC
MOV @R0,A
dec r0
pop a
mov @R0,A
MOV A,R4
PUSH A
MOV A,R3 ;将返回地址压入堆栈
PUSH ACC
MOV A,R2
PUSH ACC
RET
(16) 标号: FTOD 功能:格式化浮点数转换成双字节定点数
入口条件:格式化浮点操作数在[R0]中。
出口信息:OV=1时溢出,OV=0时转换成功:定点数的绝对值在[R0]中(双字节),数符
在位1FH中,F0=1 时为整数,CY=1时为一字节整数一字节小数,否则为纯小数。
FTOD: LCALL MVR0 ;;将[R0]传送到第一工作区
MOV A,R2
JZ FTD4 ;;阶码为零,纯小数
JB ACC.7,FTD4;;阶码为负,纯小数
SETB C
SUBB A,#10H
JC FTD1
SETB OV ;;阶码大于16,溢出
RET
FTD1: SETB C
MOV A,R2
SUBB A,#8 ;;阶码大于8否?
JC FTD3
FTD2: MOV B,#10H ;;阶码大于8,按双字节整数转换
LCALL FTD8
SETB F0 ;;设立双字节整数标志
CLR C
CLR OV
RET
FTD3: MOV B,#8 ;;按一字节整数一字节小数转换
LCALL FTD8
SETB C ;;设立一字节整数一字节小数标志
CLR F0
CLR OV
RET
FTD4: MOV B,#0 ;;按纯小数转换
LCALL FTD8
CLR OV ;;设立纯小数标志
CLR F0
CLR C
RET
FTD8: MOV A,R2 ;;按规定的整数位数进行右规
CJNE A,B,FTD9
MOV A,R3 ;;将双字节结果传送到[R0]中
MOV @R0,A
INC R0
MOV A,R4
MOV @R0,A
inc r0
MOV A,R5
MOV @R0,A
DEC R0
dec r0
RET
FTD9: CLR C
LCALL RR1 ;右规一次
SJMP FTD8

7.uClinux上的应用程序设计
在Project目录下的Makefile文件如下:
###########################################################
#
# Makefile – Whole Project makefile.
#
# Copyright (c) 2001-2002, Tsinghua MAC
#
###########################################################
#
# Get the core stuff worked out
#

ROOT_DIR = $(shell pwd)
SRC_DIR = $(ROOT_DIR)/src
CONFIG_DIR = $(ROOT_DIR)/config
SCRIPTS_DIR = $(ROOT_DIR)/scripts

CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
     else if [ -x /bin/bash ]; then echo /bin/bash; \
     else echo sh; fi ; fi)
TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi)

HPATH    = $(TOPDIR)/include
FINDHPATH  = $(HPATH)/asm $(HPATH)/linux $(HPATH)/scsi $(HPATH)/net

export ROOT_DIR SRC_DIR CONFIG_DIR SCRIPTS_DIR HPATH FINDHPATH

###########################################################
# normal make targets
#
#
.PHONY: all
all:
    $(MAKE) -C $(SRC_DIR) all
###########################################################

#
# Config stuff, we recall ourselves to load the new config.arch before
# running the kernel and other config scripts
#
.PHONY: config
config: $(CONFIG_DIR)/config.in
    cd $(CONFIG_DIR); $(CONFIG_SHELL) $(SCRIPTS_DIR)/Configure $(CONFIG_DIR)/config.in
    @rm -f $(SRC_DIR)/arch.config
    @if egrep "^CONFIG_DEFAULTS_INTEL_I386" $(CONFIG_DIR)/.config > /dev/null; then \
       ln -s "$(CONFIG_DIR)/arch.i386" $(SRC_DIR)/arch.config; \
    fi
    @if egrep "^CONFIG_DEFAULTS_MOTOROLA_M5272C3" $(CONFIG_DIR)/.config > /dev/null; then \
       ln -s "$(CONFIG_DIR)/arch.m68k" $(SRC_DIR)/arch.config; \
    fi
    @echo "#This dir.config file is automaticly generated by make config!" > $(SRC_DIR)/dir.config
    @echo "ROOT_DIR="$(ROOT_DIR) >> $(SRC_DIR)/dir.config
    @echo "CONFIG_DIR="$(CONFIG_DIR) >> $(SRC_DIR)/dir.config
    @echo "SRC_DIR="$(SRC_DIR) >> $(SRC_DIR)/dir.config
    @echo "SCRIPTS_DIR="$(SCRIPTS_DIR) >> $(SRC_DIR)/dir.config
    @echo "HPATH="$(HPATH) >> $(SRC_DIR)/dir.config
    @echo "FINDPATH="$(FINDPATH) >> $(SRC_DIR)/dir.config

###########################################################
#
# normal make dependancy
#
#
.PHONY: dep
dep:
    $(MAKE) -C $(SRC_DIR) dep

# This one removes all executables from the tree and forces their relinking
clean:
    $(MAKE) -C $(SRC_DIR) clean
   
test:
    $(MAKE) -C $(SRC_DIR) test

run:
    $(MAKE) -C $(SRC_DIR) run

config_error:
    @echo "*************************************************"
    @echo "You have not run make config."
    @echo "The build sequence for this source tree is:"
    @echo "1. "make config" or "make xconfig""
    @echo "2. "make dep""
    @echo "3. "make""
    @echo "*************************************************"
    @exit 1
###########################################################

src目录下的Makefile文件,如下:

VERSION = 2
PATCHLEVEL = 0
SUBLEVEL = 39
UCRELEASE = uc2

.EXPORT_ALL_VARIABLES:

CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
     else if [ -x /bin/bash ]; then echo /bin/bash; \
     else echo sh; fi ; fi)
TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi)

TARGET = ESGateway

all:  $(TARGET)

# Include the make variables (CC, etc...)
#

SUBDIRS       = public serial packet cal xml fifo main interface

$(TARGET):
    @set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i all_targets; done

linuxsubdirs: dummy
    set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i; done

clean:  
    @set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i clean; done

dep:   
    @set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i fastdep; done

.PHONY: test
test:
    @set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i test; done

run:   
#   @set -e; for i in $(SUBDIRS); do $(MAKE) -i -C $$i run; read junk; done
    make -C main run

src目录下的Rules.make文件给出了编译的一些规则,如下:
#
# This file contains rules which are shared between multiple Makefiles.
#

#
# False targets.
#
.PHONY: dummy

#
# Special variables which should not be exported
#
unexport EXTRA_ASFLAGS
unexport EXTRA_CFLAGS
ifneq "$(ARCH)" "h8300"
unexport EXTRA_LDFLAGS
endif
unexport EXTRA_ARFLAGS
unexport SUBDIRS
unexport SUB_DIRS
unexport ALL_SUB_DIRS
unexport MOD_SUB_DIRS
unexport O_TARGET
unexport O_OBJS
unexport L_OBJS
unexport M_OBJS
unexport MI_OBJS
unexport ALL_MOBJS
# objects that export symbol tables
unexport OX_OBJS
unexport LX_OBJS
unexport MX_OBJS
unexport MIX_OBJS
unexport SYMTAB_OBJS

unexport MOD_LIST_NAME

include ../dir.config
include $(SRC_DIR)/arch.config

#
# Get things started.
#
first_rule: sub_dirs
    $(MAKE) all_targets

#
# Common rules
#
INC_DIR = -I$(SRC_DIR)/cal -I$(SRC_DIR)/xml -I$(SRC_DIR)/serial -I$(SRC_DIR)/packet -I$(SRC_DIR)/fifo -I$(SRC_DIR)/ping -I$(SRC_DIR)/interface -I$(SRC_DIR)/public

%.o: %.c
    @echo "Compiling..."
    @echo "$<"
    $(CXX) $(INC_DIR) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
   
%.o: %.cpp
    @echo "Compiling..."
    @echo "$<" 
    $(CXX) $(INC_DIR) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
   
# Rule to compile a set of .o files into one .o file
#

ifeq (.depend,$(wildcard .depend))
include .depend
else
.depend:    fastdep 
endif

ifneq ($(O_TARGET),$(O_OBJS))
$(O_TARGET): .depend $(O_OBJS)
    @echo "Linking..."
    @echo $(O_OBJS) " --> " $@
    @$(LD) $(EXTRA_LDFLAGS) -r -o $@ $(O_OBJS)
else
$(O_TARGET): .depend
endif
#
#
#

all:  $(O_OBJS)
    echo all

all_targets: $(O_OBJS) $(O_TARGET)

#

#
# Rule to compile a set of .o files into one .a file
#
ifdef L_TARGET
$(L_TARGET): $(LX_OBJS) $(L_OBJS)
    rm -f $@
    $(AR) $(EXTRA_ARFLAGS) rcs $@ $(LX_OBJS) $(L_OBJS)
endif

#
# This make dependencies quickly
#
fastdep: dummy
    @echo "make fastdep"
    if [ -n "$(wildcard *.[chS])" ]; then \
    $(SCRIPTS_DIR)/mkdep *.[chS] > .depend; fi
    if [ -n "$(wildcard *.cpp)" ]; then \
    $(SCRIPTS_DIR)/mkdep *.cpp >> .depend; fi

#
# A rule to make subdirectories
#
sub_dirs: dummy
ifdef SUB_DIRS
    set -e; for i in $(SUB_DIRS); do $(MAKE) -C $$i; done
endif
#
# A rule to do nothing
#
dummy:

config:
    cd $(ROOT_DIR); make config

c clean:
    rm -f *.o
    rm -f *.gdb
    rm -f .depend
    rm -f test
    rm -f core
    rm -f *.elf
    rm -f *.elf2flt 

#
# This is useful for testing
#
script:
    $(SCRIPT)

run: test
    @echo ... running ...
    @echo `pwd`/test
    @./test
   
#
# This sets version suffixes on exported symbols
# Uses SYMTAB_OBJS
# Separate the object into "normal" objects and "exporting" objects
# Exporting objects are: all objects that define symbol tables
#


$(MX_OBJS):
    $(CC) $(CFLAGS) -DEXPORT_SYMTAB -c $(@:.o=.c)

$(LX_OBJS) $(OX_OBJS):
    $(CC) $(CFLAGS) -DMODVERSIONS -DEXPORT_SYMTAB -c $(@:.o=.c)

$(M_OBJS):
ifdef MAKING_MODULES
$(O_OBJS) $(L_OBJS):
endif


在config 目录下,编写两个和架构有关的文件,对于x86平台,是arch.i386,如下:
.EXPORT_ALL_VARIABLES:
###################################################################
#
# Vendor specific settings
#

CONSOLE_BAUD_RATE = 19200

###################################################################
#
# The makefiles need to know how to do things in different contexts
# To save some pain we put it all here
#
# First settings we always want for all build
#

# ARCH = kernel, TARGET_ARCH = uClibc

MACHINE    = i386
ARCH     = i386
CROSS_COMPILE =
CROSS     = $(CROSS_COMPILE)

# We"ve used -m5307 here because the bulk of the 5272 instruction timings
# happen to be closer to the 5307 than the 5200 series. Luckily, the
# actual instructions on the two processors are essentially identical.
# This should be fixed at some stage.
CPUFLAGS =
CC    = $(CROSS_COMPILE)gcc
AS    = $(CROSS_COMPILE)as
CXX    = $(CROSS_COMPILE)g++
AR    = $(CROSS_COMPILE)ar
LD    = $(CROSS_COMPILE)ld
OBJCOPY  = $(CROSS_COMPILE)objcopy
RANLIB  = $(CROSS_COMPILE)ranlib

STRIPTOOL = $(CROSS_COMPILE)strip
STRIP   = $(STRIPTOOL)

UCLINUX_BUILD_SET = 0               # have we set a special config below

###################################################################
#
# General purpose lib building rules, uClibc.config uses these when
# possible
#


###################################################################
# Settings for building user apps
#
    CFLAGS = -Wall -Wstrict-prototypes -O2 -g
    #CFLAGS = -Wstrict-prototypes -g
    LDFLAGS = -m elf_i386
###################################################################
# fall through, do other config options perhaps
#
ifeq ($(UCLINUX_BUILD_SET),1)
endif
###################################################################

在config 目录下,对于嵌入式平台,是arch.m68k,如下:

.EXPORT_ALL_VARIABLES:
###################################################################
#
# Vendor specific settings
#
CONSOLE_BAUD_RATE = 19200
###################################################################
#
# The makefiles need to know how to do things in different contexts
# To save some pain we put it all here
#
# First settings we always want for all build
#
# ARCH = kernel, TARGET_ARCH = uClibc

MACHINE    = m68k
ARCH     = m68knommu
CROSS_COMPILE = m68k-elf-
CROSS     = $(CROSS_COMPILE)

# We"ve used -m5307 here because the bulk of the 5272 instruction timings
# happen to be closer to the 5307 than the 5200 series. Luckily, the
# actual instructions on the two processors are essentially identical.
# This should be fixed at some stage.
CPUFLAGS = -m5200
CC    = $(CROSS_COMPILE)gcc
AS    = $(CROSS_COMPILE)as
CXX    = $(CROSS_COMPILE)g++
AR    = $(CROSS_COMPILE)ar
LD    = $(CROSS_COMPILE)ld
OBJCOPY  = $(CROSS_COMPILE)objcopy
RANLIB  = $(CROSS_COMPILE)ranlib
ELF2FLT  = elf2flt
STRIPTOOL = $(CROSS_COMPILE)strip
STRIP   = $(STRIPTOOL)

UCLINUX_BUILD_SET = 0               # have we set a special config below


###################################################################
#
# Settings for building user apps
#
#CFLAGS = -m5200 -msep-data -g
CFLAGS = -m5200 -msep-data
LDFLAGS = -Wl,-elf2flt
SYSLIBS = -lc -lstdc++ -lgcc
###################################################################
#
# fall through, do other config options perhaps
#

ifeq ($(UCLINUX_BUILD_SET),1)
endif
###################################################################

在config 目录下的config.in文件如下:

mainmenu_name "uClinux Configuration"
mainmenu_option next_comment
comment "Target Platform Selection"
comment "Choose a Vendor/Product combination."
choice "Vendor/Product [Intel/i386 | Motorola/M5307C3] " "1 CONFIG_DEFAULTS_INTEL_I386 \
2 CONFIG_DEFAULTS_MOTOROLA_M5307C3 \
" Intel/i386
endmenu
1、 本站不保证以上观点正确,就算是本站原创作品,本站也不保证内容正确。
2、如果您拥有本文版权,并且不想在本站转载,请书面通知本站立即删除并且向您公开道歉! 以上可能是本站收集或者转载的文章,本站可能没有文章中的元件或产品,如果您需要类似的商品请 点这里查看商品列表!
本站协议 | 版权信息 |  关于我们 |  本站地图 |  营业执照 |  发票说明 |  付款方式 |  联系方式
深圳市宝安区西乡五壹电子商行——粤ICP备16073394号-1;地址:深圳西乡河西四坊183号;邮编:518102
E-mail:51dz$163.com($改为@);Tel:(0755)27947428
工作时间:9:30-12:00和13:30-17:30和18:30-20:30,无人接听时可以再打手机13537585389