标题:
1602液晶显示用于产品的LM75A温控制器STC15F104E MCU源码
[打印本页]
作者:
冰冰洁洁
时间:
2018-11-24 03:03
标题:
1602液晶显示用于产品的LM75A温控制器STC15F104E MCU源码
微型贴片单片机STC15F104E单片机做的LM75A温控制器,带1602液晶显示器,有温度设置。用最小的单片机做最多的功能
制作出来的实物图如下:
20181124_022450.jpg
(295.33 KB, 下载次数: 54)
下载附件
2018-11-24 02:59 上传
单片机源码:
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit sda=P3^1;
sbit scl=P3^0;
void delay() //@11.0592MHz stc12(100us)
{
unsigned char i, j;
i = 2;
j = 15;
do
{
while (--j);
} while (--i);
}
void delay1(uint x)//@11.0592MHz stc12(1ms)
{
unsigned char i, j;
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
/* ***************************************************** */
// 起别名定义
/* ***************************************************** */
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;
long int SET=28000; //28.000度
//sbit led1=P3^0;//温度灯报警
//sbit led2=P3^1;//压力灯报警
sbit OUT=P3^5;//控制器输出
sbit IN=P3^4;//开关输入设置温度
/* ***************************************************** */
// 全局变量定义
/* ***************************************************** */
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;// 由于计算机中负数是以补码形式存的,所以有这样的算法。
}
}
/********************************1602**************************************/
void start() //开始信号
{
sda=1;
delay();
scl=1;
delay();
sda=0;
delay();
}
void stop() //停止
{
sda=0;
delay();
scl=1;
delay();
sda=1;
delay();
}
void respons() //应答
{
uchar i;
scl=1;
delay();
while((sda==1)&&(i<250))i++;
scl=0;
delay();
}
void init()
{
sda=1;
delay();
scl=1;
delay();
}
void write_byte(uchar date)
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
scl=0;
delay();
sda=CY;
delay();
scl=1;
delay();
}
scl=0;
delay();
sda=1;
delay();
}
void write_add(uchar date1)
{
start();
write_byte(0x4e); //8574A 地址+写入 (8574 地址+写入0x4e)//0x27+0x27=0x4e//全部空0x3f+0x3f=0x7e
respons();
write_byte(date1);
respons();
stop();
}
void write_com(uchar com) //写命令函数
{ uchar com1,com2;
com1=com|0x0f;
write_add(com1&0xfc);
delay1(2);
write_add(com1&0xf8);
com2=com<<4;
com2=com2|0x0f;
write_add(com2&0xfc);
delay1(2);
write_add(com2&0xf8);
}
void write_date(uchar date) //写数据函数
{
uchar date1,date2;
date1=date|0x0f;
write_add(date1&0xfd);
delay1(2);
write_add(date1&0xf9);
date2=date<<4;
date2=date2|0x0f;
write_add(date2&0xfd);
delay1(2);
write_add(date2&0xf9);
}
void write_zfc(uchar *p)//定义一个带指针的函数?(字符串)
{
while(*p!=0)//不能用";"
write_date(*p++);
}
void init_lcd() //初始化函数
{
write_add(0x08); //默认开始状态为关使能端,见时序图 选择状态为 写
write_com(0x0f);
write_com(0x28); //显示模式设置 0x28中高位2,设置4线。
write_add(0x0c);
write_add(0x08); //使能4线
write_com(0x28); //显示模式设置,为0x28。
write_com(0x01); //显示清屏,将上次的内容清除,默认为0x01.
write_com(0x0c); //显示功能设置0x0f为开显示,显示光标,光标闪烁;0x0c为开显示,不显光标,光标不闪
write_com(0x06); //设置光标状态默认0x06,为读一个字符光标加1.
}
void display(long temp) //显示函数
{
uchar dt1,dt2,dt3,dt4,dt5,dt6,dt7,dt8;
//temp=12345678;
dt1 = temp%10;//1位
dt2 = temp%100/10;//2位
dt3 = temp%1000/100;//3位
dt4 = temp%10000/1000;//4位
dt5 = temp%100000/10000;//5位
dt6 = temp%1000000/100000;//6位
dt7 = temp%10000000/1000000;//7位
dt8 = temp/10000000;//8位 最高位
write_com(0xC0); //第1行
write_zfc("WD:");
//write_date(dt8+0x30);
//write_date(dt7+0x30);
//write_date(dt6+0x30);
write_date(dt5+0x30);
write_date(dt4+0x30);
write_zfc(".");
write_date(dt3+0x30);
write_date(dt2+0x30);
//write_date(dt1+0x30);
write_zfc("C");
}
void display2(long temp) //显示函数
{
uchar dt1,dt2,dt3,dt4,dt5,dt6,dt7,dt8;
//temp=12345678;
dt1 = temp%10;//1位
dt2 = temp%100/10;//2位
dt3 = temp%1000/100;//3位
dt4 = temp%10000/1000;//4位
dt5 = temp%100000/10000;//5位
dt6 = temp%1000000/100000;//6位
dt7 = temp%10000000/1000000;//7位
dt8 = temp/10000000;//8位 最高位
write_com(0xc0+10); //第1行
write_zfc("SET:");
//write_date(dt8+0x30);
//write_date(dt7+0x30);
//write_date(dt6+0x30);
write_date(dt5+0x30);
write_date(dt4+0x30);
//rite_zfc(".");
//write_date(dt3+0x30);
//write_date(dt2+0x30);
//write_date(dt1+0x30);
write_zfc("C");
}
void main()
{
init_lcd();
OUT=1;//启动时关一下
while(1)
{
LM75A_TempConv();//读取温度LM75A
DelayMS(200);
LM75WD = p_fLM75ATemp * 1000;// 将温度全部转换成整数,以便数码管显示
init(); //通讯1602
display(LM75WD); // 显示1602
display2(SET); // 显示1602
if(IN==0)//设置温度
{
SET=SET+1000;
if(SET>99999)//设置温度
SET=28000;
}
if(LM75WD>=SET)// 温度30
{
OUT=0;
write_com(0x80); //第1行
write_zfc("OUT:OFF");//220V电源关闭
}
else{
if(LM75WD<=SET-1000)// 温度回落1.000度后再执行,防闪烁
{
OUT=1;
write_com(0x80); //第1行
write_zfc("OUT: ON");//220V电源输出
}
else
{
OUT=0;
write_com(0x80); //第1行
write_zfc("OUT:OFF");//220V电源关闭
}
}
}
}
复制代码
全部资料51hei下载地址:
1602显串STC15F104E LM75A温度OK3(0x4e).zip
(67.22 KB, 下载次数: 53)
2018-11-24 03:00 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
JackeyM
时间:
2023-7-16 09:39
如果需要将收集的数据传输到电脑上,该如何操作
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1