2021年第12届蓝桥杯单片机第1场程序题

该程序展示了如何使用STM32单片机读取DS18B20温度传感器数据,并通过DAC输出进行温度控制。程序中包含了温度显示、参数设置界面以及电压输出界面的实现,同时支持按键操作进行模式切换和参数调整。此外,还实现了LED状态指示灯功能。
摘要由CSDN通过智能技术生成

2021年第12届蓝桥杯单片机第1场程序题
在这里插入图片描述在这里插入代码片
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include "reg52.h"
#include "onewire.h"
#include "iic.h"

sfr P4    = 0xc0;

sbit R3 = P3^2;
sbit R4 = P3^3;
sbit C2 = P4^2;
sbit C1 = P4^4;

unsigned int temp;   //温度存储变量
unsigned int Tem=25;   //温度参数设置值
unsigned int Tem1=25;   //温度参数
unsigned int Vout=325;   //温度参数
unsigned char keys_sum=0;  //S4键值
unsigned char show=0;  //界面状态标志位
unsigned char mode=1;  //模式状态标志位

unsigned char code SMG_Duanma[]=
  {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0x7f};
	//0   1   2   3   4   5   6   7   8   9  -  .
unsigned char code YSMG_Duanma[]=
  {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
	//0   1   2   3   4   5   6   7   8   9  -  .

void Display_SMG();

/*******************系统通用函数***************/
void Init_HC138(unsigned char n)
{
	switch(n)
	{
    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;		
	}
}

void Delay(unsigned int t)
{
	while(t--);
}
/*******************************************/

/***************系统初始化函数*************/
void Init_Stystem()
{
	Init_HC138(5);
	P0 = 0x00;
	Init_HC138(4);
	P0 = 0xff;	
}
/*******************************************/

/*************DS18b20温度传感器*************/
void Temp_Delay(unsigned int t)
{
	while(t--)
	{
		Display_SMG();
	}
}


void Read_DS18B20_tamp()
{
	unsigned char LSB,MSB;
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	Temp_Delay(100);
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);	
	LSB = Read_DS18B20();
	MSB = Read_DS18B20();	
	init_ds18b20();

	temp = 0x0000;
	temp = MSB;
	temp = (temp<<= 8) | LSB;
	
	if((temp & 0xf800) == 0x0000)
	{
		temp >>= 4;  //整数部分
		temp = temp * 100;
		temp = temp + (LSB & 0X0F)* 0.625*10;
	}
}

/*******************************************/

/**********************电压输出**********************/
void DAC_OUT(unsigned char dat)
{
	IIC_Start();
	IIC_SendByte(0x90);  //写
	IIC_WaitAck();
	IIC_SendByte(0x40);  //地址/通道  0100 0000  D/A转换
	IIC_WaitAck();
	IIC_SendByte(dat);   //写入数据
	IIC_WaitAck();
	IIC_Stop(); 	
}

unsigned int Count(unsigned int x)
{
	unsigned int y;
	x = x/10;
	y = 15*x-2000;
	Vout =  y/10;
	y = (500/255)*y;
  return y;
}

void Out_Vin()
{
	unsigned int temp1;
	temp1 = temp/100;
	if(mode==1)
	{
	  if(temp1<Tem) 
		{
			DAC_OUT(0);
			Vout = 0;
		}
	  else 
		{
			DAC_OUT(255);
			Vout = 500;
		}
	}
	else if(mode==2)
	{
		if(temp1<=20) 
		{
			DAC_OUT(196);  //1.00V
			Vout = 100;
		}
		else if(temp1<=40) 
		{
			DAC_OUT(Count(temp));
		}
		else 
		{
			DAC_OUT(204);//4.00v
			Vout = 400;
		}
	}
	
}
/******************************************************/



/********************数码管显示**********************/
void Display_Bety(unsigned char channl,unsigned char dat)
{
	Init_HC138(7);
	P0 = 0xff;			
	Init_HC138(6);
	P0 = 0X01 << channl;
	Init_HC138(7);
	P0 = dat;		
}

void SMG_All()
{
	Init_HC138(6);
	P0 = 0Xff;
	Init_HC138(7);
	P0 = 0xff;			
}

void Display_C()
{
	Display_Bety(0,0xc6);  //11000110
	Delay(500);            //C
	
	Display_Bety(4,SMG_Duanma[temp/1000]);
	Delay(500);	
	Display_Bety(5,YSMG_Duanma[(temp%1000)/100]); 
	Delay(500);
	Display_Bety(6,SMG_Duanma[(temp%100)/10]); 
	Delay(500);
	Display_Bety(7,SMG_Duanma[temp%10]);
	Delay(500);
	
	SMG_All();
}

