基于STM32單片機的汽車防撞與控制系統 - 嵌入式 物聯網(含代碼)

基于STM32單片機的汽車防撞與控制系統

  • 難度系數:4分
  • 工作量:4分
  • 創新點:3分

1 簡介

基于單片機的汽車防撞與控制系統設計

2 主要器件

  • STM32F103C8T6主控芯片
  • HC-SR04超聲波模塊
  • 光敏傳感器
  • ESP-01S WIFI模塊
  • 蜂鳴器
  • OLED屏
  • 紅外傳感器模塊

3 實現效果

前后有兩個HC-SR04超聲波模塊,可以檢測車前和車后是否有障礙物,實驗中拿手機擋住前面的超聲波模塊,蜂鳴器會報警。

紅外感應模塊可檢測車前是否有人,當紅外感應模塊前面有障礙是,顯示屏上由N->Y,代表檢測到人。

顯示屏上顯示超聲波模塊探測距離

4 設計原理

4.1HC-SR04超聲波模塊

簡介

HC-SR04超聲波模塊常用于機器人避障、物體測距、液位檢測、公共安防、停車場檢測等場所。HC-SR04超聲波模塊主要是由兩個通用的壓電陶瓷超聲傳感器,并加外圍信號處理電路構成的。如圖:

兩個壓電陶瓷超聲傳感器,一個用于發出超聲波信號,一個用于接收反射回來的超聲波信號。由于發出信號和接收信號都比較微弱,所以需要通過外圍信號放大器提高發出信號的功率,和將反射回來信號進行放大,以能更穩定地將信號傳輸給單片機。模塊整體電路如圖:

模塊參數

(1)模塊主要電氣參數

  • 使用電壓:DC—5V
  • 靜態電流:小于2mA
  • 電平輸出:高5V
  • 電平輸出:底0V
  • 感應角度:不大于15度
  • 探測距離:2cm-450cm
  • 高精度 可達0.2cm

(2)模塊引腳
超聲波模塊有4個引腳,分別為Vcc、 Trig(控制端)、 Echo(接收端)、 GND;其中VCC、GND接上5V電源, Trig(控制端)控制發出的超聲波信號,Echo(接收端)接收反射回來的超聲波信號。模塊如圖

4.2 ESP-01S WIFI模塊

簡介

ESP8266 系列模組是深圳市安信可科技有限公司開發的一系列基于樂鑫ESP8266的低功耗UART-WiFi芯片模組,可以方便地進行二次開發,接入云端服務,實現手機3/4G全球隨時隨地的控制,加速產品原型設計。

尺寸、管腳定義

ESP8266的指令介紹

AT指令可以細分四種類型:
1.測試指令:AT+=?
該命令用于查詢設置指令的參數以及取值的范圍

2.查詢指令:AT+?
該命令用于返回參數的當前值

3.設置指令:AT+=<’’’>
該命令用于設置用戶自定義的參數

4.執行指令:AT+
該命令用于執行受模塊內部程序控制的變參數不可變的功能

ESP8266的指令測試
可以通過STM開發板轉為電平轉換的功能連接上ESP8266模塊在通過串口顯示窗口在PC機上熱輸入AT指令來進行操作。

ESP8266的AT指令一覽

4.3 光照傳感器

簡介
光敏傳感器是最常見的傳感器之一,它的種類繁多,主要有:光電管、光電倍增管、光敏電阻、光敏三極管、太陽能電池、紅外線傳感器、紫外線傳感器、光纖式光電傳感器、色彩傳感器、CCD和CMOS圖像傳感器等。光傳感器是目前產量最多、應用最廣的傳感器之一,它在自動控制和非電量電測技術中占有非常重要的地位。光敏傳感器是利用光敏元件將光信號轉換為電信號的傳感器,它的敏感波長在可見光波長附近,包括紅外線波長和紫外線波長。光傳感器不只局限于對光的探測,它還可以作為探測元件組成其他傳感器,對許多非電量進行檢測,只要將這些非電量轉換為光信號的變化即可。
總結:照射光敏二極管的光強不同,通過光敏二極管的電流大小就不同,所以可以通過檢測電流大小,達到檢測光強的目的。利用這個電流變化,我們串接一個電阻,就可以轉換成電壓的變化,從而通過ADC讀取電壓值,判斷外部光線的弱。

