STM32外部中斷使用注意事項(xiàng)
stm32盡管所有的gpio都可以設(shè)置為外部中斷的功能,但是不能把所有的gpio同時(shí)設(shè)置為外部中斷。例如不能把PA0和PB0同時(shí)設(shè)置為外部中斷,因?yàn)镻A0和PB0共用一個(gè)中斷線,MCU只把最后完成初始化的管腳設(shè)置為外部中斷。
如果代碼編寫者明確知道PA0和PB0不會同時(shí)觸發(fā),并且觸發(fā)有相互依賴關(guān)系,可以通過分時(shí)設(shè)置PA0和PB0的外部中斷功能。但是在大多數(shù)情況下,外部中斷的觸發(fā)都是隨機(jī)的,那么在設(shè)計(jì)原理圖的時(shí)候就要考慮到這種情況,把用到的外部中斷管腳設(shè)置到后綴不同的管腳上,如PA0,PA1,PB3,PC8,....PD12,PF16,在一個(gè)工程中最多能使用16個(gè)外部中斷,并且每個(gè)管腳的后綴不同。
如果設(shè)計(jì)電路板沒有考慮到這種情況,則需要根據(jù)實(shí)際情況把觸發(fā)頻繁的設(shè)置為外部中斷,不頻繁的通過檢測管腳電平變化來判斷是否有觸發(fā)。
檢測管腳電平變化的一種方法:
設(shè)計(jì)一個(gè)周期1ms的定時(shí)器,在定時(shí)器中斷服務(wù)函數(shù)中通過判斷管腳電平,來捕獲上升沿和下降沿。
//捕獲下降沿
void timer_isr(void)//定時(shí)器1ms的中斷服務(wù)子函數(shù)
{
if(READ_PIN)
{
state = waitting_falling_edge;
}
else
{
if(state == waitting_falling_edge)
{
falling_trigger = 1;//捕獲下降沿
state =falling_edge_detected;
}
}
}
//捕獲上升沿
void timer_isr(void)//定時(shí)器1ms的中斷服務(wù)子函數(shù)
{
if(!READ_PIN)
{
state = waitting_rising_edge;
}
else
{
if(state ==waitting_rising_edge)
{
rising_trigger = 1;//捕獲上升沿
state =rising_edge_detected;
}
}
}
類比FPGA的捕獲上升沿、下降沿代碼(verilog語言)
//捕捉上升沿
module capture_rising(iclock, ireset, isignal, orising);
input iclock;
input ireset;
input isignal;
output orising;
reg isignal_temp0;
reg isignal_temp1;
always @(posedge iclock or negedge ireset)
begin
if(!ireset)
begin
isignal_temp0 <= 1'b0;
isignal_temp1 <= 1'b0;
end
else
begin
isignal_temp0 <= isignal;
isignal_temp1 <= isignal_temp0;
end
end
assign orising = ~isignal_temp1 & isignal_temp0;
endmodule
//捕捉下降沿
module capture_falling(iclock, ireset, isignal, ofalling);
input iclock;
input ireset;
input isignal;
output ofalling;
reg isignal_temp0;
reg isignal_temp1;
always @(posedge iclock or negedge ireset)
begin
if(!ireset)
begin
isignal_temp0 <= 1'b0;
isignal_temp1 <= 1'b0;
end
else
begin
isignal_temp0 <= isignal;
isignal_temp1 <= isignal_temp0;
end
end
assign ofalling = isignal_temp1 & ~isignal_temp0;
endmodule
雖然代碼不同,但是思路是一樣的:寄存上一周期的狀態(tài),并與當(dāng)前狀態(tài)相結(jié)合進(jìn)行判斷。
stm32的1ms定時(shí)器(即每1ms執(zhí)行一次定時(shí)器中斷服務(wù)子函數(shù))相當(dāng)于fpga的1個(gè)時(shí)鐘100ns(iclock-10mhz),檢測速度相差1萬倍。