精华内容
下载资源
问答
  • 采用汇编程序利用温度传感器完成温度的采集和显示 包含LCD显示 温度模块以及相关的程序思路 适用于单片机课程设计
  • LCD显示温度序列码

    2018-04-17 08:49:42
    使用keil C语言环境、普中开发板设计的读取LCD1602的序列码,分别可以显示温度与序列码
  • MSP430F5529 温度传感器 DS18B20 LCD显示温度数值 绘制温度曲线 实验 代码 程序 一.实验要求 采用实验开发板控制温度传感器,将温度曲线及数值变化实时显示在LCD屏上。 二.系统组成 实验器材: 1.PC 一台 2.MSP430F...

    MSP430F5529 温度传感器 DS18B20 LCD显示温度数值 绘制温度曲线 实验 代码 程序

    一.实验要求
    采用实验开发板控制温度传感器,将温度曲线及数值变化实时显示在LCD屏上。
    二.系统组成
    实验器材:
    1.PC 一台
    2.MSP430F5529 一个
    3.USB数据线 一条
    4.DS18B20温度传感器 一个
    5.连接线 3条
    开发平台:
    CCS v6.1.1
    接线和配置:
    1.MSP430F5529通过左下角USB接入PC,并将开发板PowerSel拨到eZ-FET,使用CCS对开发板进行调试。
    2.将开发板上VCC接入DS18B20的VDD,GND接DS18B20的GND,P3.7接DS18B20的DQ。

    三.软件设计
    软件功能:通过DS18B20温度传感器、LCD显示屏,实现实时变化的温度显示和温度曲线。
    程序框图:

    软件总体设计方案:通过MSP430F5529获取DS18B20温度传感器上的数据,在LCD屏幕上显示温度值和绘制温度曲线。

    温度数值显示:将读取到的温度分别取十位、个位、小数点后一位。并与符号“C”、小数点“.”组合成温度数值显示,例如“27.0C”。

    温度曲线绘制:使用Dogs102x6_lineDraw画线函数,程序每进入一次循环,横坐标加1,纵坐标取温度的负值+58(该操作为了让曲线绘制在显示器中央,LCD默认为左上角为(0,0)取负数是为了屏幕从下到上为增,便于观察)。每次取新的温度后,绘制线段的起始点为上一次取的温度值,终点为下一次取的温度值,再通过横坐标递增,实现绘制连续的曲线,直到横坐标达到102,溢出屏幕时,清屏。

    四.实验步骤与结果
    实验步骤:
    1.按程序所写正确接线:MSP430F5529通过左下角USB接入PC,并将开发板PowerSel拨到eZ-FET,使用CCS对开发板进行调试。
    2.将开发板上VCC接入DS18B20的VDD,GND接DS18B20的GND,P3.7接DS18B20的DQ。
    3.通过CCS将编辑好的程序写入MSP430F5529。
    4.运行和调试。
    实验结果:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    五.参考代码
    1.main主程序关键代码及其注释。

    void main( void )
    {
    /* Stop WDT */
    WDTCTL = WDTPW + WDTHOLD; /* 关闭看门狗 */
    /* Use 32.768kHz XTAL as reference */
    LFXT_Start( XT1DRIVE_0 ); /* 利用LFXT1(32.768kHZ)作为时钟参考 */
    /* Set system clock to max (25MHz) */
    Init_FLL_Settle( 25000, 762 ); /* 利用FLL(锁频环)将系统时钟设为最大25MHZ */
    SFRIFG1 = 0; /* 清中断标志 */
    SFRIE1 |= OFIE; /* 使能晶振失效中断 */
    /* Globally enable interrupts */
    __enable_interrupt(); /* 使能全局中断 */
    /* Set up LCD */
    Dogs102x6_init(); /* 初始化LCD */
    Dogs102x6_backlightInit(); /* 背光初始化 */
    Dogs102x6_setBacklight( brightness ); /* 设置初始背光值 */
    Dogs102x6_setContrast( contrast ); /* 设置初始对比度值 */
    Dogs102x6_clearScreen(); /* 清屏 */
    /* 主循环 */
    while ( 1 )
    {
    readDS18B20andDisplay(); /* 读取温度值并显示 */
    }
    }
    

    2.lab7程序关键代码及其注释

    #define CPU_F ( (double) 25000000) /* 外部高频晶振8MHZ */
    /* #define CPU_F ((double)32768) //外部低频晶振32.768KHZ */
    #define delay_us( x ) __delay_cycles( (long) (CPU_F * (double) x / 1000000.0) )
    #define delay_ms( x ) __delay_cycles( (long) (CPU_F * (double) x / 1000.0) )
    unsigned int temp_value = 0; /* 温度 */
    unsigned int temp_2 = 27; /* temp_2初始温度 */
    unsigned int x1 = 0;
    unsigned int temp_value_1 = 0;
    unsigned int temp_3 = 0;
    /*********************************
    ** 引脚定义 使用引脚P3.7**
    *********************************/
    #define DQ_1 P3OUT |= BIT7
    #define DQ_0 P3OUT &= ~BIT7
    #define DQ_in P3DIR &= ~BIT7
    #define DQ_out P3DIR |= BIT7
    #define DQ_val (P3IN & BIT7)
    
    unsigned int DS18b20_Init(void) //初始化DS8B20
    {
    unsigned Check_val;
    DQ_out;
    DQ_0;
    delay_us(600);
    DQ_1;
    delay_us(60);
    DQ_in;
    _NOP();
    
    if ( DQ_val == 1)
    {
    Check_val = 0; /* 初始化失败 */
    }
    if ( DQ_val == 0)
    {
    Check_val = 1; /* 初始化成功 */
    }
    delay_us(10);
    DQ_out;
    DQ_1;
    delay_us(100);
    return (Check_val);
    }
    void DS18b20_write_byte(unsigned int dat)
    {
    unsigned int i;
    for (i = 0; i < 8; i++)
    {
    DQ_0;
    delay_us(2);
    if (dat & 0X01)
    DQ_1;
    else
    DQ_0;
    delay_us(60);
    dat >>= 1;
    ;
    DQ_1;
    delay_us(10);
    }
    }
    unsigned int DS18b20_read_byte(void)
    {
    unsigned i;
    unsigned int byte = 0;
    for (i = 0; i < 8; i++)
    {
    byte >>= 1;
    DQ_0;
    delay_us(2);
    DQ_1;
    delay_us(2);
    DQ_in;
    _NOP();
    if ( DQ_val)
    byte |= 0x80;
    delay_us(60);
    DQ_out;
    DQ_1;
    delay_us(10);
    }
    return (byte);
    }
    unsigned int get_one_temperature(void) /* 只读取了整数,没读取小数的部分 */
    {
    unsigned int Temp_l = 0, Temp_h = 0, Temp = 0;
    float f_temp;
    /* delay_ms( 1000 ); */
    DS18b20_Init();
    DS18b20_write_byte( Skip_ROM);
    DS18b20_write_byte( Read_Scratchpad);
    Temp_l = DS18b20_read_byte();
    Temp_h = DS18b20_read_byte();
    DS18b20_Init();
    DS18b20_write_byte( Skip_ROM);
    DS18b20_write_byte( Convert_Temperature);
    Temp_h <<= 8;
    Temp = Temp_h + Temp_l;
    f_temp = Temp * 0.0625; /* 18b20的分辨率是0.0625 */
    Temp = f_temp * 10 + 0.5; /* 乘以10表示小数点后面取一位,加0.5是四舍五入 */
    return (Temp); /* Temp是整型 */
    }
    void readDS18B20andDisplay(void)
    {
    
    //Dogs102x6_stringDraw(0, 0, " HUATU ", DOGS102x6_DRAW_NORMAL); /* 初始化显示界面 */
    unsigned char dis[10];
    unsigned char time_cyc = 0;
    while (1)
    {
    delay_ms(10);
    time_cyc = (time_cyc + 1) % 30;
    if (time_cyc == 1) /* 30 个10ms执行一次 */
    {
    temp_value = get_one_temperature(); /* 读取温度 */
    dis[0] = temp_value % 1000 / 100 + '0';
    dis[1] = temp_value % 100 / 10 + '0';
    dis[2] = '.';
    dis[3] = temp_value % 10 + '0';
    dis[4] = 'C';
    dis[5] = 0;
    Dogs102x6_stringDraw(0, 0, dis, DOGS102x6_DRAW_NORMAL);
    temp_3=58-temp_value;
    delay_us( 10 );
    Dogs102x6_lineDraw(x1,temp_2,x1+1,temp_3,0);
    temp_2=temp_3;
    x1 += 1; //横坐标+1
    if(x1>102) //LCD显示溢出时,清屏
    {
    Dogs102x6_clearScreen();
    x1=0;
    }
    }
    }
    }
    
    展开全文
  • 本系统以STC89C52单片机为控制核心,结合LCD1602液晶显示屏,DS18B20温度传感器,BT08-B蓝牙模块,设计并实现了温度测量系统。经过最终的调试,本系统已实现了题目的基本要求部分和发挥部分的所有功能。温度检测系统...
  • DS18B20+1602LCD显示温度控制
  • 实验5.LCD显示温度+串口接收温度 /******************************************************************************* * 实验名 :温度显示实验 * 使用的IO : * 实验效果 :1602显示温度 * 注意 : *******...

    实验5.LCD显示温度+串口接收温度

    /*******************************************************************************
    * 实验名			   :温度显示实验
    * 使用的IO	     : 
    * 实验效果       :1602显示温度
    *	注意					 :
    *******************************************************************************/
    
    #include<reg51.h>
    #include"lcd.h"
    #include"temp.h"
    
    uchar CNCHAR[6] = "摄氏度";
    void LcdDisplay(int);
    void UsartConfiguration();
    
    /*******************************************************************************
    * 函数名         : main
    * 函数功能		   : 主函数
    * 输入           : 无
    * 输出         	 : 无
    *******************************************************************************/
    
    void main()
    {
    	UsartConfiguration();
    	LcdInit();			 //初始化LCD1602
    	LcdWriteCom(0x88);	//写地址 80表示初始地址
    	LcdWriteData('C'); 
    	while(1)
    	{
    		LcdDisplay(Ds18b20ReadTemp());
    //		Delay1ms(1000);//1s钟刷一次
    	}
    }
    
    /*******************************************************************************
    * 函数名         : LcdDisplay()
    * 函数功能		   : LCD显示读取到的温度
    * 输入           : v
    * 输出         	 : 无
    *******************************************************************************/
    
    void LcdDisplay(int temp) 	 //lcd显示
    {
        
      	unsigned char i, datas[] = {0, 0, 0, 0, 0}; //定义数组
    	float tp;  
    	if(temp< 0)				//当温度值为负数
      	{
    	  	LcdWriteCom(0x80);		//写地址 80表示初始地址
    		SBUF='-';//将接收到的数据放入到发送寄存器
    		while(!TI);			         //等待发送数据完成
    		TI=0;						 //清除发送完成标志位
    	    LcdWriteData('-');  		//显示负
    		//因为读取的温度是实际温度的补码,所以减1,再取反求出原码
    		temp=temp-1;
    		temp=~temp;
    		tp=temp;
    		temp=tp*0.0625*100+0.5;	
    		//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
    		//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
    		//算由?.5,还是在小数点后面。
     
      	}
     	else
      	{			
    	  	LcdWriteCom(0x80);		//写地址 80表示初始地址
    	    LcdWriteData('+'); 		//显示正
    		SBUF='+';//将接收到的数据放入到发送寄存器
    		while(!TI);			         //等待发送数据完成
    		TI=0;						 //清除发送完成标志位
    		tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
    		//如果温度是正的那么,那么正数的原码就是补码它本身
    		temp=tp*0.0625*100+0.5;	
    		//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
    		//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
    		//算加上0.5,还是在小数点后面。
    	}
    	datas[0] = temp / 10000;
    	datas[1] = temp % 10000 / 1000;
    	datas[2] = temp % 1000 / 100;
    	datas[3] = temp % 100 / 10;
    	datas[4] = temp % 10;
    
    	LcdWriteCom(0x82);		  //写地址 80表示初始地址
    	LcdWriteData('0'+datas[0]); //百位 
    	SBUF = '0'+datas[0];//将接收到的数据放入到发送寄存器
    	while (!TI);			         //等待发送数据完成
    	TI = 0;
    	
    	LcdWriteCom(0x83);		 //写地址 80表示初始地址
    	LcdWriteData('0'+datas[1]); //十位
    	SBUF = '0'+datas[1];//将接收到的数据放入到发送寄存器
    	while (!TI);			         //等待发送数据完成
    	TI = 0;
    
    	LcdWriteCom(0x84);		//写地址 80表示初始地址
    	LcdWriteData('0'+datas[2]); //个位 
    	SBUF = '0'+datas[2];//将接收到的数据放入到发送寄存器
    	while (!TI);			         //等待发送数据完成
    	TI = 0;
    
    	LcdWriteCom(0x85);		//写地址 80表示初始地址
    	LcdWriteData('.'); 		//显示 ‘.’
    	SBUF = '.';//将接收到的数据放入到发送寄存器
    	while (!TI);			         //等待发送数据完成
    	TI = 0;
    
    	LcdWriteCom(0x86);		 //写地址 80表示初始地址
    	LcdWriteData('0'+datas[3]); //显示小数点  
    	SBUF = '0'+datas[3];//将接收到的数据放入到发送寄存器
    	while (!TI);			         //等待发送数据完成
    	TI = 0;
    
    	LcdWriteCom(0x87);		 //写地址 80表示初始地址
    	LcdWriteData('0'+datas[4]); //显示小数点 
    	SBUF = '0'+datas[4];//将接收到的数据放入到发送寄存器
    	while (!TI);			         //等待发送数据完成
    	TI = 0;
    	for(i=0; i<6; i++)
    	{
    	 	SBUF = CNCHAR[i];//将接收到的数据放入到发送寄存器
    		while (!TI);			         //等待发送数据完成
    		TI = 0;
    	}
    
    	 
    }
    /*******************************************************************************
    * 函 数 名         :UsartConfiguration()
    * 函数功能		   :设置串口
    * 输    入         : 无
    * 输    出         : 无
    *******************************************************************************/
    
    void UsartConfiguration()
    {
    	SCON=0X50;			//设置为工作方式1
    	TMOD=0X20;			//设置计数器工作方式2
    	PCON=0X80;			//波特率加倍
    	TH1=0XF3;				//计数器初始值设置,注意波特率是4800的
    	TL1=0XF3;
    //	ES=1;						//打开接收中断
    //	EA=1;						//打开总中断
    	TR1=1;					//打开计数器
    }
    
    
    #include"lcd.h"
    
    /*******************************************************************************
    * 函 数 名         : Lcd1602_Delay1ms
    * 函数功能		   : 延时函数,延时1ms
    * 输    入         : c
    * 输    出         : 无
    * 说    名         : 该函数是在12MHZ晶振下,12分频单片机的延时。
    *******************************************************************************/
    
    void Lcd1602_Delay1ms(uint c)   //误差 0us
    {
        uchar a,b;
    	for (; c>0; c--)
    	{
    		 for (b=199;b>0;b--)
    		 {
    		  	for(a=1;a>0;a--);
    		 }      
    	}
        	
    }
    
    /*******************************************************************************
    * 函 数 名         : LcdWriteCom
    * 函数功能		   : 向LCD写入一个字节的命令
    * 输    入         : com
    * 输    出         : 无
    *******************************************************************************/
    #ifndef 	LCD1602_4PINS	 //当没有定义这个LCD1602_4PINS时
    void LcdWriteCom(uchar com)	  //写入命令
    {
    	LCD1602_E = 0;     //使能
    	LCD1602_RS = 0;	   //选择发送命令
    	LCD1602_RW = 0;	   //选择写入
    	
    	LCD1602_DATAPINS = com;     //放入命令
    	Lcd1602_Delay1ms(1);		//等待数据稳定
    
    	LCD1602_E = 1;	          //写入时序
    	Lcd1602_Delay1ms(5);	  //保持时间
    	LCD1602_E = 0;
    }
    #else 
    void LcdWriteCom(uchar com)	  //写入命令
    {
    	LCD1602_E = 0;	 //使能清零
    	LCD1602_RS = 0;	 //选择写入命令
    	LCD1602_RW = 0;	 //选择写入
    
    	LCD1602_DATAPINS = com;	//由于4位的接线是接到P0口的高四位,所以传送高四位不用改
    	Lcd1602_Delay1ms(1);
    
    	LCD1602_E = 1;	 //写入时序
    	Lcd1602_Delay1ms(5);
    	LCD1602_E = 0;
    
    //	Lcd1602_Delay1ms(1);
    	LCD1602_DATAPINS = com << 4; //发送低四位
    	Lcd1602_Delay1ms(1);
    
    	LCD1602_E = 1;	 //写入时序
    	Lcd1602_Delay1ms(5);
    	LCD1602_E = 0;
    }
    #endif
    /*******************************************************************************
    * 函 数 名         : LcdWriteData
    * 函数功能		   : 向LCD写入一个字节的数据
    * 输    入         : dat
    * 输    出         : 无
    *******************************************************************************/		   
    #ifndef 	LCD1602_4PINS		   
    void LcdWriteData(uchar dat)			//写入数据
    {
    	LCD1602_E = 0;	//使能清零
    	LCD1602_RS = 1;	//选择输入数据
    	LCD1602_RW = 0;	//选择写入
    
    	LCD1602_DATAPINS = dat; //写入数据
    	Lcd1602_Delay1ms(1);
    
    	LCD1602_E = 1;   //写入时序
    	Lcd1602_Delay1ms(5);   //保持时间
    	LCD1602_E = 0;
    }
    #else
    void LcdWriteData(uchar dat)			//写入数据
    {
    	LCD1602_E = 0;	  //使能清零
    	LCD1602_RS = 1;	  //选择写入数据
    	LCD1602_RW = 0;	  //选择写入
    
    	LCD1602_DATAPINS = dat;	//由于4位的接线是接到P0口的高四位,所以传送高四位不用改
    	Lcd1602_Delay1ms(1);
    
    	LCD1602_E = 1;	  //写入时序
    	Lcd1602_Delay1ms(5);
    	LCD1602_E = 0;
    
    	LCD1602_DATAPINS = dat << 4; //写入低四位
    	Lcd1602_Delay1ms(1);
    
    	LCD1602_E = 1;	  //写入时序
    	Lcd1602_Delay1ms(5);
    	LCD1602_E = 0;
    }
    #endif
    /*******************************************************************************
    * 函 数 名       : LcdInit()
    * 函数功能		 : 初始化LCD屏
    * 输    入       : 无
    * 输    出       : 无
    *******************************************************************************/		   
    #ifndef		LCD1602_4PINS
    void LcdInit()						  //LCD初始化子程序
    {
     	LcdWriteCom(0x38);  //开显示
    	LcdWriteCom(0x0c);  //开显示不显示光标
    	LcdWriteCom(0x06);  //写一个指针加1
    	LcdWriteCom(0x01);  //清屏
    	LcdWriteCom(0x80);  //设置数据指针起点
    }
    #else
    void LcdInit()						  //LCD初始化子程序
    {
    	LcdWriteCom(0x32);	 //将8位总线转为4位总线
    	LcdWriteCom(0x28);	 //在四位线下的初始化
    	LcdWriteCom(0x0c);  //开显示不显示光标
    	LcdWriteCom(0x06);  //写一个指针加1
    	LcdWriteCom(0x01);  //清屏
    	LcdWriteCom(0x80);  //设置数据指针起点
    }
    #endif
    
    
    #include"temp.h"
    /*******************************************************************************
    * 函数名         : Delay1ms
    * 函数功能		   : 延时函数
    * 输入           : 无
    * 输出         	 : 无
    *******************************************************************************/
    
    void Delay1ms(unsigned int y)
    {
    	unsigned int x;
    	for(y;y>0;y--)
    		for(x=110;x>0;x--);
    }
    /*******************************************************************************
    * 函数名         : Ds18b20Init
    * 函数功能		   : 初始化
    * 输入           : 无
    * 输出         	 : 初始化成功返回1,失败返回0
    *******************************************************************************/
    
    unsigned char Ds18b20Init()
    {
    	unsigned int i;
    	DSPORT=0;			 //将总线拉低480us~960us
    	i=70;	
    	while(i--);//延时642us
    	DSPORT=1;			//然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
    	i=0;
    	while(DSPORT)	//等待DS18B20拉低总线
    	{
    		i++;
    		if(i>5000)//等待>5MS
    			return 0;//初始化失败	
    	}
    	return 1;//初始化成功
    }
    
    /*******************************************************************************
    * 函数名         : Ds18b20WriteByte
    * 函数功能		   : 向18B20写入一个字节
    * 输入           : com
    * 输出         	 : 无
    *******************************************************************************/
    
    void Ds18b20WriteByte(unsigned char dat)
    {
    	unsigned int i,j;
    	for(j=0;j<8;j++)
    	{
    		DSPORT=0;			//每写入一位数据之前先把总线拉低1us
    		i++;
    		DSPORT=dat&0x01; //然后写入一个数据,从最低位开始
    		i=6;
    		while(i--); //延时68us,持续时间最少60us
    		DSPORT=1;	//然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
    		dat>>=1;
    	}
    }
    /*******************************************************************************
    * 函数名         : Ds18b20ReadByte
    * 函数功能		   : 读取一个字节
    * 输入           : com
    * 输出         	 : 无
    *******************************************************************************/
    
    
    unsigned char Ds18b20ReadByte()
    {
    	unsigned char byte,bi;
    	unsigned int i,j;	
    	for(j=8;j>0;j--)
    	{
    		DSPORT=0;//先将总线拉低1us
    		i++;
    		DSPORT=1;//然后释放总线
    		i++;
    		i++;//延时6us等待数据稳定
    		bi=DSPORT;	 //读取数据,从最低位开始读取
    		/*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/
    		byte=(byte>>1)|(bi<<7);						  
    		i=4;		//读取完之后等待48us再接着读取下一个数
    		while(i--);
    	}				
    	return byte;
    }
    /*******************************************************************************
    * 函数名         : Ds18b20ChangTemp
    * 函数功能		   : 让18b20开始转换温度
    * 输入           : com
    * 输出         	 : 无
    *******************************************************************************/
    
    void  Ds18b20ChangTemp()
    {
    	Ds18b20Init();
    	Delay1ms(1);
    	Ds18b20WriteByte(0xcc);		//跳过ROM操作命令		 
    	Ds18b20WriteByte(0x44);	    //温度转换命令
    //	Delay1ms(100);	//等待转换成功,而如果你是一直刷着的话,就不用这个延时了
       
    }
    /*******************************************************************************
    * 函数名         : Ds18b20ReadTempCom
    * 函数功能		   : 发送读取温度命令
    * 输入           : com
    * 输出         	 : 无
    *******************************************************************************/
    
    void  Ds18b20ReadTempCom()
    {	
    
    	Ds18b20Init();
    	Delay1ms(1);
    	Ds18b20WriteByte(0xcc);	 //跳过ROM操作命令
    	Ds18b20WriteByte(0xbe);	 //发送读取温度命令
    }
    /*******************************************************************************
    * 函数名         : Ds18b20ReadTemp
    * 函数功能		   : 读取温度
    * 输入           : com
    * 输出         	 : 无
    *******************************************************************************/
    
    int Ds18b20ReadTemp()
    {
    	int temp=0;
    	unsigned char tmh,tml;
    	Ds18b20ChangTemp();			 	//先写入转换命令
    	Ds18b20ReadTempCom();			//然后等待转换完后发送读取温度命令
    	tml=Ds18b20ReadByte();		//读取温度值共16位,先读低字节
    	tmh=Ds18b20ReadByte();		//再读高字节
    	temp=tmh;
    	temp<<=8;
    	temp|=tml;
    	return temp;
    }
    
    
    
    
    展开全文
  • AT89S51和DS18B20数字温度采集器件,1602LCD显示温度
  • 51单片机LCD显示温度与串口接受温度

    千次阅读 2019-02-12 21:41:30
    void LcdDisplay(int temp) //lcd显示 { unsigned char i, datas[] = {0, 0, 0, 0, 0}; //定义数组 float tp; if(temp) //当温度值为负数 { LcdWriteCom(0x80); //写地址 80表示初始地址 SBUF='...

    外接晶振为12MHz时,51单片机相关周期的具体值为:

    振荡周期=1/12us;
    状态周期=1/6us;
    机器周期=1us;
    指令周期=1~4us;

    51单片机定时/计数器的工作由两个特殊功能寄存器控制。TMOD用于设置其工作方式;TCON用于控制其启动和中断申请。
    1、工作方式寄存器TMOD
    工作方式寄存器TMOD用于设置定时/计数器的工作方式,低四位用于T0,高四位用于T1。其格式如下:
    在这里插入图片描述
    GATE是门控位, GATE=0时,用于控制定时器的启动是否受外部中断源信号的影响。只要用软件使TCON中的TR0或TR1为1,就可以启动定时/计数器工作;GATA=1时,要用软件使TR0或TR1为1,同时外部中断引脚INT0/1也为高电平时,才能启动定时/计数器工作。即此时定时器的启动条件,加上了INT0/1引脚为高电平这一条件。
    C/T :定时/计数模式选择位。C/T =0为定时模式;C/T =1为计数模式。
    M1M0:工作方式设置位。定时/计数器有四种工作方式。
    在这里插入图片描述
    控制寄存器TCON
    TCON的高4位用于控
    制定时/计数器的启动和中断申请。其格式如下:
    在这里插入图片描述
    TF1(TCON.7):T1溢出中断请求标志位。T1计数溢出时由硬件自动置TF1为1。CPU响应中断后TF1由硬件自动清0。T1工作时,CPU可随时查询TF1的状态。所以,TF1可用作查询测试的标志。TF1也可以用软件置1或清0,同硬件置1或清0的效果一样。
    TR1(TCON.6):T1运行控制位。TR1置1时,T1开始工作;TR1置0时,T1停止工作。TR1由软件置1或清0。所以,用软件可控制定时/计数器的启动与停止。
    TF0(TCON.5):T0溢出中断请求标志位,其功能与TF1类同。
    TR0(TCON.4):T0运行控制位,其功能与TR1类同。

    定时/计数器的工作方式

    1、方式1
    方式1的计数位数是16位,由TL0作为低8位,TH0
    作为高8位,组成了16位加1计数器 。计数个数与计数初值的关系为:X=2(16次方)-N

    2、方式2
    为自动重装初值的8位计数方式。 计数个数与计数初值的关系为:X=28-N
    工作方式2特别适合于用作较精确的脉冲信号发生器。所以串口通信处用此方式。

    计数器初值的计算
    机器周期也就是CPU完成一个基本操作所需要的时间。
    机器周期=1/单片机的时钟频率。
    51单片机内部时钟频率是外部时钟的12分频。也就是说当外部晶振的频率输入到单片机里面的时候要进行12分频。比如说你用的是12MHZ的晶振,那么单片机内部的时钟频率就是12/12MHZ,当你使用12MHZ的外部晶振的时候。机器周期=1/1M=1us。
    而我们定时1ms的初值是多少呢,1ms/1us=1000。也就是要计数1000个数,初值=65535-1000+1(因为实际上计数器计数到66636才溢出)=64536=FC18H

    串口通信
    比特率是每秒钟传输二进制代码的位数,单位是:位/秒(bps)。如每秒钟传送240个字符,而每个字符格式包含10位(1个起始位、1个停止位、8个数据位),这时的比特率为:
    10位×240个/秒 = 2400 bps

    SCON 是一个特殊功能寄存器,用以设定串行口的工作方式、接收/发送控制以及设置状态标志:在这里插入图片描述
    SM0和SM1为工作方式选择位,可选择四种工作方式:
    在这里插入图片描述
    SM2,多机通信控制位,主要用于方式2和方式3。当接收机的SM2=1时可以利用收到的RB8来控制是否激活RI(RB8=0时不激活RI,收到的信息丢弃;RB8=1时收到的数据进入SBUF,并激活RI,进而在中断服务中将数据从SBUF读走)。当SM2=0时,不论收到的RB8为0和1,均可以使收到的数据进入SBUF,并激活RI(即此时RB8不具有控制RI激活的功能)。通过控制SM2,可以实现多机通信。
    在方式0时,SM2必须是0。在方式1时,如果SM2=1,则只有接收到有效停止位时,RI才置1。
    REN,允许串行接收位。由软件置REN=1,则启动串行口接收数据;若软件置REN=0,则禁止接收

    TI,发送中断标志位。在方式0时,当串行发送第8位数据结束时,或在其它方式,串行发送停止位的开始时,由内部硬件使TI置1,向CPU发中断申请。在中断服务程序中,必须用软件将其清0,取消此中断申请。

    RI,接收中断标志位。在方式0时,当串行接收第8位数据结束时,或在其它方式,串行接收停止位的中间时,由内部硬件使RI置1,向CPU发中断申请。也必须在中断服务程序中,用软件将其清0,取消此中断申请。

    PCON中只有一位SMOD与串行口工作有关 :SMOD(PCON.7) 波特率倍增位。在串行口方式1、方式2、方式3时,波特率与SMOD有关,当SMOD=1时,波特率提高一倍。复位时,SMOD=0。

    80C51串行口的工作方式
    这里只介绍方式1:
    方式1是10位数据的异步通信口。TXD为数据发送引脚,RXD为数据接收引脚,传送一帧数据的格式如图所示。其中1位起始位,8位数据位,1位停止位。
    在这里插入图片描述
    在这里插入图片描述
    用软件置REN为1时,接收器以所选择波特率的16倍速率采样RXD引脚电平,检测到RXD引脚输入电平发生负跳变时,则说明起始位有效,将其移入输入移位寄存器,并开始接收这一帧信息的其余位。接收过程中,数据从输入移位寄存器右边移入,起始位移至输入移位寄存器最左边时,控制电路进行最后一次移位。当RI=0,且SM2=0(或接收到的停止位为1)时,将接收到的9位数据的前8位数据装入接收SBUF,第9位(停止位)进入RB8,并置RI=1,向CPU请求中断。

    方式1的波特率 =(2SMOD/32)·(T1溢出率)
    T1 溢出率 = fosc /{12×[256 -(TH1)]}

    在这里插入图片描述

    DS18B20温度传感器原理
    DS18B20温度转换规则
    DS18B20的核心功能是它可以直接读出数字的温度数值。温度传感器的精度为用户可编程的9,10,11或12位,分别以0.5℃,0.25℃,0.125℃和0.0625℃增量递增。在上电状态下默认的精度为12位。

    在这里插入图片描述
    这是12位转化后得到的12位数据,存储在DS18B20的两个8位的RAM中,高字节的前5位是符号位,如果测得的温度大于0,这5位为‘0’,只要将测到的数值乘以0.0625即可得到实际温度;如果温度小于0,这5位为‘1’,测到的数值需要先减1再取反再乘以0.0625即可得到实际温度。

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述
    (1).数据线拉到低电平“0”。
    (2).延时480微妙(该时间的时间范围可以从480到960微妙)。
    (3).数据线拉到高电平“1”。
    (4).延时等待80微妙。如果初始化成功则在15到60微妙时间内产生一个由DS18B20所返回的低电平“0”.根据该状态可以来确定它的存在,但是应注意不能无限的进行等待,不然会使程序进入死循环,所以要进行超时判断。
    (5).若CPU读到了数据线上的低电平“0”后,还要做延时,其延时的时间从发出的高电平算起(第(3)步的时间算起)最少要480微妙。

    读时序
    在这里插入图片描述
    (1).将数据线拉低“0”。
    (2).延时1微妙。
    (3).将数据线拉高“1”,释放总线准备读数据。
    (4).延时10微妙。
    (5).读数据线的状态得到1个状态位,并进行数据处理。
    (6).延时45微妙。
    (7).重复1~7步骤,直到读完一个字节。

    写时序
    在这里插入图片描述
    (1).数据线先置低电平“0”
    (2).延时15微妙。
    (3).按从低位到高位的顺序发送数据(一次只发送一位)。
    (4).延时60微妙。
    (5).将数据线拉到高电平。
    (6).重复1~5步骤,直到发送完整的字节。
    (7).最后将数据线拉高。

    #include<reg51.h>	
    #define LCD1602_DATAPINS P0
    
    typedef	 unsigned int	  uint;
    typedef unsigned char	 uchar;
    
    sbit LCD1602_E=P2^7;
    sbit LCD1602_RW=P2^5;
    sbit LCD1602_RS=P2^6;
    sbit DSPORT=P3^7;
    
    uchar CNCHAR[6] = "摄氏度";
    
    void LcdInit();
    void LcdWriteData(uchar dat);
    void LcdWriteCom(uchar com);
    void LcdDisplay(int);
    void UsartConfiguration();
    uchar init();
    void writebyte(uchar datas);
    void change_temper();
    void read_tempercom();
    uint read_temper();
    uchar readbyte();
    void DelayMs(unsigned int x);
    
    void main(void)	
    {
    	UsartConfiguration();
    	LcdInit();			 //初始化LCD1602
    	LcdWriteCom(0x88);	//写地址 80表示初始地址
    	LcdWriteData('C'); 
    	while(1)
    	{
    		LcdDisplay(read_temper());
    //		Delay1ms(1000);//1s钟刷一次
    	}				
    }
    
    void DelayMs(unsigned int x)   //0.14ms误差 0us
    {
     unsigned char i;
      while(x--)
     {
      for (i = 0; i<13; i++)
     {}
     }
    }
    
    void LcdDisplay(int temp) 	 //lcd显示
    {
        
      	unsigned char i, datas[] = {0, 0, 0, 0, 0}; //定义数组
    	float tp;  
    	if(temp< 0)				//当温度值为负数
      	{
    	  	LcdWriteCom(0x80);		//写地址 80表示初始地址
    		SBUF='-';//将接收到的数据放入到发送寄存器
    		while(!TI);			         //等待发送数据完成
    		TI=0;						 //清除发送完成标志位
    	    LcdWriteData('-');  		//显示负
    		//因为读取的温度是实际温度的补码,所以减1,再取反求出原码
    		temp=temp-1;
    		temp=~temp;
    		tp=temp;
    		temp=tp*0.0625*100+0.5;	
    		//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
    		//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
    		//算由?.5,还是在小数点后面。
     
      	}
     	else
      	{			
    	  	LcdWriteCom(0x80);		//写地址 80表示初始地址
    	    LcdWriteData('+'); 		//显示正
    		SBUF='+';//将接收到的数据放入到发送寄存器
    		while(!TI);			         //等待发送数据完成
    		TI=0;						 //清除发送完成标志位
    		tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
    		//如果温度是正的那么,那么正数的原码就是补码它本身
    		temp=tp*0.0625*100+0.5;	
    		//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
    		//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
    		//算加上0.5,还是在小数点后面。
    	}
    	datas[0] = temp / 10000;
    	datas[1] = temp % 10000 / 1000;
    	datas[2] = temp % 1000 / 100;
    	datas[3] = temp % 100 / 10;
    	datas[4] = temp % 10;
    
    	LcdWriteCom(0x82);		  //写地址 80表示初始地址
    	LcdWriteData('0'+datas[0]); //百位 
    	SBUF = '0'+datas[0];//将接收到的数据放入到发送寄存器
    	while (!TI);			         //等待发送数据完成
    	TI = 0;
    	
    	LcdWriteCom(0x83);		 //写地址 80表示初始地址
    	LcdWriteData('0'+datas[1]); //十位
    	SBUF = '0'+datas[1];//将接收到的数据放入到发送寄存器
    	while (!TI);			         //等待发送数据完成
    	TI = 0;
    
    	LcdWriteCom(0x84);		//写地址 80表示初始地址
    	LcdWriteData('0'+datas[2]); //个位 
    	SBUF = '0'+datas[2];//将接收到的数据放入到发送寄存器
    	while (!TI);			         //等待发送数据完成
    	TI = 0;
    
    	LcdWriteCom(0x85);		//写地址 80表示初始地址
    	LcdWriteData('.'); 		//显示 ‘.’
    	SBUF = '.';//将接收到的数据放入到发送寄存器
    	while (!TI);			         //等待发送数据完成
    	TI = 0;
    
    	LcdWriteCom(0x86);		 //写地址 80表示初始地址
    	LcdWriteData('0'+datas[3]); //显示小数点  
    	SBUF = '0'+datas[3];//将接收到的数据放入到发送寄存器
    	while (!TI);			         //等待发送数据完成
    	TI = 0;
    
    	LcdWriteCom(0x87);		 //写地址 80表示初始地址
    	LcdWriteData('0'+datas[4]); //显示小数点 
    	SBUF = '0'+datas[4];//将接收到的数据放入到发送寄存器
    	while (!TI);			         //等待发送数据完成
    	TI = 0;
    	for(i=0; i<6; i++)
    	{
    	 	SBUF = CNCHAR[i];//将接收到的数据放入到发送寄存器
    		while (!TI);			         //等待发送数据完成
    		TI = 0;
    	}
    
    	 
    }
    
    
    void UsartConfiguration()
    {
    	SCON=0X50;			//设置为工作方式1
    	TMOD=0X20;			//设置计数器工作方式2
    	PCON=0X80;			//波特率加倍
    	TH1=0XF3;				//计数器初始值设置,注意波特率是4800的
    	TL1=0XF3;
    //	ES=1;						//打开接收中断
    //	EA=1;						//打开总中断
    	TR1=1;					//打开计数器
    }
    
    
    /****************
    温度传感器部分
    ****************/
    uchar init()
    {
    	uchar i=0;
    	DSPORT=0;
    	i = 70;				   //将总线拉低480us~960us
    	while(i--);//延时642us
    	DSPORT=1;				 //然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
    	i=0;
    	while(DSPORT)		   //等待DS18B20拉低总线
    	{
    		 DelayMs(1);
    		 i++;		  
    		 if(i>5)
    		 {
    		 	return 0;			 //初始化失败
    		 }
    	}
    	return 1;
    }
    
    void writebyte(uchar datas)
    {
    	uchar i,j=1;
    	for(i=0;i<8;i++)
    	{
    		DSPORT=0;		   //每写入一位数据之前先把总线拉低1us
    		//j++;		  //此处延时1us,好像又影响不大
    		DSPORT=datas&0x01;
    		j=6;
    		while(j--); //延时68us,持续时间最少60us
    		DSPORT=1;		 //然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
    		datas>>=1;
    	}
    }
    
    uchar readbyte()
    {
    	uchar dat=0,temp;
    	uint i ,j;
    	for(i=0;i<8;i++)
    	{
    		DSPORT=0;	 //先将总线拉低1us
    		j++;
    		DSPORT=1;	//然后释放总线
    		j++;	  //此处延时有变化,等待6us
    		j++;
    		temp=DSPORT;	 //读取数据,从最低位开始读取
    		/*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/
    		dat=(dat>>1)|(temp<<7);
    		j = 4;		//读取完之后等待48us再接着读取下一个数
    		while(j--);;			 //好像没影响
    	}
    	return dat;		//不是temp
    }
    
    void change_temper()
    {
    	init();
    	DelayMs(1);			   //无影响
    	writebyte(0xcc);		  //跳过ROM操作命令	
    	writebyte(0x44);		   //温度转换命令
    }
    
    void read_tempercom()
    {
       	init();
    	//DelayMs(1);
    	writebyte(0xcc);
    	writebyte(0xbe);		 //发送读取温度命令
    }
    
    uint read_temper()
    {
    	uchar tml,tmh;
    	uint t=0;
    	change_temper();			//先写入转换命令
    	read_tempercom();			//然后等待转换完后发送读取温度命令
    	tml=readbyte();				//读取温度值共16位,先读低字节
    	tmh=readbyte();				//再读高字节
    	t=tmh;
    	t<<=8;			//移8位
    	t=tml|t;
    
    	return t;
    }
    /********************
     LCD液晶部分
    ********************/
    
    void LcdWriteCom(uchar com)	  //写入命令
    {
    	LCD1602_E = 0;     //使能
    	LCD1602_RS = 0;	   //选择发送命令
    	LCD1602_RW = 0;	   //选择写入
    	
    	LCD1602_DATAPINS = com;     //放入命令
    	DelayMs(1);		//等待数据稳定
    
    	LCD1602_E = 1;	          //写入时序
    	DelayMs(5);	  //保持时间
    	LCD1602_E = 0;
    }
    
    void LcdWriteData(uchar dat)			//写入数据
    {
    	LCD1602_E = 0;	//使能清零
    	LCD1602_RS = 1;	//选择输入数据
    	LCD1602_RW = 0;	//选择写入
    
    	LCD1602_DATAPINS = dat; //写入数据
    	DelayMs(1);
    
    	LCD1602_E = 1;   //写入时序
    	DelayMs(5);   //保持时间
    	LCD1602_E = 0;
    }
    
    void LcdInit()						  //LCD初始化子程序
    {
     	LcdWriteCom(0x38);  //开显示
    	LcdWriteCom(0x0c);  //开显示不显示光标
    	LcdWriteCom(0x06);  //写一个指针加1
    	LcdWriteCom(0x01);  //清屏
    	LcdWriteCom(0x80);  //设置数据指针起点
    }
    

    LCD显示部分可以参考我一篇文章
    51单片机DS1302时钟LCD1602显示

    以上是我在学习过程中的一点总结,用的是普中的51单片机·。

    展开全文
  • 实物LCD1602显示温度为0,其他信息正常显示,仿真一切正常,若将显示温度的函数单独提取成文件,则正常显示温度,不知道怎么改 PS只需看主函数,LCD1602.h和temp.h就行 ``` #include"key.h" #include"lcd1602.h...
  • 绘制坐标轴大致方法和思路如下: Dogs102x6_verticalLineDraw(10, 63, 13, DOGS102x6_DRAW_NORMAL); //画垂直温度坐标轴 Dogs102x6_pixelDraw(12,11, DOGS102x6_DRAW_NORMAL); Dogs102x6_pi

    上一篇笔记请见:https://charlieva.blog.csdn.net/article/details/111405181

    绘制坐标轴大致方法和思路如下:

    
            	Dogs102x6_verticalLineDraw(10, 63, 13, DOGS102x6_DRAW_NORMAL);          //画垂直温度坐标轴
            	Dogs102x6_pixelDraw(12,11, DOGS102x6_DRAW_NORMAL);
            	Dogs102x6_pixelDraw(11,12, DOGS102x6_DRAW_NORMAL);
            	Dogs102x6_pixelDraw(14,11, DOGS102x6_DRAW_NORMAL);
            	Dogs102x6_pixelDraw(15,12, DOGS102x6_DRAW_NORMAL);
            	Dogs102x6_horizontalLineDraw(15, 95, 63, DOGS102x6_DRAW_NORMAL);       //画水平时间坐标轴
            	Dogs102x6_pixelDraw(94,62, DOGS102x6_DRAW_NORMAL);
            	Dogs102x6_pixelDraw(93,61, DOGS102x6_DRAW_NORMAL);
            	Dogs102x6_pixelDraw(94,64, DOGS102x6_DRAW_NORMAL);
            	Dogs102x6_pixelDraw(93,65, DOGS102x6_DRAW_NORMAL);
    
            	Dogs102x6_stringDraw(1, 0, "31", DOGS102x6_DRAW_NORMAL);               //写垂直温度坐标值
            	Dogs102x6_stringDraw(2, 0, "30", DOGS102x6_DRAW_NORMAL);
            	Dogs102x6_stringDraw(3, 0, "29", DOGS102x6_DRAW_NORMAL);
            	Dogs102x6_stringDraw(4, 0, "28", DOGS102x6_DRAW_NORMAL);
            	Dogs102x6_stringDraw(5, 0, "27", DOGS102x6_DRAW_NORMAL);
            	Dogs102x6_stringDraw(6, 0, "26", DOGS102x6_DRAW_NORMAL);
            	Dogs102x6_stringDraw(7, 0, "25", DOGS102x6_DRAW_NORMAL);
    
    
    展开全文
  • LCD160128显示温度与时间
  • Arduino LCD 温度显示

    千次阅读 2016-06-24 11:10:32
    实验内容:用LCD显示屏显示当前温度,一秒钟刷新两次 实验器材:跳线、LCD显示屏、温度传感器、可调电阻、面包板、数据线、220欧姆电阻 电路图: 代码:  // include the library code:  #include ...
  • LCD1602显示实时温度(DS18B20)】,是用C写的代码。
  • LCD160128中文显示温度与时间
  • 一个在51单片机上运行的程序,作用是在lcd1602上实时显示当前温度---------------------------------------------------------------------------------
  • LCD1602显示温度+串口接收温度

    千次阅读 2020-01-07 20:57:58
    LCD.H #ifndef __TEMP_H_ #define __TEMP_H_ #include<reg51.h> sbit DSPORT=P3^7; void Delay1ms(unsigned int ); unsigned char Ds18b20Init(); void Ds18b20WriteByte(unsigned char com); unsigned cha...
  • LCD1602温度显示程序设计流程

    万次阅读 2018-11-21 22:31:45
    博主福利:100G+电子设计学习资源包!... 在该系统之中,先对LCD进行初始化设置,将AD转换后的数值向LCD发送,LCD读取数据,然后写入函数,最后将采集到的温度显示LCD1602的屏幕上。其流程图如图所示。
  • #include #include "./delay/delay.h" #include "./lcd/lcd.h" #include "intrins.h" #include "stdio.h" sbit DS = P3^2; sbit led = P3^3; bit ack; void ds18b20_init() { DS = 0; delay_us(200); dela
  • 基于51单片机的温度曲线显示,欢迎大家下载,实测可用
  • 利用实验箱实现:读取温度或光照传感器的值,并送 LCD 显示, 精度为 2 位小数,如:28.13 度。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,060
精华内容 424
关键字:

lcd显示温度