一个由单片机管脚中断功能复用引发的bug
扫描二维码
随时随地手机看文章
使用单片机控制ZL30151输出时钟,引脚连接关系如下:
其中A1、A0是作为复用器的地址线信号,ZL30151 SPI模式下的有用管脚如下:
CSN(IF0)、SCLK(SCL)、RSTN、MOSI(SDA)、MISO(IF1)、AC0(GPIO0)、AC1(GPIO1)(这些管脚中的RSTN、AC0、AC1由FPGA控制),括号内是管脚的第二功能,主要用于芯片复位时的模式设置,具体到SPI模式:在RSTN的上升沿,IF1、IF0要置1,AC0、AC1置0。另外RSTN在上电之后要有一个复位的过程,需要拉低至少100ns。而RSTN是在FPGA端控制的,所以需要单片机和FPGA共同控制,方法是单片机项FPGA的寄存器写一个值,然后FPGA就将对应的管脚拉低或置1。SPI模式设置就要在单片机给FPGA发送赋值请求前,将IF1、IF0管脚的值准备好。问题就是在这里出现的。
程序通过编译,下到单片机,但是ZL30151的时钟没有出来,然后进入debug模式找问题。
int main()
{
init_devices();
init_pll();
PLL3_init();
unsigned char f_read = FPGA_read(0x3b00);
……
return 0;
}
首先怀疑和FPGA的接口有问题,读寄存器的值,看是否写入进去,但是显示一直是0,然后打断点调试:
unsigned char f_read = FPGA_read(0x3b00);在这一句打断点,结果程序根本没跑到这里,然后将断点往上打,
PLL3_init();程序运行到断点这里,再点向下运行,程序就跑飞了,问题出在PLL3_init();然后在PLL3_init()函数里打断点,
DDRD = 0x3f;
//X,X,SEL_A1,SEL_A0,MISO(IF1),MOSI(SDA),SCLK(SCL),CSN(IF0)
PORTD = 0x19;在这里程序竟然跑飞了。
这里只是一个简单的给管脚赋值的语句,实在是看不出有什么问题,况且在init_devices();这个函数里面也有给管脚赋值的语句,并没有问题。百思不得其解,请教单位的大牛王总,过来之后冷眼一扫,看到Port0、1、2、3复用了中断功能,而且在init_devices();里面是使能了INT0和INT1的,就判断应该是中断引起的。然后刚好我在给PORT管脚赋值的时候将INT0置为高了,所以程序就进入了中断程序,但是本项目工程里并没有写INT0的中断函数(没有中断函数还把中断使能打开,这就是不动脑筋复制粘贴的后果),所以程序就跑飞了。
**关于单片机的中断引脚,手册里是这样规定的:只要使能了中断,即使引脚INT7:0配置为输出,只要电平发生了合适的变化,中断也会触发。
所以虽然将引脚配置为输出引脚,也仍然引发了中断。