jjzjj

蓝桥杯单片机省赛第十一届赛题二

空心洛 2023-04-20 原文

文章目录


前言

蓝桥杯单片机——第十一届省赛赛题二解析

今年我也参加了第十三届的蓝桥杯单片机组省赛题,分享一下我在练习时写的代码,因为我是第一次

参加,如果有错误的地方欢迎大家指出来。我们大家一起加油进步,打造美好的明天!


一、题目​​

这次题目,就我个人而言难度还是比较简单的,没有什么特别难的地方,赛题总体难度中规中矩,考
的都是一些经常用到并考到的模块。

比如独立键盘、LED指示灯、数码管显示模块、DS18B20、PCF8591,这些都是蓝桥杯板子中基础的
模块,相信大家在平时的练习中都经常写过,都唯一需要注意的地方就是DAC输出,因为比赛考的比
较少,难免有可能一下子忘了怎么写。

其中那个按S4进行界面切换的时候,需要检测参数合理性,大家可以直接在进入参数界面时,将温度最大值和温度最小值分别赋给一个变量储存起来,在进入数据界面显示时在进行判定,不合理则分别将参数赋值回来。


二、代码部分

1.IIC.C

根据官方给出的驱动代码进行修改并加入自己的执行代码。(其中的ad_read函数在试题中并没有什

么大用,因为这套题根本用不了读取函数,纯粹是我在写代码时没怎么审题、直接就把这个给写出来

了。。。。。我也懒的删除了,大家直接忽略便是)

代码如下(示例):

#include "iic.h"

#define DELAY_TIME 5

//I2C总线内部延时函数
void IIC_Delay(unsigned char i)
{
    do{_nop_();}
    while(i--);        
}

//I2C总线启动信号
void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 0;
    IIC_Delay(DELAY_TIME);
    SCL = 0;	
}

//I2C总线停止信号
void IIC_Stop(void)
{
    SDA = 0;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}


//等待应答
bit IIC_WaitAck(void)
{
    bit ackbit;
	
    SCL  = 1;
    IIC_Delay(DELAY_TIME);
    ackbit = SDA;
    SCL = 0;
    IIC_Delay(DELAY_TIME);
    return ackbit;
}

//I2C总线发送一个字节数据
void IIC_SendByte(unsigned char byt)
{
    unsigned char i;

    for(i=0; i<8; i++)
    {
        SCL  = 0;
        IIC_Delay(DELAY_TIME);
        if(byt & 0x80) SDA  = 1;
        else SDA  = 0;
        IIC_Delay(DELAY_TIME);
        SCL = 1;
        byt <<= 1;
        IIC_Delay(DELAY_TIME);
    }
    SCL  = 0;  
}

//I2C总线接收一个字节数据
unsigned char IIC_RecByte(void)
{
    unsigned char i, da;
    for(i=0; i<8; i++)
    {   
    	SCL = 1;
	IIC_Delay(DELAY_TIME);
	da <<= 1;
	if(SDA) da |= 1;
	SCL = 0;
	IIC_Delay(DELAY_TIME);
    }
    return da;    
}

unsigned char ad_read(unsigned char add)
{
	unsigned char temp;
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_Stop();
	
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	temp=IIC_RecByte();
	IIC_WaitAck(); 	
	IIC_Stop();
	
	return temp;
}

void ad_write(unsigned char dat)
{
	EA=0;
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x40);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
	EA=1;
}

2.IIC.H

代码如下(示例):

#ifndef _IIC_H
#define _IIC_H

#include "stc15f2k60s2.h"
#include "intrins.h"

sbit SDA = P2^1;
sbit SCL = P2^0;

void IIC_Start(void);
void IIC_Stop(void);
bit IIC_WaitAck(void);  
void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void); 
void IIC_Delay(unsigned char i);
unsigned char ad_read(unsigned char add);
void ad_write(unsigned char dat);

#endif

3.onewire.h

