📄 main.c
字号:
#include <c8051F200.h>
#include <INTRINS.H>
sbit TEMPERCON=P2^3;
sbit WDI=P2^4;
sbit DQ=P2^5;
sbit LCD_CS=P1^7;
sbit LCD_RD=P1^6;
sbit LCD_WR=P1^5;
sbit LCD_DA=P1^4;
bit FLG_DS18B20_RET;
bit Temper_Flag=1;
float Temperature=0.0;
unsigned char lcd_dat_1;
unsigned char lcd_dat_2;
//*************************************************************************************
//函数名称;Delay_1us()
//函数功能:执行 12*cnt+1 条单指令,对于C8051F221晶振频率为12M的情况下,延时1us乘以cnt
//输入参数;unsigned char cnt
//返回参数:无
//*************************************************************************************
void Delay_1us(unsigned char cnt)
{
unsigned char i;
for (i = cnt; i > 0; i--)
{
_nop_();
_nop_();
_nop_();
}
}
//************************************************************************************
//函数名称;Delay_4ms()
//函数功能:执行 4000*cnt+1 条单指令,对于C8051F221晶振频率为12M的情况下,延时4ms乘以cnt
//输入参数;unsigned char cnt
//返回参数:无
//************************************************************************************
void Delay_4ms(unsigned char cnt)
{//(5k+4)j+9
unsigned char i,j,k;
for(i=cnt;i>0;i--)
{
for(j=224;j>0;j--)
{
for(k=42;k>0;k--)
WDI=~WDI;
_nop_();
_nop_();
}
}
}
/**************************************************************************************
函数名称;C8051F221_Init()
函数功能:寄存器及端口初始化
输入参数;无
返回参数:无
**************************************************************************************/
void C8051F221_Init(void)
{
WDTCN=0xDE; //禁止看门狗
WDTCN=0xAD;
OSCXCN |= 0x67; // External Oscillator is an external
// crystal (no divide by 2 stage)
// Delay_4ms(250);
// Delay_4ms(250);
while(!(OSCXCN & 0x80)); // Wait for crystal osc. to settle
OSCICN = 0x88; // select external oscillator as SYSCLK
// source and enable missing clock
// detector
PRT0MX |= 0x00; //定时器1使能
PRT1MX |= 0x00; //SYSCLK输出、比较器使能
PRT2MX |= 0x00; //端口弱上拉、SPI总线使能:P1口弱上拉禁止
PRT0CF |= 0x00; //设置漏极开路方式
PRT1CF |= 0x00;
PRT2CF |= 0x08; //P2.3为推挽方式
P0MODE |= 0xff; //数字输入使能,模拟输入禁止
P1MODE |= 0xff;
P2MODE |= 0xff;
//REF0CN |= 0x03; //选择VDD为VREF源
}
/**************************************************************************************
函数名称;DS18B20_Init()
函数功能:DS18B20初始化
输入参数;无
返回参数:无
全局变量:FLG_DS18B20_RET 为1初始化失败,为0初始化成功
**************************************************************************************/
void DS18B20_Init(void)
{
DQ = 0; // 单片机将DQ拉低
Delay_1us(250); // 精确延时大于480us,小于960us
Delay_1us(250);
DQ = 1; // 释放总线
Delay_1us(30); // DS18B20检测到高后,等待15-60us将总线拉低,保持60-240us
FLG_DS18B20_RET=DQ; // 稍做延时后 如果FLG_DS18B20_RET=0则初始化成功,否则初始化失败
Delay_1us(250); // 精确延时 大于 240us
}
/**************************************************************************************
函数名称;DS18B20_ReadOnebit()
函数功能:DS18B20读1位
输入参数;无
返回参数:dat_bit
全局变量:无
**************************************************************************************/
bit DS18B20_ReadOnebit(void)
{
bit dat_bit;
DQ = 0; // 读时序开始
Delay_1us(1); // 延时1us后释放总线
DQ = 1;
Delay_1us(8); // 推荐将采样时间延时到15us的后期
dat_bit=DQ;
Delay_1us(60); // 整个读时序至少保持时间60us
return(dat_bit);
}
/**************************************************************************************
函数名称;DS18B20_ReadOneChar()
函数功能:DS18B20读1个字节
输入参数;无
返回参数:CharDat
全局变量:无
**************************************************************************************/
unsigned char DS18B20_ReadOneChar(void)
{
unsigned char i,Onebit,CharDat=0;
for (i=8;i>0;i--)
{
Onebit=DS18B20_ReadOnebit();
CharDat=((Onebit<<7)|(CharDat>>1));
}
return(CharDat);
}
/**************************************************************************************
函数名称;DS18B20_WriteOneChar()
函数功能:DS18B20写1个字节
输入参数;unsigned char dat
返回参数:无
全局变量:无
**************************************************************************************/
void DS18B20_WriteOneChar(unsigned char dat)
{
unsigned char i;
bit tmp;
for (i=8; i>0; i--)
{
tmp=dat&0x01;
dat=dat>>1;
if(tmp)
{ //写“1”
DQ = 0; // 写时序开始
Delay_1us(8); // 15us内释放总线
DQ = 1; // 写"1"
Delay_1us(60); // 将写"1"保持至少60us
}
else
{ //写"0"
DQ = 0; // 写时序开始
Delay_1us(60); // 将写"0"保持60us~120us
DQ = 1;
Delay_1us(1);
}
}
}
/**************************************************************************************
函数名称;DS18B20_WriteOneChar()
函数功能:读取DS18B20温度值
输入参数;unsigned char dat
返回参数:无
全局变量:Temperature; Temper_Flag=1温度为零上,否则为零下
**************************************************************************************/
void DS18B20_ReadTemperature(void)
{
unsigned char a=0;
unsigned char b=0;
unsigned char c=0;
unsigned char d=0;
unsigned char e=0;
unsigned int t=0;
/*
DS18B20_Init();
DS18B20_WriteOneChar(0xCC); // 跳过读序号列号的操作
DS18B20_WriteOneChar(0x4E); // 写暂存器
DS18B20_WriteOneChar(0xff); // 写TH寄存器
DS18B20_WriteOneChar(0xff); // 写TL寄存器
DS18B20_WriteOneChar(0xff); // 写配置寄存器
DS18B20_WriteOneChar(0x48); // 拷贝暂存器内容到eerprom
*/
DS18B20_Init();
WDI=~WDI;
DS18B20_WriteOneChar(0xCC); // 跳过读序号列号的操作
DS18B20_WriteOneChar(0x44); // 启动温度转换
WDI=~WDI;
Delay_4ms(250);
//Delay_4ms(250);
//Delay_4ms(250);
//Delay_4ms(250);
WDI=~WDI;
DS18B20_Init();
DS18B20_WriteOneChar(0xCC); //跳过读序号列号的操作
DS18B20_WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
a=DS18B20_ReadOneChar(); // 读温度低八位
b=DS18B20_ReadOneChar(); // 读温度高八位
c=DS18B20_ReadOneChar();
d=DS18B20_ReadOneChar();
e=DS18B20_ReadOneChar();
DS18B20_Init();
t=b;
t<<=8;
t=t|a;
if((b<8)||(b!=255))
{
Temper_Flag=1; //温度值大于零
Temperature=t*0.0625;
}
else
{
Temper_Flag=0; //温度值小于零
Temperature=((~t)+1)*0.0625;
}
}
/**************************************************************************************
函数名称;LCD_WrCom()
函数功能:向LCD写入命令--LCM046
输入参数;unsigned char command
返回参数:无
全局变量:无
**************************************************************************************/
void LCD_WrCom(unsigned char command)
{
unsigned char i,tmp;
tmp = command;
LCD_CS=0;
Delay_1us(30);
LCD_WR=0; //写入"100"
LCD_DA=1;
Delay_1us(6);
LCD_WR=1;
Delay_1us(6);
LCD_WR=0;
LCD_DA=0;
Delay_1us(6);
LCD_WR=1;
Delay_1us(6);
LCD_WR=0;
LCD_DA=0;
Delay_1us(6);
LCD_WR=1;
Delay_1us(6);
CY=0;
for(i=9;i>0;i--)//写入命令
{
LCD_WR=0;
if(tmp&0x80)
LCD_DA=1;
else
LCD_DA=0;
Delay_1us(6);
LCD_WR=1;
Delay_1us(6);
tmp=tmp<<1;
}
LCD_DA=1;
LCD_WR=1;
LCD_CS=1;
Delay_1us(60);
}
/**************************************************************************************
函数名称;LCD_Add_Dat()
函数功能:向LCD写入地址、数据
输入参数;unsigned char command
返回参数:无
全局变量:无
备注: 格式;101 0 A4 A3 A2 A1 A0 D0 D1 D2 D3
**************************************************************************************/
void LCD_Add_Dat(unsigned char add,unsigned char dat)
{
unsigned char i,j,tmp1,tmp2;
tmp1=add;
tmp2=dat;
LCD_CS=0;
Delay_1us(15);
LCD_WR=0; //写入"101"
LCD_DA=1;
Delay_1us(6);
LCD_WR=1;
Delay_1us(6);
LCD_WR=0;
LCD_DA=0;
Delay_1us(6);
LCD_WR=1;
Delay_1us(6);
LCD_WR=0;
LCD_DA=1;
Delay_1us(6);
LCD_WR=1;
Delay_1us(6);
for(i=6;i>0;i--) //写入5位地址
{
LCD_WR=0;
if(tmp1&0x20)
LCD_DA=1;
else
LCD_DA=0;
Delay_1us(6);
LCD_WR=1;
Delay_1us(6);
tmp1=tmp1<<1;
}
Delay_1us(6);
for(j=4;j>0;j--) //写入4位数据
{
LCD_WR=0;
if(tmp2&0x01)
LCD_DA=1;
else
LCD_DA=0;
Delay_1us(6);
LCD_WR=1;
Delay_1us(6);
tmp2=tmp2>>1;
}
LCD_DA=1;
LCD_WR=1;
LCD_CS=1;
Delay_1us(60);
}
//LCD初始化
/**************************************************************************************
函数名称;LCD_Init()
函数功能:LCD初始化
输入参数;无
返回参数:无
全局变量:无
**************************************************************************************/
void LCD_Init(void)
{
LCD_CS=1;
LCD_WR=1;
LCD_RD=1;
Delay_1us(250);
LCD_CS=0;
Delay_1us(60);
LCD_CS=1;
Delay_1us(20);
LCD_CS=0;
Delay_1us(60);
LCD_CS=1;
Delay_1us(20);
LCD_CS=0;
Delay_1us(60);
LCD_CS=1;
Delay_1us(20);
LCD_CS=0;
Delay_1us(60);
LCD_CS=1;
Delay_1us(20);
LCD_CS=0;
Delay_1us(60);
LCD_CS=1;
Delay_1us(20);
LCD_CS=0;
Delay_1us(60);
LCD_CS=1;
Delay_1us(20);
LCD_CS=0;
Delay_1us(60);
LCD_CS=1;
Delay_1us(20);
LCD_CS=0;
Delay_1us(60);
LCD_CS=1;
Delay_1us(20);
LCD_WrCom(0x29); //初始化命令
LCD_WrCom(0x18); //内部RC
LCD_WrCom(0x01); //开振荡器
LCD_WrCom(0x03); //开显示器
LCD_Add_Dat(0x00,0x00); //不显示
LCD_Add_Dat(0x01,0x00);
LCD_Add_Dat(0x02,0x00);
LCD_Add_Dat(0x03,0x00);
LCD_Add_Dat(0x04,0x00);
LCD_Add_Dat(0x05,0x00);
LCD_Add_Dat(0x06,0x00);
LCD_Add_Dat(0x07,0x00);
}
/**************************************************************************************
函数名称;Lcd_Hex()
函数功能:将要显示的数值转换为LCD输入的十六进制
输入参数;unsigned char lcd_dat
返回参数:无
全局变量:lcd_dat_1; lcd_dat_2
**************************************************************************************/
void Lcd_Hex(unsigned char lcd_dat)
{
switch(lcd_dat)
{
case 1:
lcd_dat_1=0x00;
lcd_dat_2=0x05;
break;
case 2:
lcd_dat_1=0x05;
lcd_dat_2=0x0b;
break;
case 3:
lcd_dat_1=0x01;
lcd_dat_2=0x0f;
break;
case 4:
lcd_dat_1=0x02;
lcd_dat_2=0x07;
break;
case 5:
lcd_dat_1=0x03;
lcd_dat_2=0x0e;
break;
case 6:
lcd_dat_1=0x07;
lcd_dat_2=0x0e;
break;
case 7:
lcd_dat_1=0x01;
lcd_dat_2=0x05;
break;
case 8:
lcd_dat_1=0x07;
lcd_dat_2=0x0f;
break;
case 9:
lcd_dat_1=0x03;
lcd_dat_2=0x0f;
break;
case 0:
lcd_dat_1=0x07;
lcd_dat_2=0x0d;
break;
}
}
/**************************************************************************************
函数名称;Temper_showed()
函数功能:LCD显示温度值
输入参数;无
返回参数:无
全局变量:lcd_dat_1; lcd_dat_2; Temperature; Temper_Flag
**************************************************************************************/
void Temper_showed(void)
{
unsigned int tmp;
unsigned char lcd_dat_tmp;
tmp=(int)(Temperature*10); //将要显示的数变为整数取出
if(Temperature<100)
{
if(!Temper_Flag)
{
LCD_Add_Dat(0x00,0x00); //显示负号
LCD_Add_Dat(0x01,0x02);
}
else
{
LCD_Add_Dat(0x00,0x00); //不显示
LCD_Add_Dat(0x01,0x00);
}
lcd_dat_tmp=tmp/100; //取出十位数
Lcd_Hex(lcd_dat_tmp);
LCD_Add_Dat(0x02,lcd_dat_1); //显示十位
LCD_Add_Dat(0x03,lcd_dat_2);
lcd_dat_tmp=(tmp%100)/10; //取出个位数
Lcd_Hex(lcd_dat_tmp);
LCD_Add_Dat(0x04,lcd_dat_1); //显示个位
LCD_Add_Dat(0x05,lcd_dat_2);
lcd_dat_tmp=tmp%10; //取出小数
Lcd_Hex(lcd_dat_tmp);
LCD_Add_Dat(0x06,lcd_dat_1|0x08);//显示小数和小数点
LCD_Add_Dat(0x07,lcd_dat_2);
}
else
{
lcd_dat_tmp=tmp/1000; //取出百位数
Lcd_Hex(lcd_dat_tmp);
LCD_Add_Dat(0x00,lcd_dat_1); //显示百位
LCD_Add_Dat(0x01,lcd_dat_2);
lcd_dat_tmp=(tmp%1000)/100; //取出十位数
Lcd_Hex(lcd_dat_tmp);
LCD_Add_Dat(0x02,lcd_dat_1); //显示十位
LCD_Add_Dat(0x03,lcd_dat_2);
lcd_dat_tmp=((tmp%1000)%100)/10;//取出个位数
Lcd_Hex(lcd_dat_tmp);
LCD_Add_Dat(0x04,lcd_dat_1); //显示个位
LCD_Add_Dat(0x05,lcd_dat_2);
lcd_dat_tmp=tmp%10; //取出小数
Lcd_Hex(lcd_dat_tmp);
LCD_Add_Dat(0x06,lcd_dat_1|0x08);//显示小数和小数点
LCD_Add_Dat(0x07,lcd_dat_2);
}
}
void main(void)
{
unsigned char i;
C8051F221_Init();
TEMPERCON = 0;
WDI=0;
LCD_Init();
WDI=~WDI;
while(1)
{
WDI=~WDI;
DS18B20_ReadTemperature();
WDI=~WDI;
Temper_showed();
WDI=~WDI;
if(Temperature>37)
{
TEMPERCON = 1;
while(Temperature>35)
{
//延时180s
for(i=4;i>0;i--)
{ WDI=~WDI;
Delay_4ms(250);
WDI=~WDI;
}
DS18B20_ReadTemperature();
WDI=~WDI;
Temper_showed();
}
TEMPERCON = 0;
}
else
TEMPERCON = 0;
//延时180s
for(i=4;i>0;i--)
{
WDI=~WDI;
Delay_4ms(250);
WDI=~WDI;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -