当前位置:   article > 正文

2018年安徽省机器人大赛单片机与嵌入式系统应用技能竞赛试题(2)_安徽省单片机与嵌入式大赛答案

安徽省单片机与嵌入式大赛答案

一、任务代码分析

        开机后,屏幕第一行显示“DCFZBJQ”,第二行显示“抽签号后4位”(如0207),并自下而上滚动,3秒后停止滚动。

        代码分析:普通显示函数显示对应数据,滚动效果用清屏函数实现。三秒用延时函数控制。所以得到代码。 

  1. void runshow(void)
  2. {
  3. u8 i=0;
  4. u32 show=290;
  5. for(i=0;i<6;i++)
  6. {
  7. LCD_Clear(WHITE );
  8. LCD_ShowString(180,(show-20),200,16,16,"DCFZBGQ");
  9. LCD_ShowString(180,show,200,16,16,"0207");
  10. show-=30;
  11. delay_ms(500);
  12. }
  13. }

二、基本功能要求代码分析

1应用超声波传感器实现距离采集,并在12864点阵屏上显示。利用实验桌面到房顶距离(2.65米)进行校准。 

代码分析:这个就是简单利用超声波测距模块进行测距。在其他章节我有代码具体分析。

  1. float Distance;
  2. void Wave_SRD_Init(void)
  3. {
  4. GPIO_InitTypeDef GPIO_InitSture;
  5. EXTI_InitTypeDef EXTI_InitSture;
  6. NVIC_InitTypeDef NVIC_InitSture;
  7. //如果外部中断的话则一定使能AFIO复用功能
  8. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOF,ENABLE);
  9. //配置IO端口
  10. GPIO_InitSture.GPIO_Mode=GPIO_Mode_Out_PP; //推挽输出模式 //-->PB9
  11. GPIO_InitSture.GPIO_Pin=Trig; //将PE4于Trig相连
  12. GPIO_InitSture.GPIO_Speed=GPIO_Speed_50MHz;
  13. GPIO_Init(GPIOB,&GPIO_InitSture);
  14. GPIO_InitSture.GPIO_Mode=GPIO_Mode_IPD; //拉输入模式 //-->PF8
  15. GPIO_InitSture.GPIO_Pin=Echo; //将PE6于Echo相连
  16. GPIO_InitSture.GPIO_Speed=GPIO_Speed_50MHz;
  17. GPIO_Init(GPIOF,&GPIO_InitSture);
  18. //中断和8端口映射一起 //-->PF8
  19. GPIO_EXTILineConfig(GPIO_PortSourceGPIOF,GPIO_PinSource8);
  20. //外部中断配置
  21. EXTI_InitSture.EXTI_Line=EXTI_Line8;
  22. EXTI_InitSture.EXTI_LineCmd=ENABLE;
  23. EXTI_InitSture.EXTI_Mode=EXTI_Mode_Interrupt;
  24. EXTI_InitSture.EXTI_Trigger=EXTI_Trigger_Rising;
  25. EXTI_Init(&EXTI_InitSture);
  26. //中断优先级管理
  27. NVIC_InitSture.NVIC_IRQChannel=EXTI9_5_IRQn;
  28. NVIC_InitSture.NVIC_IRQChannelCmd=ENABLE;
  29. NVIC_InitSture.NVIC_IRQChannelPreemptionPriority=2;
  30. NVIC_InitSture.NVIC_IRQChannelSubPriority=2;
  31. NVIC_Init(&NVIC_InitSture);
  32. }
  33. void EXTI9_5_IRQHandler(void)
  34. {
  35. delay_us(10);
  36. if(EXTI_GetITStatus(EXTI_Line8)!=RESET)
  37. {
  38. TIM_SetCounter(TIM3,0);
  39. TIM_Cmd(TIM3,ENABLE);
  40. while(GPIO_ReadInputDataBit(GPIOF,Echo)); //等待低电平
  41. TIM_Cmd(TIM3,DISABLE);
  42. Distance=TIM_GetCounter(TIM3)*340/200.0;
  43. if(Distance>0)
  44. {
  45. printf("Distance:%f cm\r\n",Distance);
  46. LCD_ShowxNum(180,160,Distance,3,16,0);
  47. if(Distance>500)
  48. LCD_ShowxNum(180,160,2,3,16,0);
  49. }
  50. EXTI_ClearITPendingBit(EXTI_Line8);
  51. }
  52. }
  53. void Wave_SRD_Strat(void)
  54. {
  55. GPIO_SetBits(GPIOB,Trig); //将Trig设置为高电平
  56. delay_us(20); //持续大于10us触发,触发超声波模块工作
  57. GPIO_ResetBits(GPIOB,Trig);
  58. }
  59. //----------------------------------------------------------------
  60. s=Distance;LCD_ShowxNum(220,200,s2,3,16,0);//主函数

2  能够实现显示有效最远值、最近值存储、查阅和清除。

代码分析:定义两个变量,第一个存储最远值,第二个存储最近值。不断和超声波模块测距值对比更新数据。当按键5按下则显示最远最近值,当按键6按下两个变量赋值为0。并清屏。

最好是利用eeprom,存储。因为它掉电后依旧不会消失。时间原因当时用的变量。

  1. int smax=0
  2. int smin=300;
  3. s=Distance;
  4. if(s>smax)
  5. smax=s;
  6. if(s<smin)
  7. smin=s;
  8. e= keyhandle();
  9. if(e=5)
  10. {
  11. LCD_ShowxNum(220,200,smin,3,16,0);
  12. LCD_ShowxNum(220,220,smax,3,16,0);
  13. }
  14. if(e=6)
  15. {
  16. smin=smax=0
  17. LCD_Clear(WHITE );
  18. }

