行业知识
蓝桥杯单片机第十四届省赛题目和程序答案
2026-11-05 20:35:09
来源:互联网转载
���录
1、前言
2、题目
3、程序架构
3.1 display.c
3.2 ds1302.c
3.3 iic.c
3.4 onewire.c
3.5 main.c 主函数文件
3.6 环境配置
4. 历年蓝桥杯单片机试题和答案
1、前言
抽空复习了一下,拿下单片机省赛一等奖,在此分享一下最新的14届省赛程序设计答案
2、题目
3、程序架构
模块化编程,每个模块的程序单独写在一个文中,下面分别给出图中文件的详细代码
3.1 display.c
主要包含数码管、led显示。
#include "display.h"code unsigned char Seg_Table[] ={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, //90x88, //A0x83, //b0xc6, //C 120xa1, //d0x86, //E0x8e, //F 150xbf, // - 160x89, // H 170x8C, // P 180x88 // R 19};//0-9带小数点code unsigned char Seg_Table_f[] = { 0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00, 0x10};void Delayms(int ms)//@12.000MHz{unsigned char i, j;int k =0; for(k=0;kmin/10*16 + date->min%10; sec = date->sec/10*16 + date->sec%10; Write_Ds1302_Byte(WP,0x00); Write_Ds1302_Byte(W_HOUR,hour); Write_Ds1302_Byte(W_MIN,min); Write_Ds1302_Byte(W_SEC,sec); Write_Ds1302_Byte(WP,0x80);}//读取当前时间ds1302 ReadTimeFrom1302(){ unsigned char hour,min,sec; ds1302 date; hour = Read_Ds1302_Byte(R_HOUR); min = Read_Ds1302_Byte(R_MIN); sec = Read_Ds1302_Byte(R_SEC); date.hour = hour/16*10 + hour%16; //十六进制转十进制 date.min = min/16*10 + min%16; date.sec = sec/16*10 + sec%16; return date;} 头文件ds1302.h,该文件从今年开始官方不提供,都是自己写
#ifndef __DS1302_H__#define __DS1302_H__#include "intrins.h"#include #define SCK P17#define SDA P23#define RST P13//定义ds1302数据类型typedef struct{ unsigned char hour; unsigned char min; unsigned char sec;}ds1302;ds1302 ReadTimeFrom1302();void WriteDateTo1302(ds1302 *date);#endif 3.3 iic.c
用于读取pcf8591通道1的电压
/*# I2C代码片段说明1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题中对单片机时钟频率的要求,进行代码调试和修改。*/#include "iic.h"#include "intrins.h"#define DELAY_TIME5//static void I2C_Delay(unsigned char n){ do { _nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_(); } while(n--); }//void I2CStart(void){ sda = 1; scl = 1;I2C_Delay(DELAY_TIME); sda = 0;I2C_Delay(DELAY_TIME); scl = 0; }//void I2CStop(void){ sda = 0; scl = 1;I2C_Delay(DELAY_TIME); sda = 1;I2C_Delay(DELAY_TIME);}//void I2CSendByte(unsigned char byt){ unsigned char i; for(i=0; i h[i-1]) L6_flag = 1; //温湿度都大于上次,触发LED6 else L6_flag = 0;}else L6_flag = 0; i++; if(i>3) i = 0; last_hour = date.hour, last_min = date.min; if(temp > t_para) L4_flag = 1; //采集温度大于温度参数,触发LED4 else L4_flag = 0; } key_board(); //按键检测函数 show_switch(); //所有显示放在此函数内,为了使按键按下,不影响显示内容 }}void show_switch(){ unsigned char t_max,h_max;int t_avr,h_avr; date = ReadTimeFrom1302(); temp = rd_temperature(); t_max = max(t), h_max = max(h); t_avr = (t[0]+t[1]+t[2])/3.0 * 10; h_avr = (h[0]+h[1]+h[2])/3.0 * 10;if(show != 1){ if(show_switching == 1){ //时间显示界面 DisplaySeg(1,date.hour/10); DisplaySeg(2,date.hour%10); DisplaySeg(3,16); DisplaySeg(4,date.min/10); DisplaySeg(5,date.min%10); DisplaySeg(6,16); DisplaySeg(7,date.sec/10); DisplaySeg(8,date.sec%10);}if(show_switching == 2){ //回显界面,默认温度回显C switch(S5_flag){ // 温度回显C, 湿度回显H,时间回显F case 1: DisplaySeg(1,12); if(count_triggle != 0){ DisplaySeg(3,t_max/10); DisplaySeg(4,t_max%10); //最大温度DisplaySeg(5,16); DisplaySeg(6,t_avr/100); DisplaySeg_f(7,t_avr%100/10); DisplaySeg(8,t_avr%10);}break; case 2: DisplaySeg(1,17); if(count_triggle != 0){DisplaySeg(3,h_max/10); DisplaySeg(4,h_max%10); //最大湿度DisplaySeg(5,16); DisplaySeg(6,h_avr/100); DisplaySeg_f(7,h_avr%100/10); DisplaySeg(8,h_avr%10);}break; case 3: DisplaySeg(1,15); DisplaySeg(2,count_triggle/10); DisplaySeg(3,count_triggle%10);//触发次数if(count_triggle != 0){ DisplaySeg(4,last_hour/10); DisplaySeg(5,last_hour%10); //上一次触发的时间 DisplaySeg(6,16); DisplaySeg(7,last_min/10); DisplaySeg(8,last_min%10);} break; }}if(show_switching == 3){ //参数设置界面 DisplaySeg(1,18); DisplaySeg(7,t_para/10); DisplaySeg(8,t_para%10);}}else{ //温湿度显示界面,每次显示3S后自动推出 DisplaySeg(1,14); // E DisplaySeg(4,temp/10); DisplaySeg(5,temp%10); DisplaySeg(6,16); //温度 if(humidity != 0) { DisplaySeg(7,humidity/10); DisplaySeg(8,humidity%10); //湿度 }else{ DisplaySeg(7,19); DisplaySeg(8,19); }}// LED 显示switch(show_switching){case 1: DisplayLed(1,1);DisplayLed(2,0);DisplayLed(3,0); break;case 2: DisplayLed(2,1);DisplayLed(1,0);DisplayLed(3,0); break;case 3: DisplayLed(3,1);DisplayLed(1,0);DisplayLed(2,0); break;}if(L4_flag == 1){ if(flag_100ms) DisplayLed(4,1); //L4亮 else DisplayLed(4,0); //L4灭}else{ DisplayLed(4,0);}if(L5_flag == 1){ DisplayLed(5,1); //L5亮}else{ DisplayLed(5,0);//L5灭} if(L6_flag == 1){ DisplayLed(6,1); //L6亮}else{ DisplayLed(6,0); //L6灭}}void key_board(){ unsigned char key; P44 = 0, P42 = 1; P3 |= 0x0f; key = P3; key = key & 0x0c; if(key != 0x0c){ Delayms(5); if(key != 0x0c){ switch(key){case 0x04: key_val = 4; show_switching++; //每次进入回显界面默认是温度回显 if(show_switching > 3) { show_switching = 1 ; S5_flag = 1; } break; case 0x08: key_val = 5; if(show_switching == 2) S5_flag++; if(S5_flag > 3) S5_flag = 1; break;} }while(key != 0x0c){ key = P3; key = key & 0x0c; show_switch();} } //第二列按键 P44 = 1, P42 = 0; P3 |= 0x0f; key = P3; key = key & 0x0c; if(key != 0x0c){ Delayms(5); if(key != 0x0c){ // S8++, S9-- switch(key){case 0x04: key_val = 8; if(show_switching == 3) t_para++; if(t_para > 99) t_para = 0; break; case 0x08: key_val = 9; if(show_switching == 3) t_para--; if(t_para == 255) t_para = 99; break;}if(S5_flag == 3) { count3 = 0, count_sec = 0;} //时间回显下,S9按下2秒计时开始 }while(key != 0x0c){ key = P3; key = key & 0x0c; show_switch(); if(count_sec >= 2 && S5_flag == 3) { //时间回显界面,长按S9两秒,数据清零 memset(t,0,sizeof(t)), memset(h,0,sizeof(h)); count_triggle = 0;}} }}void Timer0Init(void)//@12.000MHz{AUXR &= 0x7F;//定时器时钟12T模式TMOD &= 0xF0;//设置定时器模式TMOD |= 0x04;TL0 = 0;//设置定时初值TH0 = 0;//设置定时初值TF0 = 0;//清除TF0标志ET0 = 1;TR0 = 1;//定时器0开始计时}void Timer1Init(void)//10毫秒@12.000MHz{AUXR &= 0xBF;//定时器时钟12T模式TMOD &= 0x0F;//设置定时器模式TL1 = 0xF0;//设置定时初值TH1 = 0xD8;//设置定时初值TF1 = 0;//清除TF1标志TR1 = 1;//定时器1开始计时ET1 = 1;EA = 1;}void Timer1() interrupt 3{ count++; count3++; if(count == 100){ count = 0; flag_1s = 1; } if(count %10 == 0){ flag_100ms = ~flag_100ms; } if(flag_1s == 1){flag_1s = 0; TR0 = 0;FREQUENTCY = TH0*256 + TL0 ;TH0 = 0, TL0 = 0; TR0 = 1; } if(count3 == 100) { count3 = 0; count_sec++; }}void Timer2Init(void)//20毫秒@12.000MHz{AUXR &= 0xFB;//定时器时钟12T模式T2L = 0xE0;//设置定时初值T2H = 0xB1;//设置定时初值//AUXR |= 0x10;//定时器2开始计时AUXR &= 0xef;IE2 |= 0x04;}void Timer2() interrupt 12{ count2++; if(count2 == 50){ count2 = 0; sec++; if(sec == 3){ sec = 0; show = 0; AUXR &= 0xef; //停止定时器2 } } }//求数组的最大值,这里数组大小固定为3unsigned char max(unsigned char str[]){ unsigned char Max = str[0] , i; for(i=1;i Max) Max = str[i] ; } return Max;} 3.6 环境配置
keil5 创建工程,选择芯片型号STC15F2K60S2,将上述.c文件都添加在Source Group 1下进行编译
编译成功后,0错误,0警告
第14届完整工程代码:
第14届蓝桥杯省赛程序设计题源码,第14届驱动代码和以往相比发生了一些改变,需要注意,只给除了c文件,头文件需要自己手写资源-CSDN文库
4. 历年蓝桥杯单片机试题和答案
需要历年程序题客观题试题和答案,可在咸鱼购买,另外需要程序指导也可私信
闲鱼】https://m.tb.cn/h.UFji1l1?tk=hM4BdnfMkVP CZ0001 「我在闲鱼发布了【蓝桥杯各模块程序驱动代码,历年试题答案,程序无bug。如需程】」
点击链接直接打开
https://m.tb.cn/h.UFji1l1?tk=hM4BdnfMkVP CZ0001