[NXP]/LPC1k2011. 8. 14. 23:57

[LPC1K EVM] Captuer 이용 IR 리모콘 테스트

[LPC1K EVM] Captuer 이용 IR 리모콘 테스트



Capture를 이용하면 펄스폭을 쉽게 측정할 수 있고 IR 리모콘 코드 분석이 가능하다. CAP32B0 입력핀인 PIO1_5에 IR 출력핀을 연결하였다.



IR포멧은 가장 많이 사용되는 NEC포멧으로 처리 할수 있도록 했다.
전체 구조는 108ms동안 시작을 알리는 리드신호와 데이터 신호를 전송한다.




좀더 자세히 보면 13ms의 리드 코드(이 길이는 제조사 마다 조금씩 차이가 있으므로 가변할 수 있도록 하면 된다.)가 시작 신호를 나타낸다. 그 뒤로 32비트의 코드가 출력된다.



데이터 비트는 펄스폭이 1.125ms이면 '0'을 2.25ms이면 '1'을 나타낸다.




실제 IR모듈의 출력은 반전된 데이터를 출력하므로 Captur입력에서 폴링일때 인터럽트가 걸리도록 해서 인식하면 된다.
void InitTimer32B0(uint32_t TimerInterval)
{
    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<9);

    LPC_TMR32B0->MR0 = TimerInterval;

    LPC_IOCON->PIO1_5 &= ~0x07; /*  Timer0_32 I/O config */
    LPC_IOCON->PIO1_5 |= 0x02; /* Timer0_32 CAP0 */
    
   // Capture 0 폴링모드 인터럽트 설정
   LPC_TMR32B0->CCR = (0x1<<1)|(0x1<<2);
   
    LPC_TMR32B0->MCR = 0;   /* Interrupt and Reset on MR0 */   
    /* Enable the TIMER0 Interrupt */
    NVIC_EnableIRQ(TIMER_32_0_IRQn);
   
    //타이머 Enalbe
    LPC_TMR32B0->TCR = 1;  




모콘 테스트 동영상
리모콘 데이터가 수신되면 코드를 인식해서 LCD에 출력하는 예제




LPC1113 Capture - IR 리모콘 테스트 코드
#include "system.h"
#include "serial.h"
#include "ir_decoder.h"

extern volatile uint8_t  gIrCode, gIrCmd, gIrRead;
//-----------------------------------------------------------------------------
//Capture interrupt handler
void CT32B0_IRQHandler(void)
{
  if ( LPC_TMR32B0->IR & (0x1<<4) )
  { 
 LPC_TMR32B0->IR = 0x1<<4;
   
    //capture값을 읽어와 펄스폭 계산  
    gNewCap = LPC_TMR32B0->CR0;
    gPulseWidth = gNewCap - gOldCap;
   
    gOldCap = gNewCap; 
   
 //IR 코드 처리
 IrDecoder(gPulseWidth);
  } 
}
//-----------------------------------------------------------------------------


int main()
{
    int i = 0;
    unsigned char buf[20];
    SystemInit();

    Led1Init();
    Led1Off();
   
    Led2Init();
    Led2Off();

    U0_Init(BAUD_115200);
    LCD_Display("LPC1K IR Test\r\n");
   
    //Capture 설정   
    InitTimer32B0(SystemAHBFrequency/10000 - 1);
   
    while(1)
    {
       if(gIrRead ==1)
      {
         Led1Toggle();
            
         sprintf(buf, "A:%02X C:%02X\n", gIrCode, gIrCmd);
         LCD_Display(buf);
         gIrRead = 0;
      }       
    }
    return 0;
}



Posted by nexp

댓글을 달아 주세요

[NXP]/LPC1k2011. 8. 14. 12:42

[LPC1K EVM] Capture 테스트 - PWM 펄스폭 측정하기

[LPC1K EVM] Capture 테스트 - PWM 펄스폭 측정하기




LPC1113의 타이머는 4개의 Capture 입력을 받을 수 각각 입력에 대한 이벤트를 받을 수 있다.
테스트는 TIMER32_B1의 PWM출력을 TIMER32_B0의 CAP0입력으로 연결하여 PWM의 펄스폭을 측정하도록 했다.




Timer32B0 Capture 초기화 함수
void InitTimer32B0(uint32_t TimerInterval)
{
    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<9);

    LPC_TMR32B0->MR0 = TimerInterval;

    //CAP PIN = P1_5
    LPC_IOCON->PIO1_5 &= ~0x07; /*  Timer0_32 I/O config */
    LPC_IOCON->PIO1_5 |= 0x02; /* Timer0_32 CAP0 */
   
   //Capture 0 on both edge, interrupt enable. 
   LPC_TMR32B0->CCR = (0x1<<0)|(0x1<<1)|(0x1<<2);
       
    LPC_TMR32B0->MCR = 0;   /* Interrupt and Reset on MR0 */    

    /* Enable the TIMER0 Interrupt */
    NVIC_EnableIRQ(TIMER_32_0_IRQn);
   
    //타이머 Enalbe
    LPC_TMR32B0->TCR = 1;  


