【蓝桥杯】第十二届单片机省赛

【蓝桥杯】第十二届单片机省赛

题目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码参考

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

typedef unsigned char uint8;
typedef unsigned int uint32;

#define LED_Channel  		4
#define BEEP_DELAY_Channel  5
#define COM_Channel  		6
#define SMG_Channel  		7

sfr P4 = 0xc0;
sfr AUXR = 0x8e;


//数码管编码
uint8 code TAB[19] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0x7f,0x8c};
//带小数点
uint8 code Dot_TAB[16]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e} ;
//矩阵按键接口  J5:12
sbit R1 = P3^0;
sbit R2 = P3^1;
sbit R3 = P3^2;
sbit R4 = P3^3;

sbit C1 = P4^4;
sbit C2 = P4^2;
sbit C3 = P3^5;
sbit C4 = P3^4;

uint8 cnttemp = 0;
uint8 cntdac = 0;
uint8 cnttemp_flag = 0;
uint8 cntdac_flag = 0;

uint8 node = 0;//0 1 2
uint8 mode = 0;//0 1 
uint32 temp = 0;
uint32 Vdac = 1;
uint8 default_temp = 25;
uint8 last_temp = 25;
//uint8 key_value = 0;

void Delay(uint32 ms);
void InitHC138(uint8 Channel);
void Init_System(void);
void Display_Bit(uint8 pos,uint8 date);
void Display_All(uint8 date);
void Dislpay(uint8 node);
void Key_Scan();
void Read_Temp(void);
void SMG_Delay(uint32 t);
void DAC_Hander(void);
void DAC(uint8 date);
void LED_Control(void);
void Timer0Init(void)		//50毫秒@11.0592MHz
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x00;		//设置定时初始值
	TH0 = 0x4C;		//设置定时初始值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	
	ET0 = 1;
	EA = 1;
}
void Time0_Hander(void) interrupt 1
{
	cnttemp++;
	cntdac++;
	
	if(cnttemp == 10)//50*10
	{
		cnttemp = 0;
		cnttemp_flag = 1;
		//Read_Temp();
	}
	if(cntdac == 5)//50*5
	{
		cntdac = 0;
		cntdac_flag = 1;
		//DAC_Hander();
	}
	
}

void main()
{
	Init_System();
	Timer0Init();
	LED_Control();
	while(1)
	{
		if(cnttemp_flag)
		{
			Read_Temp();
			cnttemp_flag = 0;
		}
		Key_Scan();
		Dislpay(node);
		if(cntdac_flag)
		{
			DAC_Hander();
			cntdac_flag = 0;
		}
		
	}
}
void LED_Control(void)
{
	uint8 date = 0xff;
	switch(node)
	{
		case 0://L2
			date = ~(date & 0x02);
			break;
		case 1://L3
			date = ~(date & 0x04);
			break;
		case 2://L4
			date = ~(date & 0x08);
			break;
		
	}
	if(!mode)
		date&=0xfe;
	InitHC138(LED_Channel);
	P0 = date;
	InitHC138(0);
}
void Delay(uint32 ms)
{
	uint32 x,y;
	for(x=0;x<ms;x++)
		for(y=846;y>0;y--){}
}
void InitHC138(uint8 Channel)
{
	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;
		default:P2 &= 0x1f;
	}
}
void Init_System(void)
{
	InitHC138(BEEP_DELAY_Channel);
	P0 = 0x00;
	InitHC138(LED_Channel);
	P0 = 0xff;
	InitHC138(0);
}

