cpubbs论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

LabVIEW+单片机学习套件全套教程资料下载[免费]LabVIEW论坛精华列表贴USB0816数据采集卡《LabVIEW宝典》
LabWindows/CVI论坛精华贴NET0816以太网数据采集卡RC0210远程设备授权系统 关闭关停锁定打开设备 户外分布式数据采集
NET1624低速高精度以太网数据采集卡WIFI0824SD无线WIFI网络数据采集卡脱机运行 SD存储 小尺寸微型 串口采集远程采集 安卓 手持移动采集 纪录仪
查看: 2377|回复: 8

关于用CPUview编译出来的EHX文件问题

[复制链接]
发表于 2009-3-29 21:16:52 | 显示全部楼层 |阅读模式
昨天下了个免费版CPUview试用了下发现生成的ehx文件很大,即便程序里只有一个“系统初始化”控件。生成的EHX文件也有3K多!而且生成的C代码前面都有一大串不知道用来干什么的代码,如下所示:

以下代码为CPUview生成的C代码前面自动加上的一段代码:
#include <AT89X55.H>
#include <intrins.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
sfr cpubbs_adc_enable=0x97;                                                         //使能ADC转换器
sfr cpubbs_adc_control_register=0xc5;                                       //ADC转换器控制寄存器
sfr cpubbs_adc_result_register=0xc6;                                        //ADC转换结果寄存器
sfr WDTRST = 0xe1;                              //STC89le54ad看门狗寄存器地址
#define PHONE P3_7
// Port4
sfr P4     = 0xC0;
sbit P4_3  = P4^3;
sbit P4_2  = P4^2;
sbit P4_1  = P4^1;
sbit P4_0  = P4^0;
//12232控制IO定义;
sbit CS=P4^2;                       //定义液晶显示器的CS引脚与单片机的P3.3连在一起,其它类似道理
sbit SID=P4^0;  
sbit SCLK=P4^1;
sbit HC595_SH_CP=P4^2;              //移位信号脚;
sbit HC595_ST_CP=P4^1;              //锁定寄存器值管脚;
sbit HC595_DS=P4^0;                 //数据管脚;
sbit DQ =P4^3;                      //定义通信端口

uchar cpubbs_serial_buffer[10];
uchar cpubbs_serial_receive_bytes=0;
uchar data_conver[4];
uchar key=0;
/*================*/
void cpubbs_reset_wdt()                     //看门狗复位程序
{
    #ifdef Cpubbs_C51WatchDog
    WDTRST=0x32;                            //8 pre-scale stc89cle54ad
    P3_6=0;
    _nop_();
    P3_6=1;
    #endif
}
void cpubbs_delay_1ms(uint x)           //延时子程序
{
    uint j;
    uchar  i;
    for(j=0;j<x;j++)
    {
        cpubbs_reset_wdt();
        for(i=0;i<120;i++);                     //空循环用于耗时,以产生延时
    }
}
uchar cpubbs_read_ad_result(uchar cpubbs_ad_channel)                //AD转换函数
{
    uchar cpubbs_ad_finished=0;
    cpubbs_adc_result_register=0;
    cpubbs_adc_control_register=cpubbs_ad_channel|0x08;
   
    cpubbs_ad_finished=0;
    while(cpubbs_ad_finished==0)
    {
        cpubbs_ad_finished=cpubbs_adc_control_register&0x10;
    }
    cpubbs_adc_control_register&=0xf7;
    return cpubbs_adc_result_register;
}
void s_int(void) interrupt 4                                                    //单片机串口中断原型
{
    if(RI)
    {
    RI=0;                                                                                   //清中断标志
    ES=0;
    cpubbs_serial_buffer[cpubbs_serial_receive_bytes]=SBUF;
        cpubbs_serial_receive_bytes++;
        if(cpubbs_serial_receive_bytes==10)
        {
            cpubbs_serial_receive_bytes=0;
        }
    ES=1;
  }
}
void cpubbs_serial_init(void)
{
   
    T2CON = 0x34;               /*T2 is setted to a baud rate generator*/
        RCAP2L = 0xdc;              /*timer2's reload value,0xffb8 corresponded to 4800,0xffdc corresponded to 9600*/
        RCAP2H = 0xff;
        TR2  = 1;                   /*start T2*/
   
    //TMOD=0x20;            /*model 2,T1*/
    //TH1=0xfd;         /*baud rate is 9600,11.0592HZ */
    //TL1=0xfd;               
    SCON=0x50;          /*receive permission*/
    PCON=0x00;
        ES=1;     
    EA=1;
    //TR1=1;
}
void delay(unsigned int i)      //延时函数
{
    while(i--);
}
void Init_DS18B20(void)             //初始化函数
{
    unsigned char x=0;
    DQ = 1;                                         //DQ复位
    delay(8);                                   //稍做延时
    DQ = 0;                                         //单片机将DQ拉低
    delay(80);                                  //精确延时 大于 480us
    DQ = 1;                                         //拉高总线
    delay(14);
    x=DQ;                                           //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
    delay(20);
}

