みなさん、こんにちは。最近、STM32プラットフォームからPICプラットフォームに切り替えましたが、最初は特にスムーズではありませんでした。まず第一に、情報は32ほど詳細ではありません。第二に、関連するフォーラムが少ないです。問題が発生した場合は、公式マニュアルとBaiduしか読むことができません。今日、公式登録マニュアルによると、<plb.h>関数ライブラリを呼び出しました。タイマー設定を書き込んだ後、割り込みを入力できないことがわかりました。何度も検索したところ、ようやく問題が見つかりました。以下にソースコードとソリューションを示します。
プラットフォーム:PIC32MX795F512Lマイクロコントローラー、メイン周波数80MHz、タイマークロック周波数は40MHzです。外部4M水晶振動子を使用して、PLL周波数乗算器20は周波数を乗算して80MHzのマスタークロックを取得し、周辺クロックを2で割って40MHzを取得します。
以下は私の初期化コードです:
/************************************************
* @函数功能:定时器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);/* 定时器中断配置 */
}
タイマー2は周辺クロックを使用し、クロックサイクルは40MHzで、周波数は64で除算されるため、1sのカウント値は40000000/64 = 625000であるため、1msのリロード値は625です。
式:プリセット値=メイン周波数/除算周波数係数/ 1000 * n、nはタイミング周期、単位はmsです。
割り込みサービス機能は以下のとおりです
/************************************************
* @函数功能:定时器2中断服务函数
* @参 数:无
* @返 回:无
*************************************************/
void __ISR(_TIMER_2_VECTOR, ipl4auto) IsrTIM2Handler(void)
{
delay_count++;
INTClearFlag(INT_T2);/* 清除中断标志位 */
}
このうち、「_ TIMER_2_VECTOR」はタイマー2のベクターアドレスであり、ipl4autoはタイマー2の割り込み優先度が4であることを示しています。
問題が発生しました。設定に問題がないことを確認したところ、デバッグ後に割り込みを入力できないことがわかりました。インターネットを検索して、ようやく見つけました。
PIC32MXには、いわゆるトータル割り込み制御ビットはありませんが、CPUには、割り込みシングルベクターモードとマルチベクターモードの2つの割り込みモードがあります。これは、シングルベクターモードで作業している場合、CPUは同じ割り込みベクターアドレスのみを入力することを意味します(使用されないため、紹介しません)。私たちは主に、異なる割り込みアドレスに応じて異なる割り込み関数を入力するマルチベクトルモードに関心があります。ただし、PIC32MXはリセットされるたびにデフォルトでシングルベクトルモードになるため、手動で構成する必要があります。以下に設定方法を説明します。
構成コード:
/* 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 );
}
この構成が必要な理由はわかりませんが、参考のために、マイクロチップの公式Webサイトで対応するマニュアルを見つけることができます。図1.1に示すように図
1.1
下の図1.2に示すように、一部の友人は(私のように)英語を読むのに苦労している可能性があるため、中国語版を見つけました。
図1.2
マルチベクトル構成関数をman()関数の先頭に配置すれば、それだけです。
最後にリファレンスマニュアルへのリンクを添付してください
中文文档链接:http://www.microchip.com.cn/newcommunity/Uploads/Download/Library/60001108h_cn.pdf
英文文档链接:http://ww1.microchip.com/downloads/en/DeviceDoc/60001108H.pdf
ブログを書くのは初めてです。誰かが何か間違っているのを見たら、私を訂正してください!