void Display_Bit(uint8 pos,uint8 date)
{
	InitHC138(COM_Channel);
	P0 = 0x01<<pos;
	InitHC138(SMG_Channel);
	P0 = date;
	InitHC138(0);
}
void Display_All(uint8 date)
{
	InitHC138(COM_Channel);
	P0 = 0xff;
	InitHC138(SMG_Channel);
	P0 = date;
	InitHC138(0);
}
void SMG_Delay(uint32 t)
{
	while(t--)
	{
		Dislpay(node);
	}
}
void Dislpay(uint8 node)//不要忘记 Delay(1)
{
	switch(node)
	{
		case 0:
			Display_Bit(0,TAB[12]),Delay(1);
			Display_Bit(1,0xff),Delay(1);
			Display_Bit(2,0xff),Delay(1);
			Display_Bit(3,0xff),Delay(1);
			Display_Bit(4,TAB[temp/1000]),Delay(1);
			Display_Bit(5,Dot_TAB[(temp%1000)/100]),Delay(1);
			Display_Bit(6,TAB[(temp%100)/10]),Delay(1);
			Display_Bit(7,TAB[temp%10]),Delay(1);
			Display_All(0xff);
			break;
		case 1:
			Display_Bit(0,TAB[18]),Delay(1);
			Display_Bit(1,0xff),Delay(1);
			Display_Bit(2,0xff),Delay(1);
			Display_Bit(3,0xff),Delay(1);
			Display_Bit(4,0xff),Delay(1);
			Display_Bit(5,0xff),Delay(1);
			Display_Bit(6,TAB[last_temp/10]),Delay(1);
			Display_Bit(7,TAB[last_temp%10]),Delay(1);
			Display_All(0xff);
			break;
		case 2:
			if(mode == 0)
			{
				Display_Bit(0,TAB[10]),Delay(1);
				Display_Bit(1,0xff),Delay(1);
				Display_Bit(2,0xff),Delay(1);
				Display_Bit(3,0xff),Delay(1);
				Display_Bit(4,0xff),Delay(1);
				Display_Bit(5,Dot_TAB[Vdac]),Delay(1);
				Display_Bit(6,TAB[0]),Delay(1);
				Display_Bit(7,TAB[0]),Delay(1);
				Display_All(0xff);
			}
			else
			{
				Display_Bit(0,TAB[10]),Delay(1);
				Display_Bit(1,0xff),Delay(1);
				Display_Bit(2,0xff),Delay(1);
				Display_Bit(3,0xff),Delay(1);
				Display_Bit(4,0xff),Delay(1);
				Display_Bit(5,Dot_TAB[Vdac/100]),Delay(1);
				Display_Bit(6,TAB[(Vdac%100)/10]),Delay(1);
				Display_Bit(7,TAB[Vdac%10]),Delay(1);
				Display_All(0xff);
			}
			
			break;
		default:Display_All(0xff);break;
	}
}
void DAC_Hander(void)
{
	
	if(mode==0)
	{
		if(temp<default_temp*100)
		{
			Vdac = 0;
			DAC(0x00);
		}
		else
		{
			Vdac = 5;
			DAC(0xff);
		}
	}
	else
	{
		if(temp<=2000)
			Vdac = 100;
		else if(temp>=4000)
			Vdac = 400;
		else
			Vdac = 0.15*temp-200;
		
		DAC( (uint8)(Vdac*0.51) );
			
	}
}
void DAC(uint8 date)	// 输入值需要转换[0~255]
{

	IIC_Start();
	IIC_SendByte(0x90);		
	IIC_WaitAck();				
	IIC_SendByte(0x40);
	IIC_WaitAck();
	IIC_SendByte(date);
	IIC_WaitAck();
	IIC_Stop();
}