優點

  • 采用靈敏型光敏電阻傳感器
  • 比較器輸出,信號干凈,波形好,驅動能力超過15mA。
  • 配可調電位器可調節檢測光線亮度
  • 工作電壓3.3V-5V
  • 輸出形式 :數字開關量輸出(0和1)
  • 設有固定螺栓孔,方便安裝

原理圖

5 部分核心代碼

//hc_sr04.c源文件: #include"stm32f10x.h" #include"hc_sr04.h" #include"stdio.h" //hc_sr04引腳初始化 void HC_SR04_Init(void)//初始化hc_sro4的連接引腳 {
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//開啟GPIOB時鐘 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;//將hc_sr04的Trig引腳連接到單片機的PB5引腳上,單片機給HC_SR04提供至少10us的脈沖 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;//將hc_sr04的Echo引腳連接到單片機的PB6引腳上,HC_SR04反饋高電平信號給單片機 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
} //通用定時器Tim2初始化 void Time2_Init(u32 Period , u32 Prescaler) {
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//開啟定時器TIM2的時鐘 TIM_TimeBaseStructure.TIM_Period = Period;//自動重裝載寄存器的值 TIM_TimeBaseStructure.TIM_Prescaler = Prescaler;//時鐘預分頻數 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//采樣分頻 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上計數 TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
	TIM_ClearFlag(TIM2,TIM_FLAG_Update);//清除溢出中斷標志位 TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//TIM2中斷使能 //	TIM_Cmd(TIM2,ENABLE);//使能定時器Tim2  } //NVIC配置 void NVIC_Config(void) {
	NVIC_InitTypeDef NVIC_InitStructure;
	
	NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn;//中斷通道號配置為TIM2 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//無占先優先級 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//無副優先級 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//中斷使能 NVIC_Init(&NVIC_InitStructure);//NVIC初始化 } //給hc_sr04一個啟動信號 void hc_sr04_start(void) {
	Trig=1;
	delay_us(20);
	Trig=0;
} //計算hc_sr04測出來的值 void hc_sr04_calculate(void) { float temp; while(Echo==1);
	hc_sr04_start();//啟動hc_sr04超聲波傳感器 while(Echo==0); printf("收到20us的脈沖,開始發送8個40KHz的方波信號!\r\n");
	delay_ms(500); printf("hc_sr04正在開始測距.......\r\n");
	TIM_SetCounter(TIM2,0);//清空計數器 TIM_Cmd(TIM2,ENABLE);//開啟定時器 while(Echo==1);//如果hc_sr04返回低電平說明還未檢測到前面有障礙物,就一直執行該程序 TIM_Cmd(TIM2,DISABLE);//停止計數 temp=TIM_GetCounter(TIM2)*340/(2*1000); printf("距離:%6.2fm\n",temp);
} //hc_sr04.h頭文件: #ifndef _HC_SRO4_H #define _HC_SR04_H #include "stm32f10x.h" #include "delay.h" #define Trig PBin(5) #define Echo PBout(6) void HC_SR04_Init(void); void Time2_Init(u32 Period , u32 Prescaler); void NVIC_Config(void); void hc_sr04_start(void); void hc_sr04_calculate(void); void delay_init(); void uart_init(u32 bound); #endif 
//wifi模塊部分 #include "esp8266.h" #include "string.h" #include "usart.h" #include "usart3.h" #include "stm32f10x.h" #include "sys.h"  #include "delay.h" //ESP8266模塊和PC進入透傳模式 void esp8266_start_trans(void) { //設置工作模式 1:station模式   2:AP模式  3:兼容 AP+station模式 esp8266_send_cmd("AT+CWMODE=1","OK",50); //讓Wifi模塊重啟的命令 esp8266_send_cmd("AT+RST","ready",20);
	
	delay_ms(1000); //延時3S等待重啟成功 delay_ms(1000);
	delay_ms(1000);
	delay_ms(1000); //讓模塊連接上自己的路由 while(esp8266_send_cmd("AT+CWJAP=\"111\",\"11111111\"","WIFI GOT IP",600)); //=0:單路連接模式     =1:多路連接模式 esp8266_send_cmd("AT+CIPMUX=0","OK",20); //建立TCP連接  這四項分別代表了 要連接的ID號0~4   連接類型  遠程服務器IP地址   遠程服務器端口號 while(esp8266_send_cmd("AT+CIPSTART=\"TCP\",\"xxx.xxx.xxx.xxx\",xxxx","CONNECT",200)); //是否開啟透傳模式  0:表示關閉 1:表示開啟透傳 esp8266_send_cmd("AT+CIPMODE=1","OK",200); //透傳模式下 開始發送數據的指令 這個指令之后就可以直接發數據了 esp8266_send_cmd("AT+CIPSEND","OK",50);
} //ESP8266退出透傳模式   返回值:0,退出成功;1,退出失敗 //配置wifi模塊,通過想wifi模塊連續發送3個+(每個+號之間 超過10ms,這樣認為是連續三次發送+) u8 esp8266_quit_trans(void) {
	u8 result=1;
	u3_printf("+++");
	delay_ms(1000); //等待500ms太少 要1000ms才可以退出 result=esp8266_send_cmd("AT","OK",20);//退出透傳判斷. if(result) printf("quit_trans failed!"); else printf("quit_trans success!"); return result;
} //向ESP8266發送命令 //cmd:發送的命令字符串;ack:期待的應答結果,如果為空,則表示不需要等待應答;waittime:等待時間(單位:10ms) //返回值:0,發送成功(得到了期待的應答結果);1,發送失敗 u8 esp8266_send_cmd(u8 *cmd,u8 *ack,u16 waittime) {
	u8 res=0; 
	USART3_RX_STA=0;
	u3_printf("%s\r\n",cmd); //發送命令 if(ack&&waittime) //需要等待應答 { while(--waittime) //等待倒計時 {
			delay_ms(10); if(USART3_RX_STA&0X8000)//接收到期待的應答結果 { if(esp8266_check_cmd(ack))
				{ printf("ack:%s\r\n",(u8*)ack); break;//得到有效數據  }
					USART3_RX_STA=0;
			} 
		} if(waittime==0)res=1; 
	} return res;
} //ESP8266發送命令后,檢測接收到的應答 //str:期待的應答結果 //返回值:0,沒有得到期待的應答結果;其他,期待應答結果的位置(str的位置) u8* esp8266_check_cmd(u8 *str) { char *strx=0; if(USART3_RX_STA&0X8000) //接收到一次數據了 { 
		USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加結束符 strx=strstr((const char*)USART3_RX_BUF,(const char*)str);
	} return (u8*)strx;
} //向ESP8266發送數據 //cmd:發送的命令字符串;waittime:等待時間(單位:10ms) //返回值:發送數據后,服務器的返回驗證碼 u8* esp8266_send_data(u8 *cmd,u16 waittime) { char temp[5]; char *ack=temp;
	USART3_RX_STA=0;
	u3_printf("%s",cmd); //發送命令 if(waittime) //需要等待應答 { while(--waittime) //等待倒計時 {
			delay_ms(10); if(USART3_RX_STA&0X8000)//接收到期待的應答結果 {
				USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加結束符 ack=(char*)USART3_RX_BUF; printf("ack:%s\r\n",(u8*)ack);
				USART3_RX_STA=0; break;//得到有效數據  } 
		}
	} return (u8*)ack;
} 

完整代碼可進群免費領取。

嵌入式物聯網的學習之路非常漫長,不少人因為學習路線不對或者學習內容不夠專業而錯失高薪offer。不過別擔心,我為大家整理了一份150多G的學習資源,基本上涵蓋了嵌入式物聯網學習的所有內容。點擊下方鏈接,0元領取學習資源,讓你的學習之路更加順暢!記得點贊、關注、收藏、轉發哦!

點擊這里找小助理0元領取:掃碼進群領資料

the end

評論(0)