LPC1343 TimerのIRフラグとGPIO MASKED_ACCESS
やったこと
1. TimerのIR(interrupt)フラグを利用して2本のPWMコントロール
2. PWMはMASKED_ACCESS機能を利用してコントロール
開発Listへ戻る
コンセプト
たいしたことじゃないんですけど
スイッチ回路のコントロールで下みたいなタイミングを作りたかったので
Timer32を使って作ってみたのです。
またGPIOのHigh LowをコントロールするときにMASKED_ACCESSというやり方で
変更したいBitだけ指定して変更するというやり方を試してみました。
接続図
P2.4とP2.5をGPIOにしてLEDの点滅を目視で確認する形にしました。
コード
#ifdef __USE_CMSIS
#include "LPC13xx.h"
#endif#include
#include// Variable to store CRP value in. Will be placed automatically
// by the linker when "Enable Code Read Protect" selected.
// See crp.h header for more information
__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;
int main(void) {
int s=0;//PIO setting
LPC_IOCON->PIO2_4 =0x00; // PIO0_4 as GPIO
LPC_IOCON->PIO2_5 =0x00; // PIO0_5 as GPIO
LPC_GPIO2->DIR |=0xFF; // PIO0_4 & 0_5 as outputLPC_GPIO2->DATA =0xFF; // Check MASKED_ACCESS
LPC_GPIO2->MASKED_ACCESS[0x030]=0x000; // Check MASKED_ACCESS
LPC_GPIO2->MASKED_ACCESS[0x030]=0x010; // Check MASKED_ACCESS
s=LPC_GPIO2->MASKED_ACCESS[0x030]; //Check MASKED_ACCESS// 32bit counter
NVIC_EnableIRQ(TIMER_32_1_IRQn); // enable Timer32_1 interrupt handlerLPC_SYSCON->SYSAHBCLKCTRL |=0x400; // Timer32B1 Turn ON
LPC_TMR32B1->PR =7200-1; // 0.1ms ,10kHz(Max 32bit dec:4294967295)
LPC_TMR32B1->MCR=0x003; // Reset timer on MR0 and interrupt
LPC_TMR32B1->MCR|=0x008; // Interrupt on MR1 no reset
LPC_TMR32B1->MCR|=0x040; // Interrupt on MR2 no reset
LPC_TMR32B1->MCR|=0x200; // Interrupt on MR3 no resetLPC_TMR32B1->MR0 = 100000; // 10sec
LPC_TMR32B1->MR1 = 80000; // 8sec
LPC_TMR32B1->MR2 = 50000; // 5sec
LPC_TMR32B1->MR3 = 30000; // 3sec
LPC_TMR32B1->TCR =2; // TCR Reset
LPC_TMR32B1->IR =0x0F; // Clear interrupt flag
LPC_TMR32B1->TCR =1; // TCR start// Enter an infinite loop, just incrementing a counter
volatile static int i = 0 ;
while(1) {
i++ ;
}
return 0 ;
}void TIMER32_1_IRQHandler(void) {
int t = 0 ;t=LPC_TMR32B1->IR; //Copy IR flag
if(t==0x1){ //match on MR0
LPC_GPIO2->MASKED_ACCESS[0x030]=0x020;
}else if(t==0x2){ // match on MR1
LPC_GPIO2->MASKED_ACCESS[0x030]=0x030;
}else if(t==0x4){ // match on MR2
LPC_GPIO2->MASKED_ACCESS[0x030]=0x010;
}else if(t==0x8){ // match on MR2
LPC_GPIO2->MASKED_ACCESS[0x030]=0x030;
}
LPC_TMR32B1->IR=0x0F; //clear interrupt flag
}
コード解説
大体コメントでわかるかなー、ということで今回調べて使ってみた部分だけ開設します。
・MASKED_ACCESS確認
GPIO2.4, 2.5だけ変化させるようにコントロールします。
まずGPIO2のDATAをわかりやすくするためにFFにしておきます。
GPIO2のDATAレジスタがFFFになっていることがわかります。 LPC_GPIO2->DATA =0xFF; // Check MASKED_ACCESS
次にMASKED_ACCESSでPIO2.4, 2.5の部分だけ00にします。
LPC_GPIO2->MASKED_ACCESS[0x030]=0x000; // Check MASKED_ACCESS
GPIO2のDATAレジスタがFFF→FCFになって
4bitと5bitが0になっていることがわかります。
"=0x00"となっているにもかかわらず、[0x030]で1になっている
4bit目と5bit目だけ変わっています。
もう一度確認、今度は2.4=1, 2.5=0を入れてみます。 LPC_GPIO2->MASKED_ACCESS[0x030]=0x000; // Check MASKED_ACCESS
今度はMASKED_ACCESSでDATAを取り出します。
初期値に0を入れておいた"s"という関数に4bit目、5bit目のみ
取り出します。
s=LPC_GPIO2->MASKED_ACCESS[0x030]; //Check MASKED_ACCESS
GPIO2のDATAは0xFDFでしたがsの値は0x10になっています。
4bit目と5bit目のみを抽出したからです。
次はTimer interruptを使ったPWM操作です。
4つのMRポイントを使って以下のようにコントロールしています。
MR0がリセットポイントです。
MRの値はLEDを目視で確認するために秒単位で設定しています。
インターラプトの割り込み処理では
どのインターラプトフラグがHighになっているかをif文で
判別してMASKED_ACCESSでPWMをコントロールしています。
そして最後にMR0-3同時にinterrupt flagをclearしています。
void TIMER32_1_IRQHandler(void) {
int t = 0 ;
t=LPC_TMR32B1->IR; //Copy IR flag
if(t==0x1){ //match on MR0
LPC_GPIO2->MASKED_ACCESS[0x030]=0x020;
}else if(t==0x2){ // match on MR1
LPC_GPIO2->MASKED_ACCESS[0x030]=0x030;
}else if(t==0x4){ // match on MR2
LPC_GPIO2->MASKED_ACCESS[0x030]=0x010;
}else if(t==0x8){ // match on MR2
LPC_GPIO2->MASKED_ACCESS[0x030]=0x030;
}
LPC_TMR32B1->IR=0x0F; //clear interrupt flag
}