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

一、真题

二、模块构建

1.编写初始化函数(init.c)

void Cls_Peripheral(void);

  1. 关闭led led对应的锁存器由Y4C控制
  2. 关闭蜂鸣器和继电器 由Y5C控制

2.编写LED函数(led.c)

void Led_Disp(unsigned char ucLed);

  1. 将ucLed取反的值赋给P0

  2. 开启锁存器

  3. 关闭锁存器

3.编写数码管函数(seg.c)

void Seg_Tran(unsigned char *pucSeg_Buf,unsigned char *pucSeg_Code);

(1)段码转换函数

  • 定义数组要加*
  • 定义两个变量i,j
  • for循环加Switch语句进行段码转换,在资源数据包查找段码表,并根据题目要求进行段码转换
  • 注意添加空格代表都不显示
  • case记得加' '
  • 判断是否有 .,是用j+1位判断

void Seg_Disp(unsigned char *pucSeg_Code,unsigned char ucSeg_Pos);

(2)数码管显示函数

  • 要对数码管进行消隐
  • 显示的位置
  • 显示的内容

4.独立按键代码编写

unsigned char Key_Read_BTN(void)

  1. 有返回值函数(unsigned char)
  2. if语句判断按键是否按下
  3. 返回按键所对应的数字
  4. 没有按键按下时返回0

5.编写ADC代码

unsigned char PCF8591_ADC(unsigned char dat);

  1. 定义SCL,SDA
  2. 添加"intrins.h"头文件
  3. 定义变量用于存储采集的电压
  4. 函数定义写入地址dat,来判断读取哪一路
  5. 写入流程:开始--发送写入地址--等待应答--发送dat地址--等待应答
  6. 读取流程:开始--发送读取地址--等待应答--变量接收数据 --发送应答--终止
  7. 读取地址为0x91 写入地址为0x90
  8. 电位器地址为0x43 光敏电阻地址为0x41

6.编写频率代码

通过TMODE 配置将定时器0配置为计数器,实现频率读取

7.编写定时器代码

  1. 将定时器1用作定时器,定时器0作为计数器供NE555使用
  2. 定时器1为1毫秒定时器,用stc-isp生成,加上ET1=1!!!;
  3. 定时器0的使用需要对TMOD寄存器进行配置

三、主函数代码

1.初始化,定时器0,定时器1,中断总开关,stdio.h

2.编写数码管函数

  1. 数码管的数组和数字位置定义 12 8 0
  2. 时间为200ms
  3. 判断显示模式
  4. 数码管转换函数

3.编写定时器中断函数

  1. 所有计时变量自增
  2. 每2ms数码管显示
  3. 每1s读取一次频率并清零
  4. 将signal和P34引脚短接

4.周期界面

  1. 周期为频率的倒数

  2. 因为题目要求周期单位为微秒,所以要乘以10的6次方后再除以频率

  3. 频率和周期都定义为unsigned int型

5.编写按键代码

  1. 时间为20ms
  2. 定义两个按键用于消抖
  3. 调用读取按键函数并赋值给变量Key_Val
  4. 判断Key_Val和Key_Val_Old是否相等,相等返回
  5. Switch语句判断哪个按键按下
  6. 再将Key_Val的值赋值给 Key_Val_Old
  7. 按下4按键,将Disp_Mode自加对3取模,因为有三个界面
  8. 当s6,s7按键按下时,定义一个新变量用于数据缓存,直接将原来的值赋值给现在的变量
  9. 对于s7是否长按的处理,将ulms的值赋值给S7_Down,然后在case 0时判断ulms - S7_Down > 1000,如果是,则直接则执行长按相关命令

6.电压界面

  1. 定义两个变量分别为光敏电阻和滑动变阻器的电压值
  2. 定义ADC_Mode用于切换两个界面

7.编写ADC函数

  1. 时间为200ms

  2. 在同时读取两路ADC时会出现反转的现象

    因此在要求同时采集两路时,将两个写入的数据调换位置

8.所有编写的函数,一定不要忘记放到主循环里

四、主函数代码

