蓝桥杯单片机快速开发笔记——特训6 温度采样与显示

一、原理分析

        DS18B20温度传感器:http://t.csdnimg.cn/K49D4

        HC573/HC138:http://t.csdnimg.cn/W0a0U

        数码管:http://t.csdnimg.cn/kfm9Y

        独立键盘:http://t.csdnimg.cn/YPInc

二、示例题目

在CT107D单片机综合训练平台上,新建工程并以I/O模式编写代码,实现以下功能:

  1. 将DS18B20的底层驱动代码文件正确移植到工程中。
  2. 配置J5为BTN模式,将S4设置为独立按键,用于切换温度的显示格式。
  3. 系统上电后,单片机循环启动DS18B20温度转换,并读取温度转换结果,进行适当的换算后,在数码管的右侧显示。
  4. 系统上电后,默认显示格式为保留2位小数;按下S4按键后松开,显示格式切换为保留1位小数;再次按下S4按键后松开,显示格式切换为只保留整数部分;再次按下S4按键后松开,显示格式重新恢复为保留2位小数;按键控制如此循环。

三、特别提醒

        移植onewire.c时,要把它的延时函数改为

void Delay_OneWire(unsigned int t)  
{
	t = t * 10;
	while(t--);
}

四、示例代码

#include "stc15.h"
#include "onewire.h"

#define TKEY 200
#define TSMG 500

unsigned char mode = 1;   //模式
float temp = 0;  //读取到的温度

sbit s4 = P3^3;

code unsigned char Seg_Table[] = 
{
	0xc0, //0
	0xf9, //1
	0xa4, //2
	0xb0, //3
	0x99, //4
	0x92, //5
	0x82, //6
	0xf8, //7
	0x80, //8
	0x90, //9
	0x88, //A
	0x83, //b
	0xc6, //C
	0xa1, //d
	0x86, //E
	0x8e //F
};

code unsigned char Seg_DotTable[] = 
{
	0x40, //0.
	0x79, //1.
	0x24, //2.
	0x30, //3.
	0x19, //4.
	0x12, //5.
	0x02, //6.
	0x78, //7.
	0x00, //8.
	0x10  //9.
};

void hc573(unsigned char channel, unsigned char dat)
{
	P2 = (P2 & 0x1f) | 0x00;
	P0 = dat;
	
	switch(channel)
	{
		case 4:
			P2 = (P2 & 0x1f) | 0x80;
		break;
		case 5:
			P2 = (P2 & 0x1f) | 0xa0;
		break;
		case 6:
			P2 = (P2 & 0x1f) | 0xc0;
		break;
		case 7:
			P2 = (P2 & 0x1f) | 0xe0;
		break;
	}
	
	P2 = (P2 & 0x1f) | 0x00;
}

void delay_smg(unsigned int t)
{
	while(t--);
}

void delay_key(unsigned int t)
{
	while(t--);
}


//控制所有数码管
void smg_all(unsigned char dat)
{
	hc573(6, 0xff);
	hc573(7, dat);
}
//控制单个数码管
void smg_bit(unsigned char pos, unsigned char dat)
{
	hc573(6, 0x01 << pos);
	hc573(7, dat);
	delay_smg(TSMG);
	hc573(6, 0x01 << pos);
	hc573(7, 0xff);
}

void smg_display()
{
	unsigned int smg_one = 0;  //数码管显示温度
	
	if(mode == 1)    //模式1
	{
		smg_one = temp * 100;
		smg_bit(4, Seg_Table[smg_one / 1000]);
		smg_bit(5, Seg_DotTable[(smg_one / 100) % 10]);
		smg_bit(6, Seg_Table[(smg_one / 10) % 10]);
		smg_bit(7, Seg_Table[smg_one % 10]);
	}
	else if(mode == 2) //模式2
	{
		smg_one = temp * 10;
		smg_bit(5, Seg_Table[smg_one / 100]);
		smg_bit(6, Seg_DotTable[(smg_one / 10) % 10]);
		smg_bit(7, Seg_Table[smg_one % 10]);
	}
	else  							//模式3
	{
		smg_one = temp;
		smg_bit(6, Seg_Table[smg_one / 10]);
		smg_bit(7, Seg_Table[smg_one % 10]);
	}
}

