基于STM32的超声波测距proteus仿真 HC-SR04(仿真+源码+讲解视频)

本设计仅供学习参考
基于STM32的超声波测距proteus仿真 HC-SR04(仿真+源码+讲解视频)
仿真:proteus8.9
程序编译器:keil 5
编程语言:C语言
编号C0037

设计说明:
基于STM32F103RC和STM32F103C6的HC-SR04超声波测距的Proteus仿真,LCD1602显示数据;
使用定时器timer3开发,数据非常准确且稳定,范围0-300左右。

仿真图(源文件):
在这里插入图片描述

main函数

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"
#include "timer.h"
#include "ds18b20.h"

int main(void)
{
    float SRF04_Value = 123.45;
    uint8_t adcxxx[3] = {0, 0, 0};

		uint8_t temp1[2] = {0, 0};
		uint8_t temp2[1] = {0};
    
    HAL_Init();                    	 
    Stm32_Clock_Init(RCC_PLL_MUL9);   
		delay_init(72);               		
		DS18B20_Init();
		
		LCD_init();					

    SRF04_init();
    
    TIM3_Init(1000-1, 72-1);   	
        
		LCD_write_string(1, 0, "Tempera:");
		LCD_write_string(0, 1, "Distance:");
		
    while(1)
    {

				u16 adc_Value_16 = 0;
				short adc_Value = 0;
		
				adc_Value = DS18B20_Get_Temp();
				adc_Value_16 = (u16)adc_Value;
            
				temp1[0] = (adc_Value_16 / 100) + 0x30;
				temp1[1] = (adc_Value_16 % 100 / 10) + 0x30;
				temp2[0] = (adc_Value_16 % 10) + 0x30;
							
				LCD_write_string(11, 0, (char*)temp1);
				LCD_write_string(13, 0, ".");
				LCD_write_string(14, 0, (char*)temp2);
				
        SRF04_Value = Hcsr04GetLength();
        if(SRF04_Value >= 600)
            SRF04_Value = 400;
        
        adcxxx[0] = (uint16_t)SRF04_Value / 100 + 48;
        adcxxx[1] = (uint16_t)SRF04_Value % 100 / 10 + 48;
        adcxxx[2] = (uint16_t)SRF04_Value % 100 % 10 + 48;

        LCD_write_string(11, 1, (char*)adcxxx);
        
        delay_ms(200);             	
    }
}




按键处理函数

//按键初始化函数
void KEY_Init(void)
{
    GPIO_InitTypeDef GPIO_Initure;
    
    __HAL_RCC_GPIOA_CLK_ENABLE();           //开启GPIOA时钟
    __HAL_RCC_GPIOC_CLK_ENABLE();           //开启GPIOC时钟

    
    GPIO_Initure.Pin=GPIO_PIN_0;            //PA0
    GPIO_Initure.Mode=GPIO_MODE_INPUT;      //输入
    GPIO_Initure.Pull=GPIO_PULLDOWN;        //下拉
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;     //高速
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
    
	GPIO_Initure.Pin=GPIO_PIN_15; 			//PA15
    GPIO_Initure.Pull=GPIO_PULLUP;          //上拉
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
    
	GPIO_Initure.Pin=GPIO_PIN_5; 			//PC5
    GPIO_Initure.Pull=GPIO_PULLUP;          //上拉
    HAL_GPIO_Init(GPIOC,&GPIO_Initure);
}

//按键处理函数
//返回按键值
//mode:0,不支持连续按;1,支持连续按;
//0,没有任何按键按下
//1,WKUP按下 WK_UP
//注意此函数有响应优先级,KEY0>KEY1>KEY2>WK_UP!!
u8 KEY_Scan(u8 mode)
{
    static u8 key_up=1;     //按键松开标志
    if(mode==1)key_up=1;    //支持连按
    if(key_up&&(KEY0==0||KEY1==0||WK_UP==1))
    {
        delay_ms(10);
        key_up=0;
        if(KEY0==0)       return KEY0_PRES;
        else if(KEY1==0)  return KEY1_PRES;
        else if(WK_UP==1) return WKUP_PRES;          
    }else if(KEY0==1&&KEY1==1&&WK_UP==0)key_up=1;
    return 0;   //无按键按下
}

DS18B20获取温度函数

#include "ds18b20.h"
#include "led.h"  

void DS18B20_IO_OUT(void)
{
    GPIO_InitTypeDef GPIO_Initure;

    __HAL_RCC_GPIOA_CLK_ENABLE();           	//开启GPIOA时钟
	
    GPIO_Initure.Pin=GPIO_PIN_14; 
    GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  	//推挽输出
    GPIO_Initure.Pull=GPIO_PULLUP;          	//上拉
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;    	 	//高速
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
}

