stc12c2052ad单片机 求一个接收温度变送器传来的电压信号 然后ad转换 并把结果通过串口传给PC的C语言程序

求一个单片机的HEX程序啊 C的

第1个回答  2013-05-06
/************* ADC Test *************
************** 电压 P0.0电压采集 可以测试0-5V的外部电压值 用1602显示*************
//////////////////////// /***********************************************************************
/* LCD1602
LCD1602显示 rs P3^5 rw P3^6 ep P3^7 P2口 为数据输出口

***********************************************************************///////////////////////
************** STC12 ADC电压采集测试程序 *************/

#include <reg52.H>
#include "intrins.h"

#define uchar unsigned char
#define uint unsigned int

uchar Vo; //A/D转换后换算的电压值

int i,e;

/*Define ADC operation const for ADC_CONTR*/
#define ADC_POWER 0x80 //ADC power control bit
#define ADC_FLAG 0x10 //ADC complete flag 模数转换结束标志位
#define ADC_START 0x08 //ADC start control bit 模数转换启动控制位

//转换速度控制位SPEED0和SPEED1,共四种状态,对应四种转换速度
#define ADC_SPEEDLL 0x00 //540 clocks
#define ADC_SPEEDL 0x20 //360 clocks
#define ADC_SPEEDH 0x40 //180 clocks
#define ADC_SPEEDHH 0x60 //90 clocks

sbit rw=P3^6; //1602 IO口定义 这里用的数据口是P2口
sbit rs=P3^5;
sbit ep=P3^7;

uchar code asc[] = "0123456789";

unsigned char code d[] = {"ADC Test"};

unsigned char code a[] ={ //汉字
0x04,0x1f,0x15,0x1f,0x15,0x1f,0x05,0x07, //电
0x0f,0x08,0x0a,0x0a,0x0f,0x0a,0x13,0x0f, //压
};

/**************************** 延时函数 ***********************************/
void delay(unsigned int a)
{
while(a--);
}

/*----------------------------
Get ADC result
----------------------------*/
uchar GetADCResult(uchar ch) //这里如有不懂 请仔细看资料
{
P1ASF = 0x01; //选择P1口的哪一口 这里的口和ch要对应才能达到选择该口
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;//0x00|0x00|ch|0x08:选择A/D输入通道,开始A/D转换
// 这么用语句的主要原因就是不能位寻址
// 通道选择在后3位所以直接用一个整数表示ch
//例如ch=6 那么对应的后三位就是110
_nop_(); //Must wait before inquiry ,
_nop_(); //设置ADC_CONTR寄存器后需加4个CPU时钟周期的延时,才能保证值被写入ADC_CONTR寄存器
_nop_();
_nop_();
while (!(ADC_CONTR & ADC_FLAG));//Wait complete flag
ADC_CONTR &= ~ADC_FLAG; //Close ADC 将标志位清零等待下次硬件置1
//也可以写成 ADC_CONTR= ADC_CONTR & ( ~ADC_FLAG)

Vo=ADC_RES*5*10/256; //Return ADC result(为显示整数,这里将电压值扩大了十倍)
//5/256 因为是8位 把5V分成256份 ADC_RES为采集的份数
//ADC_RES*(5/256) 为采集的电压值 然后扩大10倍便于计算
return Vo;
}

/*************************************************************************************/

/*************************************************************************************/

/***************************** 1602 *******************************************/
bit lcd_busy() //查忙 这部很重要 否则有的显示容易出现乱码
{
bit result;
rs = 0;
rw = 1;
ep = 1;
delay(50);
result = (bit)(P2&0x80);
ep = 0;
return result; //返回值
}

void lcd_com(unsigned char com)// 地址
{
while(lcd_busy());
rs=0;
ep=0;
rw=0;
P2=com;
delay(50);
ep=1;
delay(50);
ep=0;
}

void lcd_date(unsigned char date)//采集输出数据
{
while(lcd_busy());
rs=1; //1是些数据 0是写指令
rw=0; // 1是读 0是写
ep=0; //E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令
P2=date;
delay(5);
ep=1;
delay(5);
ep=0;
}

void lcd_pos(unsigned char pos)
{
lcd_com(pos|0x80); //数据指针=80+地址变量
}

void writetab() // 写 汉字函数
{
unsigned char m;
lcd_com(0x40); //写CGRAM 此处是指令
for (m = 0; m<16; m++)
lcd_date(a[m]);

}

void init()//1602初始化
{

lcd_com(0x38);
delay(50);
lcd_com(0x38);
delay(50);

lcd_com(0x38);
delay(50);
lcd_com(0x0c);
delay(50);
lcd_com(0x06);
delay(50);
lcd_com(0x01);

delay(2000);

writetab() ; // 汉字初始化

}

/*******************************************************************************/
/*******************************************************************************/
/*******************************************************************************/

void hanzi() //汉字显示
{

lcd_pos(0x40); //电压
lcd_date(0x00);

lcd_pos(0x40+1);
lcd_date(0x01);

}

/************************************************************************/

void main(void)
{
TMOD=0x01; //选择定时器T0 在工作方式1上 即16位定时器
TH0=(65536-50000)/256; //11.592M晶振的一个机器周期接近1us 这里5W就是0.05s
TL0=(65536-50000)%256;
EA=1; //开启总中断
ET0=1; //开启定时器T0
TR0=1; // 启动定时器 使其开始计算

init(); //1602初始化

lcd_pos(0x00); //显示字母
i=0;
while(d[i]!='\0')
{
lcd_date(d[i]);
i++;
}

hanzi(); //显示汉字
delay(300);

while(1)
{

lcd_pos(0x42);
lcd_date(':');
lcd_date(asc[Vo/10]);
lcd_date('.');
lcd_date(asc[Vo%10]);
lcd_date('V');

}

}

void ADCt0() interrupt 1
{
TH0 = (65536-50000)/256;
TL0 = (65536-50000)%256;
e++;
if(e==20)
{ e=0;
GetADCResult(0);
}

}
第2个回答  2011-08-24
建议 去 我的领地 5d6d 的 proteus 论坛看看

那里有很多 单片机仿真实例,包括proteus 仿真图 和 源码
相似回答