//完成首次温度转换
void init_one()
{
	unsigned int MSB = 0;
	unsigned int LSB = 0;
	init_ds18b20();
	Write_DS18B20(0xcc);  //忽略ROM
	Write_DS18B20(0x44);	//启动温度转化
	
	do
	{
		init_ds18b20();
	  Write_DS18B20(0xcc);  //忽略ROM
	  Write_DS18B20(0xbe);	//读取暂存
		LSB = Read_DS18B20(); //读取低八位
		MSB = Read_DS18B20(); //读取高八位
		MSB = (MSB << 8) | LSB;  //合成16位
	}while(MSB == 85);
}

//读取温度
void read_one()
{
	unsigned int MSB = 0;
	unsigned int LSB = 0;
	smg_display();
	init_ds18b20();
	Write_DS18B20(0xcc);  //忽略ROM
	Write_DS18B20(0x44);	//启动温度转化
	smg_display();
	
	init_ds18b20();
	smg_display();
	Write_DS18B20(0xcc);  //忽略ROM
	Write_DS18B20(0xbe);	//读取暂存
	LSB = Read_DS18B20(); //读取低八位
	MSB = Read_DS18B20(); //读取高八位
	MSB = (MSB << 8) | LSB;  //合成16位
	smg_display();
	if((MSB & 0xf800) == 0x0000)  //如果温度为正
	{
		temp = MSB * 0.0625;
	}
	smg_display();
	//上述程序中插入多处数码管刷新,可使显示亮度充足
}

void scan_key()
{
	unsigned char key_mode = 1;   //暂时保存模式值,以便实现按完按键后才改变模式值
	key_mode = mode;              //获取当前模式
	if(s4 == 0)
	{
		delay_key(TKEY);
		if(s4 == 0)
		{
			key_mode++;
			if(key_mode== 4)
			{
				key_mode = 1;
			}
			while(s4 == 0)
			{
				smg_display();
			}
		}
	}
	mode = key_mode;
}


void init_sys()
{
	hc573(5, 0x00);
	hc573(4, 0xff);
	smg_all(0xff);
	init_one();      //初始化温度读取
}

void main()
{
	init_sys();
	while(1)
	{
		scan_key();  //键盘扫描
		read_one();  //刷新温度读取
	}
}
  1. void hc573(unsigned char channel, unsigned char dat):定义了一个函数hc573,用于控制74HC573锁存器芯片,根据通道和数据写入数据。
  2. void delay_smg(unsigned int t):定义了一个延时函数delay_smg,用于实现数码管的延时控制。
  3. void delay_key(unsigned int t):定义了一个延时函数delay_key,用于按键的延时控制。
  4. void smg_all(unsigned char dat):定义了一个函数smg_all,用于控制所有数码管显示相同的数据。
  5. void smg_bit(unsigned char pos, unsigned char dat):定义了一个函数smg_bit,用于控制单个数码管显示特定位置的数据。
  6. void smg_display():定义了一个函数smg_display,根据当前模式和温度值控制数码管显示。
  7. void init_one():定义了一个函数init_one,用于首次温度转换,初始化DS18B20传感器并获取温度值。
  8. void read_one():定义了一个函数read_one,用于读取温度值,启动温度转换并获取温度数据。
  9. void scan_key():定义了一个函数scan_key,用于扫描按键状态并根据按键切换显示模式。
  10. void init_sys():定义了一个函数init_sys,用于系统初始化,包括数码管初始化和温度传感器初始化。
  11. void main():定义了主函数,程序入口,初始化系统后进入主循环,循环中进行按键扫描和温度读取。
  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木木不迷茫(˵¯͒¯͒˵)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值