📄 main.c
字号:
//1602驱动 完成时间06.10.7 测试成功!
#include <reg51.h>
#include <stdio.h>
extern void _nop_(void);
sbit Rs_1602 = P2^0;
sbit Rw_1602 = P2^1;//定义引脚
sbit E_1602 = P2^2;
#define Data_1602 P0
#define Busy 0x80 //用于检测_1602状态字中的Busy标识
//----------------------
sbit DQ =P1^0; //定义通信端口
//----------------------
void ReadStatus_1602(void);//读状态
unsigned char ReadData_1602(void);//读数据
void WriteData_1602(unsigned char Dat);//写数据(单字)
void WriteCommand_1602(unsigned char Dat);//写指令
void DisplayOneChar_1602(unsigned char x, unsigned char y, unsigned char Dat);//指定位置写单字;
void DisplayListChar_1602(unsigned char x, unsigned char y, unsigned char *Dat,unsigned char c);//指定位置写字符串(c=1不
void Delay_1602(unsigned int i);
void Init_1602(void); //_1602初始化
void ftoa(unsigned char *Dataa,float dat,unsigned char n);
//----------------------
void delay(unsigned int i);
Init_DS18B20(void);
ReadOneChar(void);
WriteOneChar(unsigned char dat);
float ReadTemperature(void);
//------------------
code char CgramDot[]={
0x04,0x04,0x1F,0x0E,0x15,0x04,0x04,0x04, //木 代码 0x00
0x08,0x04,0x1F,0x00,0x0E,0x0A,0x0A,0x13, //杭 代码 0x01
0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02, //年,代码 0x02
0x0f,0x09,0x0f,0x09,0x0f,0x09,0x11,0x00, //月,代码 0x03
0x1f,0x11,0x11,0x1f,0x11,0x11,0x1f,0x00, //日,代码 0x04
0x11,0x0a,0x04,0x1f,0x04,0x1f,0x04,0x00, //$,代码 0x05
0x0e,0x00,0x1f,0x0a,0x0a,0x0a,0x13,0x00, //元,代码 0x06
0x18,0x18,0x07,0x08,0x08,0x08,0x07,0x00, //C,代码 0x07
0x04,0x0a,0x15,0x04,0x04,0x04,0x04,0x00, //^, 代码 0x08
0x17,0x15,0x15,0x15,0x15,0x15,0x17,0x00, //10, 代码 0x09
};
void main(void)
{
unsigned char i;
float f=3.1415926;
unsigned char s[15];
// unsigned char d[15];
Delay_1602(500); //启动等待,等_1602讲入工作状态
Init_1602(); //_1602初始化
// 装入cgram
for(i=0;i<64;i++)
{
WriteCommand_1602(0x40+i);
WriteData_1602(CgramDot[i]);
}
//test:
ftoa(s,f,4);////字符转换无舍入资源小小数至少一位!
// sprintf(d, "%.4f", f);//字符转换资源大
DisplayListChar_1602(1, 10, "Test!",0);
WriteData_1602('T');
DisplayOneChar_1602(1,1,'-');
DisplayListChar_1602(1,16,"y000",1);
// DisplayListChar_1602(1, 1 ,s,0);
// DisplayListChar_1602(2, 1 ,d,0);
for(i=1;i<8;i++)
DisplayOneChar_1602(2,i+5,i-1);//显示汉字
DisplayListChar_1602(1,16,"y000",1);
// DisplayOneChar_1602(2,5,'T');
DisplayOneChar_1602(1,6,7);//显示汉字
DisplayOneChar_1602(2,1,0);//显示汉字
while(1)
{
f = ReadTemperature();
ftoa(s,f,2);
DisplayListChar_1602(1, 1 ,s,0);
}
}
//---------------------
//读状态
void ReadStatus_1602(void)
{
do
{
Data_1602 = 0xFF;
Rs_1602= 0;
Rw_1602= 1;
E_1602 = 0;
_nop_(); //或者E_1602 = 0延时;
E_1602 = 1;
_nop_(); //或者E_1602 = 0延时;(实际不用)
}while(Data_1602 & Busy);
}
//------------------------
//读数据 可不用
/*unsigned char ReadData_1602(void)
{
Rs_1602 = 1;
Rw_1602 = 1;
E_1602 = 0;
_nop_();//E_1602 = 0;
E_1602 = 1;
return(Data_1602);
}
//-------------------------*/
//写数据
void WriteData_1602(unsigned char Dat)
{
ReadStatus_1602(); //检测忙
Data_1602 = Dat;
Rs_1602 = 1;
Rw_1602= 0;
E_1602 = 0; //若晶振速度太高可以在这后加小的延时
_nop_();//E_1602 = 0; //延时
E_1602 = 1;
}
//----------------------
void WriteCommand_1602(unsigned char Dat)
{
ReadStatus_1602();
Data_1602 = Dat;
Rs_1602 = 0;
Rw_1602= 0;
E_1602 = 0;
_nop_();
E_1602 = 1;
}
//按指定位置显示一个字符
void DisplayOneChar_1602(unsigned char x, unsigned char y, unsigned char Dat)
{
x--;
y--;
x &= 0x1;
y &= 0xF; //限制x不能大于15,y不能大于1
if (x) y |= 0x40; //当要显示第二行时地址码 0x40;
y |= 0x80; // 算出指令码
WriteCommand_1602(y); //这里不检测忙信号,发送地址码
WriteData_1602(Dat);
}
//按指定位置显示一串字符
void DisplayListChar_1602(unsigned char x, unsigned char y, unsigned char *Dat,unsigned char c)
{
unsigned char ListLength;
ListLength = 0;
if (--y <= 0x0F && Dat[ListLength]!='\0') //x坐标应小于0xF
{
DisplayOneChar_1602(x, ++y, Dat[ListLength]); //显示单个字符
ListLength++;
}
while (Dat[ListLength]!='\0')
{
if((y+ListLength)>0x10 && c==1 && x==1)
{
x=2;
DisplayOneChar_1602(2, 1, Dat[ListLength]); //显示单个字符
ListLength++;
}
WriteData_1602(Dat[ListLength]); //显示单个字符
ListLength++;
}
}
//------------
void Delay_1602(unsigned int i)
{
while(i--);
}
void Init_1602(void) //_1602初始化
{
Data_1602 = 0xff;
WriteCommand_1602(0x38); //显示模式设置,开始要求每次检测忙信号
WriteCommand_1602(0x08); //关闭显示
WriteCommand_1602(0x01); //显示清屏
WriteCommand_1602(0x06); // 显示光标移动设置
WriteCommand_1602(0x0c); // 显示开及光标设置
}
void ftoa(unsigned char *Dataa,float dat,unsigned char n)
{
unsigned char i,length=0;
int ddat;
bit flag_dat =0;
if(dat < 0)
{
flag_dat=1;
dat *= -1;
}
for(i=1;i<=n;i++)
{
dat=dat*10;
}
ddat = (int) dat ;
if(dat == 0)
{
Dataa[0]='0';
Dataa[1]='.';
for(i=2;i<= n+1;i++) Dataa[i]='0';
Dataa[n+2]='\0';
return;
}
do
{
dat=dat/10;
length++;
}while(dat>=1);
Dataa[length-n]='.';
Dataa[length+1]='\0';
for(i=1;i<=length;i++)
{
if(i<=n)
{
Dataa[length-i+1]=(ddat-ddat/10*10+48);
ddat=ddat/10;
}
else
{
Dataa[length-i]=(ddat-ddat/10*10+48);
ddat=ddat/10;
}
}
Dataa[length-n]='.';
Dataa[length+1]='\0';
if( flag_dat == 1 )
{
for( i=length+2 ;i > 0;i--)
{
Dataa[i]=Dataa[i-1];
}
Dataa[0]='-';
}
}
//-------------------
//-------------------------------------------------------------------
void delay(unsigned int i)
{
while(i--);
}
//--------------------
Init_DS18B20(void)
{
bit x=0;
DQ = 1; //DQ复位
delay(8); //稍做延时
DQ = 0; //单片机将DQ拉低
delay(80); //精确延时 大于 480us
DQ = 1; //拉高总线
delay(14);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay(20);
}
//读一个字节
ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
delay(4);
}
return(dat);
}
//写一个字节
WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay(5);
DQ = 1;
dat>>=1;
}
delay(4);
}
//读取温度
float ReadTemperature(void)
{
unsigned char a=0;
unsigned char b=0;
int t1=0;
float tt=0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
a=ReadOneChar(); //读取温度值低位
b=ReadOneChar(); //读取温度值高位
t1 = (a|(b<<8)); //得到的全部(16位)数据.
tt = t1;
tt *= 0.0625;//返回的温度.
return(tt);
}
//-------------END-------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -