• 售前

  • 售后

热门帖子
入门百科

备战蓝桥杯(2)——第七届蓝桥杯嵌入式省赛赛题实战

[复制链接]
心醉的斜阳呈 显示全部楼层 发表于 2022-1-15 21:02:25 |阅读模式 打印 上一主题 下一主题
文章目次




一、第七届蓝桥杯嵌入式省赛赛题展示

第七届省赛赛题第一遍看完以后就有了大抵的思绪,标题难度不大,很适当练手熟悉熟悉板子。


三、设置所需外设

着实这个在读完赛题以后根本上就确定完了,都是一些常用的外设,比方GPIO,串口,ADC什么的。这里我还是上一个CUBEMX的设置图。

这个设置是很简朴的,只必要设置好串口和ADC,外加几个IO口就搞定了,看着板子的手册设置对应引脚即可。必要留意要把串口克制打开。
四、步伐编写

这里我按照标题的各个要求的序次来举行编程。我给出的都是重要代码,整个工程文件的下载链接在文末给出。
1、液位检测

液位丈量着实就是根据ADC的值来乘K值算出液位高度,同时要求ADC的值有滤波的过程。K值我信任大多数人都会算,就是100/3.3=30.303。滤波算法我用的是最最偷懒最最方便的求均匀值,10个数据一组,求均匀值就算滤波了(尚有其他许多更好的滤波算法,只是我太懒了),同时将处置惩罚玩的ADC的值生存两位小数,否则出来的液面高度会不稳固。液面品级就是比巨细,这里不多说了。
代码如下
  1. adc=get_ADC_av()*3.3/4096;//求ADC的值
  2.       adc = change_2(adc);//保留两位小时
  3.       height=adc*k;//计算液面高度
  4.       sprintf((char *)str,"   ADC:%.2f",adc);
  5.       LCD_DisplayStringLine(Line4,str);
  6.       sprintf((char *)str1,"   Height:%.2f",height);
  7.       LCD_DisplayStringLine(Line2,str1);
  8.       
  9.       if(height<=h1)
  10.       {
  11.           LCD_DisplayStringLine(Line6,"   Level:0");
  12.           l=0;//l表示液面高度等级
  13.       }
  14.       if(height<=h2 && height >h1)
  15.       {
  16.           LCD_DisplayStringLine(Line6,"   Level:1");
  17.           l=1;
  18.       }
  19.       if(height<=h3 && height>h2)
  20.       {
  21.           LCD_DisplayStringLine(Line6,"   Level:2");
  22.           l=2;
  23.       }
  24.       if(height>h3)
  25.       {
  26.           LCD_DisplayStringLine(Line6,"   Level:3");
  27.           l=3;
  28.       }
  29. uint16_t get_ADC(void)
  30. {
  31.     uint16_t adc_data;
  32.     HAL_ADC_Start(&hadc2);
  33.     adc_data=HAL_ADC_GetValue(&hadc2);
  34.     return adc_data;
  35. }
  36. uint16_t get_ADC_av(void)//取十个ADC的值并且求其平均值
  37. {
  38.     int t=0;
  39.     uint16_t data=0;
  40.     while(t++!=10)
  41.     {
  42.         data = data+get_ADC();
  43.     }
  44.     data = data/10;
  45.     return data;
  46. }
  47. float change_2(float num)//将ADC的值变成两位小数
  48. {
  49.     int temp;
  50.     temp = (int)(num*100);
  51.     num = (float)(temp/100.0);
  52.     return num;
  53. }
复制代码
2、液位阈值设定

