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

一、任务代码分析

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

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

void runshow(void)
{
	u8 i=0;	
	u32 show=290;
	for(i=0;i<6;i++)
{
	LCD_Clear(WHITE );
	LCD_ShowString(180,(show-20),200,16,16,"DCFZBGQ");	
	LCD_ShowString(180,show,200,16,16,"0207");
	
	show-=30;
	delay_ms(500);
}	


}

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

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

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

float Distance;


void Wave_SRD_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitSture;
	EXTI_InitTypeDef  EXTI_InitSture;
	NVIC_InitTypeDef  NVIC_InitSture;
	//如果外部中断的话则一定使能AFIO复用功能
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOF,ENABLE);
	
	
	//配置IO端口
	GPIO_InitSture.GPIO_Mode=GPIO_Mode_Out_PP;   //推挽输出模式  //-->PB9
	GPIO_InitSture.GPIO_Pin=Trig;                //将PE4于Trig相连
	GPIO_InitSture.GPIO_Speed=GPIO_Speed_50MHz;  
	GPIO_Init(GPIOB,&GPIO_InitSture);
	
	GPIO_InitSture.GPIO_Mode=GPIO_Mode_IPD;      //拉输入模式   //-->PF8
	GPIO_InitSture.GPIO_Pin=Echo;                //将PE6于Echo相连
	GPIO_InitSture.GPIO_Speed=GPIO_Speed_50MHz;  
	GPIO_Init(GPIOF,&GPIO_InitSture);
	
	
	
	//中断和8端口映射一起			//-->PF8
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOF,GPIO_PinSource8);	
	
	
	//外部中断配置
	EXTI_InitSture.EXTI_Line=EXTI_Line8;
	EXTI_InitSture.EXTI_LineCmd=ENABLE;
	EXTI_InitSture.EXTI_Mode=EXTI_Mode_Interrupt;
	EXTI_InitSture.EXTI_Trigger=EXTI_Trigger_Rising;
	EXTI_Init(&EXTI_InitSture);
	
	
	//中断优先级管理
	NVIC_InitSture.NVIC_IRQChannel=EXTI9_5_IRQn;
	NVIC_InitSture.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitSture.NVIC_IRQChannelPreemptionPriority=2;
	NVIC_InitSture.NVIC_IRQChannelSubPriority=2;
	NVIC_Init(&NVIC_InitSture);
}

void EXTI9_5_IRQHandler(void)
{
	delay_us(10);
	
	
	if(EXTI_GetITStatus(EXTI_Line8)!=RESET)
	{
		TIM_SetCounter(TIM3,0);
		TIM_Cmd(TIM3,ENABLE);
		
		while(GPIO_ReadInputDataBit(GPIOF,Echo));  //等待低电平
		
		TIM_Cmd(TIM3,DISABLE);
		
		Distance=TIM_GetCounter(TIM3)*340/200.0;
		
		if(Distance>0)
		{
			printf("Distance:%f cm\r\n",Distance);
			LCD_ShowxNum(180,160,Distance,3,16,0);
			if(Distance>500)
			LCD_ShowxNum(180,160,2,3,16,0);	
		}
			
		EXTI_ClearITPendingBit(EXTI_Line8);
	}
}

void Wave_SRD_Strat(void)
{
	GPIO_SetBits(GPIOB,Trig);   //将Trig设置为高电平
	delay_us(20);               //持续大于10us触发,触发超声波模块工作
	GPIO_ResetBits(GPIOB,Trig); 
	
}

//----------------------------------------------------------------
s=Distance;LCD_ShowxNum(220,200,s2,3,16,0);//主函数

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

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

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

int smax=0
int smin=300;
s=Distance;
if(s>smax)
    smax=s;
if(s<smin)
    smin=s;
e= keyhandle(); 
if(e=5)
{
    LCD_ShowxNum(220,200,smin,3,16,0);

     LCD_ShowxNum(220,220,smax,3,16,0);
}
if(e=6)
{
    smin=smax=0
    LCD_Clear(WHITE );
}

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

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

int s1,s2,s3;
e= keyhandle(); 
if(e=8)
{
    s1=Distance;
    TIM_Cmd(TIM2,ENABLE);
}
if(e=9)
{
    s2=Distance;
    TIM_Cmd(TIM2,DISABLE);
    time=TIM_GetCounter(TIM2);
   if(s1>=s2)
    s3=s1-s2;
   else
    s3=s2-s1
   v=s3/(time*100);
}

三、发挥要求

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

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

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

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

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

	e= keyhandle(); 

		while(1)
	{
	    f= keyhandle();
		if(f!=0&&g==0)
		{
													  
			LCD_ShowNum(212,200,f,2,16);
			g=f;
		}
		adcx=Get_Adc_Average(ADC_Channel_8,10);
		LED0=0;
		BEEP=1;
		adcx=Get_Adc_Average(ADC_Channel_8,10);
        adcx=(adcx/4096)*100;
        d = adcx / 1 % 10;
        c =adcx / 10 % 10;
        b =adcx / 100 % 10;
		if(d>(e*10))
		{
		    if(d<(g))	
		{LED0=~LED0; BEEP=0;}

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

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

if(adcx>120)
{
    int i;
	i=1000-c;
	count = 0 ;
	timer_count = 0 ;											     //电机正转
	stepper(Pos,i);    //间隔最少是5ms   
	
	while(1)
	{	
		if(timer_count > 0)
		{	
			count_temp = count;
			count = 0;
			timer_count = 0;	
			
			LCD_ShowNum(78,170,count_temp,4,16);		//当前显示的为 1s内转的格数
			
			count_temp = 0 ;
		}  
	}
 }											
	}
	if(adcx<90)
	{
		stepper(Neg,8); 
	}
	if(adcx<50)
	{
															
		LED0=~LED0;
	}

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

 代码分析:用RTC显示。

u8 t=0;
time1=a;
LCD_Clear(WHITE );
while(time1==3)
if(t!=calendar.sec)
{
	t=calendar.sec;
	LCD_ShowString(140,130,200,16,16,"    -  -  ");	   
	LCD_ShowString(140,168,200,16,16,"  :  :  ");	
	LCD_ShowNum(140,130,calendar.w_year,4,16);									  
    LCD_ShowNum(180,130,calendar.w_month,2,16);									  
	LCD_ShowNum(204,130,calendar.w_date,2,16);	 
	switch(calendar.week)
	{
	case 0:
		LCD_ShowString(140,148,200,16,16,"Sunday   ");
												break;
	case 1:
		LCD_ShowString(140,148,200,16,16,"Monday   ");
												break;
	case 2:
		LCD_ShowString(140,148,200,16,16,"Tuesday  ");
												break;
	case 3:
		LCD_ShowString(140,148,200,16,16,"Wednesday");
												break;
	case 4:
		LCD_ShowString(140,148,200,16,16,"Thursday ");
												break;
	case 5:
		LCD_ShowString(140,148,200,16,16,"Friday   ");
												break;
	case 6:
		LCD_ShowString(140,148,200,16,16,"Saturday ");
												break;  
										}
	LCD_ShowNum(140,168,calendar.hour,2,16);									  
	LCD_ShowNum(164,168,calendar.min,2,16);									  
	LCD_ShowNum(188,168,calendar.sec,2,16);

(5)按键返回

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

	x=keyhandle();
	if(x==16)
	goto jump;

  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式小趴菜学习记录

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值