|
昨天下了个免费版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文件能用吗?
本人为初学,很想弄清这些问题,谢谢指导 |
|