阈值设定,只需设置三个变量就行,难点就是处置惩罚按键之间的逻辑关系。在修改完以后要将阈值写入E2PROM中,同时在步伐进入循环前先读一次E2PROM的数据。这里要留意:==** 数据写入E2PROM后要耽误一会才可以在写入下一条数据,这是由于I2C通讯有应答时间。 **==时间不消太长,我这里给的是10毫秒。
代码如下
  1.   h1_e = x24c02_read(0);//向E2PROM读数据
  2.   HAL_Delay(10);
  3.   h2_e = x24c02_read(1);
  4.   HAL_Delay(10);
  5.   h3_e = x24c02_read(2);
  6.   h1 = (int)h1_e;
  7.   h2 = (int)h2_e;
  8.   h3 = (int)h3_e;
  9. int count=0;
  10.     if(HAL_GPIO_ReadPin(SETTING_GPIO_Port,SETTING_Pin)==0)//判断B2是否按下
  11.     {
  12.         HAL_Delay(50);///消抖
  13.         if(HAL_GPIO_ReadPin(SETTING_GPIO_Port,SETTING_Pin)==0)
  14.         {
  15.             HAL_Delay(500);//防止按久了跳回去
  16.             LCD_Clear(White);
  17.             LCD_DisplayStringLine(Line0,"    Parameter Setup");
  18.             LCD_SetTextColor(Green);
  19.             LCD_DisplayStringLine(Line2,"   Threshold1:10cm");
  20.             LCD_SetTextColor(Black);
  21.             LCD_DisplayStringLine(Line4,"   Threshold2:25cm");
  22.             LCD_DisplayStringLine(Line6,"   Threshold3:30cm");
  23.             while(HAL_GPIO_ReadPin(SETTING_GPIO_Port,SETTING_Pin)==1)//如果B2按下,就返回测量界面
  24.             {
  25.                 if(HAL_GPIO_ReadPin(CHANGE_GPIO_Port,CHANGE_Pin)==0)//判断B3是否按下
  26.                 {
  27.                     HAL_Delay(100);
  28.                     if(HAL_GPIO_ReadPin(CHANGE_GPIO_Port,CHANGE_Pin)==0)
  29.                     {
  30.                         count = count + 1;
  31.                         if(count == 3)
  32.                         {
  33.                             count = 0;
  34.                         }
  35.                     }
  36.                     
  37.                 }
  38.                 if(count == 0)
  39.                 {
  40.                     LCD_SetTextColor(Green);
  41.                     LCD_DisplayStringLine(Line2,str2);
  42.                     LCD_SetTextColor(Black);
  43.                     LCD_DisplayStringLine(Line4,str3);
  44.                     LCD_DisplayStringLine(Line6,str4);                    
  45.                 }
  46.                 if(count == 1)
  47.                 {
  48.                     LCD_SetTextColor(Black);
  49.                     LCD_DisplayStringLine(Line2,str2);
  50.                     LCD_SetTextColor(Green);
  51.                     LCD_DisplayStringLine(Line4,str3);
  52.                     LCD_SetTextColor(Black);
  53.                     LCD_DisplayStringLine(Line6,str4);                    
  54.                 }
  55.                 if(count == 2)
  56.                 {
  57.                     LCD_SetTextColor(Black);
  58.                     LCD_DisplayStringLine(Line2,str2);
  59.                     LCD_DisplayStringLine(Line4,str3);
  60.                     LCD_SetTextColor(Green);
  61.                     LCD_DisplayStringLine(Line6,str4);                    
  62.                 }
  63.                 if(HAL_GPIO_ReadPin(UP_GPIO_Port,UP_Pin)==0)
  64.                 {
  65.                     HAL_Delay(100);
  66.                     if(HAL_GPIO_ReadPin(UP_GPIO_Port,UP_Pin)==0)
  67.                     {
  68.                         if(count == 0)
  69.                         {
  70.                             h1 = h1+5;
  71.                         }
  72.                         if(count == 1)
  73.                         {
  74.                             h2 = h2+5;
  75.                         }
  76.                         if(count == 2)
  77.                         {
  78.                             h3 = h3+5;
  79.                         }
  80.                     }
  81.                 }
  82.                 if(HAL_GPIO_ReadPin(DOWN_GPIO_Port,DOWN_Pin)==0)//判断B4是否按下
  83.                 {
  84.                     HAL_Delay(100);
  85.                     if(HAL_GPIO_ReadPin(DOWN_GPIO_Port,DOWN_Pin)==0)
  86.                     {
  87.                         if(count == 0)
  88.                         {
  89.                             h1 = h1-5;
  90.                         }
  91.                         if(count == 1)
  92.                         {
  93.                             h2 = h2-5;
  94.                         }
  95.                         if(count == 2)
  96.                         {
  97.                             h3 = h3-5;
  98.                         }
  99.                     x24c02_write(0,(uint8_t)h1);//将阈值数据写入E2PROM中
  100.                     HAL_Delay(10);
  101.                     x24c02_write(1,(uint8_t)h2);
  102.                     HAL_Delay(10);
  103.                     x24c02_write(2,(uint8_t)h3);                        
  104.                     }
  105.                 }
  106.                 sprintf((char *)str2,"   Threshold1:%dcm",h1);
  107.                 sprintf((char *)str3,"   Threshold2:%dcm",h2);
  108.                 sprintf((char *)str4,"   Threshold3:%dcm",h3);
  109.             }
  110.             LCD_Clear(White);
  111.             LCD_SetTextColor(Black);
  112.             LCD_DisplayStringLine(Line0,"      Liquid Level");   
  113.             x24c02_write(0,(uint8_t)h1);   
  114.             HAL_Delay(10);
  115.             x24c02_write(1,(uint8_t)h2);
  116.             HAL_Delay(10);
  117.             x24c02_write(2,(uint8_t)h3);
  118.             return ;
  119.         }
  120.     }
复制代码
3、串口查询与输出功能