Captuer0 인터럽트 핸들러
Capture입력시 마다 Capture레지스터의 값을 저장해 펄스폭을 계산할 수 있따.
//-----------------------------------------------------------------------------
//Capture0 interrupt handler
void CT32B0_IRQHandler(void)
{
  if ( LPC_TMR32B0->IR & 0x01 )
  { 
 LPC_TMR32B0->IR = 1;    
  }
 
  if ( LPC_TMR32B0->IR & (0x1<<4) )
  { 
    // clear interrupt flag
    LPC_TMR32B0->IR = 0x1<<4;   
 
    Led1Toggle();

    //capture값을 읽어와 펄스폭 계산  
    gNewCap = LPC_TMR32B0->CR0;
    gPulseWidth = gNewCap - gOldCap;
   
    gOldCap = gNewCap;    
  } 
  return;
}
//-----------------------------------------------------------------------------



LPC1113 Capture테스트 예제 소스코드
TIMER1에서 PWM출력하고 TIMER0 caputre로 펄스폭을 측정하는 예제
int main()
{
    unsigned long period=0;
    unsigned long cnt = 0;
   
    SystemInit();

    Led1Init();
    Led1Off();
   
    Led2Init();
    Led2Off();

    U0_Init(BAUD_115200);
    DebugPrint("LPC1K UART Test\r\n");
   
   
    //CAPTURE 설정   
    InitTimer32B0(SystemAHBFrequency/1000 - 1);
   
   
    //PWM 초기화
    init_timer32PWM(TIMER_1, PWM_INTERVAL, (1<<PWM_CH2));
   enablePWM(TIMER_1, 1);
   
    //주기 설정
    period = SET_PWM(PWM_INTERVAL, 50);       //   50%
    setMatch_timer32PWM (TIMER_1, PWM_CH2, period);   
   
    while(1)
    {
        switch(U0_GetByte())
        {
        case 'g':
            DebugPrint("PulseWidth= %dus\r\n", gPulseWidth/48);
            break;  
            
        case '+':
            cnt += 1;
            period = SET_PWM(PWM_INTERVAL, cnt);
           
            DebugPrint("CNT= %d, %d\r\n", cnt, period);
            setMatch_timer32PWM (TIMER_1, PWM_CH2, period);
            break;            
           
           
        case '-':
            cnt -= 1;
            period = SET_PWM(PWM_INTERVAL, cnt);
           
            DebugPrint("CNT= %d, %d\r\n", cnt, period);
            setMatch_timer32PWM (TIMER_1, PWM_CH2, period);
            break;              
        }
   
    }
 
    return 0;
}
Posted by nexp

댓글을 달아 주세요

[NXP]/LPC1k2011. 8. 13. 16:56

[LPC1K EVM] LPC1114 타이머 테스트 - 1초 만들기

[LPC1K EVM] LPC1114 타이머 테스트 - 1초 만들기
CortexM0의 SysTick Timer 를 이용하여 1ms마다 인터럽트 발생하게 하여 1초간격으로 구동할 수 있다.
SysTick Timer는 24bit down counter타이머로 아래와 같은 구조를 가지고 있다.


인터럽트 핸들러(SysTick_Handler) 정의 해 주고 SysTick_Config()함수로 주기를 설정하면 된다.
여기서는 메인 클럭이 48Mhz이므로 1ms로 설정하기 위해 4800/48000000 = 0.001, 1ms로 설정 할 수 있다.

SysTick 타이머 초기화
SysTick_Config 함수는 core_cm0.h 에 정의되어 있다.
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
  if (ticks > SYSTICK_MAXCOUNT)  return (1);                                             /* Reload value impossible */

  SysTick->LOAD  =  (ticks & SYSTICK_MAXCOUNT) - 1;                                      /* set reload register */
  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);                            /* set Priority for Cortex-M0 System Interrupts */
  SysTick->VAL   =  (0x00);                                                              /* Load the SysTick Counter Value */
  SysTick->CTRL = (1 << SYSTICK_CLKSOURCE) | (1<<SYSTICK_ENABLE) | (1<<SYSTICK_TICKINT); /* Enable SysTick IRQ and SysTick Timer */
  return (0);                                                                            /* Function successful */
}


