关于单片机,我用的是STM32F103精英版,(系统板也可以)。
超声波就是常用的HC-SR04。原理简单的说一下
基本工作原理:
(1)采用IO口TRIG触发测距,给至少10us的高电平信号;
(2)模块自动发送8个40khz的方波,自动检测是否有信号返回;
(3)有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2;
本模块使用方法简单,一个控制口发一个10US以上的高电平,就可以在接收口等待高电平输出.一有输出就可以开定时器计时,当此口变为低电平时就可以读定时器的值,此时就为此次测距的时间,方可算出距离.如此不断的周期测,即可以达到你移动测量的值
引脚方面:我接的是vcc +,Trig C1口,Echo C2口 gnd -;
接下来就是屏幕的问题。
屏幕原理较为复杂,再次不一一赘述,看看例程源码,清晰易懂。
接下来上一些主要代码片段
超声波:
#include "sr04.h"
float time = 0;
void SR04_Init(void)
{
/* ³õʼ»¯Trip */
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //ʹÄÜPC¶Ë¿ÚʱÖÓ
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //Trip-->PC1¶Ë¿ÚÅäÖÃ
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //ÍÆÍìÊä³ö
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO¿ÚËÙ¶ÈΪ50MHz
GPIO_Init(GPIOC, &GPIO_InitStructure); //¸ù¾ÝÉ趨²ÎÊý³õʼ»¯GPIOC1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //Echo-->PC2¶Ë¿ÚÅäÖÃ
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //ÏÂÀÊäÈë
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO¿ÚËÙ¶ÈΪ50MHz
GPIO_Init(GPIOC, &GPIO_InitStructure); //¸ù¾ÝÉ趨²ÎÊý³õʼ»¯GPIOC2
GPIO_ResetBits(GPIOC,GPIO_Pin_1); //TripÏÈÀµÍ
GPIO_ResetBits(GPIOC,GPIO_Pin_2); //EchoÒ²ÀµÍ
TIM4_Init(65535,71);
}
void TIM4_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //ʹÄܶ¨Ê±Æ÷3ʱÖÓ
//¶¨Ê±Æ÷TIM4³õʼ»¯
TIM_TimeBaseStructure.TIM_Period = arr; //ÉèÖÃÔÚÏÂÒ»¸ö¸üÐÂʼþ×°Èë»î¶¯µÄ×Ô¶¯ÖØ×°ÔؼĴæÆ÷ÖÜÆÚµÄÖµ
TIM_TimeBaseStructure.TIM_Prescaler =psc; //ÉèÖÃÓÃÀ´×÷ΪTIMxʱÖÓƵÂʳýÊýµÄÔ¤·ÖƵֵ
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //ÉèÖÃʱÖÓ·Ö¸î:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIMÏòÉϼÆÊýģʽ
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //¸ù¾ÝÖ¸¶¨µÄ²ÎÊý³õʼ»¯TIMxµÄʱ¼ä»ùÊýµ¥Î»
TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE ); //ʹÄÜÖ¸¶¨µÄTIM4ÖжÏ,ÔÊÐí¸üÐÂÖжÏ
TIM_Cmd(TIM4, DISABLE); //¹Ø±ÕTIMx £¬µ½Ê±ÔÙ¿ª
}
float SR04_Getlen(void)
{
Trip = 1;
delay_us(20);
Trip = 0;
while(Echo == 0)
{
TIM_SetCounter(TIM4,0);
TIM_Cmd(TIM4, DISABLE);
}
while(Echo == 1)
{
TIM_Cmd(TIM4, ENABLE);
}
time = TIM_GetCounter(TIM4);
return time;
}
LCD:
void LCD_ShowString(u16 x,u16 y,u16 width,u16 height,u8 size,u8 *p)
{
u8 x0=x;
width+=x;
height+=y;
while((*p<='~')&&(*p>=' '))//ÅжÏÊDz»ÊÇ·Ç·¨×Ö·û!
{
if(x>=width){x=x0;y+=size;}
if(y>=height)break;//Í˳ö
LCD_ShowChar(x,y,*p,size,0);
x+=size/2;
p++;
}
}
关于汉字显示:我用的是取模的方式,用取模软件来取模,再相应的显示:
代码如下
void LCD_ShowhanziChar(u16 x,u16 y,u8 num,u8 size,u8 mode,u16 color)
{
#if USE_HORIZONTAL==1
#define MAX_CHAR_POSX 312
#define MAX_CHAR_POSY 232
#else
#define MAX_CHAR_POSX 232
#define MAX_CHAR_POSY 312
#endif
u8 temp;
u8 pos,t;
u16 x0=x,y0=y;
u16 x1,y1;
u16 colortemp=color;
if(x>MAX_CHAR_POSX||y>MAX_CHAR_POSY)return;
//????
if(!mode) //?????
{
for(pos=0;pos
{
temp= hanzi[num][pos]; for(t=0;t
{ if(temp&0x01)POINT_COLOR=colortemp; else POINT_COLOR=BACK_COLOR; LCD_DrawPoint(x,y); temp>>=1; x++; } pos=pos+1; x=x0; y++; } x1=x0+8; y1=y0; for(pos=1;pos
{ temp= hanzi[num][pos]; for(t=0;t
{ if(temp&0x01)POINT_COLOR=colortemp; else POINT_COLOR=BACK_COLOR; LCD_DrawPoint(x1,y1); temp>>=1; x1++; } pos=pos+1; x1=x0+8; y1++; }
} else//???? ???... { for(pos=0;pos
{ temp= hanzi[num][pos]; for(t=0;t
{ if(temp&0x01)LCD_DrawPoint(x+t,y+pos);//???? temp>>=1; } pos=pos+1; } for(pos=1;pos
{ temp= hanzi[num][pos]; for(t=0;t
{ if(temp&0x01)LCD_DrawPoint(x+8+t,y+pos);//???? temp>>=1; } pos=pos+1; } } POINT_COLOR=colortemp; } 若有多个汉字,就多取一些字模,多调用一下此函数(数组名要改) const unsigned char hanzi[30][72]={ {0x10,0x02,0x10,0x02,0xD0,0x3F,0x08,0x02,0x08,0x02,0x0C,0x02,0xFC,0x7F,0x0A,0x00,0x09,0x02,0x08,0x02,0xC8,0x3F,0x08,0x02,0x08,0x02,0x08,0x02,0xF8,0x7F,0x08,0x00},/*"?",0*/ }; 类似于此。
|