void Key_Scan()
{	
	R1=1,R2=1,R3=0,R4=1;
	C1=1,C2=1,C3=1,C4=1;
	if(C1==0&&node==2)//s5
	{
		Delay(10);
		if(C1==0)
		{
			++mode;
			if(mode>=2)
				mode = 0;
			while(C1==0)
			{
				Dislpay(node);
				LED_Control();
			}
		}
	}
	
	if(C2==0&&node==1)//s9 +1
	{
		Delay(10);
		if(C2==0&&node==1)
		{
			if(last_temp<99)
				++last_temp;
			while(C2==0)
			{
				Dislpay(node);
				LED_Control();
			}
		}
	}
	
	
	R1=1,R2=1,R3=1,R4=0;
	C1=1,C2=1,C3=1,C4=1;
	if(C1==0)//s4
	{
		Delay(10);
		if(C1==0)
		{
			++node;
			if(node == 2)
			{
				default_temp = last_temp;
			}
			if(node>=3)
				node = 0;
			while(C1==0)
			{
				Dislpay(node);
				LED_Control();
			}
		}
	}
	if(C2==0&&node==1)//s8 -1
	{
		Delay(10);
		if(C2==0&&node==1)
		{
			if(last_temp>0)
				--last_temp;
			
			while(C2==0)
			{
				Dislpay(node);
				LED_Control();
			}
		}
	}
}
//初始化,跳过rom,操作
//前5位是符号位,后4位是小数位,小数存放在LSB(低位先读),//0.0625*10
void Read_Temp(void)
{
	uint8 LSB,MSB;
	
	init_ds18b20();
	Write_DS18B20(0xcc);  //跳过ROM指令
	Write_DS18B20(0x44);	//开始温度转换
	SMG_Delay(50);
	//Delay_OneWire(200);	   // 延时一段时间
	
	init_ds18b20();
	Write_DS18B20(0xcc);	//跳过ROM指令
	Write_DS18B20(0xbe);	//读取高速暂存器
	//SMG_Delay(400);
	
	LSB =Read_DS18B20();  //读取第一个字节
	MSB =Read_DS18B20();	//读取第二字节

	temp = (MSB<<8)|LSB;
	
	//包含小数 ,如果不包含小数,直接将temp右移4位即可
	if((temp & 0xf800)== 0x0000)  //判断高五位符号位是否为0 ,即是否为正数
	{
		temp = temp>>4;
		temp = temp * 100;
		temp = temp + (LSB & 0x0f)*6.25 ;
	}
	if(temp==8500)
		temp = 0;
}
/*
float Read_Temp(void)
{
	uint8 LSB,MSB;
	uint32 result;
	float ans;
	init_ds18b20();
	Write_DS18B20(0xcc);  //跳过ROM指令
	Write_DS18B20(0x44);	//开始温度转换
	//SMG_Delay(50);
	Delay_OneWire(200);	   // 延时一段时间
	
	init_ds18b20();
	Write_DS18B20(0xcc);	//跳过ROM指令
	Write_DS18B20(0xbe);	//读取高速暂存器
	
	LSB =Read_DS18B20();  //读取第一个字节
	MSB =Read_DS18B20();	//读取第二字节

	
	result = ( (MSB&0x0f)<<8 )| LSB;
	
	ans = result*0.0625;
	
	return ans;
	
}
*/

总结

好久没看单片机,一开始数码管动态显示忘了加Delay(1),屏幕乱闪,翻了以前代码才看出bug,最后花了点时间写了一下也没细看,基本功能实现,优化和改错之后再弄。

蓝桥杯是中国最具影响力的计算机竞赛之一,每年都吸引着全国各地的优秀程序员参赛。而蓝桥杯第十二届danpianji组省赛则是该竞赛中一个重要的分支。 在蓝桥杯第十二届danpianji组省赛中,参赛者需要通过编程解决一系列与单片机相关的问题。单片机是一种集成电路芯片,具有计算、控制和存储等功能。参赛者需要用编程语言如C/C++或汇编语言来控制单片机,实现特定的功能。 比赛中的题目涉及到各个方面的单片机应用,如输入输出控制、定时器中断、模拟信号转换、通信接口等。参赛者需要深度理解单片机的工作原理,熟练掌握各种编程技巧和调试方法。他们需要用编程语言编写程序,将问题转化为代码,并通过单片机的运行来验证解决方案的正确性。 蓝桥杯第十二届danpianji组省赛旨在考察参赛者的编程能力、技术水平和解决问题的能力。参赛者需要在有限的时间内独立完成题目,并保证输出结果的准确性和高效性。比赛过程中,参赛者还需要具备良好的团队合作精神与沟通能力,因为他们有时需要分工合作,共同解决复杂的问题。 蓝桥杯第十二届danpianji组省赛为广大单片机爱好者提供了一个锻炼自己技术的机会,也促进了单片机应用技术的发展。相信通过这样的比赛平台,参赛者能够不断提升自身能力,为我国的科技进步贡献自己的力量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值