一、题目分析
1.本届赛题添加了超声波,由于超声波加入,可能让题难度加大,但逻辑并不是很难,需要注意的是超声波获取的时间,避免与其他冲突,导致数码管闪烁。
2.参数退出界面生效问题,按键在界面切换时生效,保证参数设置状态下,测距功能不受影响。
二、代码
主函数
#include "main.h" void main() { Init_Sys(); Timer2_Init(); while(1) { Task_LED(); Task_Collect(); Task_key(); Task_Seg(); } }
#ifndef __MAIN_H #define __MAIN_H #include <STC15F2K60S2.H> #include "task.h" #include "dsp.h" #include "key.h" #include "chaosheng.h" #include "PCF8591.h" #include "uart.h" #define LED(x) {P0 = x;P2 = (P2 & 0x1f) | 0x80;P2 &= 0x1f;} #define BUZ(x) {P0 = x;P2 = (P2 & 0x1f) | 0xa0;P2 &= 0x1f;} #define COM(x) {P0 = x;P2 = (P2 & 0x1f) | 0xc0;P2 &= 0x1f;} #define SEG(x) {P0 = x;P2 = (P2 & 0x1f) | 0xe0;P2 &= 0x1f;} #endif
任务函数
#include "task.h" unsigned int seg_count=0; unsigned int key_count=0; unsigned int dis_count=0; unsigned int adc_count=0; unsigned int led_count=0; unsigned char ui=1; unsigned char volt_up_can=45; unsigned char volt_down_can=5; unsigned char f_up_can=45; unsigned char f_down_can=5; unsigned int Dis=0; unsigned int ADC=0; unsigned char DAC=0; unsigned char LED_state=0xff; unsigned char uart[8]={0}; bit can_state=0; bit f_led=0; void Timer2_Init(void) //1毫秒@12.000MHz { AUXR |= 0x04; //定时器时钟1T模式 T2L = 0x20; //设置定时初始值 T2H = 0xD1; //设置定时初始值 AUXR |= 0x10; //定时器2开始计时 IE2 |= 0x04; //使能定时器2中断 EA = 1; } void Init_Sys() { LED(0xff); BUZ(0x00); Init_Dsp(); Init_key(); Uart1_Init(); } void Timer2_Isr(void) interrupt 12 { GetDisplayStruct()->SegDisplay(); if(key_count < 10) key_count++; if(seg_count < 50) seg_count++; if(led_count < 100) led_count++; if(adc_count < 150) adc_count++; if(dis_count < 200) dis_count++; } void Task_LED() { if(led_count >= 100) { led_count=0; if(ui == 1) { LED_state &= ~0x01; LED_state |= 0x02; LED_state |= 0x04; } else if(ui == 2) { LED_state &= ~0x02; LED_state |= 0x01; LED_state |= 0x04; } else if(ui == 3) { LED_state &= ~0x04; LED_state |= 0x02; LED_state |= 0x01; } if((ADC < volt_up_can * 10) && (ADC > volt_down_can * 10)) { if((LED_state & 0x80) == 0x80) { LED_state &= ~0x80; } else LED_state |= 0x80; } else LED_state |= 0x80; LED(LED_state); } } void Task_Collect() { if(dis_count >= 200) { dis_count = 0; if((ADC < volt_up_can * 10) && (ADC > volt_down_can * 10)) Dis = GetDis(); else Dis = 999; sprintf(uart,"%d\r\n",Dis); Send_String(uart); } if(adc_count >= 150) { adc_count = 0; ADC = (unsigned int)(PCF8591_ADC() * 500.0 / 255); if(Dis <= 20)PCF8591_DAC(61); else if(Dis >= 80)PCF8591_DAC(255); else { DAC = (unsigned char)(((255 - 61) / 60.0) * (Dis - 20) + 61); PCF8591_DAC(DAC); } } } void Task_key() { if(key_count >= 10) { key_count = 0; GetKeyStruct()->pFun(); } switch(GetKeyStruct()->value) { case 4: if(ui == 1)ui = 2; else if(ui == 2)ui = 3; else if(ui == 3)ui = 1; volt_up_can = f_up_can; volt_down_can = f_down_can; GetKeyStruct()->value = 0; break; case 5: if(can_state == 0)can_state=1; else can_state=0; GetKeyStruct()->value = 0; break; case 6: if(can_state == 0)f_up_can+=5; else f_down_can+=5; if(f_up_can > 50)f_up_can=5; if(f_down_can > 50)f_down_can=5; GetKeyStruct()->value = 0; break; case 7: if(can_state == 0)f_up_can-=5; else f_down_can-=5; if(f_up_can < 5)f_up_can=50; if(f_down_can < 5)f_down_can=50; GetKeyStruct()->value = 0; break; } } void Task_Seg() { DisplayStruct* seg = GetDisplayStruct(); if(seg_count < 50) return; seg_count=0; if(ui == 1) { seg->dot[0] = 5; seg->dot[1] = 10; seg->buf[0] = 11; seg->buf[1] = 10; seg->buf[2] = 10; seg->buf[3] = 10; seg->buf[4] = 10; seg->buf[5] = ADC / 100 % 10; seg->buf[6] = ADC / 10 % 10; seg->buf[7] = ADC % 10; } if(ui == 2) { seg->dot[0] = 3; seg->dot[1] = 6; seg->buf[0] = 12; seg->buf[1] = 10; seg->buf[2] = 10; seg->buf[3] = f_up_can / 10 % 10; seg->buf[4] = f_up_can % 10; seg->buf[5] = 10; seg->buf[6] = f_down_can / 10 % 10; seg->buf[7] = f_down_can % 10; } if(ui == 3) { seg->dot[0] = 10; seg->dot[1] = 10; seg->buf[0] = 13; seg->buf[1] = 10; seg->buf[2] = 10; seg->buf[3] = 10; seg->buf[4] = 10; if(Dis != 999) { seg->buf[5] = (Dis > 99)?(Dis / 100 % 10):(10); seg->buf[6] = (Dis > 9)?(Dis / 10 % 10):(10); seg->buf[7] = Dis % 10; } else { seg->buf[5] = 14; seg->buf[6] = 14; seg->buf[7] = 14; } } }
超声波(采用PCA模块)
#include "chaosheng.h" sbit TX = P1^0; sbit RX = P1^1; void Delay12us(void) //@12.000MHz { unsigned char data i; _nop_(); _nop_(); i = 33; while (--i); } void Send_40KHz() { unsigned char i=8; while(i--) { TX = 1; Delay12us(); TX = 0; Delay12us(); } } unsigned int GetDis() { unsigned int t; CMOD = 0x00; CH = CL = 0; Send_40KHz(); CR = 1; while((CF == 0) && (RX == 1)); CR = 0; if(CF == 1) { CF = 0; return 0; } else { t = (CH << 8) | CL; return (unsigned int)(t * 0.0172); } }
附上所有代码链接,大家可以参考学习。
蓝桥杯单片机十三届第二次https://gitcode.com/fsm_csdn/lanqiao13-2