本設(shè)計(jì)僅供學(xué)習(xí)參考
基于STM32的超聲波測距proteus仿真 HC-SR04(仿真+源碼+講解視頻)
仿真:proteus8.9
程序編譯器:keil 5
編程語言:C語言
編號C0037
設(shè)計(jì)說明:
基于STM32F103RC和STM32F103C6的HC-SR04超聲波測距的Proteus仿真,LCD1602顯示數(shù)據(jù);
使用定時(shí)器timer3開發(fā),數(shù)據(jù)非常準(zhǔn)確且穩(wěn)定,范圍0-300左右。
仿真圖(源文件):
main函數(shù)
#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);
}
}
按鍵處理函數(shù)
//按鍵初始化函數(shù)
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOA_CLK_ENABLE(); //開啟GPIOA時(shí)鐘
__HAL_RCC_GPIOC_CLK_ENABLE(); //開啟GPIOC時(shí)鐘
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);
}
//按鍵處理函數(shù)
//返回按鍵值
//mode:0,不支持連續(xù)按;1,支持連續(xù)按;
//0,沒有任何按鍵按下
//1,WKUP按下 WK_UP
//注意此函數(shù)有響應(yīng)優(yōu)先級,KEY0>KEY1>KEY2>WK_UP!!
u8 KEY_Scan(u8 mode)
{
static u8 key_up=1; //按鍵松開標(biāo)志
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獲取溫度函數(shù)
#include "ds18b20.h"
#include "led.h"
void DS18B20_IO_OUT(void)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOA_CLK_ENABLE(); //開啟GPIOA時(shí)鐘
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時(shí)鐘
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);
}
//復(fù)位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的回應(yīng)
//返回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讀取一個(gè)位
//返回值: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讀取一個(gè)字節(jié)
//返回值:讀到的數(shù)據(jù)
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;
}
//寫一個(gè)字節(jié)到DS18B20
//dat:要寫入的字節(jié)
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);
}
}
}
//開始溫度轉(zhuǎn)換
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 同時(shí)檢測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;//溫度為負(fù)
}
else
temp=1;//溫度為正
tem=TH; //獲得高八位
tem<<=8;
tem+=TL;//獲得底八位
tem=(float)tem*0.625;//轉(zhuǎn)換
if(temp)
return tem; //返回溫度值
else
return -tem;
}
設(shè)計(jì)資料
- 常見使用問題及解決方法–必讀!?。?!
- 源程序
- 仿真
- 功能要求
- 講解視頻
Altium Designer 軟件資料
KEIL軟件資料
Proteus軟件資料
單片機(jī)學(xué)習(xí)資料
答辯技巧
設(shè)計(jì)報(bào)告常用描述
超聲波srf04參考書.pdf
鼠標(biāo)雙擊打開查找更多51 STM32單片機(jī)課程畢業(yè)設(shè)計(jì).url
網(wǎng)盤下載鏈接