找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1782|回复: 13
打印 上一主题 下一主题
收起左侧

我用LCD串行的方式显示,为什么HC-SR04超声波的数值不更新。其他数据显示正常

[复制链接]
跳转到指定楼层
楼主
ID:652483 发表于 2021-4-14 01:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
主函数
#include <reg52.h>
#include <intrins.h>
#include "LCD12864.h"
#include "timer1.h"
#include "ADC0832.h"
#include "DS18B20.h"
#include "eepom52.h"
#include "HC_SR04.h"
sbit beep = P2^0;
sbit setKey = P3^3;
sbit addKey = P3^4;
sbit subKey = P3^5;
int S;
float dataV[4]= {0};
unsigned char dataTH[8]={110,30, 99, 30, 8,2, 45, 15};

unsigned char lcd[8] = {0};

void alarm();

void delay(unsigned int i){
    while(i--);
}


float pre_ph_v, phv;
void setKeyDeal();
void addKeyDeal();
void subKeyDeal();

//³õʼ»¯eeprom
void init_eeprom(){
    unsigned char is_first_init =  byte_read(0x2020);
    if(is_first_init == 1){
        dataTH[0] = byte_read(0x2000);
        dataTH[1] = byte_read(0x2001);
        dataTH[2] = byte_read(0x2002);
        dataTH[3] = byte_read(0x2003);
        dataTH[4] = byte_read(0x2004);
        dataTH[5] = byte_read(0x2005);
        dataTH[6] = byte_read(0x2006);
        dataTH[7] = byte_read(0x2007);
    }else{
            SectorErase(0x2000);
            byte_write(0x2000, dataTH[0]);
            byte_write(0x2001, dataTH[1]);
            byte_write(0x2002, dataTH[2]);
            byte_write(0x2003, dataTH[3]);
            byte_write(0x2004, dataTH[4]);
            byte_write(0x2005, dataTH[5]);
            byte_write(0x2006, dataTH[6]);
            byte_write(0x2007, dataTH[7]);
            byte_write(0x2020, 1);   
    }
}

//¸üÐÂeeprom´æ´¢µÄÊý¾Ý
void update_eeprom(){
            SectorErase(0x2000);
            byte_write(0x2000, dataTH[0]);
            byte_write(0x2001, dataTH[1]);
            byte_write(0x2002, dataTH[2]);
            byte_write(0x2003, dataTH[3]);
            byte_write(0x2004, dataTH[4]);
            byte_write(0x2005, dataTH[5]);
            byte_write(0x2006, dataTH[6]);
            byte_write(0x2007, dataTH[7]);
            byte_write(0x2020, 1);   
}

void updateLCD(){
    dataV[0] = get_0832_AD_data(0); //PH
    dataV[1] = get_hc_sr04_distance();  //SW
    dataV[2] = get_0832_AD_data(1);  //ZD
    dataV[3] = Get18B20Temp();  //WD
   
    phv = -58.87*(dataV[0]*5.0/255.0) + 216.77;
    if(phv > 141 || phv < 0 ) { phv = pre_ph_v; }
    pre_ph_v = phv;
    lcd[0] = ((int)phv)%1000/100+48;
    lcd[1] = ((int)phv)%100/10 + 48;
    lcd[2] =  '.';
    lcd[3] = ((int)phv)%10 + 48;
    lcd[4] =  '\0';
    PutStr(0,1, lcd);
    dataV[0] = phv;

    dataV[2]  = dataV[2] /2.55;
    if(dataV[2] > 99) dataV[2] = 99;
    lcd[0] = ((int)dataV[2])%100/10 + 48;
    lcd[1] = ((int)dataV[2])%10 + 48;
    lcd[2] =  '\0';
    PutStr(1,1, lcd);
   
    //dataV[1]  = 10 - (dataV[1]-40) /19;
    //if(dataV[1] > 10) dataV[1] = 10;
    //if(dataV[1] < 0) dataV[1] = 0;
    lcd[0] = ((int)dataV[1])%100/10 + 48;
    lcd[1] = ((int)dataV[1])%10 + 48;
    lcd[2] =  '\0';
    PutStr(2,1, lcd);
   
    lcd[0] = ((int)dataV[3])%100/10 + 48;
    lcd[1] = ((int)dataV[3])%10 + 48;
    lcd[2] =  '\0';
    PutStr(3,1, lcd);

}

