基于STM32F103的超声波测距,LCD1602显示

目录

一、STM32F103RCT6电路图

二、使用元器件

1.HC-SR04超声波测传感器初始化

2.LCD1602的初始化

总结


 前言

  期末我们开设了感知技术实习,两人一小组,我们组分到的题目为超声波测距。从电路设计到焊板子,检测,再到写程序,收获不少。


一、STM32F103RCT6电路图

 

 单片机电路不由我们设计,我们只需要将响应的元件焊上去就行了。但是看电路图真的很重要(

二、使用元器件

1.HC-SR04超声波测传感器初始化

传感器hc-rs04.c:(库函数是用的正点原子的)


 

#include "delay.h"
#include "sys.h"
#include "usart.h"    
#include "led.h"
#include "key.h"
#include "lcd.h"
#include "hcsr04.h"

#define HCSR04_PORT   GPIOA
#define HCSR04_CLK    RCC_APB2Periph_GPIOA
#define HCSR04_TRIG   GPIO_Pin_3
#define HCSR04_ECHO   GPIO_Pin_2

u16 msHcCount = 0;
void Hcsr04Init(){
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;   
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(HCSR04_CLK, ENABLE);
   
    GPIO_InitStructure.GPIO_Pin =HCSR04_TRIG;     
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);
    GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);
     
    GPIO_InitStructure.GPIO_Pin =   HCSR04_ECHO;    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);  
    GPIO_ResetBits(HCSR04_PORT,HCSR04_ECHO);    
     
       
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);   
     
    TIM_DeInit(TIM2);//1000*72/72000000
    TIM_TimeBaseStructure.TIM_Period = (1000-1); 
    TIM_TimeBaseStructure.TIM_Prescaler =(72-1); 
    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);          
        
    TIM_ClearFlag(TIM4, TIM_FLAG_Update);  
    TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);    
    hcsr04_NVIC();
    TIM_Cmd(TIM4,DISABLE);     
}

static void OpenTimerForHc(){
     TIM_SetCounter(TIM4,0);
   msHcCount = 0;
   TIM_Cmd(TIM4, ENABLE); 

}
static void CloseTimerForHc()    
{
   TIM_Cmd(TIM4, DISABLE); 
}
void hcsr04_NVIC()
{
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
            
    NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;         
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;        
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;       
    NVIC_Init(&NVIC_InitStructure);
}
void TIM4_IRQHandler(void)  
{
   if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)  
   {
       TIM_ClearITPendingBit(TIM4, TIM_IT_Update  ); 
       msHcCount++;
   }
}
u32 GetEchoTimer(void)
{
   u32 t = 0;
   t = msHcCount*1000;
   t += TIM_GetCounter(TIM4);
   TIM4->CNT = 0;  
   delay_ms(50);
   return t;
}
float Hcsr04GetLength(void)
{
   u32 t = 0;
   int i = 0;
   float lengthTemp = 0;
   float sum = 0;
   while(i!=5)
   {
      TRIG_Send = 1;      
      delay_us(20);
      TRIG_Send = 0;
      while(ECHO_Reci == 0);      
      OpenTimerForHc();        
      i = i + 1;
      while(ECHO_Reci == 1);
      CloseTimerForHc();        
      t = GetEchoTimer();        
      lengthTemp = ((float)t/58.0);//cm
      sum = lengthTemp + sum ;
        
    }
    lengthTemp = sum/5.0;
    return lengthTemp;
}

hc-rs04.h:

#ifndef __HC_H
#define __HC_H	
#include "sys.h"



void hcsr04_NVIC(void);


void Hcsr04Init(void);


static void OpenTimerForHc(void);


static void CloseTimerForHc(void);


void TIM4_IRQHandler(void);


u32 GetEchoTimer(void);


float Hcsr04GetLength(void);



#endif

2.LCD1602的初始化

这东西搞了我半天,实在是太坑了,一开始写完代码初始化后lcd只亮没有显示任何东西,我就一直以为是代码问题,最后看到电路图

这里是有个滑动变阻,用来调节lcd显示的对比度,用螺丝刀扭动R22直到有显示为止

lcd1602.c:

#include "lcd1602.h"
#include "delay.h"
#include "sys.h"


void gpio_config()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOC, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|
	GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9 ;
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
	GPIO_Init(GPIOC, &GPIO_InitStructure);


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ;
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}

