基于STM32F103的超声波测距+屏幕显示功能(汉字显示)

关于单片机,我用的是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<size;pos++)
        {
        
            temp= hanzi[num][pos];         
            for(t=0;t<size/2;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<size;pos++)
        {        
            temp= hanzi[num][pos];         
            for(t=0;t<size/4;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<size;pos++)
        {
            temp= hanzi[num][pos];
            for(t=0;t<size/4;t++)
            {                 
                if(temp&0x01)LCD_DrawPoint(x+t,y+pos);//????     
                temp>>=1; 
            }
            pos=pos+1;
        }
        for(pos=1;pos<size;pos++)
        {
            temp= hanzi[num][pos];
            for(t=0;t<size/4;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*/

};

 类似于此。

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值