void Display_P()
{
	Display_Bety(0,0x8c);  //10001100
	Delay(500);            //P
	
	Display_Bety(6,SMG_Duanma[Tem1/10]);
	Delay(500);
	Display_Bety(7,SMG_Duanma[Tem1%10]);
	Delay(500);
	
	SMG_All();	
}

void Display_A()
{
	Display_Bety(0,0x88);  //10001000
	Delay(500);            //A
	
	Display_Bety(5,YSMG_Duanma[Vout/100]);
	Delay(500);
	Display_Bety(6,SMG_Duanma[Vout%100/10]);
	Delay(500);
	Display_Bety(7,SMG_Duanma[Vout%10]);
	Delay(500);
	
	
	SMG_All();		
}

void Display_SMG()
{
	if(show==0) Display_C();
	else if(show==1) Display_P();	
  else if(show==2) Display_A();	   		
}
/******************************************************/

/************************独立按键**********************/
void Scan_Keys()
{
	R4 = 0;
	R3 = 1;
	C1 = C2 = 1;
	if(C1==0)     //S4 显示界面切换
	{
		Delay(100);
		if(C1==0)
		{
			switch(show)
			{
				case 0:
					show=1;  //参数设置界面
				break;
				case 1:
			   	show=2;   //DAC输出界面
				  Tem = Tem1;
				break;
				case 2:
					show=0;   //温度显示界面
				break;				
			}
		}
		while(C1==0) 
		{
			Read_DS18B20_tamp();
			Display_SMG();
		}
	}
	/*******************/
	else if(C2==0)     //S8 减 - 
	{
		Delay(100);
		if(C2==0)
		{
	    if(show==1)  //温度参数界面
	    { 
			  if(Tem1>=1) Tem1--;
				else Tem1 = 0;
			}
		}
		while(C2==0) 
		{
			Read_DS18B20_tamp();
			Display_SMG();
		}
	}
	/*******************/
	R3 = 0;
	R4 = 1;
	C1 = C2 = 1;
	if(C1==0)     //S5 模式
	{
		Delay(100);
		if(C1==0)
		{
	    if(mode==1)	mode=2;
			else if(mode==2) mode=1;
		}
		while(C1==0) 
		{
			Read_DS18B20_tamp();
			Display_SMG();
		}
	}	
	/*******************/
	if(C2==0)     //S9 加+
	{
		Delay(100);
		if(C2==0)
		{
	    if(show==1)  //温度参数界面
	    { 
			  if(Tem1<=85) Tem1++;
				else Tem1 = 85;
			}
		}
		while(C2==0) 
		{
			Read_DS18B20_tamp();
			Display_SMG();
		}
	}	
}
/******************************************************/

/**********************LED转态指示灯*******************/
void State_LED()
{
	//L1指示灯
	if(mode==1) 
	{
		Init_HC138(4);
		P0 = (P0 & 0XFE) | 0X00; //点亮L1
	}
	else
	{
		Init_HC138(4);
	  P0 = (P0 & 0XFE) | 0X01; //熄灭L1
	}
	//L2指示灯
	if(show==0)
	{
	  Init_HC138(4);
	  P0 = (P0 & 0XFD) | 0X00; //点亮L2	
	}
	else
	{
	  Init_HC138(4);
	  P0 = (P0 & 0XFD) | 0X02; //熄灭L2			
	}
	//L3指示灯
	if(show==1)
	{
	  Init_HC138(4);
	  P0 = (P0 & 0XFB) | 0X00; //点亮L3
	}
	else
	{
	  Init_HC138(4);
	  P0 = (P0 & 0XFB) | 0X04; //熄灭L3		
	}
	//L4指示灯
	if(show==2)
	{
	  Init_HC138(4);
	  P0 = (P0 & 0XF7) | 0X00; //点亮L4
	}
	else
	{
	  Init_HC138(4);
	  P0 = (P0 & 0XF7) | 0X08; //熄灭L4		
	}	
}
/******************************************************/

/*******************主函数******************/
/*******************************************/
void main()
{
	Init_Stystem();
	while(1)
	{
		Read_DS18B20_tamp();
    Scan_Keys();
		Display_SMG();
		Out_Vin();
		State_LED();
	}
}
/*******************************************/

参考文章:
(1)https://blog.csdn.net/weixin_45386875/article/details/113861559;
(2)https://blog.csdn.net/AllErrors/article/details/109777277;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值