uchar ReadOneChar(void)             //读一个字节
{
    unsigned char i=0;
    unsigned char dat = 0;
    for (i=8;i>0;i--)
    {
        DQ = 0;                                     // 给脉冲信号
        dat>>=1;
        DQ = 1;                                     // 给脉冲信号
        if(DQ)
        dat|=0x80;
        delay(4);
    }
    return(dat);
}

void WriteOneChar(unsigned char dat)    //写一个字节
{
    unsigned char i;
    for (i=8; i>0; i--)
    {
        DQ = 0;
        DQ = dat&0x01;
        delay(5);
        DQ = 1;
        dat>>=1;
    }
    //delay(4);
}
uint ReadTemperature(void)                  //读取温度
{
    unsigned char a=0;
    unsigned char b=0;
    unsigned int t=0;
    float tt=0;
    Init_DS18B20();
    WriteOneChar(0xCC);                             // 跳过读序号列号的操作
    WriteOneChar(0x44);                             // 启动温度转换
    Init_DS18B20();
    WriteOneChar(0xCC);                             //跳过读序号列号的操作
    WriteOneChar(0xBE);                             //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
    a=ReadOneChar();
    b=ReadOneChar();
    t=b;
    t<<=8;
    t=t|a;
    tt=t*0.0625;
    return(t);
}

void data_convert_temp(uint data_to_convert)    //把数据折开成四字节,为了方便发送
{
uchar cpubbs_temp_data;
uint cpubbs_temp;
cpubbs_temp_data=0;
cpubbs_temp=data_to_convert;
    data_conver[0]=(uchar)((data_to_convert&0xf000)>>12);
    data_conver[1]=(uchar)((data_to_convert&0x0f00)>>8);
    data_conver[2]=(uchar)((data_to_convert&0x00f0)>>4);
    data_conver[3]=(uchar)(data_to_convert&0x000f);
    if(data_conver[0])                                          //判断是不是负温度
    {
        cpubbs_temp_data=data_conver[0];            //为了在下面的转换中不至于数据丢失
        cpubbs_temp=~cpubbs_temp+1;                     //是的话进行按位取反再加1,这是这种温度转换芯片的计算温度的方法
        //data_convert(cpubbs_temp);                        //判断是的话之后然后再进行一次转换
    data_conver[0]=(uchar)((cpubbs_temp&0xf000)>>12);
    data_conver[1]=(uchar)((cpubbs_temp&0x0f00)>>8);
    data_conver[2]=(uchar)((cpubbs_temp&0x00f0)>>4);
    data_conver[3]=(uchar)(cpubbs_temp&0x000f);
        data_conver[0]=cpubbs_temp_data;            //符号位仍然放回去原来的地方,给计算机识别是负温度还是正温度
    }
}


void data_convert(uchar data_to_convert)                                //把数据折开成四字节,为了方便发送,也为了PC机的程序和以前的兼容
{
    data_conver[0]=0;
    data_conver[1]=0;
    data_conver[2]=(uchar)((data_to_convert&0x00f0)>>4);
    data_conver[3]=(uchar)(data_to_convert&0x000f);
   
}
void cpubbs_scankey(void)
{
    key=~P0;
    if(key)
    {
        cpubbs_delay_1ms(20);
        key=~P0;
        if(key)
            key=~P0;
        else
            key=0;
    }
    else
        key=0;
}
/*
uchar cpubbs_compare_sn_statue_function()
{
return 1;
}
*/
#ifdef cpubbs_iic_initialize
/* 一个通用的24C01-24C256共9种EEPROM的字节读写操作程序,
此程序有五个入口条件,分别为读写数据缓冲区指针,
进行读写的字节数,EEPROM首址,EEPROM控制字节,
以及EEPROM类型。此程序结构性良好,具有极好的容错性,程序机器码也不多:
DataBuff为读写数据输入/输出缓冲区的首址
Length 为要读写数据的字节数量
Addr 为EEPROM的片内地址 AT24256为0~32767
Control 为EEPROM的控制字节,具体形式为(1)(0)(1)(0)(A2)(A1)(A0)(R/W),其中R/W=1,
表示读操作,R/W=0为写操作,A2,A1,A0为EEPROM的页选或片选地址;
enumer为枚举变量,需为AT2401至AT24256中的一种,分别对应AT24C01至AT24C256;
函数返回值为一个位变量,若返回1表示此次操作失效,0表示操作成功;
ERROR为允许最大次数,若出现ERRORCOUNT次操作失效后,则函数中止操作,并返回1
SDA和SCL由用户自定义,这里暂定义为P3^0和P3^1; */
/*对于1K位,2K位,4K位,8K位,16K位芯片采用一个8位长的字节地址码,对于32K位以上
的采用2个8位长的字节地址码直接寻址,而4K位,8K位,16K位配合页面地址来寻址*/

