标题:
求大神帮我看看我的LCD为啥不出数,仿真,单片机程序如下
[打印本页]
作者:
sanjiajiu
时间:
2020-5-26 16:48
标题:
求大神帮我看看我的LCD为啥不出数,仿真,单片机程序如下
1.png
(88.16 KB, 下载次数: 25)
下载附件
2020-5-26 16:47 上传
按键实现摄氏度华氏度转换
#include "reg52.h"
#include "intrins.h"
#include "stdio.h"
//================
关键字别名定义
===========================
typedef unsigned char uint8;
typedef char int8;
typedef unsigned int uint16;
typedef int int16;
typedef unsigned long uint32;
typedef long int32;
//======================
端口定义
=========================
sbit key = P2^0;
sbit DS18B20_IO = P2^3; //DS18B20通信端口
#define IO_18B20_L() DS18B20_IO = 0
#define IO_18B20_H() DS18B20_IO = 1
#define IO_18B20_R() (DS18B20_IO)
#define LCD1602_DATA P0 //
定义
LCD1602
的数据端口
sbit LCD1602_RS = P2^6;//
定义
LCD1602
的
RS
脚
sbit LCD1602_RW = P2^5;//
定义
LCD1602
的
RW
脚
sbit LCD1602_E = P2^4;//
定义
LCD1602
的
E
脚
uint8 buffer[16];//
显示缓冲数组
int16 DS18B20_tpr;
bit HuaShiDuFlg=0;
//10
微秒精确延时
void Delay10us(void)
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
//50
微秒精确延时
void Delay50us(void)
{
Delay10us();
Delay10us();
Delay10us();
Delay10us();
Delay10us();
}
//N
毫秒精确延时
void DelayNms(uint16 i)
{
uint8j;
for(;i;i--)
{
j=83; //
延时精度调节
for(;j;j--) Delay10us();
}
}
/****************
对
LCD1602
写入
1
个字节数据
*****************
*@style - 待写入数据的类型:0
表示指令,
1
表示数据
*@dat -
待写入的指令或数据
**********************************************************/
void LCD1602_WriteOneByte(bit style,uint8dat)
{
LCD1602_E = 0;
_nop_();
_nop_();
LCD1602_RS = style; //
写入指令或数据标志置位
LCD1602_RW = 0;
LCD1602_DATA = dat; //
首先送入数据
_nop_();
_nop_();
LCD1602_E = 1; //
使能置
1
_nop_();
_nop_();
LCD1602_E = 0;
}
//LCD1602忙等待,当读取的数据最高位为0
时,才可以进行读写操作
void LCD1602_WaitBusy(void)
{
LCD1602_E = 0;
LCD1602_DATA = 0xFF;
LCD1602_RS = 0;
LCD1602_RW = 1;
_nop_();
_nop_();
LCD1602_E = 1; //
使能
_nop_();
_nop_();
_nop_();
_nop_();
while( LCD1602_DATA & 0x80 ); //检测忙信号,如果为最高位为1
则等待
LCD1602_E = 0;
}
/***************LCD1602
在指定位置显示字符串
****************
*@hang - 待显示数据的行坐标:0~1
行
*@lie -
待显示数据的列坐标:
0~15
列
*@pDat - 数据指针,指向待显示数据
**********************************************************/
void LCD1602_DisStr(uint8 hang,uint8lie,uint8 *pDat)
{
if(hang==0) lie=0x80+lie;
else if(hang==1) lie=0xc0+lie;
LCD1602_WaitBusy();//
写入前需要读忙信号
LCD1602_WriteOneByte(0,lie); //
发送地址
while(*pDat)
{
LCD1602_WaitBusy();//
写入前需要读忙信号
LCD1602_WriteOneByte(1,*pDat);//
发送数据
pDat++; //
数据指针递增
}
}
void LCD1602_ClrScreen(void)
{
// LCD1602_WaitBusy();//
写入前需要读忙信号
// LCD1602_WriteOneByte(0,0x01); //
清屏
LCD1602_DisStr(0,0," ");
LCD1602_DisStr(1,0," ");
}
//LCD1602初始化,开机时需要初始化一次
void LCD1602_Init(void)
{
LCD1602_WriteOneByte(0,0x38); //
显示模式设置,
16*2
显示,
5*7
点阵
DelayNms(5);
LCD1602_WriteOneByte(0,0x38); //
显示模式设置,
16*2
显示,
5*7
点阵
DelayNms(5);
LCD1602_WriteOneByte(0,0x38); //
显示模式设置,
16*2
显示,
5*7
点阵
DelayNms(5);
LCD1602_WriteOneByte(0,0x38); //
显示模式设置,
16*2
显示,
5*7
点阵
DelayNms(5);
LCD1602_WriteOneByte(0,0x08); //
关闭显示,关闭光标
DelayNms(5);
LCD1602_WriteOneByte(0,0x01); //
清屏
DelayNms(5);
LCD1602_WriteOneByte(0,0x06); //
设置显示光标地址递增
DelayNms(5);
LCD1602_WriteOneByte(0,0x0C); //
开显示
}
//DS18B20初始化
void DS18B20_init(void)
{
uint8 i;
IO_18B20_H(); // DQ
复位
_nop_();_nop_(); //
稍做延时
IO_18B20_L(); //
单片机将
DQ
拉低至少
480us
以初始化器件
for(i=0;i<10;i++) Delay50us();
IO_18B20_H(); //
释放总线
//
主机释放总线后
15~60us(
实测
30us
左右
)
,器件将总线拉低
60~240us(
这叫存在脉冲,实测
100us
左右
)
后再释放总线
//
这里延时
300us
,确保器件已经释放总线
for(i=0;i<6;i++) Delay50us();
}
//
写一个字节
void DS18B20_WriteOneByte(uint8 dat)
{
uint8i;
for(i=0;i<8; i++)
{
IO_18B20_L(); //
启动写时序
if(dat&0x01) //
写
1
时要在
15us
内释放总线;写
0
至少要拉低
60us
总线,然后再释放
{
_nop_();_nop_();
IO_18B20_H();
}
Delay50us();Delay10us();
IO_18B20_H();
_nop_(); //
写周期间隔时间最小为
1us
dat>>= 1;
}
}
//
读一个字节
uint8 DS18B20_ReadOneByte(void)
{
uint8i;
uint8dat=0;
for(i=0;i<8; i++)
{
IO_18B20_L();//
启动读时序,低电平至少保持
1us
dat>>=1;
_nop_();
IO_18B20_H();//
释放总线,在
15us
内读数据
_nop_();_nop_();
if(IO_18B20_R()) dat |= 0x80;
Delay10us();Delay10us();Delay10us();Delay10us();
}
returndat;
}
//
读取温度,结果支持负温度值
void DS18B20_GetTpr(int16 *pTemper)
{
staticuint8 step=0;
static uint8 i=0;
uint8 LByte;
uint8HByte;
int16dat;
if(step==0)
{
DS18B20_init();
DS18B20_WriteOneByte(0xCC); //
跳过读序列号的操作
DS18B20_WriteOneByte(0x44); //
启动温度转换
step=1;
i=0;
}
else if(step==1) //
延时
500ms
左右去取温度值
{
i++;
if(i>=50)
{
i=0;
step=2;
}
}
else if(step==2)
{
DS18B20_init();
DS18B20_WriteOneByte(0xCC); //
跳过读序列号的操作
DS18B20_WriteOneByte(0xBE); //
读取温度寄存器等(共可读
9
个寄存器)
前两个就是温度
LByte = DS18B20_ReadOneByte(); //
先读温度的低字节
HByte = DS18B20_ReadOneByte(); //
再读温度的高字节
dat = ((uint16)HByte<<8) |LByte; //
合成数据
//
分辨率为
0.0625
,结果
= dat*0.0625 = dat*5/80
,结果范围为
-55 ~ 125
*pTemper = dat*5/8; //
换算温度,放大
10
倍
step=0;
}
}
void KeyScan(void)
{
static uint8 KeyCnt=0;
if(key==0)
{
if(KeyCnt<0xff) KeyCnt++;
if(KeyCnt==10)
{
HuaShiDuFlg=!HuaShiDuFlg;
}
}
else KeyCnt=0;
}
void LcdDisplay(void)
{
float buf;
if(HuaShiDuFlg==0) //
显示摄氏度
{
sprintf(buffer,"T:%05.1f C",DS18B20_tpr/10.0);
LCD1602_DisStr(0,0,buffer);
}
else //
显示华氏度
,
华氏度
=
摄氏度
*1.8+32
{
buf = DS18B20_tpr*0.18+32; //
因为温度是乘了
10
保留了
1
个小数位在里面,所以这里要先除
10
,算下来就是乘
0.18
sprintf(buffer,"T:%05.1f F",buf);
LCD1602_DisStr(0,0,buffer);
}
}
void main(void)
{
LCD1602_Init();
while(1)
{
DS18B20_GetTpr(&DS18B20_tpr);
KeyScan();
LcdDisplay();
DelayNms(10);
}
}
作者:
sanjiajiu
时间:
2020-5-26 16:49
不是不显示,是不出数
作者:
man1234567
时间:
2020-5-27 06:06
抄程序很累吧 ?直接搭个实景就知道问题所在了,纸上谈兵总会丢三落四。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1