void lcd_write_com(u8 com){
	EN_CLR;
	
	delay_us(1);
	RS_CLR;
	delay_us(1);
	RW_CLR;
	delay_us(10);
	
	GPIOC->ODR = (GPIOC->ODR&0xFF00)|com;;
	//GPIO_Write(GPIOC,com);
	delay_us(400);

	EN_SET;
	delay_us(400);
	EN_CLR;

	delay_us(300);
}

void lcd_write_ascii(u8 ascii){
	EN_CLR;
	
	delay_us(1);
	RS_SET;
	delay_us(1);
	RW_CLR;
	delay_us(10);

	GPIOC->ODR = (GPIOC->ODR&0xFF00)|ascii;
	//GPIO_Write(GPIOC,ascii);
	delay_us(300);
	EN_SET;
	
	delay_us(400);
	EN_CLR;

	delay_us(300);
}

void lcd_write_char(u8 x,u8 y,u8 data){
	if(y==0){
		lcd_write_com(0x80+x);
	}
	else{
		lcd_write_com(0xc0+x);
	}
	
	lcd_write_ascii(data);
	delay_us(500);
}

void lcd_write_string(u8 x,u8 y,u8* str){
	if(y==0)
		lcd_write_com(0x80+x);
	else
		lcd_write_com(0xc0+x);
	while(*str){
		lcd_write_ascii(*str);
		str++;
		delay_us(500);
	}
		
}



void lcd_clear(){
	lcd_write_com(0x01);
	delay_ms(5);
}


void lcd_init(){

	
	delay_ms(100);
	lcd_write_com(0x38); 
	delay_ms(10);
	lcd_write_com(0x38);
	delay_ms(10);
	lcd_write_com(0x38);
	delay_ms(10);
	lcd_write_com(0x38);
	delay_ms(10);
	lcd_write_com(0x08);  
	delay_ms(10);
	lcd_write_com(0x01); 
	delay_ms(10);
	lcd_write_com(0x06); 
	delay_ms(10);
	lcd_write_com(0x0c); 
	delay_ms(10);
}

lcd1602.h:

#ifndef __LCD1602_H
#define __LCD1602_H


#include "stm32f10x.h"

#define RS_SET GPIO_SetBits(GPIOC,GPIO_Pin_8)
#define RS_CLR GPIO_ResetBits(GPIOC,GPIO_Pin_8)

#define RW_CLR GPIO_ResetBits(GPIOC,GPIO_Pin_9)
#define RW_SET GPIO_SetBits(GPIOC,GPIO_Pin_9)

#define EN_CLR GPIO_ResetBits(GPIOB,GPIO_Pin_1)
#define EN_SET GPIO_SetBits(GPIOB,GPIO_Pin_1)


void lcd_write_char(u8 x,u8 y,u8 data);
void lcd_write_string(u8 x,u8 y,u8* str);
void lcd_init(void);
void gpio_config(void);

#endif

mian.c:

#include "delay.h"
#include "sys.h"	
#include "hcsr04.h"	
#include "lcd1602.h"
#include "usart.h"
u8 u1buffer[4]={0};
static void LCD_Disp(u16 u1);
static void user_init()
{
lcd_write_string(0,0,(u8*)"DIST=    cm");

}
int main(){
	u16 u1;
	u16 distance=0.0;
	user_init();

	delay_init();
	NVIC_Configuration();
	uart_init(115200);
    LCD_GPIO_Init();//lcd的引脚初始化一定要在lcd初始化之前,很重要
	lcd_init();
	Hcsr04Init();	
	while(1){
			distance = Hcsr04GetLength();
            u1=distance;
			LCD_Disp(u1);
	}
	
	

}
static void LCD_Disp(u16 u1)
{ 
u1buffer[0] = u1/1000; 
u1buffer[1] = u1%1000/100; 
u1buffer[2] = u1%100/10;
u1buffer[3] = u1%10;


lcd_write_char(6,0,u1buffer[0]+0X30);
lcd_write_char(7,0,u1buffer[1]+0X30);
lcd_write_char(8,0,u1buffer[2]+0X30);
lcd_write_char(9,0,u1buffer[3]+0X30);

}

总结

最后成果,本人水平有限,如有错误请大家批评指正 !


  • 3
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

鶕雀

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

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

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

打赏作者

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

抵扣说明:

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

余额充值