- /**************************************************************************************
- * 温度传感器实验 *
- 实现现象: 具体接线操作请看视频。
- 下载程序后,在温度传感器接口处,按照丝印方向插好温度传感器,数码管就会显示
- 检测的温度值,
- 注意事项:
- ***************************************************************************************/
- #include <reg52.h> //此文件中定义了单片机的一些特殊功能寄存器
- #include <stdio.h>
- #include <eeprom.h>
- typedef unsigned int u16; //对数据类型进行声明定义
- typedef unsigned char u8;
- #define WRITE24C02 0xA0 //10100000,器件地址,写操作
- #define READ24C02 0xA1 //10100001,器件地址,读操作
- sbit LSA=P2^2;
- sbit LSB=P2^3;
- sbit LSC=P2^4;
- sbit key1=P1^0;
- sbit key2=P1^1;
- sbit zongkong=P2^7;
- sbit output=P2^6;
- sbit SO=P3^2;
- sbit CS=P3^0;
- sbit SCK=P3^1;
- char num=0;
- u8 xw[8],sdwd,a=101,sjwd;
- u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
- void display0 ( te );
- void display1(h);
- #define uchar unsigned char
- #define uint unsigned int //--------------热电偶数字转换器MAX6675
- /*******************************************************************************
- * 函 数 名 : delay_ms(uchar ntimes)
- * 函数功能 :
- * 输 入 : temp
- * 输 出 : 无
- *******************************************************************************/
- void delay(u16 i)
- {
- while(i--);
- }
- /********************************
- //读取MAX6675
- *********************************/
- int Read_6675()
- { uchar i;
- uint dat_temp;
- uint dat_6675;
- i=0;
- dat_temp=0;
- dat_6675=0;
- //ready
- CS=0;
- //delay_us(10);
- SCK=0;
- //delay_us(10);
- //get D15-D0 from 6675
- for(i=0;i<16;i++)
- {
- SCK=1;
- dat_temp=dat_temp<<1;
- if(SO==1)
- dat_temp=dat_temp|0x01;
- SCK=0;
- //delay_us(10);
- }
- CS=1;
- dat_temp=dat_temp<<1;
- dat_temp=dat_temp>>4;
- dat_temp=dat_temp/4;
- dat_6675 = dat_temp;
- return dat_6675;
- }
- /*******************************************************************************
- * 函 数 名 : datapros()
- * 函数功能 : 温度读取处理转换函数
- * 输 入 : temp
- * 输 出 : 无
- *******************************************************************************/
- void datapros(int temp)
- {
- float tp;
- if(temp< 0) //当温度值为负数
- {
- xw[2] = 0x40; // -
- //因为读取的温度是实际温度的补码,所以减1,再取反求出原码
- temp=temp-1;
- temp=~temp;
- tp=temp;
- temp=tp*0.0025*100+0.5;
- //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
- //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
- //算加上0.5,还是在小数点后面。
- }
- else
- {
- xw[0] = 0x00;
- tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
- //如果温度是正的那么,那么正数的原码就是补码它本身
- temp=tp*0.0025*100+0.5;
- //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
- //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
- //算加上0.5,还是在小数点后面。
- }
- xw[4] = smgduan[temp % 10000 / 1000];
- xw[5] = smgduan[temp % 1000 / 100] | 0x80;
- xw[6] = smgduan[temp % 100 / 10];
- xw[7] = smgduan[temp % 10];
- sjwd=temp % 10000 / 1000*10+temp % 1000 / 100;
- }
- /*******************************************************************************
- * 函数名 :DigDisplay()
- * 函数功能 :数码管显示函数
- * 输入 : 无
- * 输出 : 无
- *******************************************************************************/
- void DDP()
- {
- u8 i;
- for(i=0;i<8;i++)
- {
- switch(i) //位选,选择点亮的数码管,
- {
- case(0):
- LSA=0;LSB=0;LSC=0; break;//显示第0位
- case(1):
- LSA=1;LSB=0;LSC=0; break;//显示第1位
- case(2):
- LSA=0;LSB=1;LSC=0; break;//显示第2位
- case(3):
- LSA=1;LSB=1;LSC=0; break;//显示第3位
- case(4):
- LSA=0;LSB=0;LSC=1; break;//显示第4位
- case(5):
- LSA=1;LSB=0;LSC=1; break;//显示第5位
- case(6):
- LSA=0;LSB=1;LSC=1; break;//显示第6位
- case(7):
- LSA=1;LSB=1;LSC=1; break;//显示第7位
- }
- P0=xw[i];//发送数据
- delay(200);
- P0=0x00;//消隐
- }
- }
- /*******************************************************************************
- * 函 数 名 : Initialization
- * 函数功能 : 初始化函数
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void Initialization()
- {
- uchar i=0;
- P0=0x00;
- P1=0x00;
- P2=0XFF;
- P3=0XFF;
- sdwd=30;
- for(i=0;i++;i<8)
- {
- xw[i]=0x08;
- }
- readeeprom();
- datapros(Read_6675() );
- }
- /*******************************************************************************
- * 函 数 名 : main
- * 函数功能 : 主函数
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void main()
- {
- Initialization();
- delay(50);
- while(1)
- {
- if(zongkong==1)
- {
- while(a>100)
- {
- a=0;
- datapros(Read_6675() );
-
- }
- a++;
- xw[0]=smgduan[sdwd/10%10];
- xw[1]=smgduan[sdwd%10];
- xw[2]=0x08;
- xw[3]=0x08;
- DDP();
- if(key1==1)
- {
- while(key1==1)DDP();
- sdwd++;
- if(sdwd>50)sdwd=50;
- }
- if(key2==1)
- {
- while(key2==1)DDP();
- sdwd--;
- if(sdwd<10)sdwd=10;
- }
- if(sdwd>sjwd+2)
- {
- output=0;
- }
- if(sdwd<sjwd+1)
- {
- output=1;
- }
- }
- if(zongkong==0)
- {
- while(a>100)
- {
- a=0;
- datapros(Read_6675() );
-
- }
- a++;
- xw[0]=smgduan[sdwd/10%10];
- xw[1]=smgduan[sdwd%10];
- xw[2]=0x08;
- xw[3]=0x08;
- DDP();
- if(key1==1)
- {
- while(key1==1)DDP();
- sdwd++;
- if(sdwd>50)sdwd=50;
- }
- if(key2==1)
- {
- while(key2==1)DDP();
- sdwd--;
- if(sdwd<10)sdwd=10;
- }
- output=0;
- }
- }
- }
- #include "reg52.h" //包含头文件
- #include"intrins.h" //_nop_();延时函数用
- #include<eeprom.h>
- #define uchar unsigned char
- #define uint unsigned int
- void Delay1ms(uint y)
- {
- uint x;
- for( ; y>0; y--)
- {
- for(x=110; x>0; x--);
- }
- }
- //**************************************************************************************************
- //启动(SCL为高,SDA由高变为低是一个开始条件)
- //**************************************************************************************************
- void start()
- {
- sda=1; //数据线置高,
- _nop_(); //延时
- scl=1; //时钟线置高
- _nop_(); //延时
- sda=0; //数据线置低,由高变低
- _nop_(); //延时
- scl=0; //时钟线置低,准备发送或接收数据,总线进入忙状态(I2C总线在空闲状态时,SDA与SCL均被置高)
- _nop_(); //延时
- }
- //**************************************************************************************************
- //停止(SCL为高,SDA由低变为高是一个结束条件)
- //**************************************************************************************************
- void stop()
- {
- sda=0; //数据线置低
- _nop_(); //延时
- scl=1; //时钟线置高
- _nop_(); //延时
- sda=1; //数据线置高,由低变高
- _nop_(); //延时
- }
- //**************************************************************************************************
- //检测应答(所有的地址和数据字都是以8bit,在第9个时钟周期,从器件发出"0"信号来作为收到一个字的应答信号)
- //**************************************************************************************************
- void checkACK() //主器件检测从器件是否返回应答
- {
- scl=1; //时钟线置高
- _nop_(); //延时
- while(sda==1); //等待第9个时钟周期器件发出的响应信号"0"
- scl=0; //时钟线置低
- _nop_(); //延时
- }
- //**************************************************************************************************
- //发送应答(发送方为主器件,接收方为从器件,控制器作为从器件接收完1数据时,发送应答信号
- //**************************************************************************************************
- void sendACK(bit ACK)
- {
- if(ACK)sda=1; //如果i位为1则发送1,即发送"非应答信号"
- else sda=0; //如果i位为0则发送0,即发送"应答信号"
- scl=1; //时钟线置高,给一个脉冲
- _nop_(); //延时
- scl=0; //时钟线置低
- _nop_(); //延时
- }
- //**************************************************************************************************
- //写一字节
- //**************************************************************************************************
- void send_byte(uchar date) //写一个8位字
- {
- uchar i,temp; //定义局部变量
- temp=date; //待发8位数据赋予temp
- for(i=0;i<8;i++) //循环8次,每次写入1位,从最高位开始发送
- {
- if(temp&0x80)sda=1; //如果temp最高位为1则发送1
- else sda=0; //如果temp最高位为0则发送0
- _nop_(); //延时
- scl=1; //给一个脉冲,发送sda当前这位数据
- _nop_(); //延时,需大于4us(参考数据手册时序图)
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- scl=0; //时钟线置低,准备下一脉冲
- _nop_(); //延时,需大于4.7us(参考数据手册时序图)
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- temp=temp<<1; //左移1位,准备好下1位待发送的数据
- }
- checkACK(); //查询是否返回应答信号
- }
- //**************************************************************************************************
- //读一字节
- //**************************************************************************************************
- uchar receive_byte() //读一个8位字
- {
- uchar i,temp; //定义局部变量
- sda=1; //设置数据线为输入
- _nop_(); //延时
- for(i=0;i<8;i++) //循环8次,每次读取1位,从最高位开始接收
- {
- scl=1; //给一脉冲,准备发送1位数据
- _nop_(); //延时,需大于4us(参考数据手册时序图)
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- temp=(temp<<1)|sda; //读取1位数据,放在temp最低位
- scl=0; //准备给下1个脉冲
- _nop_(); //延时,需大于4.7us(参考数据手册时序图)
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
- return temp; //返回读取的8位数据
- }
- //**************************************************************************************************
- //向某I2C器件的某字地址写一字节数据
- //**************************************************************************************************
- void write_word(uchar device_add,uchar word_add,uchar date) //写进去一个存储数据
- {
- start(); //启动
- send_byte(device_add); //选择从器件地址,RW位为0,即选择写命令
- send_byte(word_add); //写字地址
- send_byte(date); //写数据
- stop(); //停止
- }
- //**************************************************************************************************
- //向某I2C器件的某字地址读一字节数据
- //**************************************************************************************************
- uchar read_word(uchar device_add,uchar word_add) //读出一个存储的数据
- {
- uchar date;
- start(); //启动
- send_byte(device_add); //选择从器件地址,RW位为0,即选择写命令
- send_byte(word_add); //写字地址
- start(); //启动
- send_byte(device_add+1); //选择从器件地址,RW位为1,即选择读命令
- date=receive_byte(); //读数据
- sendACK(1); //发送非应答信号
- stop(); //停止
- return date; //返回读取结果数据
- }
- //**************************************************************************************************
- //主函数
- //**************************************************************************************************
- int readeeprom()
- {
- uchar temp; //定义中间变量
- temp=read_word(0xa0,0); //从I2C器件a0的第0个地址读出数据赋予temp
- write_word(0xa0,0,temp+1); //向I2C器件a0的第0个地址写etmp+1
- Delay1ms(50);
- while(1) //死循环
- {
- temp=read_word(0xa0,0); //从第0个地址读出一个数据
- Delay1ms (10);
- P1=~temp; //送数据到P1口显示
- }
- }
复制代码
|