void updateTH(){
    lcd[0] = ((int)dataTH[0])%1000/100+48;
    lcd[1] = ((int)dataTH[0])%100/10 + 48;
    lcd[2] =  '\0';
    PutStr(0,4, lcd);
   
  lcd[0] = ((int)dataTH[1])%1000/100+48;
    lcd[1] = ((int)dataTH[1])%100/10 + 48;
    lcd[2] =  '\0';
    PutStr(0,7, lcd);
   
    lcd[0] = ((int)dataTH[2])%100/10+48;
    lcd[1] = ((int)dataTH[2])%10 + 48;
    lcd[2] =  '\0';
    PutStr(1,4, lcd);

    lcd[0] = ((int)dataTH[3])%100/10+48;
    lcd[1] = ((int)dataTH[3])%10 + 48;
    lcd[2] =  '\0';
    PutStr(1,7, lcd);

    lcd[0] = ((int)dataTH[4])%100/10+48;
    lcd[1] = ((int)dataTH[4])%10 + 48;
    lcd[2] =  '\0';
    PutStr(2,4, lcd);

    lcd[0] = ((int)dataTH[5])%100/10+48;
    lcd[1] = ((int)dataTH[5])%10 + 48;
    lcd[2] =  '\0';
    PutStr(2,7, lcd);

    lcd[0] = ((int)dataTH[6])%100/10+48;
    lcd[1] = ((int)dataTH[6])%10 + 48;
    lcd[2] =  '\0';
    PutStr(3,4, lcd);

    lcd[0] = ((int)dataTH[7])%100/10+48;
    lcd[1] = ((int)dataTH[7])%10 + 48;
    lcd[2] =  '\0';
    PutStr(3,7, lcd);
}


void timer1(){
    updateLCD();
    updateTH();
    alarm();
}

void main(){
   
    init_hc_sr04();
    DS18B20Init();
    LcmInit();           //LCD12864³õʼ»¯                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
    LcmClearTXT();       //LCD12864ÇåÆÁ        
    init_eeprom();
    timer1_start(1000, timer1);
   
    PutStr(0,0, "PH     H     L  ");  
    PutStr(1,0, "ZD     H     L  ");  
    PutStr(2,0, "SW     H     L  ");  
    PutStr(3,0, "WD     H     L  ");  
   
    while(1){
        setKeyDeal();
        addKeyDeal();
        subKeyDeal();
    }
}



void alarm(){//±¨¾¯
    if( (int)dataV[0] > dataTH[0] || (int)dataV[0] < dataTH[1] || \
            (int)dataV[2] > dataTH[2] || (int)dataV[2] < dataTH[3] ||  \
            (int)dataV[1] > dataTH[4] || (int)dataV[1] < dataTH[5] ||  \
            (int)dataV[3] > dataTH[6] || (int)dataV[3] < dataTH[7]   \
    ){
        //beep=0;
    }else{
        beep=1;
    }
}


char flagSet = 0;

void setDeal(){
    switch(flagSet){
        case 0: PutStr(3,6, " "); break;
        case 1: PutStr(0,3, "*"); break;
        case 2: PutStr(0,6, "*"); PutStr(0,3, " "); break;
        case 3: PutStr(1,3, "*"); PutStr(0,6, " "); break;
        case 4: PutStr(1,6, "*"); PutStr(1,3, " "); break;
        case 5: PutStr(2,3, "*"); PutStr(1,6, " "); break;
        case 6: PutStr(2,6, "*"); PutStr(2,3, " "); break;
        case 7: PutStr(3,3, "*"); PutStr(2,6, " "); break;
        case 8: PutStr(3,6, "*"); PutStr(3,3, " "); break;
    }
}

void setKeyDeal(){
    setKey = 1;
    if(setKey == 0){
        delay(1000);
        if(setKey == 0){
            flagSet++;
            if(flagSet > 8){ flagSet = 0; }
            setDeal();
            while(setKey == 0);
        }
    }
}

void addKeyDeal(){
    addKey = 1;
    if(addKey == 0 && flagSet > 0){
        delay(1000);
        if(addKey == 0){
            
            switch(flagSet){
                case 1: if(dataTH[0] < 141)        dataTH[0]+=10;  break;
                case 2: if(dataTH[1] < dataTH[0]) dataTH[1]+=10;  break;
                case 3: if(dataTH[2] < 99)        dataTH[2]++;  break;
                case 4: if(dataTH[3] < dataTH[2]) dataTH[3]++;  break;
                case 5: if(dataTH[4] < 10)        dataTH[4]++;  break;
                case 6: if(dataTH[5] < dataTH[4]) dataTH[5]++;  break;
                case 7: if(dataTH[6] < 99)        dataTH[6]++;  break;
                case 8: if(dataTH[7] < dataTH[6]) dataTH[7]++;  break;
            }
            updateTH();
            update_eeprom();
            while(addKey == 0);
        }
    }
}

