目錄
一、紅外避障模塊?概述
二、直接讀取OUT引腳電平
三、使用中斷方式觸發
一、紅外避障模塊?概述
引腳解釋:
VCC | 接3.3V?或 5.0V |
GND | 接開發板的GND |
OUT | 數字量輸出(0或1);?低電平時表示前方有障礙 ;?通過可調電阻調整檢測距離? |
產品特點:
工作電壓 | 推薦3.3V,?也可以5V |
模塊功耗 | 23mA~40mA |
檢測距離 | <=30cm ;?通過可調電阻調整檢測距離? |
指示燈 | 電壓燈 +?障礙指示燈 |
模塊描述:
1、可以廣泛應用于機器人避障、避障小車、流水線計數、黑白線循跡 等眾多場合。
2、采用3.3V?或?5V 直流電源對模塊進行供電。當電源接通時,電源指示燈點亮;
3、該傳感器模塊對環境光線適應能力強,其具有一對紅外線發射與接收管,發射管發射出一定頻率的紅外線,當檢測方向遇到障礙物(反射面)時,紅外線反射回來被接收管接收,經過比較器電路處理之后,綠色指示燈會亮起,同時OUT端口持續輸出低電平信號(0);
4、檢測距離2~30cm,檢測角度35°; 檢測距離可以通過電位器進行調節,順時針調電位器,檢測距離增加;逆時針調電位器,檢測距離減少。
5、傳感器是主動紅外線反射探測, 因此目標的反射率和形狀是探測距離的關鍵。其中黑色探測距離最小, 白色最大; 小面積物體距離小,大面積距離大。
6、輸出端口OUT可直接與單片機IO口連接,使用代碼讀取OUT電平,或使用中斷觸發的方式;? 另外,?OUT引腳也可以直接驅動一個5V繼電器;
7、使用前,建議先用螺絲刀調節好需要的觸發距離 (綠燈亮),再接入單片機進行開發調試。
8、具有3mm的螺絲孔,便于固定、安裝;
二、程序直接讀取OUT引腳電平
OUT接口在閑時(沒有發現障礙物),是持續的高電平狀態;高電平的電壓值是供電電壓值;
當發現障礙物時,OUT接口將持續地輸出低電平,直到障礙物消失時再輸出高電平;
因此,我們可以在STM32工程中,直接用代碼讀取OUT接口的電平,即可知道是否遇到障礙物。
- 這里以OUT接口,連接PC12引腳為示例;(哪個引腳都可以,只要是空閑的引腳即可)
- PC12引腳工作模式,無需初始化、設置。因為讀電平,不管哪種模式狀態下都可以直接讀。
在main的while中,編寫以下代碼即可:
HAL_Delay(500); // 延時間隔uint8_t state = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_12); // 讀取OUT引腳電平; 只是讀引腳電平,用哪個引腳都可以,無需提前初始化
if (state == 0) // 判斷 OUT 引腳是否是低電平(閑時高電平,遇到障礙物時持續輸出低電平)
{HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET); // 點亮藍色LED; 引腳PB2, 低電平通路點亮;printf("發現障礙物!\r\n"); // 打印提示信息; printf需要預先使能UART1,并重定向到UART1輸出
}
else
{HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET); // 熄滅藍色LED; 引腳PB2, 高電平斷路熄滅;
}
完成后,位置如下圖:
上面的代碼,當PC12為低電平時(遇到障礙物):亮燈、printf輸出提示信息;
三、使用中斷方式觸發
上面的讀取方式,操作簡單、容易理解。
但這種方式有一個潛在隱患:處理可能不及時。
如,當小車高速開跑中,遇到了障礙物,但程序卻正在運行其它功能的代碼, ......。
小車翻車沒啥事,但如果用在工業現場,如電機、導軌等,?那就嚴重了!
我們可以使用中斷觸發的方式,發現障礙物,立即進入執行處理!
下面,還是以OUT接口連接PC12作示例,示范CubeMX的中斷觸發配置、編寫回調函數代碼。
1、配置引腳的工作模式
- 點擊需要使用的引腳,選擇:GPIO_EXTI,即 外部中斷模式
2、配置觸發方式
- 根據OUT接口的工作特點,配置為: Interrupt? Falling ,即下降沿觸發中斷;
- 設置為上拉,即?閑時引腳電平保持在高電平狀態;
3、使能中斷線
- 在 NVIC 中斷控制器頁面中,打勾對應的中斷線,令中斷控制器能夠響應該中斷線,從而使芯片能夠接收并處理引腳的電平跳變事件。
引腳編號與中斷線對應的關系是:
GPIO_PIN_0 | EXTI_Line0 |
GPIO_PIN_1 | EXTI_Line |
GPIO_PIN_2 | EXTI_Line |
GPIO_PIN_3 | EXTI_Line |
GPIO_PIN_4 | EXTI_Line |
GPIO_PIN_5? ? 至? GPIO_PIN_9? ? 共用一個中斷線 | EXTI_Line[9:5] |
GPIO_PIN_10? 至? GPIO_PIN_15??共用一個中斷線 | EXTI_LineEXTI_Line[15:10] |
至此,引腳的中斷觸發,配置完成,重新生成。
4、編寫中斷回調函數
CubeMX配置上述中斷后,將自動生成底層的初始化、中斷服務函數等代碼。
當引腳發生了配置中的電平跳變時,將觸發硬件自動調用程序里的中斷服務函數,繼而調用程序里的EXTI中斷回調函數:HAL_GPIO_EXTI_Callback ( );
這個回調函數在CubeMX生成時,在stm32xx_hal_gpio.c中已生成了弱定義;
我們在適合的、喜歡的位置,自行重新編寫HAL_GPIO_EXTI_Callback函數,即能被中斷函數調用到。
我們在main.c的下方,/* USER CODE BEGIN 4 */之下,編寫此回調函數:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{if (GPIO_Pin == GPIO_PIN_12) // 由PC12觸發{HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET); // 點亮藍色LED; 引腳PB2, 低電平通路點亮;printf("發現障礙物!\r\n"); // 打印提示信息; printf需要預先使能UART1,并重定向到UART1輸出}}
完成后,位置如下圖:
如上,即可實現遇到障礙物時,實時地執行處理。
這里的亮燈、printf,只是示范,你可以替換成需要的執行,如剎車、關閉設備電源等。
5、多次觸發的解決思路
當使用中斷觸發,可能會有一個使用上明顯的bug:連續多次觸發!
這個bug的產生,是OUT接口輸出低電平信號過程中的振鈴現象所導致的。
測試了三個不同店家的紅外避障模塊,有兩家模塊存在多次觸發現象。
物理解決方案:
????????在?OUT接口與GND間,并聯一個1uF左右的小電容(1uF只是建議,具體得根據現場而定);
代碼解決方案:
????????在中斷回調函數里,增加5ms延時,即HAL_Delay(10ms),讓程序刻意“錯過”振鈴導致的多次觸發。這種方式有點像按鍵的消抖處理。但是,不建議使用這種方式,因為在中斷里延時死等,有可能導致其它通信的中斷無法及時執行,數據丟包! 如果確定要使用這種方式(在中斷里使用HAL_Delay),? 注意會產生中斷嵌套沖突。需要在CubeMX里修改NVIC的Time base響應優先級,默認是15 (最低),把它修改為0 (最高),然后,把引腳中斷線的優先級,默認是0 (最高),修改為大于0的值,如1、6等。這樣處理后,在EXTI的中斷回調函數里才能使用HAL_Delay函數。
操作如下圖:
如有錯漏,望指正,將及時更新修改~~~