#include "onewire.h"

//单总线内部延时函数
void Delay_OneWire(unsigned int t)  
{
	while(t--);
}

//单总线写操作
void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(50);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(50);
}

//单总线读操作
unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;
  
	for(i=0;i<8;i++)
	{
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		Delay_OneWire(1);
		if(DQ)
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(50);
	}
	return dat;
}

//DS18B20初始化
bit init_ds18b20(void)
{
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(120);
  	DQ = 0;
  	Delay_OneWire(800);
  	DQ = 1;
  	Delay_OneWire(100); 
    initflag = DQ;     
  	Delay_OneWire(50);
  
  	return initflag;
}

unsigned char ds_read()
{
	unsigned char temp;
	unsigned char low,high;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	Delay_OneWire(200);
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	Delay_OneWire(200);
	
	low=Read_DS18B20();
	high=Read_DS18B20();
	
	temp=(high<<4)|(low>>4);
	return temp;
}

4.onewire.h

#ifndef __ONEWIRE_H
#define __ONEWIRE_H

#include "stc15f2k60s2.h"

sbit DQ = P1^4;  

unsigned char ds_read();
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);


#endif

5. main.c

#include "IIC.H"
#include "onewire.h"

sbit S7=P3^0;
sbit S6=P3^1;
sbit S5=P3^2;
sbit S4=P3^3;

#define uchar  unsigned char
	
uchar temp[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xBF,0XFF,0xc6,0x8c};                //12c,13P
uchar yi,er,san,si,wu,liu,qi,ba;
unsigned char tempare;
unsigned int voltage,mode=0,team=0,TMAX;TMIN,jia=30,jian=20,mode_tt=0,tempare_tt=0,sflg=1;

void delayms(int ms);
void us_waishe();
void display1(uchar yi,uchar er);
void display2(uchar san,uchar si);
void display3(uchar wu,uchar liu);
void display4(uchar qi,uchar ba);
void discan();
void Timer0Init(void);
void mode0_dis();
void mode1_dis();
void display();

void main()
{
	Timer0Init();
	us_waishe();
	while(1)
	{
		voltage=ad_read(0x03);
		mode1_dis();
		mode0_dis();
		display1(yi,er);
		display2(san,si);
		display3(wu,liu);
		display4(qi,ba);
		discan();
		display();
	}
}
void display()
{
	if((jia>jian)||(jia=jian))
	{
		if(tempare>jia)
		{
			ad_write(204);P2=0X80;P0=0XFE;
		}
		else if((tempare>=jian)&&(tempare<=jia))
		{
			ad_write(153);P2=0X80;P0=0XFD;
		}
		else if(tempare<jian)
		{
			ad_write(102);P2=0X80;P0=0XFB;
		}
	}
	else
	{
		P2=0X80;P0=0XFF;
	}		
}
void Timer0Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x20;		//设置定时初值
	TH0 = 0xD1;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	
	ET0=1;
	EA=1;
}

void Timer0() interrupt 1
{
	mode_tt++;tempare_tt++;
	if(mode_tt==200)                                //每200ms选中的模块闪一次
	{
		if(mode==1)sflg=1;                              //sflg==1时全显
	}
	else if(mode_tt==400)
	{
		mode_tt=0;
		if(mode==1)sflg=0;
	}
	
	if(tempare_tt==400)                                       //每400ms刷新一次温度
	{
		tempare_tt=0;
		tempare=ds_read();
	}
}

