本设计仅供学习参考
基于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;
}
设计资料
- 常见使用问题及解决方法–必读!!!!
- 源程序
- 仿真
- 功能要求
- 讲解视频
Altium Designer 软件资料
KEIL软件资料
Proteus软件资料
单片机学习资料
答辩技巧
设计报告常用描述
超声波srf04参考书.pdf
鼠标双击打开查找更多51 STM32单片机课程毕业设计.url
网盘下载链接
阅读全文