由於設計的需求,原本是想要利用pwm的捕獲中斷,進行中斷的定義,但是研究了一會,發現pwm一直進不了中斷狀態。
但是在無意中發現,gpio中也有中斷函式。
因此萌發出利用gpio獲取pwm的輸入波形,從而進入中斷狀態。
但是官方wujian100給出的中斷vic案例中只是簡單利用gpio中斷直接跳出迴圈,並沒有涉及連續邊沿中斷的應用。
於是我修改了**,利用pwm輸入gpio口,想產生1s的中斷嘗試一下,發現中斷間隔並不是1s。
因此除錯觀察gpio的中斷情況,發現當產生中斷後,gpio中斷清除暫存器不能將中斷清除,導致無限的進入中斷。
修改過程
閱讀手冊,獲得gpio基礎位址為base = 0x60018000。
手冊中找到清除中斷位原理,為在clear interrupt暫存器中寫入1
在c專案中gpio口呼叫的中斷位清除函式定義。
static
void
gpio_irq_clear
(gpio_pin_handle_t pin, uint32_t idx)
觀察發現其是在 gpio_control_reg->porta_eoi 對應的gpio口寫入1使其執行中斷清除(對應手冊的清除中斷暫存器)。
但是經除錯發現寫入之後並不能清除中斷狀態,導致無限進入中斷迴圈狀態。
暫存器結構體定義
typedef struct wj_oip_gpio_control_reg_t;
在一次嘗試中,發現在中斷函式中進行中斷關閉與重開,能夠成功進出中斷,自定義中斷函式如下。
static
void
gpio_interrupt_handler
(int32_t idx)
於是觀察csi_gpio_pin_set_irq(),發現其涉及了中斷觸發模式的設定與對中斷的使能控制。
int32_t csi_gpio_pin_set_irq
(gpio_pin_handle_t handle, gpio_irq_mode_e mode, bool enable)
gpio_irq_enable
(handle)
;//開啟中斷
}else
return ret;
}
於是對中斷使能函式進行**,發現其與清除中斷的原理相似,只是功能上是對中斷的關閉與開啟。
gpio_irq_enable
(handle)
;//開啟中斷
gpio_irq_disable
(handle)
;//關閉中斷
手冊中寫道,0為普通訊號io口,1為中斷io口
於是修改void wj_oip_gpio_irqhandler(int idx)中的內容,使其每次對中斷進行重啟,實現中斷點清除。
wj_oip_gpio_control_reg_t *gpio_control_reg =
(wj_oip_gpio_control_reg_t *
)(gpio_handle[idx]
.base +
0x30
);
獲取暫存器結構的位址 = gpio_base位址 + 偏移量(0x30),可以在手冊中查詢
修改**內容如下,部分省略,主要修改了增加變數value_en、注釋**行 gpio_irq_clear(gpio_pin_priv, (1 << i))以及對使能中斷暫存器的關閉重啟。
void
wj_oip_gpio_irqhandler
(int idx)
最後執行原先編寫的中斷程式,成功實現1s的中斷計時。
由於收到板子的時間只有2、3天並且專案期限的原因,沒有時間去解決pwm的中斷捕獲與gpio中斷清除暫存器的內部問題,但是專案完成之後,如果工具允許將再次深入研究。
第一次發表文章,有錯誤請多多包涵!!!
2440GPIO口在linux中的定義
2440gpio口在linux中的定義 在移植mini2440的驅動到2.6.31的時候,編譯提示s3c2410 gpb5 s3c2410 gpb5 output等類似的定義缺失。遂在核心中相關的部分arch arm mach 2410 include mach中的標頭檔案尋覓了一番,果然沒有這些定...
MTK中GPIO的使用
一 gpio有關的函式 1 gpio modesetup 函式原型 void gpio modesetup kal uint16 pin,kal uint16 conf dada 功能 設定gpio的工作模式是作為gpio,還是作為專有功能介面。引數 pin gpio 的pin腳號,對應於原理圖上m...
arm中GPIO巨集的分析
linux核心標頭檔案中關於s3c2410 gpio的巨集 一 gpio暫存器定義 1 define gpcon x reg2 0x56000000,x 0x10 這句是定義2410的gpio的控制暫存器,注意 reg2的引數是暫存器的實體地址,這個實體地址經 reg2巨集轉換為虛擬位址,對照241...