自己的热敏电阻 想让他精确些 以下是程序
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define AddWr 0x90 //写数据地址
#define AddRd 0x91 //读数据地址
#define NUM 4 //接收和发送缓存区的深度
uchar idata receivebuf[NUM]; //数据接收缓冲区
sbit RST=P2^4; //时钟 加上后可以关掉DS1302芯片输出
sbit Sda=P2^0; // 将p2.0口模拟数据口
sbit Scl=P2^1; // 将p2.1口模拟时钟口
sbit rs=P1^0;
sbit rw=P1^1;
sbit e=P2^5;
sbit dula=P2^6;
sbit wela=P2^7;
uint data dis[4] = {0x00,0x00,0x00,0x00}; //定义3个显示数据单元和1个数据存储单元
bit ADFlag; //定义AD采样标志位
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
uchar code table3[] = "A: . B: . ";
uchar code table4[] = "C: . D: . ";
/*******************延时函数ms*****************/
void delay(uint x)
{
uint a,b;//定义了两个变量
for(a=x;a>0;a--)//循环x个1ms就是多少xms
for(b=110;b>0;b--);//在11.0592MHz的晶振下,循环110此约为1ms,但不是精确的
}
/****************lcd写指令****************/
void write_12864com(uchar com) //写指令
{
rw=0;
rs=0;
delay(5);
P0=com;
e=1;
delay(10);
e=0;
delay(5);
}
/****************lcd写数据****************/
void write_12864deta(uchar deta) //写数据
{
rw=0;
rs=1;
delay(5);
P0=deta;
e=1;
delay(10);
e=0;
delay(5);
}
/******************lce初始化****************/
void init12864()
{
write_12864com(0x30);
delay(5);
write_12864com(0x0c);
delay(5);
write_12864com(0x01);
delay(5);
}
/******************lce显示****************/
void display1()
{
uchar j;
write_12864com(0x88);
delay(10);
for(j=0;j<16;j++)
{
write_12864deta(table3[j]);
delay(5);
}
write_12864com(0x98);
delay(10);
for(j=0;j<16;j++)
{
write_12864deta(table4[j]);
delay(5);
}
}
/*******************************************************************/
/* */
/* 设定显示位置 */
/* */
/*******************************************************************/
void lcd_pos(uchar pos)
{
write_12864com(pos | 0x98); //数据指针=80+地址变量
}
/******************************************************************/
/* */
/* 数据处理与显示 */
/* 将采集到的数据进行16进制转换为ASCLL码。 */
/* */
/******************************************************************/
show_value(uchar ad_data)
{
dis[2]=(-ad_data/45); //AD值转换为3为BCD码,最大为5.00V。
dis[2]=dis[2]+0x30; //转换为ACSII码
dis[3]=(-ad_data%45); //余数暂存
dis[3]=dis[3]*10; //计算小数第一位
dis[1]=dis[3]/46;
dis[1]=dis[1]+0x30; //转换为ACSII码
dis[3]=dis[3]%46;
dis[3]=dis[3]*10; //计算小数第二位
dis[0]=dis[3]/46; //
dis[0]=dis[0]+0x30; //转换为ACSII码
return(0);
}
/******************启动IIC总线****************/
void Start(void)
{
Sda=1;
_nop_();
Scl=1;
_nop_();
Sda=0;
_nop_();
Scl=0;
}
/******************停止IIC总线****************/
void Stop(void)
{
Sda=0;
_nop_();
Scl=1;
_nop_();
Sda=1;
_nop_();
Scl=0;
}
/*****************应答IIC总线****************/
void Ack(void)
{
Sda=0;
_nop_();
Scl=1;
_nop_();
Scl=0;
_nop_();
}
/*****************非应答IIC总线****************/
void NoAck(void)
{
Sda=1;
_nop_();
Scl=1;
_nop_();
Scl=0;
_nop_();
}
/*****************发送一个字节*****************/
void Send(uchar Data)
{
uchar BitCounter=8;
uchar temp;
do
{
temp=Data;
Scl=0;
_nop_();
if((temp&0x80)==0x80)
Sda=1;
else
Sda=0;
Scl=1;
temp=Data<<1;
Data=temp;
BitCounter--;
}
while(BitCounter);
Scl=0;
}
/*****************读入一个字节并返回*****************/
uchar Read(void)
{
uchar temp=0;
uchar temp1=0;
uchar BitCounter=8;
Sda=1;
do
{
Scl=0;
_nop_();
Scl=1;
_nop_();
if(Sda) temp=temp|0x01;
else temp=temp&0xfe;
if(BitCounter-1)
{
temp1=temp<<1;
temp=temp1;
}
BitCounter--;
}
while(BitCounter);
return(temp);
}
/*********读取AD模数转换的值,有返回值**************/
uchar ReadADC(uchar Ch1)
{
uchar Data;
Start(); //写入芯片地址
Send(AddWr);
Ack();
Send(0x40|Ch1); //写入选择的通道,本程序只用单端输入,差分部分需要自行添加
//Chl的值分别为0、1、2、3,分别代表1-4通道
Ack();
Start();
Send(AddRd); //读入地址
Ack();
Data=Read(); //读数据
Scl=0;
NoAck();
Stop();
return Data; //返回值
}
void main()
{
init12864();
display1();
delay(5);
RST=0; //关时钟DS1302
delay(5);
TMOD |= 0x10;
TH1=0xff;
TL1=0x00;
EA=1;
ET1=1;
TR1=1;
while(1)
{
if(ADFlag) //定时采集输入模拟量
{
ADFlag=0;
show_value(ReadADC(0)); //显示通道0
lcd_pos(0x01);
write_12864deta(dis[2]); //整数位显示
lcd_pos(0x02);
write_12864deta(dis[1]); //第一位小数显示
lcd_pos(0x03);
write_12864deta(dis[0]); //第二位小数显示
show_value(ReadADC(3)); //显示通道3
lcd_pos(0x05);
write_12864deta(dis[2]); //整数位显示
lcd_pos(0x06);
write_12864deta(dis[1]); //第一位小数显示
lcd_pos(0x07);
write_12864deta(dis[0]); //第二位小数显示
}
}
}
/**************定时器中断程序**************/
void Timer1_isr(void) interrupt 3 using 1//定时器1执行数码管动态扫描
{
static unsigned int j;
TH1=0xfb; //重新赋值
TL1=0x00;
j++;
if(j==200)
{
j=0;
ADFlag=1;
} //定时置位AD采样标志位
}
|