void DS18B20_IO_IN(void)
{
    GPIO_InitTypeDef GPIO_Initure;

    __HAL_RCC_GPIOA_CLK_ENABLE();           	//开启GPIOA时钟
	
    GPIO_Initure.Pin=GPIO_PIN_14; 
    GPIO_Initure.Mode=GPIO_MODE_INPUT;  	//推挽输出
    GPIO_Initure.Pull=GPIO_PULLUP;          	//上拉
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;    	 	//高速
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
}

//复位DS18B20
void DS18B20_Rst(void)	   
{                 
	DS18B20_IO_OUT(); //SET PA0 OUTPUT
    DS18B20_DQ_OUT(0); //拉低DQ
    lcd_delay_us(750);    //拉低750us
    DS18B20_DQ_OUT(1); //DQ=1 
	lcd_delay_us(15);     //15US
}
//等待DS18B20的回应
//返回1:未检测到DS18B20的存在
//返回0:存在
u8 DS18B20_Check(void) 	   
{   
	u8 retry=0;
	DS18B20_IO_IN();//SET PA0 INPUT	 
    while (DS18B20_DQ_IN&&retry<200)
	{
		retry++;
		lcd_delay_us(1);
	};	 
	if(retry>=200)return 1;
	else retry=0;
    while (!DS18B20_DQ_IN&&retry<240)
	{
		retry++;
		lcd_delay_us(1);
	};
	if(retry>=240)return 1;	    
	return 0;
}
//从DS18B20读取一个位
//返回值:1/0
u8 DS18B20_Read_Bit(void) 			 // read one bit
{
    u8 data;
	DS18B20_IO_OUT();//SET PA0 OUTPUT
    DS18B20_DQ_OUT(0); 
	lcd_delay_us(2);
    DS18B20_DQ_OUT(1); 
	DS18B20_IO_IN();//SET PA0 INPUT
	lcd_delay_us(12);
	if(DS18B20_DQ_IN)data=1;
    else data=0;	 
    lcd_delay_us(50);           
    return data;
}
//从DS18B20读取一个字节
//返回值:读到的数据
u8 DS18B20_Read_Byte(void)    // read one byte
{        
    u8 i,j,dat;
    dat=0;
	for (i=1;i<=8;i++) 
	{
        j=DS18B20_Read_Bit();
        dat=(j<<7)|(dat>>1);
    }						    
    return dat;
}
//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_Write_Byte(u8 dat)     
 {             
    u8 j;
    u8 testb;
	DS18B20_IO_OUT();//SET PA0 OUTPUT;
    for (j=1;j<=8;j++) 
	{
        testb=dat&0x01;
        dat=dat>>1;
        if (testb) 
        {
            DS18B20_DQ_OUT(0);// Write 1
            lcd_delay_us(2);                            
            DS18B20_DQ_OUT(1);
            lcd_delay_us(60);             
        }
        else 
        {
            DS18B20_DQ_OUT(0);// Write 0
            lcd_delay_us(60);             
            DS18B20_DQ_OUT(1);
            lcd_delay_us(2);                          
        }
    }
}
//开始温度转换
void DS18B20_Start(void)// ds1820 start convert
{   						               
    DS18B20_Rst();	   
	DS18B20_Check();	 
    DS18B20_Write_Byte(0xcc);// skip rom
    DS18B20_Write_Byte(0x44);// convert
} 
//初始化DS18B20的IO口 DQ 同时检测DS的存在
//返回1:不存在
//返回0:存在    	 
u8 DS18B20_Init(void)
{
	DS18B20_IO_OUT();

	DS18B20_Rst();

	return DS18B20_Check();
}  
//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值 (-550~1250) 
short DS18B20_Get_Temp(void)
{
    u8 temp;
    u8 TL,TH;
	short tem;
    
    DS18B20_Start ();                    // ds1820 start convert
    DS18B20_Rst();
    DS18B20_Check();	 
    DS18B20_Write_Byte(0xcc);// skip rom
    DS18B20_Write_Byte(0xbe);// convert	    
    TL=DS18B20_Read_Byte(); // LSB   
    TH=DS18B20_Read_Byte(); // MSB  
	    	  
    if(TH>7)
    {
        TH=~TH;
        TL=~TL; 
        temp=0;//温度为负  
    }
    else 
        temp=1;//温度为正
    
    tem=TH; //获得高八位
    tem<<=8;    
    tem+=TL;//获得底八位
    tem=(float)tem*0.625;//转换 
    
	if(temp)
        return tem; //返回温度值
	else 
        return -tem;    
} 
 

设计资料

在这里插入图片描述

  1. 常见使用问题及解决方法–必读!!!!
  2. 源程序
  3. 仿真
  4. 功能要求
  5. 讲解视频
    Altium Designer 软件资料
    KEIL软件资料
    Proteus软件资料
    单片机学习资料
    答辩技巧
    设计报告常用描述
    超声波srf04参考书.pdf
    鼠标双击打开查找更多51 STM32单片机课程毕业设计.url

网盘下载链接

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

BT-BOX

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

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

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

打赏作者

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

抵扣说明:

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

余额充值