void subKeyDeal(){
    subKey = 1;
    if(subKey == 0 && flagSet > 0){
        delay(1000);
        if(subKey == 0){
            
            switch(flagSet){
                case 1: if(dataTH[0] > dataTH[1]+10)        dataTH[0]-=10;  break;
                case 2: if(dataTH[1] > 10) dataTH[1]-=10;  break;
                case 3: if(dataTH[2] > dataTH[3])        dataTH[2]--;  break;
                case 4: if(dataTH[3] > 0) dataTH[3]--;  break;
                case 5: if(dataTH[4] > dataTH[5])        dataTH[4]--;  break;
                case 6: if(dataTH[5] > 0) dataTH[5]--;  break;
                case 7: if(dataTH[6] > dataTH[7])        dataTH[6]--;  break;
                case 8: if(dataTH[7] > 0) dataTH[7]--;  break;
            }
            updateTH();
            update_eeprom();
            while(subKey == 0);
        }
    }
}
超声波函数
#include "HC_SR04.h"

unsigned char FLAG_OVERFLOW = 0;   //³¬Éù²¨Ê±¼ä¹ý³¤Òç³ö±êÖ¾

//10us
void delay10us(unsigned int i)
{
    while(i--);
}

void init_hc_sr04()
{
    TRIG = 0;
   
    TMOD &= 0xf0;
    TMOD |= 0x01;
    TH0 = 0x3c;
    TL0 = 0xb0;
    TF0 = 0;
    ET0 = 1;
    PT0 = 1;
    EA = 1;
}

void timer0() interrupt 1
{
    FLAG_OVERFLOW=1;
}

int get_hc_sr04_distance(void){
        unsigned int distance;
        
    TH0 = 0x3c;
    TL0 = 0xb0;
        TR0 = 0;
            
        FLAG_OVERFLOW = 0;     
        TRIG = 1;   
        delay10us(2);
        TRIG = 0;
        TR0 = 1;
   
        while(!ECHO && FLAG_OVERFLOW == 0);
    TH0 = 0x3c;
    TL0 = 0xb0;
        TR0 = 1;  
   
        while(ECHO && FLAG_OVERFLOW == 0);  
        TR0 = 0;  

    distance = TH0 << 8 | TL0;  

    distance = (distance-15536)/58;

    if(FLAG_OVERFLOW == 1){
       FLAG_OVERFLOW = 0;
             distance = 999;
    }
        
        return (distance);
}








分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:332214 发表于 2021-4-14 10:03 | 只看该作者
delay10us(2);
TRIG = 0;
TR0 = 1; //这个定时器0 没必要打开
while(!ECHO && FLAG_OVERFLOW == 0);  //&& FLAG_OVERFLOW == 0 这个标志位也没必要
这样改试试,想更精确点把ECHO脚接外部中断来开启定时器时间计数。
回复

使用道具 举报

板凳
ID:332214 发表于 2021-4-14 10:09 | 只看该作者
每个人的编程习惯不同,提个小意见,个人觉得,参数设置可以放在定时器里,数据更新放在主函数里,这样参数设置的时候并不需要考虑数据更新,但是如果反过来,会出现一种情况,就是参数在设置时,进入到定时器里进行数据更新。
回复

使用道具 举报