void mode0_dis()
{
	if(mode==0)                                  //数据界面
	{
		yi=12;er=11;san=11;si=11;wu=11;liu=11;qi=tempare/10;ba=tempare%10;
	}

}
void mode1_dis()                                        //参数界面显示函数
{
	if(mode==1)
	{
		if(sflg==1)
		{
			if((jia/10!=0)&&(jian/10!=0))                                               //判断是两位数还是一位数
			{
				yi=13;er=11;san=11;si=jia/10;wu=jia%10;liu=11;qi=jian/10;ba=jian%10;
			}
			else if((jia/10==0)&&(jian/10==0))
			{
				yi=13;er=11;san=11;si=11;wu=jia;liu=11;qi=11;ba=jian;
			}
			else if((jia/10!=0)&&(jian/10==0))
			{
				yi=13;er=11;san=11;si=jia/10;wu=jia%10;liu=11;qi=11;ba=jian;
			}
			else if((jia/10==0)&&(jian/10!=0))
			{
				yi=13;er=11;san=11;si=11;wu=jia;liu=11;qi=jian/10;ba=jian%10;
			}
		}
		else if(sflg==0)
		{
			if(team==1)                                                 //TMIN
			{
				if(jia/10!=0)                                            //判断是两位数还是一位数
				{
					yi=13;er=11;san=11;si=jia/10;wu=jia%10;liu=11;qi=11;ba=11;
				}
				else if(jia/10==0)
				{
					yi=13;er=11;san=11;si=11;wu=jia;liu=11;qi=11;ba=11;
				}
			}
			else if(team==0)                                                  //TMAX
			{
				if(jian/10!=0)                                               //判断是两位数还是一位数
				{
					yi=13;er=11;san=11;si=11;wu=11;liu=11;qi=jian/10;ba=jian%10;
				}
				else if(jian/10==0)
				{
					yi=13;er=11;san=11;si=11;wu=11;liu=11;qi=11;ba=jian;
				}
			}
		}
	}
}
void discan()
{
	if(S4==0)
	{
		delayms(5);
		if(S4==0)
		{ 
			if(mode==0)
			{
				TMAX=jia;TMIN=jian;
				mode=1;team=1;
			}				                    							//mode=0进入数据界面,mode=1进入参数界面。(有问题)
			else if(mode==1)
			{
				mode=0;
				if(jia<jian)                                         //参数不合理则赋值;
				{
					jia=TMAX;jian=TMIN;
				}
//				else if(jia>=jian)
//				{
//					jia=jia;jian=jian;
//				}
			}
		}
		while(!S4);
	}
	else if(S5==0)
	{
		delayms(5);
		if(S5==0)
		{
			if(team==0)team=1;                                      //team=0时,选择TMAX,team=1时,选择TMIN
			else if(team==1)team=0;
		}
		while(!S5);
	}
	else if(S6==0)
	{
		delayms(5);
		if(S6==0)
		{
			if(mode==1)
			{

				if(team==0)
				{
					if((jia<100)&&(jia>=0))jia=jia+1;
				}
				else if(team==1)
				{
					if((jian>=0)&&(jian<100))jian=jian+1;
				}
			}
		}
		while(!S6);
	}
	else if(S7==0)
	{
		delayms(5);
		if(S7==0)
		{
			if(mode==1)
			{

				if(team==0)
				{
					if((jia<100)&&(jia>0))jia=jia-1;
				}
				else if(team==1)
				{
					if((jian<100)&&(jian>0))jian=jian-1;
				}
			}
		}
		while(!S7);
	}
}

void us_waishe()
{
	P2=0X80;P0=0XFF;
	P2=0XA0;P0=0X00;
	P2=0XC0;P0=0XFF;P2=0XFF;P0=0XFF;
}

void delayms(int ms)
{
	unsigned int i,j;
	for(i=ms;i>0;i--)
		for(j=845;j>0;j--);
}
void display1(uchar yi,uchar er)
{
	P2=0XC0;
	P0=0X01;
	P2=0XE0;
	P0=temp[yi];
	delayms(1);
	
	P2=0XC0;
	P0=0X02;
	P2=0XE0;
	P0=temp[er];
	delayms(1);
}
void display2(uchar san,uchar si)
{
	P2=0XC0;
	P0=0X04;
	P2=0XE0;
	P0=temp[san];
	delayms(1);
	
	P2=0XC0;
	P0=0X08;
	P2=0XE0;
	P0=temp[si];
	delayms(1);
}

