PIC32MX microcontroller can not enter the interrupt problem-solution2020-08-12

Hello, everyone, I recently switched from the STM32 platform to the PIC platform, which was not particularly smooth at first. First of all, the information is not as detailed as 32. Secondly, there are fewer relevant forums. If you encounter problems, you can only read the official manual and Baidu. Today, according to the official register manual, I called the <plb.h> function library. After writing the timer configuration, I found that I could not enter the interrupt. After a lot of searching, I finally found the problem. I will put the source code and solution below.

Platform: PIC32MX795F512L microcontroller, main frequency 80MHz, timer clock frequency is 40MHz. Using an external 4M crystal oscillator, the PLL frequency multiplier 20 multiplies the frequency to get the 80MHz master clock, and the peripheral clock is divided by 2 to get 40MHz.

Below is my initialization code:

/************************************************
*  @函数功能:定时器2初始化
*  @参    数:无
*  @返    回:无
*  @说    明:定时时间为1ms  外设时钟为40M
*************************************************/
void Tim2_Init()
{
    
    
	//定时器2初始化
	OpenTimer2(T2_ON             /* 打开定时器 */
	 	  |T2_IDLE_CON       /* 空闲模式继续 */
	    	  |T2_PS_1_64,       /* 64分频 */
	          625);             /* 定时周期设置 1ms */
        TMR2 = 0; /* 清除计数 */
	ConfigIntTimer2(T2_INT_ON|T2_INT_PRIOR_4);/* 定时器中断配置 */
}

Timer 2 uses the peripheral clock, the clock cycle is 40MHz, and the frequency is divided by 64, so the count value of 1s is 40000000/64 = 625000, so the reload value of 1ms is 625.
Formula: preset value = main frequency / division Frequency coefficient / 1000 * n, n is the timing period, the unit is ms.

The following is the interrupt service function

/************************************************
*  @函数功能:定时器2中断服务函数
*  @参    数:无
*  @返    回:无
*************************************************/
void __ISR(_TIMER_2_VECTOR, ipl4auto) IsrTIM2Handler(void)
{
    
    
	delay_count++;
	INTClearFlag(INT_T2);/* 清除中断标志位 */
}

Among them, "_TIMER_2_VECTOR" is the vector address of timer 2, ipl4auto indicates that the interrupt priority of timer 2 is 4.

The problem is coming. After confirming that the configuration is ok, I found that I couldn't enter the interrupt after debugging. I searched the Internet and finally found it.

PIC32MX does not have the so-called total interrupt control bit, but the CPU has two interrupt modes, interrupt single vector mode and multi vector mode. It means that if working in single vector mode, the CPU will only enter the same interrupt vector address (not used, so I won't introduce it). We are mainly concerned about the multi-vector mode, which is to enter different interrupt functions according to different interrupt addresses. But PIC32MX is in single vector mode by default every time it is reset, so manual configuration is required. The following describes how to configure.

Configuration code:

/* CPU工作多中断向量模式配置 */
#define hwGLOBAL_INTERRUPT_BIT   	( 0x01UL )
#define hwBEV_BIT       		( 0x00400000 )
#define hwEXL_BIT       		( 0x00000002 )
#define hwIV_BIT       			( 0x00800000 )
/************************************************
*  @函数功能:设置CPU工作于多向量模式
*  @参    数:无
*  @返    回:无
*  @说    明:定时时间为1ms  外设时钟为40M
*************************************************/
void vHardwareUseMultiVectoredInterrupts( void )
{
    
    
	unsigned long ulStatus, ulCause;
	extern unsigned long _ebase_address[];
	/* 获取当前状态 */
	ulStatus = _CP0_GET_STATUS();
	/* 禁止中断 */
	ulStatus &= ~hwGLOBAL_INTERRUPT_BIT;
	/* 设置 BEV */
	ulStatus |= hwBEV_BIT;
	/* 写状态返回 */
	_CP0_SET_STATUS( ulStatus );
	/* 设置 Ebase */
	_CP0_SET_EBASE( ( unsigned long ) _ebase_address );
	/* 0x20字节空间向量 */
	_CP0_XCH_INTCTL( 0x20 );
	/* 设置 CAUSE寄存器的 IV位 */
	ulCause = _CP0_GET_CAUSE();
 	ulCause |= hwIV_BIT;
	 _CP0_SET_CAUSE( ulCause );
	/* 清除 BEV和 EXL */
	ulStatus &= ~( hwBEV_BIT | hwEXL_BIT );
	 _CP0_SET_STATUS( ulStatus );

	/* 设置MVEC */
	INTCONbits.MVEC = 1;	
	
	/* 使能中断 */
	ulStatus |= hwGLOBAL_INTERRUPT_BIT;
	 _CP0_SET_STATUS( ulStatus );
	
}


I don't know why this configuration is needed, but for reference, you can find the corresponding manual on microchip's official website. As shown in Figure 1.1
Insert picture description here
Figure 1.1

Some friends may struggle to read English (like me), so they found the Chinese version, as shown in Figure 1.2 below.

Insert picture description here
Figure 1.2

Put the multi-vector configuration function at the beginning of the man() function, and that's it!

Attach a link to the reference manual at the end

中文文档链接:http://www.microchip.com.cn/newcommunity/Uploads/Download/Library/60001108h_cn.pdf
英文文档链接:http://ww1.microchip.com/downloads/en/DeviceDoc/60001108H.pdf

It’s the first time to write a blog. If someone sees something wrong, please correct me!

Guess you like

Origin blog.csdn.net/weixin_42952614/article/details/107968615