인터럽트 핸들러
//-----------------------------------------------------------------------------
//SysTick interrupt handler
void SysTick_Handler(void)
{
    Led2Toggle();
    TimeTick1_1ms++;
}
//-----------------------------------------------------------------------------


LPC1114 타이머 테스트 예제코드
#define SYSTICK_DELAY  48000       //1ms (48000/48M)

volatile uint32_t TimeTick1_1ms = 0;

//-----------------------------------------------------------------------------
//SysTick interrupt handler
void SysTick_Handler(void)
{
    Led2Toggle();
    TimeTick1_1ms++;
}
//-----------------------------------------------------------------------------

int main()
{
    SystemInit();

    Led1Init();
    Led1Off();
   
    Led2Init();
    Led2Off();

    //SysTick 설정   
    SysTick_Config( SYSTICK_DELAY );
   
    while(1)
    {
        //1초마다 Led 점등
        if(TimeTick1_1ms>1000)
        {
            Led1Toggle();
            TimeTick1_1ms = 0;
        }
   
    }
 
    return 0;
}




Timer32 사용하기
LPC11xx는 SysTick Timer외에 2개의 32bit 타이머와 2개의 16bit타이머가 있다.

타이머 초기화 함수
#define TIME_INTERVAL (SystemAHBFrequency/1000 - 1)

void InitTimer32B0(uint32_t TimerInterval)
{
    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<9);

    LPC_TMR32B0->MR0 = TimerInterval;

    LPC_TMR32B0->MCR = 3;   /* Interrupt and Reset on MR0 */

    /* Enable the TIMER0 Interrupt */
    NVIC_EnableIRQ(TIMER_32_0_IRQn);
   
    //타이머 Enalbe
    LPC_TMR32B0->TCR = 1;  


인터럽트 핸들러
//-----------------------------------------------------------------------------
//SysTick interrupt handler
void CT32B0_IRQHandler(void)
{
  if ( LPC_TMR32B0->IR & 0x01 )
  { 
    LPC_TMR32B0->IR = 1;    /* clear interrupt flag */
   TimeTick1_1ms++;
  }
  return;
}
//-----------------------------------------------------------------------------



LPC1114 Timer32 이용 테스트 예제 소스코드

int main()
{
    SystemInit();

    Led1Init();
    Led1Off();
   
    Led2Init();
    Led2Off();

    //SysTick 설정   
    InitTimer32B0(TIME_INTERVAL);
   
    while(1)
    {
        //1초마다 Led 점등
        if(TimeTick1_1ms>1000)
        {
            Led1Toggle();
            TimeTick1_1ms = 0;
        }
   
    }
 
    return 0;
}
Posted by nexp

댓글을 달아 주세요

[NXP]/LPC1k2011. 2. 25. 23:00

[LPC1K EVM] SPI 테스트 - 가속도 센서 테스트

[LPC1K EVM] SPI 테스트 - 가속도 센서 테스트

LCP1K SPI 특징
- Maximum SPI speed of 25 Mbit/s (master) or 4.17 Mbit/s (slave) (in SSP mode)
- Compatible with Motorola SPI, 4-wire Texas Instruments SSI, and National Semiconductor Microwire buses
- Synchronous serial communication
- Master or slave operation
- 8-frame FIFOs for both transmit and receive
- 4-bit to 16-bit frame


SPI SLK핀은 P0.10, 2.11, P0.6포트에 리맵이 가능한데 [LPC1K EVM] 보드는 0.6에 되어 있으므로 아래와 같이 설정할 수 있다.
#define IOCON_SCKLOC_SCKPIN_PIO0_10               0 // Set SCK function to pin 0.10
#define IOCON_SCKLOC_SCKPIN_PIO2_11               1 // Set SCK function to pin 2.11
#define IOCON_SCKLOC_SCKPIN_PIO0_6                1 // Set SCK function to pin 0.6

 //Set 0.6 to SSP SCK (2.11 and 0.10 can also be used)
    LPC_IOCON->SCK_LOC = IOCON_SCKLOC_SCKPIN_PIO0_6;
    LPC_IOCON->PIO0_6 = IOCON_PIO0_6_FUNC_SCK; 
    LPC_IOCON->PIO0_6  |= IOCON_PIO0_6_MODE_PULLUP;



