找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1511|回复: 6
收起左侧

请教LCD12864显示温度负数的问题

[复制链接]
ID:891876 发表于 2024-6-7 09:44 | 显示全部楼层 |阅读模式
程序能正常显示温度,当温度负数时变量闪烁,请问怎样在主函数里显示“—”号?

#include <STC32G.H>
#include <intrins.h>  
typedef         unsigned char        u8;
typedef         unsigned int        u16;

#define MAIN_Fosc        24000000UL

#if (MAIN_Fosc >= 24000000L)
    #define usrNOP() _nop_();_nop_();_nop_();_nop_();_nop_();_nop_()
#endif

#define LCD_data  P2             //数据口
sbit LCD_RS  =  P4^1;            //寄存器选择输入
sbit LCD_RW  =  P4^2;            //液晶读/写控制
sbit LCD_EN  =  P4^4;            //液晶使能控制
sbit LCD_PSB =  P4^5;            //串/并方式控制
sbit LCD_RST =  P3^7;
sbit DQ_1= P1^0;  //18B20气温数据口

bit MinusFlag=0;       //负数标志,0:正数,1:负数

u16 QW;    //气温变量
u8 mun_char_table[]={"0123456789"};
u8 code dis1[] = {"气温:       ℃"};
u8 code dis2[] = {"气温: -     ℃"}; //零下气温

void delay_ms(u16 z)    //延时ms
{
   u16 x,y;
   for(x=z;x>0;x--)
   for(y=614;y>0;y--);
}

void delay_us(u8 us)
{
    do{
        usrNOP();
        usrNOP();
      }
        while(--us);
}

/**************************************
复位DS18B20,并检测设备是否存在
**************************************/
void DS18B20_Reset()
{
    CY = 1;
    while (CY)
     {  
        DQ_1 = 0;                     //送出低电平复位信号
        delay_us(240);              //延时至少480us
        delay_us(240);
        DQ_1 = 1;                     //释放数据线
        delay_us(60);               //等待60us
        CY = DQ_1;                    //检测存在脉冲
        delay_us(240);              //等待设备释放数据线
        delay_us(240);
     }
}

/**************************************
从DS18B20读1字节数据
**************************************/
u8 DS18B20_ReadByte()
{
    u8 i;
    u8 dat = 0;

    for (i=0; i<8; i++)             //8位计数器
    {
        dat >>= 1;
        DQ_1 = 0;                     //开始时间片
                delay_us(1);          //延时等待
        DQ_1 = 1;                     //准备接收
                delay_us(1);           //接收延时
        if (DQ_1) dat |= 0x80;        //读取数据
        delay_us(60);                 //等待时间片结束
        DQ_1 = 1;

    }

    return dat;
}

/**************************************
向DS18B20写1字节数据
**************************************/
void DS18B20_WriteByte(u8 dat)
{
    char i;

    for (i=0; i<8; i++)             //8位计数器
    {
        DQ_1 = 0;                     //开始时间片
        delay_us(1);                //延时等待
        dat >>= 1;                  //送出数据
        DQ_1 = CY;
        delay_us(60);               //等待时间片结束
        DQ_1 = 1;                     //恢复数据线
        delay_us(1);                //恢复延时
    }
}
//========================================================================
// 函数: u16 ReadTemperature()
// 描述: 读取温度函数。
// 参数: none.
// 返回: 温度值.
//========================================================================
u16 ReadTemperature()   //气温
{
    u16 TempH, TempL, Temperature;
        
    DS18B20_Reset_1();                //设备复位
    DS18B20_WriteByte_1(0xCC);        //跳过ROM命令
    DS18B20_WriteByte_1(0x44);        //开始转换命令
    while (!DQ_1);                    //等待转换完成        
    DS18B20_Reset_1();                //设备复位
    DS18B20_WriteByte_1(0xCC);        //跳过ROM命令
    DS18B20_WriteByte_1(0xBE);        //读暂存存储器命令
    TempL = DS18B20_ReadByte_1();     //读温度低字节
    TempH = DS18B20_ReadByte_1();     //读温度高字节
        
   if(TempH & 0xf8)    //判断是否位负数
    {
        MinusFlag = 1;  //设置负数标志
        Temperature = (TempH<<8) | TempL;
        Temperature = ~Temperature + 1;
        Temperature *= 0.625;       //0.0625 * 10,保留1位小数点
        }
   else
    {
        MinusFlag = 0;  //清除负数标志
        Temperature = (((TempH<<8) | TempL) * 0.625); //0.0625 * 10,保留1位小数点
    }

    return Temperature;
}

//////////////以下是LCD12864驱动程序////////////////