/* -----  AT24C01~AT24C256 的读写程序 ------ */
bit   RW24xx(unsigned char *DataBuff,unsigned char Length,unsigned int Addr,
                     unsigned char Control,enum eepromtype enumer)
{ //void Delay(unsigned char DelayCount);  /*   延时   */
  void Start(void);  /*   启动总线   */
  void Stop(void);   /*   停止IIC总线   */
  bit  RecAck(void); /*   检查应答位   */
  void NoAck(void);  /*   不对IIC总线产生应答   */
  void Ack(void);    /*   对IIC总线产生应答   */
  unsigned char Receive(void); /*   从IIC总线上读数据子程序  */
  void Send(unsigned char sendbyte); /*   向IIC总线写数据   */
  unsigned char data j,i=10;//i=ERROR;
  bit errorflag=1;  /*   出错标志   */
  while(i--)
  { Start();  /*   启动总线   */
    Send(Control & 0xfe); /*   向IIC总线写数据,器件地址 */
    if(RecAck()) continue; /*   如写不正确结束本次循环   */
    if(enumer > AT2416)
    { Send((unsigned char)(Addr >> 8));//把整型数据转换为字符型数据:弃高取低,只取低8位.如果容量大于32K位,使用16位地址寻址,写入高八位地址
      if(RecAck())  continue;
    }
    Send((unsigned char)Addr); /*   向IIC总线写数据   */
    if(RecAck())  continue; /*   如写正确结束本次循环   */
    if(!(Control & 0x01))   //判断是读器件还是写器件
    { j=Length;
      errorflag=0;         /* 清错误特征位 */
      while(j--)
      { Send(*DataBuff++); /*   向IIC总线写数据   */
        if(!RecAck()) continue; /*   如写正确结束本次循环   */
        errorflag=1;
        break;
      }
      if(errorflag==1) continue;
      break;
    }
    else
    { Start();  /*   启动总线   */
      Send(Control); /*   向IIC总线写数据   */
      if(RecAck()) continue;//器件没应答结束本次本层循环
      while(--Length)  /*   字节长为0结束   */
      { *DataBuff ++= Receive();
        Ack();   /*   对IIC总线产生应答   */
      }
      *DataBuff=Receive(); /* 读最后一个字节 */
      NoAck();  /*   不对IIC总线产生应答   */
      errorflag=0;
      break;
    }
  }
  Stop();  /*   停止IIC总线   */
  if(!(Control & 0x01))
  { delay(255); delay(255); delay(255); delay(255);
  }
  return(errorflag);
}

/* * * * * 以下是对IIC总线的操作子程序 * * * * */
/* * * * * * 启动总线 * * * * */
void Start(void)
{ SCL=0; /* SCL处于高电平时,SDA从高电平转向低电平表示 */
  SDA=1; /* 一个"开始"状态,该状态必须在其他命令之前执行 */
  SCL=1;
  _nop_(); _nop_(); _nop_();
  SDA=0;
  _nop_(); _nop_(); _nop_(); _nop_();
  SCL=0;
  SDA=1;     
}

/* * * * * 停止IIC总线 * * * * */
void Stop(void)
{ SCL=0; /*SCL处于高电平时,SDA从低电平转向高电平 */
  SDA=0; /*表示一个"停止"状态,该状态终止所有通讯 */
  SCL=1;
  _nop_(); _nop_(); _nop_(); /* 空操作 */
  SDA=1;
  _nop_(); _nop_(); _nop_();
  SCL=0;
}

/* * * * * 检查应答位 * * * * */
bit RecAck(void)
{ SCL=0;
  SDA=1;
  SCL=1;
  _nop_(); _nop_(); _nop_(); _nop_();
  CY=SDA;     /* 因为返回值总是放在CY中的 */
  SCL=0;
  return(CY);
}

/* * * * *对IIC总线产生应答 * * * * */
void Ack(void)
{ SDA=0; /* EEPROM通过在收到每个地址或数据之后, */
  SCL=1; /* 置SDA低电平的方式确认表示收到读SDA口状态 */
  _nop_(); _nop_(); _nop_(); _nop_();
  SCL=0;
  _nop_();
  SDA=1;
}

