本实验是根据热敏电阻MFD-103AT随温度变化而其阻值的变化,通过PCF8591对其进行AD采集,送单片机进行运算处理,得出温度值。
简单原程序:
#include <STC12C5A60S2.H> //STC头文件
#include <MATH.H> //STC头文件
double AD_Value;
unsigned int Temp;
sbit speaker = P1^0;//蜂鸣器
sbit SCL=P1^1;//时钟脉冲
sbit SDA=P1^2;//双向输入输出数据端
#define SCL_SET SCL=1
#define SCL_CLR SCL=0
#define SDA_SET SDA=1
#define SDA_CLR SDA=0
#define AddWr 0x90 //写数据地址 1001 0000
#define AddRd 0x91 //读数据地址 1001 0001
#define adCon 0x40 //AD控制字节 0100 0000
/*********************************************************************************************/
/*-- 调入了一幅图像:C:\Documents and Settings\dz\桌面\logo.bmp --*/
/*-- 宽度x高度=128x22 --*/
unsigned char code logo[] =
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xFF,0xFF,0xFF,0xFF,0xFF,0xC7,0x81,0xE0,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xFF,0xFF,0xFF,0xFF,0xFF,0xF3,0x83,0xE0,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xFF,0xFF,0xFF,0xFF,0xFF,0xF9,0x87,0xF0,0x7C,0x03,0x00,0x80,0x80,0x00,0x00,0x00,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,0x87,0xF0,0xFC,0x06,0x03,0x41,0xC0,0xC0,0x00,0xC0,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x47,0xF0,0xFC,0x03,0xC0,0x40,0x41,0x40,0x22,0xE0,
0xFC,0x01,0xF0,0x00,0xF8,0x7E,0x07,0xF8,0xFC,0x07,0x00,0x81,0xE1,0x82,0xA3,0xC0,
0xFC,0x01,0xF0,0x00,0xF8,0x3F,0x0F,0xF8,0xF8,0x14,0x07,0xE2,0x40,0x27,0xF1,0x00,
0xFF,0xF9,0xF0,0x00,0xF8,0x3F,0x0F,0xF8,0xF8,0x12,0x80,0x82,0xC3,0x72,0xA3,0xE0,
0xFF,0xF9,0xFF,0xFF,0xF8,0x7F,0x0F,0xF8,0xF8,0x0B,0x80,0x82,0xC5,0x52,0x63,0x18,
0xFF,0xF9,0xFF,0xFF,0xFF,0xFE,0x5F,0xFD,0xF8,0x07,0x02,0x84,0xE3,0x61,0xF5,0x80,
0xFF,0xF9,0xFF,0xFF,0xFF,0xFE,0x5F,0x7D,0xF8,0x01,0x81,0x04,0x00,0x00,0x00,0x80,
0xFF,0xF9,0xFF,0xFF,0xFF,0xFC,0xDF,0x7D,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xFC,0x01,0xFF,0xFF,0xFF,0xF9,0xFE,0x3F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xFC,0x01,0xF0,0x00,0xFF,0xF3,0xFE,0x3F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xFC,0x01,0xF0,0x00,0xFF,0xC3,0xFE,0x3F,0xF0,0x00,0xE1,0xE3,0x66,0x03,0x8D,0x80,
0xFC,0x01,0xF0,0x00,0xF8,0x03,0xFE,0x3F,0xE0,0x01,0xFB,0xF3,0xFF,0x07,0xEF,0xC0,
0xFF,0xFF,0xFF,0xFF,0xF8,0x03,0xFC,0x1F,0xE0,0x03,0x03,0x33,0xBB,0x0C,0x0E,0xC0,
0xFF,0xFF,0xFF,0xFF,0xF8,0x01,0xFC,0x1F,0xE0,0x03,0x03,0x33,0x33,0x0C,0x0C,0xC0,
0xFF,0xFF,0xFF,0xFF,0xF8,0x01,0xFC,0x1F,0xE0,0x1B,0x9B,0x33,0x33,0x6E,0x6C,0xC0,
0xFF,0xFF,0xFF,0xFF,0xF8,0x00,0x70,0x07,0x80,0x19,0xF1,0xE3,0x33,0x67,0xCC,0xC0,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
/*****************************************************************************/
/****************************************************************************/
//LCD接口定义
sbit RS = P2^4; //模式位,为0输入指令,为1输入数据
sbit RW = P2^5; //读写位,为0读,为1写
sbit E = P2^6; //使能位
#define Lcd_Bus P0 //数据总线
sbit PSB = P2^1; //H:8位或4位并口方式,L:串口方式
sbit NC = P2^2; //空脚
sbit RES = P2^3; //复位端,低电平有效
/*****************************************************************************/
/*********************************************************************************************/
void DELAY_MS (unsigned int a){
unsigned int i;
while( a-- != 0){
for(i = 0; i < 600; i++);
}
}
/*********************************************************************************************/
/******************************************************************************/
//LCD驱动
/******************************************************************************/
void chk_busy(){//检查忙位
RS=0;
RW=1;
E=1;
Lcd_Bus=0xff;
while((Lcd_Bus&0x80)==0x80);
E=0;
}
/******************************************************************************/
void write_com(unsigned char cmdcode){ //写命令到LCD
chk_busy();
RS=0;
RW=0;
E=1;
Lcd_Bus=cmdcode;
E=0;
}
/******************************************************************************/
void write_data(unsigned char Dispdata){ //写数据到LCD
chk_busy();
RS=1;
RW=0;
E=1;
Lcd_Bus=Dispdata;
E=0;
}
/******************************************************************************/
void lcm_init(){ //初始化LCD屏)
PSB = 1; //H:8位或4位并口方式,L:串口方式
NC = 0; //空脚
RES = 1; //复位端,低电平有效
write_com(0x30); //选择8bit数据流
write_com(0x0c); //开显示(无游标、不反白)
write_com(0x01); //清除显示,并且设定地址指针为00H
}
/*****************************************************************************/
void lcm_w_word(unsigned char *s){ //向LCM发送一个字符串,长度64字符之内。
while(*s>0){ //
write_data(*s);
s++;
}
}
/******************************************************************************/
void lcm_w_test(bit i,unsigned char word){//写指令或数据
if(i == 0){
write_com(word); //写指令或数据(0,指令)
}else{
write_data(word);//写指令或数据(1,数据)
}
}
/******************************************************************************/
void lcm_clr(void){//清屏函数
lcm_w_test(0,0x01);
}
/******************************************************************************/
/******************************************************************************
//指定显示位置// (设置LCD显示的起始位置)
/******************************************************************************/
void LCD_set_xy( unsigned char x, unsigned char y ){//X为行(1~4),Y为列(0~7)
unsigned char address;
switch(x){
case 0: address = 0x80 + y; break;
case 1: address = 0x80 + y; break;
case 2: address = 0x90 + y; break;
case 3: address = 0x88 + y; break;
case 4: address = 0x98 + y; break;
default:address = 0x80 + y; break;
}
lcm_w_test(0, address);
}
/******************************************************************************
//图形方式12864显示字模(横向8位左高位取模)
/******************************************************************************/
void Disp_img(unsigned char *img){
unsigned char i,j;
unsigned int k = 0;
lcm_w_test(0,0x36); //图形方式
for(i=0;i<32;i++){
lcm_w_test(0,0x80+i);
lcm_w_test(0,0x80);
for(j=0;j<16;j++) {
lcm_w_test(1,img[k++]);
}
}
for(i=0;i<32;i++){
lcm_w_test(0,0x80+i);
lcm_w_test(0,0x88);
for(j=0;j<16;j++) {
lcm_w_test(1,img[k++]);
}
}
}
/**********************************************************/
//延时1US
void delay(unsigned int cnt)
{
while(--cnt);
}
//延时1MS
void delayms(unsigned int time)
{
unsigned int i;
for(i=0; i<time; i++)
delay(120);
}
void start()
{
SDA_SET;
delay(1);
SCL_SET;
delay(5);
SDA_CLR;
}
void stop()
{
SDA_CLR;
delay(1);
SCL_SET;
delay(5);
SDA_SET;
}
void ack()
{
SDA_CLR;
SCL_SET;
delay(1);
SCL_CLR;
}
void noAck()
{
SDA_SET;
SCL_SET;
delay(1);
SCL_CLR;
}
void send(unsigned char Data)
{
unsigned char i=0;
unsigned char temp=0;
temp=Data;
for(i=0; i<8; i++)
{
SCL_CLR;
delay(1);
if(temp&0x80) SDA_SET;
else SDA_CLR;
delay(1);
SCL_SET;
delay(1);
temp<<=1;
}
SCL_CLR;
}
unsigned char recive()
{
unsigned char i=0;
unsigned char temp=0;
SDA_SET; //必须设置
for(i=0; i<8; i++)
{
SCL_CLR;//拉低允许数据改变
delay(1);
SCL_SET;//拉高保持数据,等待读走
delay(2);
if(SDA) temp|=0x01;
else temp&=0xfe;
if(i<7) temp<<=1;//最低位发送完成不能移位,否则出错
}
SCL_CLR;
return temp;
}
unsigned char read(unsigned char ch )
{
unsigned char temp=0;
start();
send(AddWr);//确认芯片
ack();
send(adCon|ch);//确认通道
ack();
//读出数据,放进temp
start();
send(AddRd);
ack();
temp=recive();
noAck();
stop();
return temp;
}
unsigned char DAC(unsigned char light)
{
start();
send(AddWr);
ack();
send(0x40); //写入控制位,使能DAC输出
ack();
send(light);
ack();
stop();
}
/*****************************************************************************/
//---主程序---//
/*****************************************************************************/
main() {
speaker=0;
lcm_init(); //初始化液晶显示器
Disp_img(logo);//显示图片测试内容
DELAY_MS (10000);
lcm_clr();
lcm_init(); //初始化液晶显示器
LCD_set_xy(1,0); //写入字符的位置
lcm_w_word(" NTC1测温实验 "); //写入字符内容
LCD_set_xy(3,0);
lcm_w_word(" 温度: ℃ ");
while(1){ //主循环
AD_Value=read(1);
Temp = floor((1/(log(AD_Value/(255-AD_Value))/3380 + 1/298.15)- 273.15)*10);
lcm_w_test(0,0x8c); //秒值在LCM上的写入位置
lcm_w_test(1,Temp/100+0x30);
if(Temp/100>2){
speaker = 1;
DELAY_MS(20);
speaker = 0;
DELAY_MS(20);
}
lcm_w_test(1,Temp%100/10+0x30);
lcm_w_test(1,0x2e);
lcm_w_test(1,Temp%10+0x30);
DELAY_MS (300);
}
}