自己的熱敏電阻 想讓他精確些 以下是程序
#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采樣標志位
}
|