黄工无刷电机学习
直播中

笔画张

13年用户 1058经验值
私信 关注
[问答]

如何将温度传感器中的数值在LCD显示出来?

如何将温度传感器中的数值在LCD显示出来?

回帖(1)

唐红菊

2021-10-20 09:35:43
环境
软件
uVision V4.02
ISIS Professional 7.8
芯片
AT89C51
DS18B20
L298
实现效果
将温度传感器中的数值在LCD显示出来并且在不同温度时控制电机顺时针或逆时针旋转



相关代码及资源
代码位置:https://github.com/duganlx/DSP
1-Wire总线温度传感器DS18B20应用测试
1602字符液晶显示
正反转可控的步进电机
操作小记
DS18B20相关函数
#include //register
#include //_nop_() _crol_()


#define INT8U unsigned char
#define INT16U unsigned int
#define delay4us();        {_nop_();_nop_();_nop_();_nop_();}


extern void delay_ms(INT16U x);
***it DQ=P3^3;


INT8U Temp_Value[]={0x00,0x00};        //温度数据的低8位与高8位


/*
void delay_ms(INT16U x)
{
        INT8U i;
        while(x--)
        {
                for(i=0;i<120;i++);
        }
}
*/


void delayx(INT16U x)
{
        while(x--);
}


/***********AT89C51的主频一定要设为11.0592MHz*****/
INT8U Init_DS18B20()//初始化和检测DS18B20
{
        INT8U DQ_status;
        DQ=1; delayx(8);//delay77us
        DQ=0; delayx(90);//>delay480us
        DQ=1; delayx(5);//>delay15us
        DQ_status=DQ; delayx(90);
        return DQ_status;
}


INT8U Readonebyte()//读取DS18B20中的1个字节的数据
{
        INT8U i,datatemp=0x00;
        for(i=0x01;i!=0x00;i<<=1)//100000000
        {
                DQ=0;_nop_();  
                DQ=1;_nop_();
                if(DQ) datatemp=datatemp|i;
                delayx(8);
        }
        return datatemp;
}


void Writeonebyte(INT8U dat)//dat>>1 00001010 1CY ACC
{
        INT8U i;
        for(i=0;i<8;i++)
        {
                DQ=1;_nop_();
                DQ=0;_nop_();
                dat=dat>>1;  //PSW
                DQ=CY;
                delayx(8);
        }
}


INT8U Read_temperature()
{
        if(Init_DS18B20()==1) return 0;
        else
        {
                Writeonebyte(0xCC);//跳检序列号
                Writeonebyte(0x44);//启动转换
                Init_DS18B20();
                Writeonebyte(0xCC);//跳检序列号 因为只有一个DS18B20
                Writeonebyte(0xBE);//读温度寄存器里的第0,1字节
                Temp_Value[0]=Readonebyte();
                Temp_Value[1]=Readonebyte();
                return 1;
        }
}


LCD1602相关函数
#include
#include


#define INT8U unsigned char
#define INT16U unsigned int


***it RS=P2^0;
***it RW=P2^1;
***it EN=P2^2;


void delay_ms(INT16U x)
{
        INT8U i;
        while(x--)
        {
                for(i=0;i<120;i++);
        }
}


void Busy_Wait()
{
        INT8U LCD_Status;
        do
        {
                P0=0xFF;
                EN=0;RS=0;RW=1;
                EN=1; LCD_Status=P0;
                EN=0;
        }
        while(LCD_Status&0x80);//1000 0000
}


void Write_LCD_Command(INT8U cmd)
{
        Busy_Wait();
        EN=0;RS=0;RW=0;
        P0=cmd;
        EN=1;_nop_();EN=0;
}


void Write_LCD_Data(INT8U data1)
{
        Busy_Wait();
        EN=0;RS=1;RW=0;
        P0=data1;
        EN=1;_nop_();EN=0;
}


void LCD_String(INT8U r,INT8U c,INT8U *str)
{
        INT8U i=0;
        INT8U code DDRAM[]={0x80,0xC0};
        Write_LCD_Command(DDRAM[r]|c);
        for(i=0;i<16&&str;i++)
        {
                Write_LCD_Data(str);
        }
        for(;i<16;i++)
                Write_LCD_Data(' ');
}


void LCD_Initialize()
{
        Write_LCD_Command(0x38);delay_ms(1);//置功能位,8位,双行,每一个字符占5*7        0011 1000
        Write_LCD_Command(0x01);delay_ms(1);//清屏
        Write_LCD_Command(0x06);delay_ms(1);//字符进入模式,屏幕不动,字符后移
        Write_LCD_Command(0x0C);delay_ms(1);//开显示,关光标
}


主函数
为了减轻DS18B20的读数据压力,我们并不是实时进行数据采集,而是在一个时段内去采集一次,这个就是用定时器来做


#include
#include
#include
#include
#include


#define INT8U unsigned char
#define INT16U unsigned int


extern void delay_ms(INT16U x);
extern void LCD_Initialize();
extern void LCD_String(INT8U r,INT8U c,INT8U *str);
extern INT8U Temp_Value[];
extern void delayx(INT16U x);
extern INT8U Read_temperature();


***it MA=P1^0;//直流电机A端
***it MB=P1^1;//直流电机B端
***it PWM=P1^2;//pulse width modification 脉冲宽度调制 功能调速


static int count = 0;
float tempv; //温度值
INT8U buff[17]; //缓冲区


void T0_interrupt() interrupt 1 //INT0 0, T0 1, INT1 2, T1 3, Serial T 4
{
        count++;
        TL0 = ((INT16U)(65536-(INT16U)(11.0592/12*500)))%256; //t0 low delay->500us
        TH0 = ((INT16U)(65536-(INT16U)(11.0592/12*500)))%256; //t0 high
       
        if(count==10)                //增加延时 -> 50ms
        {
                count=0;
               
                if(Read_temperature()==1) //顺序程序设计会把执行语句作为延时
                {
                        count=0;
                        tempv=(((int)Temp_Value[1]<<8)|((int)Temp_Value[0]))*0.0625;
                        sprintf(buff,"temp:  %5.1fxDFx43",tempv);  
                        LCD_String(1,0,buff);
                        if(tempv>=75)
                                tempv=75;//正转75度是全速了  temp speed
                        if(tempv<=0)
                                tempv=0;//反转0度是全速了
                        if(tempv>=45)
                        {   
                                MA=1;
                                MB=0;
                                if(tempv==45)
                                        PWM=0;
                                else if(tempv==75)
                                        PWM=1;
                                else
                                {   
                                        PWM=1;delay_ms(tempv-45); //给力
                                        PWM=0;delay_ms(75-tempv);//不给力
                                }
                        }
                        else if(tempv<=10)
                        {   
                                MA=0;
                                MB=1;
                                if(tempv==10)
                                        PWM=0;
                                else if(tempv==0)  
                                        PWM=1;
                                else
                                {   
                                        PWM=1;delay_ms(10-tempv); //给力
                                        PWM=0;delay_ms(tempv-0);//不给力
                                }


                        }
                        else
                        {   
                                MA=0;
                                MB=0;
                        }
                }
        }
}


void main()
{
        LCD_Initialize();       
        LCD_String(0,0,"  recent temp");
        LCD_String(1,0,"  Waiting.......");
        Read_temperature();
        delay_ms(1500);
        TMOD=0x01; //定时器16位 65535
        EA = 1; //总开关
        ET0 = 1; //分开关
        TR0 = 1; //定时器开关
       
        while(1);//避免跑飞
}
举报

更多回帖

×
20
完善资料,
赚取积分