/*******************************************************************/
/*                                                                 */
/*检查LCD忙状态                                                    */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。      */
/*                                                                 */
/*******************************************************************/
bit lcd_busy()
{

    bit result;
    P2=0X00;              //关掉数据口信号。阻止LCD受到P2口信号的影响
    LCD_RS = 0;
    LCD_RW = 1;
    LCD_EN = 1;
    delay_ms(1);
    result = (bit)(P0&0x80);
    LCD_EN = 0;
    return(result);
}
/*******************************************************************/
/*                                                                 */
/*写指令数据到LCD                                                  */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。                             */
/*                                                                 */
/*******************************************************************/
void lcd_wcmd(u8 cmd)
{   

   while(lcd_busy());
    LCD_RS = 0;
    LCD_RW = 0;
    LCD_EN = 0;
    _nop_();
    _nop_();
    P2 = cmd;
    delay_ms(1);
    LCD_EN = 1;
    delay_ms(1);
    LCD_EN = 0;  
}
/*******************************************************************/
/*                                                                 */
/*写显示数据到LCD                                                  */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。                               */
/*                                                                 */
/*******************************************************************/
void lcd_wdat(u8 dat)
{                          
   while(lcd_busy());
    LCD_RS = 1;
    LCD_RW = 0;
    LCD_EN = 0;
    P2 = dat;
    delay_ms(1);
    LCD_EN = 1;
    delay_ms(1);
    LCD_EN = 0;
}
/*******************************************************************/
/*                                                                 */
/*  LCD初始化设定                                                  */
/*                                                                 */
/*******************************************************************/
void lcd_init()
{

    LCD_PSB = 1;         //并口方式
    lcd_wcmd(0x34);      //扩充指令操作
    delay_ms(5);
    lcd_wcmd(0x30);      //基本指令操作
    delay_ms(5);
    lcd_wcmd(0x0C);      //显示开,关光标
    delay_ms(5);
    lcd_wcmd(0x01);      //清除LCD的显示内容
    delay_ms(5);
}
/*********************************************************/
/*                                                       */
/* 设定显示位置                                          */
/*                                                       */
/*********************************************************/
void lcd_pos(u8 X,u8 Y)
{                          
   u8  pos;
   if (X==0)
     {X=0x80;}
   else if (X==1)
     {X=0x90;}
   else if (X==2)
     {X=0x88;}
   else if (X==3)
     {X=0x98;}
   pos = X+Y ;  
   lcd_wcmd(pos);     //显示地址
}
/*---------------------以上是LCD12864驱动程序-----------------------*/

void main()//主函数模块//   
{      
    u8 i=0;
    P1M0 = 0x00; P1M1 = 0x00;  
    P2M0 = 0x00; P2M1 = 0x00;
    P3M0 = 0x00; P3M1 = 0x00;
    P4M0 = 0x00; P4M1 = 0x00;
    lcd_init();            //LCD初始化
    LCD_RST=1;
    delay_ms(100);
    LCD_RST=0;
/*-------------------------------------------------------------------*/
           
  if(MinusFlag==0)
   {
      lcd_pos(0,0);             //设置显示位置为第1行的第1个字符
      i = 0;
     while(dis1 != '\0')
        {                         //显示字符
           lcd_wdat(dis1);
           i++;
        }

         }
    else
      {
         lcd_pos(0,0);             //设置显示位置为第1行的第1个字符
         i = 0;
        while(dis2 != '\0')
         {                         //显示字符
            lcd_wdat(dis2);
            i++;
                        
          }
      }
        
  while(1)     
    {  
                                                   
        QW=ReadTemperature();
        lcd_pos(0,4);   
        lcd_wdat(mun_char_table[QW/1000%10]);
        lcd_wdat(mun_char_table[QW/100%10]);
        lcd_wdat(mun_char_table[QW/10%10]);  
      //lcd_wdat(mun_char_table[QW%10]);
                                                                                         
        }  
}

回复

使用道具 举报

ID:619259 发表于 2024-6-7 10:40 | 显示全部楼层
18B20程序中有负温度标志,当标志有效时,显示“-”
回复

使用道具 举报

ID:1124188 发表于 2024-6-7 12:30 | 显示全部楼层
if(TempH & 0xf8)    //判断是否位负数
    {
        MinusFlag = 1;  //设置负数标志
        Temperature = (TempH<<8) | TempL;
        Temperature = ~Temperature + 1;
        Temperature *= 0.625;       //0.0625 * 10,保留1位小数点
        }
   else
    {
        MinusFlag = 0;  //清除负数标志
        Temperature = (((TempH<<8) | TempL) * 0.625); //0.0625 * 10,保留1位小数点
    }
看看你的这行代码,这是负数标志位的设置
回复

使用道具 举报

ID:1109793 发表于 2024-6-7 13:28 | 显示全部楼层
小于0就显示-
回复

使用道具 举报

ID:891876 发表于 2024-6-7 14:33 | 显示全部楼层
LotusVirginMary 发表于 2024-6-7 12:30
if(TempH & 0xf8)    //判断是否位负数
    {
        MinusFlag = 1;  //设置负数标志

试过了,,,在主程序中判断负数标志位,加人程序后温度变量闪烁变暗,应该是while语句造成的

while(dis2[ i] != '\0')
         {                         //显示字符
            lcd_wdat(dis2[ i]);
            i++;
回复

使用道具 举报

ID:1109793 发表于 2024-6-7 19:26 | 显示全部楼层
芙蓉焊料 发表于 2024-6-7 14:33
试过了,,,在主程序中判断负数标志位,加人程序后温度变量闪烁变暗,应该是while语句造成的

while(d ...

液晶啊,写完了就在那里显示了,又不是动态的数码管。会收到延时的影响
回复

使用道具 举报

ID:879809 发表于 2024-6-8 15:57 | 显示全部楼层
芙蓉焊料 发表于 2024-6-7 14:33
试过了,,,在主程序中判断负数标志位,加人程序后温度变量闪烁变暗,应该是while语句造成的

while(d ...

这里明明应该用if,用while是给自己找不自在。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表