3能够按键记录当前距离值,能计算两次按键所记录距离间的速度并显示。(见说明)

代码分析:当第一个按键按下时我们将超声波测距返回值赋值给第一个变量,并利用定时器开始计时。第二个按键按下时我们将超声波测距返回值赋值给第二个变量,并利用定时器结束计时。将所得的数值进行计算即可。

  1. int s1,s2,s3;
  2. e= keyhandle();
  3. if(e=8)
  4. {
  5. s1=Distance;
  6. TIM_Cmd(TIM2,ENABLE);
  7. }
  8. if(e=9)
  9. {
  10. s2=Distance;
  11. TIM_Cmd(TIM2,DISABLE);
  12. time=TIM_GetCounter(TIM2);
  13. if(s1>=s2)
  14. s3=s1-s2;
  15. else
  16. s3=s2-s1
  17. v=s3/(time*100);
  18. }

三、发挥要求

(1)应用可变电阻通过A/D(10位)输入3位半数值(保留2位小数),模拟超声波传感器输入0-10米。

代码分析:利用A/D数模转换得到一个值。理论值是0-4095,我们将得到的值除以4095再*10就转换到0-10。我们将数据类型设置位float。将所得到的值乘一百分别求余就得到了整数小数位。再显示即可。

  1. adcx=Get_Adc_Average(ADC_Channel_8,10);
  2. adcx=(adcx/4096)*100;
  3. d = adcx / 1 % 10;
  4. c =adcx / 10 % 10;
  5. b =adcx / 100 % 10;
  6. LCD_ShowxNum(180,240,b,2,16,0);
  7. LCD_ShowString(200,240,12,16,16,".");
  8. LCD_ShowxNum(210,240,c,1,16,0);
  9. LCD_ShowxNum(220,240,d,1,16,0);

(2)设计4x4矩阵键盘输入,能够设置限定值报警功能,并实现声、光报警。

代码分析:我们先判断输入的两个值我们固定第一个为最大值,第二个为最小值。用两个变量接收。不断判断滑动变阻模拟输入值是否在范围内。在蜂鸣器响,LED灯闪。

  1. e= keyhandle();
  2. while(1)
  3. {
  4. f= keyhandle();
  5. if(f!=0&&g==0)
  6. {
  7. LCD_ShowNum(212,200,f,2,16);
  8. g=f;
  9. }
  10. adcx=Get_Adc_Average(ADC_Channel_8,10);
  11. LED0=0;
  12. BEEP=1;
  13. adcx=Get_Adc_Average(ADC_Channel_8,10);
  14. adcx=(adcx/4096)*100;
  15. d = adcx / 1 % 10;
  16. c =adcx / 10 % 10;
  17. b =adcx / 100 % 10;
  18. if(d>(e*10))
  19. {
  20. if(d<(g))
  21. {LED0=~LED0; BEEP=0;}

(3)模拟输入值>1.2米时,输出控制电动机正转,并实现数值越大转速越快, 数值越小转速越慢,并显示速度;<0.9米时,电机反转,<0.5米报警。

代码分析:和(2)原理一样,测速用红外对管。

  1. if(adcx>120)
  2. {
  3. int i;
  4. i=1000-c;
  5. count = 0 ;
  6. timer_count = 0 ; //电机正转
  7. stepper(Pos,i); //间隔最少是5ms
  8. while(1)
  9. {
  10. if(timer_count > 0)
  11. {
  12. count_temp = count;
  13. count = 0;
  14. timer_count = 0;
  15. LCD_ShowNum(78,170,count_temp,4,16); //当前显示的为 1s内转的格数
  16. count_temp = 0 ;
  17. }
  18. }
  19. }
  20. }
  21. if(adcx<90)
  22. {
  23. stepper(Neg,8);
  24. }
  25. if(adcx<50)
  26. {
  27. LED0=~LED0;
  28. }

 (4)按键实现日期时间显示功能(使用单片机定时器实现)。

 代码分析:用RTC显示。

  1. u8 t=0;
  2. time1=a;
  3. LCD_Clear(WHITE );
  4. while(time1==3)
  5. if(t!=calendar.sec)
  6. {
  7. t=calendar.sec;
  8. LCD_ShowString(140,130,200,16,16," - - ");
  9. LCD_ShowString(140,168,200,16,16," : : ");
  10. LCD_ShowNum(140,130,calendar.w_year,4,16);
  11. LCD_ShowNum(180,130,calendar.w_month,2,16);
  12. LCD_ShowNum(204,130,calendar.w_date,2,16);
  13. switch(calendar.week)
  14. {
  15. case 0:
  16. LCD_ShowString(140,148,200,16,16,"Sunday ");
  17. break;
  18. case 1:
  19. LCD_ShowString(140,148,200,16,16,"Monday ");
  20. break;
  21. case 2:
  22. LCD_ShowString(140,148,200,16,16,"Tuesday ");
  23. break;
  24. case 3:
  25. LCD_ShowString(140,148,200,16,16,"Wednesday");
  26. break;
  27. case 4:
  28. LCD_ShowString(140,148,200,16,16,"Thursday ");
  29. break;
  30. case 5:
  31. LCD_ShowString(140,148,200,16,16,"Friday ");
  32. break;
  33. case 6:
  34. LCD_ShowString(140,148,200,16,16,"Saturday ");
  35. break;
  36. }
  37. LCD_ShowNum(140,168,calendar.hour,2,16);
  38. LCD_ShowNum(164,168,calendar.min,2,16);
  39. LCD_ShowNum(188,168,calendar.sec,2,16);

(5)按键返回

代码分析:按键判断确定按下利用goto语句返回到菜单处。

  1. x=keyhandle();
  2. if(x==16)
  3. goto jump;

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/448719
推荐阅读
相关标签
  

闽ICP备14008679号