一個(gè)由單片機(jī)管腳中斷功能復(fù)用引發(fā)的bug
使用單片機(jī)控制ZL30151輸出時(shí)鐘,引腳連接關(guān)系如下:
其中A1、A0是作為復(fù)用器的地址線信號(hào),ZL30151 SPI模式下的有用管腳如下:
CSN(IF0)、SCLK(SCL)、RSTN、MOSI(SDA)、MISO(IF1)、AC0(GPIO0)、AC1(GPIO1)(這些管腳中的RSTN、AC0、AC1由FPGA控制),括號(hào)內(nèi)是管腳的第二功能,主要用于芯片復(fù)位時(shí)的模式設(shè)置,具體到SPI模式:在RSTN的上升沿,IF1、IF0要置1,AC0、AC1置0。另外RSTN在上電之后要有一個(gè)復(fù)位的過程,需要拉低至少100ns。而RSTN是在FPGA端控制的,所以需要單片機(jī)和FPGA共同控制,方法是單片機(jī)項(xiàng)FPGA的寄存器寫一個(gè)值,然后FPGA就將對(duì)應(yīng)的管腳拉低或置1。SPI模式設(shè)置就要在單片機(jī)給FPGA發(fā)送賦值請(qǐng)求前,將IF1、IF0管腳的值準(zhǔn)備好。問題就是在這里出現(xiàn)的。
程序通過編譯,下到單片機(jī),但是ZL30151的時(shí)鐘沒有出來,然后進(jìn)入debug模式找問題。
int main()
{
init_devices();
init_pll();
PLL3_init();
unsigned char f_read = FPGA_read(0x3b00);
……
return 0;
}
首先懷疑和FPGA的接口有問題,讀寄存器的值,看是否寫入進(jìn)去,但是顯示一直是0,然后打斷點(diǎn)調(diào)試:
unsigned char f_read = FPGA_read(0x3b00);在這一句打斷點(diǎn),結(jié)果程序根本沒跑到這里,然后將斷點(diǎn)往上打,
PLL3_init();程序運(yùn)行到斷點(diǎn)這里,再點(diǎn)向下運(yùn)行,程序就跑飛了,問題出在PLL3_init();然后在PLL3_init()函數(shù)里打斷點(diǎn),
DDRD = 0x3f;
//X,X,SEL_A1,SEL_A0,MISO(IF1),MOSI(SDA),SCLK(SCL),CSN(IF0)
PORTD = 0x19;在這里程序竟然跑飛了。
這里只是一個(gè)簡(jiǎn)單的給管腳賦值的語句,實(shí)在是看不出有什么問題,況且在init_devices();這個(gè)函數(shù)里面也有給管腳賦值的語句,并沒有問題。百思不得其解,請(qǐng)教單位的大牛王總,過來之后冷眼一掃,看到Port0、1、2、3復(fù)用了中斷功能,而且在init_devices();里面是使能了INT0和INT1的,就判斷應(yīng)該是中斷引起的。然后剛好我在給PORT管腳賦值的時(shí)候?qū)NT0置為高了,所以程序就進(jìn)入了中斷程序,但是本項(xiàng)目工程里并沒有寫INT0的中斷函數(shù)(沒有中斷函數(shù)還把中斷使能打開,這就是不動(dòng)腦筋復(fù)制粘貼的后果),所以程序就跑飛了。
**關(guān)于單片機(jī)的中斷引腳,手冊(cè)里是這樣規(guī)定的:只要使能了中斷,即使引腳INT7:0配置為輸出,只要電平發(fā)生了合適的變化,中斷也會(huì)觸發(fā)。
所以雖然將引腳配置為輸出引腳,也仍然引發(fā)了中斷。