/* * * * * * * * * 不对IIC总线产生应答 * * * * */
void NoAck(void)
{ SDA=1;
  SCL=1;
  _nop_(); _nop_(); _nop_(); _nop_();
  SCL=0;
}
/* * * * * * * * * 向IIC总线写数据 * * * * */
void Send(unsigned char sendbyte)
{ unsigned char data j=8;
  for(;j>0;j--)
  { SCL=0;
    sendbyte <<= 1; /* 使CY=sendbyte^7; */
    SDA=CY; /* CY 进位标志位 */
    SCL=1;
  }
  SCL=0;
}
/* * * * * * * * * 从IIC总线上读数据子程序 * * * * */
unsigned char Receive(void)
{ register receivebyte,i=8;
  SCL=0;
  while(i--)
  { SCL=1;
    receivebyte = (receivebyte <<1 ) | SDA;
    SCL=0;
  }
  return(receivebyte);
}
/* * * * * * * * 一个简单延时程序 * * * * * * * * * * * * */
//void Delay(unsigned char DelayCount)
//{ while(DelayCount--);
//}

#endif


请问下版主,以上的C代码是做什么用的?以上的代码连同自己编的程序一起编译进机器代码里了,这样编译出的HEX文件能用吗?
本人为初学,很想弄清这些问题,谢谢指导
发表于 2009-3-31 13:40:35 | 显示全部楼层
这些主要是相当于各部分驱动程序!当然,其实这些库可以精减的,比如做成需要IIC的,就装载IIC驱动,就像第三版本学习套件的库一样,可以将LCD和LED等做成一个独立的节点,需要才装载,这样程序能做到非常的小(和C可以等效大小了);但是这样有一个问题:用图形化,图的就是简便(当然,主程序运行起来效率也会一样的),但是如果要用户决定装载哪个驱动好点,用户会嫌麻烦,所以我们就默认将这些都装上!这样用户的操作就极大地简单化了!
发表于 2009-3-31 13:41:06 | 显示全部楼层
"以上的代码连同自己编的程序一起编译进机器代码里了,这样编译出的HEX文件能用吗?
本人为初学,很想弄清这些问题,谢谢指导"

能用的,完全没有问题!
 楼主| 发表于 2009-3-31 20:21:43 | 显示全部楼层
明白了,谢谢版主仔细解答。

  昨天做实验用cpuview编了个停车场红绿灯控制系统,用porteus仿真成功了,十分高兴!cpuview能让我们这些只会搞硬件的人也能编出些实用的程序。



顺便提条建议:cpuview默认加载了所有的驱动程序,编译出来的HEX文件很大,象89c2051这样的片子就很难得装下了,正如版主所说:“如果要用户决定装载哪个驱动好点,用户会嫌麻烦”但用户水平是会慢慢提高的,当有能力选择的时候却发现无法选择!(不知道付费版能不能选择,打算熟悉了买一套)所以还是希望有个选择的方法
发表于 2009-3-31 21:38:32 | 显示全部楼层
如果只是用51的话,付费版本和免费版本基本上来说没有区别的!

您用咱们的第三版本学习套件的库(免费版本中也包含有,c51_v3或C51_v3_adv)这二个库,应该来说是更好的,比如串口它是更优化的!其实您这个要做到精减的话是很容易的!可以独立将其他您不需要的从库中去掉即可!(需要另外做个库)生成的HEX文件是3K,不代表它机器码也是3K,会小点的!
发表于 2009-3-31 21:39:05 | 显示全部楼层
不过现在芯片也不太贵,用大点的存储空间的CPU也是没多大问题的!看来我们需要做个精减版的库才好,呵呵!
 楼主| 发表于 2009-4-1 13:28:01 | 显示全部楼层
如果只是用来学习,机器码多大都没关系,如要用来实际应用就不行了,程序的大小非常重要。现在很多小厂对产品的成本控制得很严,能用便宜的就不用贵的。象我公司生产的防盗报警器用的芯片大多是78p156、78p153、pic16c45、cf745之类的。内存在512-1K之间,想给这类芯片编程怎么办啊

  另外问下cpuview有没有pic或仪陇78p系列的库?
发表于 2009-4-1 13:33:00 | 显示全部楼层
如果只是用来学习,机器码多大都没关系,如要用来实际应用就不行了,程序的大小非常重要。现在很多小厂对产品的成本控制得很严,能用便宜的就不用贵的。象我公司生产的防盗报警器用的芯片大多是78p156、78p153、pic1 ...
zhengxing0108 发表于 2009-4-1 13:28


可以做精减的库的,这个没有问题!

PIC的库目前还没有去做!华邦的这个是51的核的吗?如果是的话,通用的功能都是直接用51的就可以支持的!
发表于 2009-4-1 13:34:01 | 显示全部楼层
希望有朋友愿意去做一些库,这些大家可以做出来向需要的朋友销售的,PIC的应该用户很多,不少用户问过我们有没有!有兴趣并且熟PIC的朋友可以尝试一下!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|cpubbs论坛. ( 粤ICP备09171248号 )

GMT+8, 2025-5-4 14:40 , Processed in 0.530193 second(s), 8 queries , Gzip On, File On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表