cpp 复制代码
#include "init.h"
#include "seg.h"
#include "led.h"
#include "key.h"
#include "iic.h"
#include "stdio.h"
#include "tim.h"
//seg
unsigned char pucSeg_Buf[12],pucSeg_Code[8],ucSeg_Pos=0;
//led
unsigned char ucLed=0;
//key
unsigned char Key_Val=0,Key_Val_Old=0;
//ADC
unsigned char ucADC_Res=0,ucADC_Photo=0;
unsigned char ucADC_Res_Buf=255;
//Timer
unsigned long ulms=0;
unsigned long S7_Down=0;
unsigned int uiSeg_Dly=0;
unsigned int uiKey_Dly=0;
unsigned int uiADC_Dly=0;
unsigned int uiLed_Dly=0;
//freq
unsigned int uiFreq=0;
unsigned int uiTime=0;
unsigned int uiFreq_Buf=65535;
//function
void Seg_Proc(void);
void Key_Proc(void);
void ADC_Proc(void);
void Led_Proc(void);
//mode
unsigned char Disp_Mode=0;
unsigned char ADC_Mode=1;
unsigned char Led_Mode = 1;
void main(void)
{
	Cls_Peripheral();
	Timer0Init();
	Timer1Init();
	EA=1;
	
	while(1)
	{
	Seg_Proc();
	Key_Proc();
	ADC_Proc();
	Led_Proc();
	}
}
void Led_Proc(void)
{
	if(uiLed_Dly<200)
	return;
	uiLed_Dly=0;
	
	if(Led_Mode == 0)
	{
		ucLed = 0x00;
	}
	else
	{
	if(ucADC_Res>ucADC_Res_Buf)
	{
		ucLed|=0x01;
	}
	else
	{
		ucLed&=~0x01;
	}
	if(uiFreq > uiFreq_Buf)
		{
			ucLed |= 0x02;
		}
		else
		{
			ucLed &= ~0x02;
		}
		if(Disp_Mode == 0)
		{
			ucLed |= 0x04;
			ucLed &= ~0x18;
		}
		else if(Disp_Mode == 1)
		{
			ucLed |= 0x08;
			ucLed &= ~0x14;
		}
		else
		{
			ucLed |= 0x10;
			ucLed &= ~0x0C;
		}
		Led_Disp(ucLed);
	}
}
void Seg_Proc(void)
{
	if(uiSeg_Dly<200)
	return;
	uiSeg_Dly=0;
	if(Disp_Mode==0)
	{
	sprintf(pucSeg_Buf,"F%7u",uiFreq);
	}
	else if(Disp_Mode==1)
	{
		sprintf(pucSeg_Buf,"N%7u",uiTime);
	}
	else 
	{
		if(ADC_Mode==1)
		{
		sprintf(pucSeg_Buf,"U-1  %4.2f",ucADC_Photo/51.0);
		}
		else
		{
		sprintf(pucSeg_Buf,"U-3  %4.2f",ucADC_Res/51.0);
		}
	}
	Seg_Tran(pucSeg_Buf,pucSeg_Code);
}
void Key_Proc(void)
{
	if(uiKey_Dly<20)
	return;
	uiKey_Dly=0;
	Key_Val=Key_Read_BTN();
	if(Key_Val==Key_Val_Old)
		return;
	switch(Key_Val)
	{
		case 0:
			if(Key_Val_Old==7)
			{
				if(ulms-S7_Down>1000)			
				{
				Led_Mode=(Led_Mode+1)%2;
				}
				else
				{
					uiFreq_Buf = uiFreq;
				}
			}
		case 4:
			Disp_Mode=(Disp_Mode+1)%3;
		if(Disp_Mode==2)
		{
			ADC_Mode=1;
		}
			break;
		case 5:
			if(Disp_Mode==2)
			{
				if(ADC_Mode==1)
					ADC_Mode=3;
				else
					ADC_Mode=1;
			}
			break;
		case 6:
			ucADC_Res_Buf=ucADC_Res;
			break;
		case 7:
			S7_Down=ulms;
			uiFreq_Buf=uiFreq;
			break;
	}
	Key_Val_Old=Key_Val;
}
void ADC_Proc(void)
{
	if(uiADC_Dly<200)
	return;
	uiADC_Dly=0;
	
	ucADC_Res=PCF8591_ADC(0x41);
	ucADC_Photo=PCF8591_ADC(0x43);
}
void Time_1(void) interrupt 3
{
	ulms++;
	uiSeg_Dly++;
	uiKey_Dly++;
	uiADC_Dly++;
	uiLed_Dly++;
	if(ulms%2==0)
	{
		ucSeg_Pos=(ucSeg_Pos+1)%8;
		Seg_Disp(pucSeg_Code,ucSeg_Pos);
	}
	
	if(ulms%1000==0)
	{
		uiFreq=((TH0<<8)|TL0);
		uiTime=1000000/uiFreq;//以微秒为单位
		TH0=0;
		TL0=0;
	}
}
相关推荐
眰恦ゞLYF16 小时前
嵌入式硬件——IMX6ULL时钟配置
单片机·嵌入式硬件·时钟·imx6ull
小莞尔17 小时前
【51单片机】【protues仿真】基于51单片机秒表系统(LCD1602多功能、可保持30条记录)
c语言·stm32·单片机·嵌入式硬件·51单片机
Tolines18 小时前
PCIe外接卡标准尺寸
嵌入式硬件·硬件工程·设计规范
寅双木18 小时前
常见的九种二极管
笔记·嵌入式硬件·稳压二极管·tvs·肖特基二极管·发光二极管·齐纳击穿
Black doncky prince18 小时前
QR反激电源副边整流二极管电压波形分析
单片机·嵌入式硬件·硬件工程
currycheng618 小时前
开关电源测试及方法
单片机·嵌入式硬件·硬件架构·硬件工程
SundayBear19 小时前
基于MCU的文件系统
linux·服务器·单片机
DIY机器人工房1 天前
关于解决 libwebsockets 库编译时遇到的问题的方法:
服务器·stm32·单片机·嵌入式硬件·tcp
GilgameshJSS1 天前
STM32H743-ARM例程3-SYSTICK定时闪烁LED
arm开发·stm32·单片机·嵌入式硬件·学习
云山工作室1 天前
基于单片机的按摩椅系统的设计(论文+源码)
stm32·单片机·嵌入式硬件·毕业设计·毕设