地板
ID:652483 发表于 2021-4-14 10:16 | 只看该作者
不行啊,为什么一按按键显示屏就灭,显示屏是串行方式,
超声波数值是更新了,但是要显示屏灭了之后才更新
void updateLCD(){
    dataV[0] = get_0832_AD_data(0); //PH
    dataV[1] = get_hc_sr04_distance();  //SW---------是不是这里有什么问题
    dataV[2] = get_0832_AD_data(1);  //ZD
    dataV[3] = Get18B20Temp();  //WD
回复

使用道具 举报

5#
ID:332214 发表于 2021-4-14 10:27 | 只看该作者
最好办法是,key按钮里面不做显示屏数据更新,只做参数设置,显示屏更新接口应该只放在一个函数里完成。这就是我上面提的小意见。你那边好好考虑一下,中断函数经量少占用执行周期。比较你这边的功能上,对时间的要求并不严格。
回复

使用道具 举报

6#
ID:390416 发表于 2021-4-14 10:38 | 只看该作者
那就用一个持续增加的变量 代替超声波,看看能不能正常变化显示
回复

使用道具 举报

7#
ID:652483 发表于 2021-4-14 10:43 | 只看该作者
啊哈哈123 发表于 2021-4-14 10:27
最好办法是,key按钮里面不做显示屏数据更新,只做参数设置,显示屏更新接口应该只放在一个函数里完成。这 ...

key不参与更新,主要是超声波的问题,其他显示正常,加入超声波就有问题了
回复

使用道具 举报

8#
ID:332214 发表于 2021-4-14 10:51 | 只看该作者
你这边问题主函数在调用  PutStr();这个屏幕更新函数,定时器1也在调用。为啥你那边把超声波获取函数注释就正常,那是因为你那边用定时器0来等待超声波回传信息的计时,所以在单片机指令执行周期上,就会显的占用周期,屏幕会黑屏。你可以把,主函数调用程序里,所有用到  PutStr();这个函数注释,超声波正常执行。你在看看你按 按钮是不是黑屏。
回复

使用道具 举报

9#
ID:652483 发表于 2021-4-14 11:14 | 只看该作者
啊哈哈123 发表于 2021-4-14 10:51
你这边问题主函数在调用  PutStr();这个屏幕更新函数,定时器1也在调用。为啥你那边把超声波获取函数注释就 ...

我改了一下就是先显示前两行再测量超声波,然后前两行才显示一下就被超声波给中断了
回复

使用道具 举报

10#
ID:652483 发表于 2021-4-14 11:16 | 只看该作者
啊哈哈123 发表于 2021-4-14 10:51
你这边问题主函数在调用  PutStr();这个屏幕更新函数,定时器1也在调用。为啥你那边把超声波获取函数注释就 ...

那超声波不用定时器可以吗,没用过超声波
回复

使用道具 举报

11#
ID:332214 发表于 2021-4-14 11:27 | 只看该作者
这看你对超声波的精确要求了,不用定时器也行,但是在超声波测距的时候等待时间计算的时候,最好不要有中断打断计时时间。不然测距是很不准的。
你这边现有的程序,就是把逻辑改改,还可以用的。如果对超声波测距 距离稍微精确点,最好多读几遍,求平均。
回复

使用道具 举报

12#
ID:652483 发表于 2021-4-14 11:29 | 只看该作者
人人学会单片机 发表于 2021-4-14 10:38
那就用一个持续增加的变量 代替超声波,看看能不能正常变化显示

可以,可就是超声波的测量方法跟to冲突了
回复

使用道具 举报

13#
ID:652483 发表于 2021-4-14 11:49 | 只看该作者
啊哈哈123 发表于 2021-4-14 11:27
这看你对超声波的精确要求了,不用定时器也行,但是在超声波测距的时候等待时间计算的时候,最好不要有中断 ...

int get_hc_sr04_distance(void){
                unsigned int distance;
               
    TH0 = 0x3c;
    TL0 = 0xb0;
                TR0 = 0;
                       
                //FLAG_OVERFLOW = 0;     
                Trig = 1;   
                delay10us(2);
                Trig = 0;
                TR0 = 1;
   
                while(!Echo);
    TH0 = 0x3c;
    TL0 = 0xb0;
                TR0 = 1;  
   
                while(Echo);  
                TR0 = 0;  

    distance = TH0 << 8 | TL0;  

    distance = (distance-15536)/58;

                return (distance);
}
这就是测量的函数,具体要怎么改呢
回复

使用道具 举报

14#
ID:332214 发表于 2021-4-14 13:27 | 只看该作者
超声波原理,就是发射极发送脉冲信号一段时间,接收极接收信号,当接收到信号的时候,数据脚是高电平,计录高电平的时间,然后根据声在空气传播速度,计算出距离。这个就是基本思想(声在空气传播速度 受温湿度影响)。你这边改不用定时器计时,就把定时器的记录时间改成自己写的时间记录。我觉得你现在没必要改成不用定时器,你现在的问题,就是确定好中断与刷屏时间的关系,前面已经建议你这边把刷屏接口放在同一个函数,放在同一个顺序逻辑上。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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