一、任务代码分析
开机后,屏幕第一行显示“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)设计4×4矩阵键盘输入,能够设置限定值报警功能,并实现声、光报警。
代码分析:我们先判断输入的两个值我们固定第一个为最大值,第二个为最小值。用两个变量接收。不断判断滑动变阻模拟输入值是否在范围内。在蜂鸣器响,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;
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/37780.html