SPI 드라이버 함수(spi.c)의 초기화 함수 및 송수신 함수를 수정하면 기존 코드를 그대로 사용할 수 있다.
void SPI0_Init(void)
{
 LPC_SYSCON->PRESETCTRL    |=  (1 <<  0);
 LPC_SYSCON->SSP0CLKDIV    =  SCB_SSP0CLKDIV_DIV4;
 LPC_SYSCON->SYSAHBCLKCTRL |= SCB_SYSAHBCLKCTRL_SSP0;

    /* Set P0.8 to SSP MISO */
    LPC_IOCON->PIO0_8 &= ~IOCON_PIO0_8_FUNC_MASK;
    LPC_IOCON->PIO0_8 |= IOCON_PIO0_8_FUNC_MISO0;
    LPC_IOCON->PIO0_8  |= IOCON_PIO0_8_MODE_PULLUP; 
 
    /* Set P0.9 to SSP MOSI */
    LPC_IOCON->PIO0_9  &= ~IOCON_PIO0_9_FUNC_MASK;
    LPC_IOCON->PIO0_9  |= IOCON_PIO0_9_FUNC_MOSI0;
    LPC_IOCON->PIO0_9  |= IOCON_PIO0_9_MODE_PULLUP;

 //Set 0.6 to SSP SCK (2.11 and 0.10 can also be used)
    LPC_IOCON->SCK_LOC = IOCON_SCKLOC_SCKPIN_PIO0_6;
    LPC_IOCON->PIO0_6 = IOCON_PIO0_6_FUNC_SCK; 
    LPC_IOCON->PIO0_6  |= IOCON_PIO0_6_MODE_PULLUP;
  
    // Set clock polarity
 Cbi(LPC_SSP0->CR0, SSP_SSP0CR0_CPOL_MASK);

 // Set edge transition
 Sbi(LPC_SSP0->CR0, SSP_SSP0CR0_CPHA_SECOND); 


 /* Master mode */
 LPC_SSP0->CR1 = SSP_SSP0CR1_SSE_ENABLED | SSP_SSP0CR1_MS_MASTER | SSP_SSP0CR1_LBM_NORMAL;
 
    /* Clock prescale register must be even and at least 2 in master mode */ 
    LPC_SSP0->CPSR = 2;
}


SUINT SPI0_WriteReadByte(SUINT Data)
{
 /* Move on only if NOT busy and TX FIFO not full. */
 while ((LPC_SSP0->SR & (SSP_SSP0SR_TNF_NOTFULL | SSP_SSP0SR_BSY_BUSY)) != SSP_SSP0SR_TNF_NOTFULL);
 LPC_SSP0->DR = Data;
 
 while ( (LPC_SSP0->SR & (SSP_SSP0SR_BSY_BUSY|SSP_SSP0SR_RNE_NOTEMPTY)) != SSP_SSP0SR_RNE_NOTEMPTY );
 return(LPC_SSP0->DR);  
}


LPC1113 SPI 가속도 센서 테스트
가속도 센서를 테스트하기 위해 [NET-EVM]보드를 이용하였다. [NET-EVM]보드의 가속도 센서 CS는 CN7의 P8에 연결되어 있는데 LPC1K EVM보드는 핀수가 적어 할당되어 있지 않다.
그래서 점퍼를 이용하여 P3.5에 연결하여 테스트 하였다.


Posted by nexp

댓글을 달아 주세요

[NXP]/LPC1k2011. 1. 1. 23:00

[LPC1K-SM EVM] LPC1113 ADC테스트

[LPC1K-SM EVM] LPC1113 ADC테스트



LPC1K는 10비트 ADC(Sample time 2.44 μs)가 있다. VR을 이용하여 ADC값을 그래프로 출력하는 테스트 예제를 작성해 보았다.

LPC1113 ADC초기화
void AdcInit(unsigned int AD_Chan)
{
    unsigned long reg;
    unsigned char CLKDIV;

    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<13);
    CLKDIV = (uint8_t)ceil((double)SystemCoreClock/(double)4500000);
    reg = AD_Chan;
   
    InitAdcPort(AD_Chan);
   
    //ADC Clock 
    reg |= (CLKDIV << 8);
   
    LPC_ADC->CR = reg;
    LPC_ADC->INTEN = 0xFF & AD_Chan;
   
 LPC_ADC->CR |= (1 << 24);   
   
//    NVIC_EnableIRQ(ADC_IRQn);
}


ADC Read함수
unsigned int AdcRead(unsigned char port)
{
    return (0x3FF & (LPC_ADC->DR[port] >> 6));
}


LPC1113 ADC테스트 예제 코드
int main()
{
 unsigned int adc_value = 0;
 
    SystemInit();

    U0_Init(BAUD_115200);
    DebugPrint("LPC1K ADC Test\r\n");
   
    Led1Init();
    Led1On();

 //ADC 초기화
 AdcInit(BIT0);    

    while(1)
    {
  //LPC1K ADC Polling
  adc_value = AdcRead(BIT0);
  DebugPrint("%d\r\n", adc_value);
  Delay(10); 
 }
    
    return 0;
}


LPC1K ADC테스트 동영상
Posted by nexp

댓글을 달아 주세요