小工具知识网

当前位置: 首页 > 行业知识 > 蓝桥杯单片机第十四届省赛题目和程序答案

行业知识

蓝桥杯单片机第十四届省赛题目和程序答案

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

     

 

 

上一篇:后端链接服务器怎么连接?

下一篇:微信支付宝集成指南,轻松实现WP支付功能与支付宝集成!