因T友要求,分享下使用STCF104E单片机加1637数码管IIC接囗,只用2根线,加LM75A温控头IIC接囗,制作的温度控制器。实测很稳定,只用一个按键完成温度设置,42-99度。正常工作时实测温度和设置温度交替显示,成本很低。不到10元。现上源代码
制作出来的实物图如下:
单片机源程序如下:
- #include <stc15.h>
- #include <INTRINS.H>
- #include <stdio.h>
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- /* ***************************************************** */
- // 起别名定义
- /* ***************************************************** */
- typedef unsigned char uChar8;
- typedef unsigned int uInt16;
- typedef enum{FALSE,TRUE} BOOL;
- /* ***************************************************** */
- // 宏定义
- /* ***************************************************** */
- #define LM75ADevIDAddr 0x90
- #define IIC_WRITE 0x00
- #define IIC_READ 0x01
- /* ***************************************************** */
- // 位定义
- /* ***************************************************** */
- sbit SCL = P3^2;//绿色线
- sbit SDA = P3^3;//白色线
- long int LM75WD;//定义一个温度长整型变量
- sbit out = P3^5;//输出继电器
- sbit k = P3^4;//调节温度
- int set;//设置温度
- /* ***************************************************** */
- // 全局变量定义
- /* ***************************************************** */
- bit p_bH0L_Flag; // 温度"0"上、下标志位
- float p_fLM75ATemp; // 温度值
-
- /* ***************************************************** */
- // 函数名称:Delay5US()
- // 函数功能:微秒延时
- // 入口参数:延时微秒数(ValUS)
- // 出口参数:无
- /* ***************************************************** */
- void Delay5US(void)
- {
- unsigned char i;
- _nop_();
- i = 11;
- while (--i);
- }
- /* ***************************************************** */
- // 函数名称:DelayMS()
- // 函数功能:毫秒延时
- // 入口参数:延时毫秒数(ValMS)
- // 出口参数:无
- /* ***************************************************** */
- void DelayMS(uInt16 ValMS)
- {
- unsigned char i, j;
- _nop_();
- _nop_();
- _nop_();
- i = 11;
- j = 190;
- do
- {
- while (--j);
- } while (--i);
- }
-
- /* ***************************************************** */
- // 函数名称:IIC_Start()
- // 函数功能:IIC起动
- // 入口参数:无
- // 出口参数:无
- /* ***************************************************** */
- void IIC_Start(void)
- {
- SDA = 1;
- Delay5US();
- SCL = 1;
- Delay5US();
- SDA = 0;
- Delay5US();
- }
- /* ***************************************************** */
- // 函数名称:IIC_Stop()
- // 函数功能:IIC停止
- // 入口参数:无
- // 出口参数:无
- /* ***************************************************** */
- void IIC_Stop(void)
- {
- SDA = 0;
- Delay5US();
- SCL = 1;
- Delay5US();
- SDA =1;
- }
- /* ***************************************************** */
- // 函数名称:IIC_Ack()
- // 函数功能:IIC应答
- // 入口参数:无
- // 出口参数:无
- /* ***************************************************** */
- void IIC_Ack(void)
- {
- SCL = 0; // 为产生脉冲准备
- SDA = 0; // 产生应答信号
- Delay5US(); // 延时你懂得
- SCL = 1;Delay5US();
- SCL = 0;Delay5US(); // 产生高脉冲
- SDA = 1; // 释放总线
- }
- /* ***************************************************** */
- // 函数名称:IIC_RdAck()
- // 函数功能:读IIC应答
- // 入口参数:无
- // 出口参数:是否应答真值
- /* ***************************************************** */
- BOOL IIC_RdAck(void)
- {
- BOOL AckFlag;
- uChar8 uiVal = 0;
- SCL = 0;Delay5US();
- SDA = 1;
- SCL = 1;Delay5US();
- while((1 == SDA) && (uiVal < 255))
- {
- uiVal ++;
- AckFlag = SDA;
- }
- SCL = 0;
- return AckFlag; // 应答返回:0;不应答返回:1
- }
- /* ***************************************************** */
- // 函数名称:IIC_Nack()
- // 函数功能:IIC不应答
- // 入口参数:无
- // 出口参数:无
- /* ***************************************************** */
- void IIC_Nack(void)
- {
- SDA = 1;
- SCL = 0;Delay5US();
- SCL = 1;Delay5US();
- SCL = 0;
- }
- /* ***************************************************** */
- // 函数名称:OutputOneByte()
- // 函数功能:从IIC器件中读出一个字节
- // 入口参数:无
- // 出口参数:读出的一个字节(uByteVal)
- /* ***************************************************** */
- uChar8 OutputOneByte(void)
- {
- uChar8 uByteVal = 0;
- uChar8 iCount;
- SDA = 1;
- for (iCount = 0;iCount < 8;iCount++)
- {
- SCL = 0;
- Delay5US();
- SCL = 1;
- Delay5US();
- uByteVal <<= 1;
- if(SDA)
- uByteVal |= 0x01;
- }
- SCL = 0;
- return(uByteVal);
- }
- /* ***************************************************** */
- // 函数名称:InputOneByte()
- // 函数功能:向IIC器件写入一个字节
- // 入口参数:待写入的一个字节(uByteVal)
- // 出口参数:无
- /* ***************************************************** */
- void InputOneByte(uChar8 uByteVal)
- {
- uChar8 iCount;
- for(iCount = 0;iCount < 8;iCount++)
- {
- SCL = 0;
- Delay5US();
- SDA = (uByteVal & 0x80) >> 7;
- Delay5US();
- SCL = 1;
- Delay5US();
- uByteVal <<= 1;
- }
- SCL = 0;
- }
- /* ***************************************************** */
- // 函数名称:IIC_WrDevAddAndDatAdd()
- // 函数功能:向IIC器件写入器件和数据地址
- // 入口参数:器件地址(uDevAdd),数据地址(uDatAdd)
- // 出口参数:写入是否成功真值
- /* ***************************************************** */
- BOOL IIC_WrDevAddAndDatAdd(uChar8 uDevAdd,uChar8 uDatAdd)
- {
- IIC_Start(); // 发送开始信号
- InputOneByte(uDevAdd); // 输入器件地址
- IIC_RdAck(); // 读应答信号
- InputOneByte(uDatAdd); // 输入数据地址
- IIC_RdAck(); // 读应答信号
- return TRUE;
- }
- /* ***************************************************** */
- // 函数名称:IIC_RdDatFromAdd()
- // 函数功能:向IIC器件读数据
- // 入口参数:器件ID(uDevID)、数据存储地址(uStaAddVal)
- // 待存数据(*p)、连续存储数据的个数(uiLenVal)
- // 出口参数:无
- /* ***************************************************** */
- void IIC_RdDatFromAdd(uChar8 uDevID, uChar8 uStaAddVal, uChar8 *p, uChar8 uiLenVal)
- {
- uChar8 iCount;
- IIC_WrDevAddAndDatAdd(uDevID | IIC_WRITE,uStaAddVal);
- IIC_Start();
- InputOneByte(uDevID | IIC_READ);
- // IIC_READ 为写命令后缀符
- IIC_RdAck();
- for(iCount = 0;iCount < uiLenVal;iCount++)
- {
- *p++ = OutputOneByte();
- if(iCount != (uiLenVal - 1))
- IIC_Ack();
- }
- IIC_Nack();
- IIC_Stop();
- }
- /* ***************************************************** */
- // 函数名称:LM75A_ReadReg()
- // 函数功能:读LM75A任意寄存器值
- // 入口参数:寄存器地址(addr),uLenVal,读出字节的长度
- // 出口参数:寄存器内容(*val)
- /* ***************************************************** */
- void LM75A_ReadReg(uChar8 addr, uChar8 *val, uChar8 uLenVal)
- {
- IIC_RdDatFromAdd(LM75ADevIDAddr, addr, val, uLenVal);
- }
- /* ***************************************************** */
- // 函数名称:LM75A_TempConv()
- // 函数功能:温度转换
- // 入口参数:无
- // 出口参数:无
- /* ***************************************************** */
- void LM75A_TempConv(void)
- {
- uChar8 TempML[2]={0}; // 临时数值,用于存放Temp的高低字节
- uInt16 uiTemp; // 用于存放Temp的11位字节数据
- LM75A_ReadReg(0x00,TempML,2); // 读出温度,并存于数组TempHL中
- uiTemp = (uInt16)TempML[0]; // 将高字节存入变量uiTemp中
- uiTemp = (uiTemp << 8 | TempML[1]) >> 5; // 接着并入后3位,最后右移5位就是11位补码数(8+3共11位)
- /* ***** 首先判断温度是“0上”还是是“0下” ***** */
- if(!(TempML[0] & 0x80)) // 最高位为“0”则为“0上”
- {
- p_bH0L_Flag = 0;
- p_fLM75ATemp = uiTemp * 0.125;
- }
- else // 这时为“0下”(p_fLM75ATemp)℃
- {
- p_bH0L_Flag = 1;
- p_fLM75ATemp = (0x800 - uiTemp) * 0.125;// 由于计算机中负数是以补码形式存的,所以有这样的算法。
- }
- }
- sbit SCL1=P3^0; //CLK
- sbit SDA1=P3^1; //DIO
- unsigned char code xsbcdbuf[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77};
- void Delay1000ms() //@11.0592MHz
- {
- unsigned char i, j, k;
- _nop_();
- _nop_();
- i = 43;
- j = 6;
- k = 203;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
- void IIC_delay(void)
- {
- unsigned char i;
- for(i=0;i<20;i++) _nop_();
- }
- void start_IIC(void)// 启动IIC
- {
- SCL1=1; //给芯片发送开始信号
- SDA1=1;
- IIC_delay();
- SDA1=0;
- IIC_delay();
- SCL1=0; //开始信号传送完
- IIC_delay();
- }
- void stop_IIC(void) //停止IIC
- {
- SCL1=0;
- IIC_delay();
- SDA1=0;
- IIC_delay();
- SCL1=1;
- IIC_delay();
- SDA1=1;
- }
- void ack_IIC()
- {
- SCL1=0;
- _nop_();_nop_();_nop_();
- while(SDA1);
- SCL1=1;
- _nop_();_nop_();_nop_();
- SCL1=0;
- }
- void WriteByte(unsigned char WriteData) //写一个字节数据
- {
- unsigned char i;
- for(i=0;i<8;i++)//开始传送8位数据,每循环一次传送一位数据
- {
- SCL1=0;
- IIC_delay();
- WriteData=WriteData>>1;
- SDA1=CY;
- IIC_delay();
- SCL1=1;
- IIC_delay();
- }
- //8位数据传送完
- ack_IIC(); //判断芯片发过来的ACK应答信号
- }
- void write_LEDSROM(unsigned char addr,unsigned char WData) //写一字节数据到LEDSROM
- {
- start_IIC(); //调用开始信号
- WriteByte(addr); //写起始地址命令(0C0H),地址00H单元。
- WriteByte(WData);//给显示寄存器写显示数据,值可根据实参改变
- stop_IIC(); //调用结束信号,一个字节命令发送完毕,可以发送下一个命令
- }
-
-
- void dsplay(int temp) //显示
- {
-
- SDA1=1;
- SCL1=1;
- start_IIC(); //调用开始信号
- WriteByte(0x40);//写命令40H(数据设置)
- stop_IIC(); //调用结束信号,一个字节命令发送完毕,可以发送下一个命令
-
-
- write_LEDSROM(0xC0,xsbcdbuf[temp/1000]); //第一个数码管
- // write_LEDSROM(0xC1,xsbcdbuf[temp%1000/100]); //第二个数码管,0x80打开DP小数点
- write_LEDSROM(0xC1,xsbcdbuf[temp%1000/100]|0x80); //第二个数码管,0x80打开DP小数点
- write_LEDSROM(0xC2,xsbcdbuf[temp%100/10]); //第三个数码管
- //write_LEDSROM(0xC3,xsbcdbuf[temp%10]);//第四个数码管
-
- write_LEDSROM(0xC3,0x39);//第四个数码管
-
-
-
-
-
- IIC_delay();
- start_IIC(); //调用开始信号
- WriteByte(0x8a); //送开屏命令,(8BH),亮度可以根据低三位调节。//显示亮度
- stop_IIC(); //调用结束信号,一个字节命令发送完毕,可以发送下一个命令
- }
- void dsplay2(int temp) //显示
- {
-
- SDA1=1;
- SCL1=1;
- start_IIC(); //调用开始信号
- WriteByte(0x40);//写命令40H(数据设置)
- stop_IIC(); //调用结束信号,一个字节命令发送完毕,可以发送下一个命令
-
-
- write_LEDSROM(0xC0,xsbcdbuf[temp/1000]); //第一个数码管
- write_LEDSROM(0xC1,xsbcdbuf[temp%1000/100]); //第二个数码管,0x80打开DP小数点
- // write_LEDSROM(0xC1,xsbcdbuf[temp%1000/100]|0x80); //第二个数码管,0x80打开DP小数点
- // write_LEDSROM(0xC2,xsbcdbuf[temp%100/10]); //第三个数码管
- //write_LEDSROM(0xC3,xsbcdbuf[temp%10]);//第四个数码管
-
- //write_LEDSROM(0xC3,0x39);//第四个数码管
-
- write_LEDSROM(0xC3,0x00);//第4个数码管//关闭
- write_LEDSROM(0xC2,0x00);//第3个数码管
-
-
- IIC_delay();
- start_IIC(); //调用开始信号
- WriteByte(0x8a); //送开屏命令,(8BH),亮度可以根据低三位调节。//显示亮度
- stop_IIC(); //调用结束信号,一个字节命令发送完毕,可以发送下一个命令
- }
- /* ***************************************************** */
- // 函数名称:main()
- // 函数功能:读取LN75A温度值,数码管显示并串口打印
- // 入口参数:无
- // 出口参数:无
- /* ***************************************************** */
- void main()
- {
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
1637数显STC15F104E LM75A温度OK2.zip
(50.93 KB, 下载次数: 62)
|