这个我就不多说了,按要求处置惩罚好逻辑关系就行,直接上代码。
  1. if(l > l_old)//液面等级降低
  2.       {
  3.         sprintf((char *)str7,"A:H%d+L%d+U\r\n",(int)height,l);
  4.         HAL_UART_Transmit(&huart1,str7,sizeof(str7),1000);
  5.         l_old = l;
  6.         l_c=1;//液面变化标志位,用于指示灯
  7.       }
  8.       if(l < l_old)
  9.       {
  10.         sprintf((char *)str8,"A:H%d+L%d+D\r\n",(int)height,l);
  11.         HAL_UART_Transmit(&huart1,str8,sizeof(str8),1000);
  12.         l_old = l;
  13.         l_c=1;
  14.       }
  15.       RX_State();
  16. void RX_State(void)
  17. {
  18.     HAL_UART_Receive_IT(&huart1,rx_buf,1);
  19.     if(rx_buf[0] == 'C')
  20.     {
  21.         sprintf((char *)str5,"C:H%d+L%d\r\n",(int)height,l);
  22.         HAL_UART_Transmit(&huart1,str5,sizeof(str5),1000);
  23.         memset(rx_buf,0,2); //rx_buf清零   
  24.         r_c = 1;//串口接收字符标注位,用于指示灯
  25.     }
  26.     if(rx_buf[0] == 'S')
  27.     {
  28.         sprintf((char *)str6,"S:TL%d+TM%d+TH%d\r\n",h1,h2,h3);
  29.         HAL_UART_Transmit(&huart1,str6,sizeof(str6),1000);
  30.         memset(rx_buf,0,2);
  31.         r_c = 1;        
  32.     }
  33. }
复制代码
4、状态指示

状态指示这边,用的是三个LED灯,这里着实用定时器是很好的,但是这个板子的定时器有点让我蒙,设置好调了好久但是不绝欠好使,看了例程,内里居然用的寄存器写而不是用HAL库写,岂非用了定时器IO口控制要用寄存器写了吗?
由于程度不敷(着实是太懒了),以是我只能用HAL_Delay()来做,处置惩罚好逻辑关系(这里逻辑关系有些复杂,大脑有些过载),但是还是让我磨出来了,上代码。
  1. if(t1 == 20)//用于运行指示灯,闪烁间隔一秒
  2.         {
  3.             HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_SET);
  4.             HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
  5.             HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
  6.             
  7.         }
  8.          if(t1 == 40)//每1秒翻转一次
  9.         {
  10.             HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_RESET);
  11.             HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
  12.             HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
  13.             t1 = 0;
  14.         }
  15.       led_l();//液面变化指示灯
  16.       led_r();//串口接收指示灯
  17.                 HAL_Delay(50);
  18. void led_l(void)
  19. {
  20.     if(l_c == 1)
  21.       {
  22.           t2++;
  23.           if(t2 == 4)//每0.2秒翻转一次
  24.           {
  25.             HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_SET);
  26.             HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
  27.             HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
  28.           }
  29.           if(t2 == 8)
  30.           {
  31.             HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_RESET);
  32.             HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
  33.             HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
  34.             t2 = 0;
  35.             t2_c++;//闪烁计数
  36.           }
  37.           if(t2_c == 5)
  38.           {
  39.               t2_c = 0;
  40.               l_c = 0;
  41.               t2 = 0;
  42.           }
  43.       }
  44. }
  45. void led_r(void)
  46. {
  47.           if(r_c == 1)
  48.       {
  49.           t3++;
  50.           if(t3 == 4)
  51.           {
  52.             HAL_GPIO_WritePin(GPIOC, GPIO_PIN_10, GPIO_PIN_SET);
  53.             HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
  54.             HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
  55.           }
  56.           if(t3 == 8)
  57.           {
  58.             HAL_GPIO_WritePin(GPIOC, GPIO_PIN_10, GPIO_PIN_RESET);
  59.             HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
  60.             HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
  61.             t3 = 0;
  62.             t3_c++;
  63.           }
  64.           if(t3_c == 5)
  65.           {
  66.               t3_c = 0;
  67.               r_c = 0;
  68.               t3 = 0;
  69.           }
  70.       }
  71. }
复制代码
上面的都是重要代码,工程总体文件在文末的链接中给出,有必要的可以下载。
总结

做了第六届和第七届的赛题以后,对于板子也更加熟悉,但是仍然有一些外设没有搞明确(比方定时器,我肯定要把这个定时器整明确的),也算是发现题目,我会在反面进一步地学习这个板子,用惯了祖传的C8T6一下换到这么高级的板子确实有些用不风俗。接下来就是做第八届的赛题了,加油!!
接待各人在下方留言,一起学习,一起进步。
这里再附上我的工程项目链接:第七届蓝桥杯嵌入式省赛赛题步伐

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作