void display3(uchar wu,uchar liu)
{
	P2=0XC0;
	P0=0X10;
	P2=0XE0;
	P0=temp[wu];
	delayms(1);
	
	P2=0XC0;
	P0=0X20;
	P2=0XE0;
	P0=temp[liu];
	delayms(1);
}
void display4(uchar qi,uchar ba)
{
	P2=0XC0;
	P0=0X40;
	P2=0XE0;
	P0=temp[qi];
	delayms(1);
	
	P2=0XC0;
	P0=0X80;
	P2=0XE0;
	P0=temp[ba];
	delayms(1);
	P2=0XC0;P0=0XFF;P2=0XFF;P0=0XFF;
}

总结

这些就是蓝桥杯单片机第十一届省赛题赛题二的解析部分,祝大家都能进郭赛!!!!!!!!!!!!

有关蓝桥杯单片机省赛第十一届赛题二的更多相关文章

  1. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

  2. 蓝桥杯备赛(二) - 2

    目录前言: 一、ASC分析代码实现二、 卡片分析代码实现三、 直线分析代码实现四、货物摆放分析代码实现小结:前言:  在刷题的过程中,发现蓝桥杯的题目和力扣的差别很大。让人有一种不一样的感觉,蓝桥杯题目偏向对于实际问题用编程去的解决,而力扣给人感觉很锻炼自己的编程思维,逻辑能力。两者结合去刷,相信会有不一样的收获。 一、ASC  已知大写字母A的ASCII码为65,请问大写字母L的ASCII码是多少?分析  这道题目看上去很简单,我们需确定自己计算的准确,所以我建议用编程去解决。代码实现publicclassTest8{publicstaticvoidmain(String[]args){Sy

  3. 蓝桥杯C/C++VIP试题每日一练之报时助手 - 2

    ?作者主页:静Yu?简介:CSDN全栈优质创作者、华为云享专家、阿里云社区博客专家,前端知识交流社区创建者?社区地址:前端知识交流社区?博主的个人博客:静Yu的个人博客?博主的个人笔记本:前端面试题个人笔记本只记录前端领域的面试题目,项目总结,面试技巧等等。接下来会更新蓝桥杯官方系统基础练习的VIP试题,依然包括解题思路,源代码等等。问题描述:给定当前的时间,请用英文的读法将它读出来。时间用时h和分m表示,在英文的读法中,读一个时间的方法是:  如果m为0,则将时读出来,然后加上“o’clock”,如3:00读作“threeo’clock”。  如果m不为0,则将时读出来,然后将分读出来,如5

  4. micropython复现经典单片机项目(二)可视化音频 频谱解析(基本搞定) - 2

    本人是音乐爱好者,从小就特别喜欢那个随着音乐跳动的方框效果,就是这个:arduino上一大把对,我忍你很久了,我就想用mpy做,全网没有,行我自己研究。果然兴趣是最好的老师,我之前有篇博客专门讲音频,有兴趣的可以回顾一下。提到可视化频谱,必然绕不开fft,大学学过这玩意,当时一心玩,老师讲的一个字都么听进去,网上教程简略扫了一下,大该就是把时域转频域的工具,我大mpy居然没有fft函数,奶奶的,先放着。音频信息如何收集?第一种傻瓜式的ADC,模拟转数字,原始粗暴,第二种,I2S库,我之前博客有讲过,数据是PCM编码。然后又去学PCM编码,一学豁然开朗,舒服,以代码为例:audio_in=I2S

  5. 十四届蓝桥青少组模拟赛Python-20221108 - 2

    十四届蓝桥青少组模拟赛Python-20221108T1.二进制位数十进制整数2在十进制中是1位数,在二进制中对应10,是2位数。十进制整数22在十进制中是2位数,在二进制中对应10110,是5位数。请问十进制整数2022在二进制中是几位数?print(len(bin(2022))-2)#运行结果:11T2.晨跑小蓝每周六、周日都晨跑,每月的1、11、21、31日也晨跑。其它时间不晨跑。已知2022年1月1日是周六,请问小蓝整个2022年晨跑多少天?#样例代码1ls=[0,31,28,31,30,31,30,31,31,30,31,30,31]ans=0k=6foriinrange(1,13)

  6. 蓝桥杯 stm32 MCP4017 - 2

    本文代码使用HAL库。文章目录前言一、MCP4017的重要特性二、MCP4017计算RBW阻值三、MCP4017地址四、MCP4017读写函数五、CubeMX创建工程(利用ADC测量MCP4017电压)、对应代码:总结前言一、MCP4017的重要特性蓝桥杯板子上的是MCP4017T-104ELT,如图1。MCP4017是一个可编程电阻,通过写入的数值可以改变电阻的大小。重点在于6引脚(W),5引脚(B&#

  7. 51单片机——74HC595的应用(SPI实践) - 2

    目录SPI总线SPI总线概述 SPI总线分类SPI优点及缺点SPI接口硬件原理SPI四种工作模式 74HC595应用74HC595芯片概述74HC595封装及管脚功能74HC595工作原理 ​编辑 74HC595串行转并行点亮LED灯 程序实现  Proteus运行结构示意图SPI总线SPI总线概述 SPI(SerialPeripheralinterface):串行外围设备接口 用途:用来在微控制器与外围设备芯片之间实现数据交换 特点:高速、全双工、同步 SPI总线分类四线制全双工SPI(同时收发)MISO    主机输入/从机输出MOSI    主机输出/从机输入SCLK   串行时钟CS或

  8. 【毕业设计】基于单片机的智能温控农业大棚系统 - 物联网 stm32 - 2

    文章目录1简介2绪论2.1课题背景与目的3系统设计详细设计描述3.2硬件部分温度测量电路其他电路部分3.3软件部分主程序子系统程序温湿度程序流程键盘显示子程序3.4实现效果3.5部分相关代码4最后1简介Hi,大家好,这里是丹成学长,今天向大家介绍一个单片机项目基于单片机的智能温控农业大棚系统大家可用于课程设计或毕业设计单片机-嵌入式毕设选题大全及项目分享:https://blog.csdn.net/m0_71572576/article/details/1254090522绪论2.1课题背景与目的近年来我国的温室控制取得了长足的进步,首先在温室群控制方面,进行了初步的探索和理论研究,其次在温室

  9. AT24C04、AT24C08、AT24C16系列EEPROM芯片单片机读写驱动程序 - 2

    一、概述在之前的一篇博文中,记录了AT24C01、AT24C02芯片的读写驱动,先将之前的相关文章include一下:1.IIC驱动:4位数码管显示模块TM1637芯片C语言驱动程序2.AT24C01/AT24C02读写:AT24C01/AT24C02系列EEPROM芯片单片机读写驱动程序本文记录分享AT24C04、AT24C08、AT24C16芯片的单片机C语言读写驱动程序。二、芯片对比介绍型号容量bit容量byte页数字节/页器件寻址位可寻址器件数WordAddress位数/字节数备注AT24C044k5123216A2A149/1WordAddress使用P0位AT24C088k1024

  10. 基于51单片机、DS1302时钟模块的电子闹钟设计 - 2

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录一、设计原理1.DS1302介绍2.闹钟音乐播放原理二、程序设计1.DS1302.h2.ds1302.c3.music.h4.main.c三、电路图四、运行结果1.proteus仿真2.开发板实验五、总结六、附件提示:以下是本篇文章正文内容,下面案例可供参考一、设计原理1.DS1302介绍DS1302是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.0V~5.5V。该芯片采用普通32.768kHz晶振,DS1302工作时功耗很

随机推荐