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 output

LPC_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 handler

LPC_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 reset

LPC_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
}


開発Listにもどる