Busan IT/ARM Controller2015. 11. 2. 12:06

==================================Outline====================================

PWM를 사용한 LED 불 밝기 조절

----------------------------------------------------------------------------

 

PWM를 사용한 LED 불 밝기 조절

 

PA0번 핀의 기능을 확인해보자.

 

[PA0]

 

 

PA0PWM의 출력으로 사용 설정을 해준다

 

1. PA/AFIO/TIM2 clock 공급: RCC->APB2ENR, APB1ENR

2. PA 설정: PA0 출력 설정. AFIO를 사용한다. 내부적인 특수 기능을 사용하기 때문에 AFIO를 사용해야 한다.

 

출력 설정 시 open drainpush pull을 사용할 수 있다. push/pull은 입출력시 high/low값이 확실하게 구분된다. open drain값은 high출력이 없고 low만 존재한다. open drain은 그라운드 연결을 스위치로 제어하면서 제어하는 방식을 뜻한다.

 

3. TIM2 설정: TIM2_ARR은 카운팅 시 꼭지점이다. TIM2_CCR은 카운터의 비교 값이 들어있는 레지스터이다. 카운터의 값이 CCR과 일치할 경우 인터럽트가 발생한다.

 

 

특정 키를 입력 받았을 때 불 밝기가 조절 되도록 코딩을 해보자.





/*** 소스 ***/

#include <stm32f10x.h>
volatile unsigned int Timer2_Counter=0;
 
void init_port(void)
{    
    GPIO_InitTypeDef PORTA;
    GPIO_InitTypeDef PORTC;
 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE);
     
    PORTA.GPIO_Pin = GPIO_Pin_0;
    PORTA.GPIO_Mode = GPIO_Mode_AF_PP;
    PORTA.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_Init(GPIOA, &PORTA);
     
    PORTC.GPIO_Pin = GPIO_Pin_12;
    PORTC.GPIO_Mode = GPIO_Mode_Out_PP;
    PORTC.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_Init(GPIOC, &PORTC);
}
 
void TIM2_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET)
    {
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // Clear the interrupt flag
        Timer2_Counter++;
        GPIOC->BRR = GPIO_Pin_12;  // PB0 OFF
    }
 
    if(TIM_GetITStatus(TIM2,TIM_IT_CC1) != RESET)
    {
        TIM_ClearITPendingBit(TIM2,TIM_IT_CC1);
        GPIOC->BSRR = GPIO_Pin_12;  // PB0 ON
    }
}
 
void init_Timer2()
{
    NVIC_InitTypeDef NVIC_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef OutputChannel;    
     
    /* TIM2 Clock Enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
     
    /* Enable TIM2 Global Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
     
    /* TIM2 Initialize */   
    TIM_TimeBaseStructure.TIM_Period=100-1// 100kHz
    TIM_TimeBaseStructure.TIM_Prescaler=24-1;
    TIM_TimeBaseStructure.TIM_ClockDivision=0;
    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
     
    /* TIM2 PWM Initialize */
    OutputChannel.TIM_OCMode = TIM_OCMode_PWM1;
    OutputChannel.TIM_OutputState=TIM_OutputState_Enable;
    OutputChannel.TIM_OutputNState=TIM_OutputNState_Enable;
    OutputChannel.TIM_Pulse=50-1// 50% duty ratio
    OutputChannel.TIM_OCPolarity=TIM_OCPolarity_Low;
    OutputChannel.TIM_OCNPolarity=TIM_OCNPolarity_High;
    OutputChannel.TIM_OCIdleState=TIM_OCIdleState_Set;
    OutputChannel.TIM_OCNIdleState=TIM_OCIdleState_Reset;
    TIM_OC1Init(TIM2,&OutputChannel);
     
    /* TIM2 Enale */
    TIM_Cmd(TIM2,ENABLE);
    TIM_ITConfig(TIM2,TIM_IT_Update | TIM_IT_CC1 ,ENABLE); // interrupt enable
}
 
void make_pwm(u16 val)
{
    TIM_OCInitTypeDef OutputChannel;
     
    OutputChannel.TIM_OCMode = TIM_OCMode_PWM1;
    OutputChannel.TIM_OutputState=TIM_OutputState_Enable;
    OutputChannel.TIM_OutputNState=TIM_OutputNState_Enable;
    OutputChannel.TIM_Pulse=val;
    OutputChannel.TIM_OCPolarity=TIM_OCPolarity_Low;
    OutputChannel.TIM_OCNPolarity=TIM_OCNPolarity_High;
    OutputChannel.TIM_OCIdleState=TIM_OCIdleState_Set;
    OutputChannel.TIM_OCNIdleState=TIM_OCIdleState_Reset;
    TIM_OC1Init(TIM2,&OutputChannel);
}
 
void delay(unsigned int del)
{
    Timer2_Counter=0;
    while(Timer2_Counter < del);
}
 
int main()
{
    u16 i;
    SystemInit();
    init_port();
    init_Timer2();
     
    while(1)
    {        
        for(i=0; i<100; i++)
        {
            TIM2->CCR1 = i;
            delay(100);
        }
         
        for(i=98; i>0; i--)
        {
            TIM2->CCR1 = i;
            delay(100);
        }
    }
}


반응형

'Busan IT > ARM Controller' 카테고리의 다른 글

USART를 활용한 LED ON/OFF  (0) 2015.10.30
Timer를 활용한 LED제어, LCD 제어  (0) 2015.10.20
Timer  (0) 2015.10.19
Advanced-control timers(TIM1&8)  (0) 2015.10.16
인터럽트 코드 분석  (0) 2015.10.13
Posted by newind2000
Busan IT/ARM Controller2015. 10. 30. 16:46

==================================Outline====================================

USART

USART를 활용한 LED ON/OFF

----------------------------------------------------------------------------

 

USART

- 싱크로모터 AC모터의 종류 배에 들어가는 풍향 풍속계에 사용 비쌈 사용자가 제어할 부분이 없다.

 

- 비동기 통신: asynchronous communication

 

- 통신 방식은 단방향, 양방향. 단방향의 예는 라디오. 양방향은 다시 반이중(half duplex), 전이중(full duplex)방식, 반이중은 무전기, 전이중은 전화기

 

- Baud rate4.5Mbits 이것을 바이트로 나누면 562KByte이다. 속지 말자

 

** MAX232

 

- ATmega보다 4배 빠르다. 클럭의 차이에서 온다.

 

- 송수신 비트가 나눠져 있다.

 

- 그 외의 내용은 훑어본다.

 

USART 코딩을 해보자. Keil 편집기를 실행하고 새 프로젝트를 만든다. 실행환경에서 'USART'를 추가적으로 체크해 주어야 한다.

 

 

//RCC = Reset and clock control



[USART 블록 다이어그램]

 

 

- RTS, CTS핀은 많이 사용되진 않는다. RS485제어에 사용된다. 반이중 통신에 사용된다.

 

- USART_BRRBaud Rate 설정에 사용되는데 firmware library의 레퍼런스를 사용하면 간단하다.

 

- 직렬통신 시 통신 방법은 두 가지로 나뉜다. 폴링과 인터럽트이다. 수신시에는 인터럽트 방식을 발신시에는 폴링 방식을 많이 사용한다. 데이터 수신 시 프로그램은 입력이 있을 때까지 대기하기 때문에 인터럽트 방식을 사용하는 것이 좋다. 

 

 

 

USART를 활용한 LED On/Off

 

하이퍼터미널에서 ‘+’ 키를 누르면 LED(PA0 떠는 PC12)가 켜지고 ‘-’키를 누르면 LED가 꺼지도록 코딩해보자.

 

펌웨어 라이브러리에 존재하는 함수를 사용하여 USART를 설정하고 송/수신 함수를 만들어보자.




 

//펌웨어 라이브러리에 제시된 예제를 용도에 맞게 수정하면 편하다.

]

'USART_GetFlagStatus' 함수를 사용하여 송/수신 함수를 만들 것이다. /수신 상태를 확인하는 플래그의 상태를 확인한 후 데이터가 존재하지 않을 때 ‘while'을 사용하여 프로그램을 잡아주면 된다.

USART를 설정 후 설정된 USART채널을 사용할 수 있도록 만들어주어야 한다.

 


 

 

 

 

 

/*** 코드 ***/


#include <stm32f10x.h>

void Clocks(void)
{
  /* Enable GPIOA, USART1 clocks */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | 
                        RCC_APB2Periph_USART1|
                        
                        RCC_APB2Periph_AFIO, ENABLE);
  
  return;
}

void USART1_init(void)
{
  /* The following example illustrates how to configure the USART1 */
  USART_InitTypeDef USART_InitStructure;
  USART_InitStructure.USART_BaudRate = 9600;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
  USART_Init(USART1, &USART_InitStructure);
  
  /* Enables the USART1 transmit interrupt */
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
  
  return;
}

void PA9_AF_out()
{
  /* Configure GPIO9 Input Floating mode */
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
  return;
}

void PA10_in()
{
  /* Configure GPIO9 Input Floating mode */
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);                  
  
  return;
}

void PA0_out()
{
  /* Configure GPIO9 Input Floating mode */
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);               
  
  return;
}

void Tx_Data(unsigned char Tx)
{
  /* chekcing status of Tx buffer */
  while0 == USART_GetFlagStatus(USART1, USART_FLAG_TXE) );
  /* Send one HalfWord on USART1 */
  USART_SendData(USART1, Tx);  
  
  return;
}
unsigned char Rx_Data()
{
  unsigned char uiRx;  
  while0 == USART_GetFlagStatus(USART1, USART_FLAG_RXNE) );     
  uiRx = USART_ReceiveData(USART1);
      
  return uiRx;
}


void USART1_IRQHandler()
{
  unsigned char ucRx;
  
  if(USART_GetITStatus(USART1, USART_IT_RXNE) == +-SET )
  {
    ucRx = Rx_Data();
    switch(ucRx)
    {
      default:
        break;
      
      case '+':                    
        GPIOA->ODR = 0x01;
        
        break;
      
      case '-':               
        GPIOA->ODR = 0x00;
        break;        
        
    }
    
  }
  /* Clear the CTS interrupt pending bit */
  USART_ClearITPendingBit(USART1, USART_IT_RXNE);
  
  
  return;
}

void NVIC_init()
{
  NVIC_InitTypeDef NVIC_InitStructure;
  /* Enable USART1 global interrupt with Preemption Priority 1 and Sub
  Priority as 5 */

  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 5;
  NVIC_Init(&NVIC_InitStructure);
  
  return;
  
}


int main(void)
{
  unsigned char ucRx;
  Clocks();
  PA9_AF_out();
  PA10_in();
  USART1_init();
  NVIC_init();
  PA0_out();
  USART_Cmd(USART1, ENABLE);     

  while(1)
  {   
    ;    
  }
  
  return 0;
}


반응형

'Busan IT > ARM Controller' 카테고리의 다른 글

PWM를 사용한 LED 불 밝기 조절  (0) 2015.11.02
Timer를 활용한 LED제어, LCD 제어  (0) 2015.10.20
Timer  (0) 2015.10.19
Advanced-control timers(TIM1&8)  (0) 2015.10.16
인터럽트 코드 분석  (0) 2015.10.13
Posted by newind2000
Busan IT/ARM Controller2015. 10. 20. 13:37

==================================Outline====================================

Timer를 활용한 LED제어

LCD 제어

----------------------------------------------------------------------------

 

Timer를 활용한 LED제어

 

 

Timer를 사용하여 1초에 한번 타이머 인터럽트가 발생하게 한 후에 딜레이 함수를 만들어 보자.

 

만드는 방법은 간단하다. 전역 변수를 선언해준 후 인터럽트 함수에서 1씩 더해준 다음 딜레이 함수를 만들어 딜레이 함수의 인자 값과 전역 변수의 값을 비교하는 'while'문을 사용하여 프로그램을 잡아주면 된다.

 

unsigned int uiDelay;

 

void TIM2_IRQHandler(void)

{

if(TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET)

{

// Timer Interrupt 가 처리하는 내용

//GPIOA->ODR ^= (uint32_t)0x01;

TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // Clear the interrupt flag

++uiDelay;

}

return;

}

 

 

void Delay_s(unsigned int uiNum)

{

uiDelay = 0;

while(uiNum > uiDelay) ;

}

 

이를 활용하여 PC12에 연결된 LED5초 간격으로 깜빡이게 하고, PA0에 연결된 LED1초 간격으로 깜빡이는 프로그램을 작성해보자.




/*** 코드 ***/

#include <stm32f10x.h>

#define ON 0x01
#define OFF 0x00

unsigned int uiDelay;

void  TIM2_IRQHandler(void)
{
    
  if(TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET)
    {
      // Timer Interrupt 가 처리하는 내용
      //GPIOA->ODR ^= (uint32_t)0x01;
                
      TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // Clear the interrupt flag
      ++uiDelay;  
    }
    
    return;
}

void PA0_out(void)
{
  /* Configure all the GPIOA in Input Floating mode */
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void TIM2_init(void)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  
  /* TIM2 Initialize */   
    TIM_TimeBaseStructure.TIM_Period = (1200-1); 
    TIM_TimeBaseStructure.TIM_Prescaler = (60000-1); 
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
}
void PC12_out(void)
{
    /* Configure all the GPIOA in Input Floating mode */
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
  
}

void NVIC_init(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  /* Enable TIM2 global interrupt with Preemption Priority 0 and Sub Priority as 2 */
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}
void Delay_s(unsigned int uiNum)
{
  uiDelay = 0;
  while(uiNum > uiDelay) ;
}
void init(void)
{
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  PA0_out();
  PC12_out();
  TIM2_init();
  NVIC_init();  
  TIM_Cmd(TIM2, ENABLE);    // Timer 활성화
  TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);  // Timer Interrupt 활성화
}

int main(void)
{
  unsigned int uiCnt;
  
  // 사용할 기능 : GPIOA0, TIM2
  init();
  
  while(1)
  {
    //PC12에 연결된 LED를 5초 간격으로 깜빡이게 하고,
    //PA0에 연결된  LED를 1초 간격으로 깜빡이는 프로그램을 작성
    for(uiCnt = 0; uiCnt < 5; ++uiCnt)
    {
      Delay_s(1);
      GPIOA->ODR ^= (uint32_t)0x01;      
    }
    GPIOC->ODR ^= (uint32_t)0x1000;
      //GPIO_SetBits(GPIOC, GPIO_Pin_12);
  }
}

 

 

 

LCD 제어

 

우선 회로도의 핀 설명을 보고 회로 연결을 한다.

 



PORTGPORTF를 사용해서 코딩을 한다. 일반출력은 F, INSTRUCTIONG포트를 사용한다.

 

 

 

 

 

 

 

반응형

'Busan IT > ARM Controller' 카테고리의 다른 글

PWM를 사용한 LED 불 밝기 조절  (0) 2015.11.02
USART를 활용한 LED ON/OFF  (0) 2015.10.30
Timer  (0) 2015.10.19
Advanced-control timers(TIM1&8)  (0) 2015.10.16
인터럽트 코드 분석  (0) 2015.10.13
Posted by newind2000
Busan IT/ARM Controller2015. 10. 19. 13:48

==================================Outline====================================

Timer

----------------------------------------------------------------------------

 

reference manual p/372

 

타이머는 클럭의 설정의 따라 사용이 달라지게 된다.

 

//시간과 관련된 기능들은 모두 클럭의 영향을 받는다.

 

 


 

캡쳐/비교 채널은 쉐도우 레지스터를 가지고 있는다. 이것은 필요한 정보를 잠시 저장하는 레지스터이다.

 

 

타이머를 사용한 딜레이 함수를 만들어 보자.

 

함수 이름 : Delay_ms(uint8_t time)

 

ex) 8ms 지연 -> Delay_ms(8); 

 

1ms 간격의 Timer Interrupt 함수를 우선 만들어야 한다.

 

1ms Timer Interrupt 서비스 루틴 안에서 별도의 카운트가 필요하다.


코딩 순서는 다음과 같다.

- 클럭을 공급한다.

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);


- 타이머 설정을 해준다.(TIM2, NVIC)


void  TIM2_IRQHandler(void)

{

if(TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET)

    {

// Timer Interrupt 가 처리하는 내용

//GPIOA->ODR ^= (uint32_t)0x01;

     

TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // Clear the interrupt flag

++uiDelay;

    }

return;

}

void TIM2_init(void)

{

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

/* TIM2 Initialize */   

    TIM_TimeBaseStructure.TIM_Period = (1200-1); 

    TIM_TimeBaseStructure.TIM_Prescaler = (60-1); 

    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);

}


void NVIC_init(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

/* Enable TIM2 global interrupt with Preemption Priority 0 and Sub Priority as 2 */

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

- 타이머 작동 확인을 위한 내부 LED설정을 해준다.

void PA0_out(void)

{

/* Configure all the GPIOA in Input Floating mode */

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(GPIOA, &GPIO_InitStructure);

}




/*** 소스 ***/

#include <stm32f10x.h>

#define ON 0x01
#define OFF 0x00

unsigned int uiDelay;

void  TIM2_IRQHandler(void)
{
    
  if(TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET)
    {
      // Timer Interrupt 가 처리하는 내용
      //GPIOA->ODR ^= (uint32_t)0x01;
                
      TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // Clear the interrupt flag
      ++uiDelay;  
    }
    
    return;
}

void PA0_out(void)
{
  /* Configure all the GPIOA in Input Floating mode */
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void TIM2_init(void)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  
  /* TIM2 Initialize */   
    TIM_TimeBaseStructure.TIM_Period = (1200-1); 
    TIM_TimeBaseStructure.TIM_Prescaler = (60-1); 
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
}

void NVIC_init(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  /* Enable TIM2 global interrupt with Preemption Priority 0 and Sub Priority as 2 */
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}
void Delay_ms(unsigned int uiNum)
{
  uiDelay = 0;
  while(uiNum > uiDelay) ;
}

int main(void)
{
  // 사용할 기능 : GPIOA0, TIM2
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  PA0_out();
  TIM2_init();
  NVIC_init();
  
  TIM_Cmd(TIM2, ENABLE);    // Timer 활성화
  TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);  // Timer Interrupt 활성화
  
  while(1)
  {
    Delay_ms(1000);
    GPIOA->ODR ^= (uint32_t)0x01;
  }
}

 

반응형

'Busan IT > ARM Controller' 카테고리의 다른 글

USART를 활용한 LED ON/OFF  (0) 2015.10.30
Timer를 활용한 LED제어, LCD 제어  (0) 2015.10.20
Advanced-control timers(TIM1&8)  (0) 2015.10.16
인터럽트 코드 분석  (0) 2015.10.13
Interrupt  (0) 2015.10.12
Posted by newind2000
Busan IT/ARM Controller2015. 10. 16. 12:48

==================================Outline====================================

Advanced-control timers(TIM1&8)

----------------------------------------------------------------------------

 

Advanced-control timers(TIM1&8)

 

RM0008 p/292

 

//PWM은 인터럽트가 아니라 단순 비교 출력이다.

 

타이머/카운터와 인터럽트는 분리하여 설명할 수 없다.

 

타이머/카운터와 PWM의 공통점

- 타이머/카운터를 사용한다

- 클럭의 속도에 따라 결과 값이 바뀐다.



Timer의 모드는 아래와 같다. 

1. Base Mode

2. Counter Mode

- up count

- down count

- center-aligned

...











 

 

반응형

'Busan IT > ARM Controller' 카테고리의 다른 글

Timer를 활용한 LED제어, LCD 제어  (0) 2015.10.20
Timer  (0) 2015.10.19
인터럽트 코드 분석  (0) 2015.10.13
Interrupt  (0) 2015.10.12
ARM Clock 설정  (0) 2015.10.12
Posted by newind2000
Busan IT/ARM Controller2015. 10. 13. 13:27

==================================Outline====================================

인터럽트 코드 분석

----------------------------------------------------------------------------

 

EXTI는 외부 인터럽트를 말한다.

 

인터럽트는 크게 내부 인터럽트(소프트웨어)와 외부 인터럽트로 나뉜다.

 

ARM에서 인터럽트를 설정할 때 인터럽트의 종류와 함께 인터럽트자체 설정을 해주는데 이때 사용하는 인터럽트 설정이 ‘NVIC’이다.

 

인터럽트의 종류가 바뀌면 핸들러의 이름을 바꾸어 주어야 한다.

 

void EXTI2_IRQHandler(void)

{

...

}

 

void NVIC_init(void)

{

/* Enable and set EXTI2 Interrupt to the lowest priority */

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;

...

}

 

우선 순위(priority)0 - 15까지 나뉜다. 숫자가 낮을수록 우선순위가 높다.

 

외부 인터럽트를 사용한다는 것은 GPIO의 특수기능을 사용한다는 것이다. 때문에 특수기능을 활성화 시키는 명령어를 추가해주어야 한다.

 



 

GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource2);

외부 pin을 인터럽트로 활성화시키는 코드이다.

 

코드 속 내용을 하나씩 뜯어서 분석해보자.

 

 

반응형

'Busan IT > ARM Controller' 카테고리의 다른 글

Timer  (0) 2015.10.19
Advanced-control timers(TIM1&8)  (0) 2015.10.16
Interrupt  (0) 2015.10.12
ARM Clock 설정  (0) 2015.10.12
내부 LED 반전 프로그램 만들기  (0) 2015.10.08
Posted by newind2000
Busan IT/ARM Controller2015. 10. 12. 12:59

==================================Outline====================================

Interrupt

----------------------------------------------------------------------------

 

 

인터럽트 사용에 대해 알아보자. 레지스터 데이터시트 p/196이다.

 

 




 

회색으로 표시된 인터럽트는 시스템 인터럽트이고 흰색으로 표시된 것들은 소프트웨어 인터럽트이다.

 

종류가 많다는 것을 알 수 있다.

 

이번 시간에 주로 살펴볼 인터럽트는 ‘EXTI’라는 인터럽트이다. 20개의 edge 감지기를 가지고 있다.

 

주요 특징을 살펴보자.




 

firmware 라이브러리 함수를 사용하여 설정해주면 된다.

 

원하는 인터럽트를 선택해야 한다.

 

 

주요 레지스터들을 살펴보자.




 

인터럽트 레지스터와 이벤트 마스크 레지스터에서 원하는 자리를 set해주면 해당 인터럽트가 작동하게 된다.

 

상승에지와 하강에지 인터럽트를 설정하는 레지스터

상승에지와 하강에지 인터럽트를 동시에 set하는 것도 가능하다.

 

‘EXTI_PR'은 인터럽트가 발생하면 ‘1’로 바뀌는 레지스터이다.



 

변수 생성 시 24가지 종류의 변수 타입을 참고한다.

 

** 4byte 변수는 int가 아니라 long임을 주의하자.





 

EXTI설정은 쉬우나 NVIC설정은 까다롭다.

 

 

PM0056 프로그래밍 매뉴얼 p/118




원하는 인터럽트 자리에 ‘1’를 입력해주면 해당 인터럽트가 활성화된다.

 






각 레지스터들의 기능을 참고하여 프로그래밍을 해보자.

firmware 라이브러리를 사용하면 간단하다. 

 

- 전원 ON LED(PA0)1초 간격으로 깜빡거리게 만든다.

- 스위치(PA2)를 누르면 깜빡거리는 기능이 멈춘다.

- 스위치(PA2)를 떼면 다시 정상 작동한다.

 








#include <stm32f10x.h>
#include <misc.h>


vu32 vulCnt;

#define Delay(x) for(vulCnt = 0; vulCnt < x; ++vulCnt)

//    EXTI2_IRQn
void EXTI2_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line2) != RESET)
    {
      //  처리할 내용  : while (A가 눌러진 상태)
      while0==(GPIOA->IDR & 0x04) )
      {
           ;
      }        
      
    }
    EXTI_ClearITPendingBit(EXTI_Line2);
}
void EXTI2_init(void)
{
  /* Enables external lines 2 interrupt generation on falling edge */
  EXTI_InitTypeDef EXTI_InitStructure;
  EXTI_InitStructure.EXTI_Line = EXTI_Line2;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);
}

void NVIC_init(void)
{
  /* Enable and set EXTI2 Interrupt to the lowest priority */
  NVIC_InitTypeDef NVIC_InitStructure;   
  NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

void PA2_in(void)
{
    /* Configure all the GPIOA in Input Floating mode */
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
}

void PA0_out(void)
{
      /* Configure all the GPIOA in Input Floating mode */
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
}



void Init(void)
{
    EXTI2_init();
    NVIC_init();
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);
    PA0_out();
    PA2_in();    
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource2);

}

int main(void)
{
    Init();
    while(1)
    {
      GPIO_SetBits(GPIOA, GPIO_Pin_0);
      Delay(1000000);
      GPIO_ResetBits(GPIOA, GPIO_Pin_0);
      Delay(1000000);        
    }
  
    return 0;
}


반응형

'Busan IT > ARM Controller' 카테고리의 다른 글

Advanced-control timers(TIM1&8)  (0) 2015.10.16
인터럽트 코드 분석  (0) 2015.10.13
ARM Clock 설정  (0) 2015.10.12
내부 LED 반전 프로그램 만들기  (0) 2015.10.08
ARM 3 Core Test, 내부 LED 동작 프로그래밍  (0) 2015.10.06
Posted by newind2000
Busan IT/ARM Controller2015. 10. 12. 09:16

==================================Outline====================================

ARM Clock 설정

----------------------------------------------------------------------------

 

manual p/90 Reset

 

Reset3가지 종류로 나눈다.

1. 시스템(system)

2. 파워(power)

3. 백업 도메인(backup domain)

 

리셋은 두 가지 볼 수 있다.

1. Low Active(/RST)

2. High Active(RST(bar))

 

회로에는 반드시 리셋이 존재해야 한다.

 

기존의 ARM의 클럭은 8MB이지만 이를 증폭하여 사용할 수 있다.

 

 

증폭을 활용하여 최대로 만들 수 있는 클럭은 72MHZ이다.

 


 

 

클럭을 증폭시키기 위해 사용하는 것이 PLL이다.

 

시스템 클럭은 MUX에서 존재하는 클럭 중 하나를 선택한 것이 된다.


해당 비트에 ‘1’을 삽입하면 해당 기능이 리셋되게 된다.

 

ENR레지스터는 리셋의 반대



 

반응형

'Busan IT > ARM Controller' 카테고리의 다른 글

인터럽트 코드 분석  (0) 2015.10.13
Interrupt  (0) 2015.10.12
내부 LED 반전 프로그램 만들기  (0) 2015.10.08
ARM 3 Core Test, 내부 LED 동작 프로그래밍  (0) 2015.10.06
ARM Core3 M3 프로그래밍 환경 설정  (0) 2015.10.05
Posted by newind2000
Busan IT/ARM Controller2015. 10. 8. 08:34

==================================Outline====================================

내부 LED 반전 프로그램 만들기

----------------------------------------------------------------------------

 내부 LED 반전 프로그램 만들기



 

pull-up, pull-down은 주로 외부에서 설정해준다.

 

 

출력모드가 push-pullopen-drain으로 나누어져 있다.

push-pull은 내부의 신호를 그대로 전달하는 것이다. 내부 회로가 설계되어 있어 안정적이다.

 

open-drain은 전압불충분 현상을 해결하기 위한 방법이다. BJT는 전류 제어 형태의 트랜지스터이다. BJT는 전류가 많이 흘러 열이 발생하게 되는데 이를 보완하기 위해 만들어진 것이다 FET이다.

 

FET(FIELD EFFECTIVE TRANSISTOR)N채널과 P채널로 나누어진다.

 

MOS(METAL OXIDE SILICON)

 

전기/전자분야에서 Z는 임피던스 즉 FLOATING상태를 뜻한다.

 




 

코딩할 때 표를 보면서 설정하면 된다.

 

 

MCU에 있는 LED가 보드에 위치한 LED와 반전되도록 코딩을 해보자.

 

 

PORTC에 클럭을 공급해주고 PORTC 12번 핀에 highlow를 넣어주는 코딩만 하면 된다.






반응형

'Busan IT > ARM Controller' 카테고리의 다른 글

Interrupt  (0) 2015.10.12
ARM Clock 설정  (0) 2015.10.12
ARM 3 Core Test, 내부 LED 동작 프로그래밍  (0) 2015.10.06
ARM Core3 M3 프로그래밍 환경 설정  (0) 2015.10.05
ADC 전압측정  (0) 2015.09.18
Posted by newind2000
Busan IT/ARM Controller2015. 10. 6. 14:00

==================================Outline====================================

ARM 3 Core 동작 Test

Keil 컴파일러 사용법

내부 LED 동작 프로그래밍

----------------------------------------------------------------------------

 

ARM 3 Core 동작 Test

 

SERIAL 단자에 USB를 연결하고 카메라를 장착한다.

 

 

하이퍼 터미널을 실행시켜 통신 설정을 해준다.

 



 

[1]번부터 [a]까지 실행시켜 ARM3가 제대로 동작하는지 확인한다.

 

[1]'LED test'LED 단자에 불이 조작에 따라 켜고 꺼지면 정상 작동하는 것이다.

 

[2]'Timer test'LED 단자의 일정한 간격으로 깜빡거린다면 정상 작동하는 것이다.

 

[3]RTC test는 실시간으로 시간이 작동하면 정상 작동이다.

 

...

 

Keil 컴파일러 사용법

 

Keil 컴파일러는 알고 쓰면 편하지만 모르면 복잡한 컴파일러이다.

 

- Ctrl키를 누른 상태에서 마우스 휠을 위로 움직이면 글자 크기가 늘어나고 휠을 아래로 내리면 글자 크기가 줄어든다.

 

- 사용가능 ARM Core의 목록을 보고 싶다면 Pack Installer를 클릭해서 정보를 살펴보면 된다.

- 실행환경 설정을 하고 싶다면 주사위 같이 생긴 버튼을 눌러주면 된다.




- Ctrl + n을 생성하여 코드를 작성할 문서를 생성해주고 원하는 이름과 파일형식을 지정하여 저장해준다.




생성된 파일을 프로젝트에 추가해주어야 한다.




- 새 프로젝트를 생성하기 위해서는 우선 새로운 폴더를 하나 만들고 'Project' -> 'New uVision Project...' 를 선택한 후 폴더의 경로를 지정해주면 해당 폴더 안에 파일들이 생성된다.


 

폴더를 지정해 주고 나면 디바이스 설정 창이 나온다. 디바이스 설정 창에서 Software Packs을 선택하고 search에서는 디바이스의 전체 이름을 검색한 후 선택해준다.

실행 환경 설정에서 'Core', 'Startup', 'Framework', 'GPIO', 'RCC'의 체크박스를 선택해준다.

(추가 사용할 기능이 있으면 추가적으로 체크박스를 선택해주면 된다.)

체크 박스를 선택했을 시 노란색이 뜨면 경고이다. 경고 메세지를 확인하여 수정해주면 노란색이 초록색으로 변동하게 된다.

 

 

내부 LED 동작 프로그래밍



PA2가 low인 상태에서 PA0가 high일 때 LED에 불이 들어오게 된다.




 해당 프로그램을 3가지 방식으로 작성해본다.


1. 단순 코딩(메모리의 주소 값을 사용하여 메모리에 직접 접근)

2. 헤더 파일을 사용

3. firmware를 사용

 

데이터시트에는 레지스터 정보가 없다. 레지스터 정보를 확인하려면 RM0008이라는 'Reference manual'을 참조해야 한다. 페이지 수가 천페이지를 넘기 때문에 원하는 내용을 효율적으로 검색하기 위해서 책갈피를 사용하해야 한다.

 

GPIO(General Purpose Input/Output)가 아니면 APIO(Alternative Purpose Input/Output)라고 생각하면 된다.

 

GPIO를 사용하여 LED를 동작시키는 코딩을 해보자.

 

- GPIO레지스터는 설정 레지스터, 데이터 레지스터, /리셋 레지스터와 잠금레지스터로 구성된다.

- 지금까지 사용한 output방식은 push-pull 방식이다. open-drain방식은 따로 설명할 예정이다.


GPIO_CRLGPIO 0 - 7번까지 입출력 설정을 해주는 레지스터이다.

 


output모드는 어떤 값을 넣어도 상관없다.




 

BSRR레지스터로 BRR의 기능을 사용할 수 있다.

 

컴파일 시 요술봉을 누른 후

 





 

클럭 공급이 필요하다.

 

 

define 값을 사용하지 않고 header 파일을 사용해 코딩을 해보자.

 

헤더 파일을 사용할 때 원하는 구조체의 양식을 보고 싶다면 구조체 위에서 'F12'키를 누르면 구조체가 있는 자리로 이동한다.

 

firmware 라이브러리를 활용하여 프로그램을 만들 수도 있다.




/*** 코드 ***/

#include <stm32f10x.h>

/*
#define GPIOA_CRL   (*((volatile unsigned int *)0x40010800))
#define GPIOA_IDR   (*((volatile unsigned int *)0x40010808))
#define GPIOA_ODR   (*((volatile unsigned int *)0x4001080C))
#define GPIOA_BRR   (*((volatile unsigned int *)0x40010810))
#define GPIOA_BSRR  (*((volatile unsigned int *)0x40010814))
#define RCC_APB2ENR  (*((volatile unsigned int *)0x40021018))
*/
  

void PA2_in(void)
{
    /* Configure all the GPIOA in Input Floating mode */
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
}

void PA0_out(void)
{
      /* Configure all the GPIOA in Input Floating mode */
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
}
int main(void)
{
//RCC->APB2ENR |= 0x04;    //clock supply to GPIOA
//RCC_APB2ENR |= 0x04;
/* Enable GPIOA, GPIOB and SPI1 clocks */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);

  
  
//GPIOA->CRL = 0x44444441;  //I/O setting
//GPIOA_CRL = 0x44444441;  //I/O setting
  PA2_in();
  PA0_out();

  
  while(1)
  {  
    //if(0==(GPIOA->IDR & 0x04)) //Switch On
    if(0 == GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2))
    {
          //GPIOA->BSRR = 0x01;
          GPIO_SetBits(GPIOA, GPIO_Pin_0);
    }
    else                                  // Switch Off
    {
        //GPIOA->BRR = 0x01;
      GPIO_ResetBits(GPIOA, GPIO_Pin_0);
    }
  }
  
    
  
    return 0;
}


반응형

'Busan IT > ARM Controller' 카테고리의 다른 글

ARM Clock 설정  (0) 2015.10.12
내부 LED 반전 프로그램 만들기  (0) 2015.10.08
ARM Core3 M3 프로그래밍 환경 설정  (0) 2015.10.05
ADC 전압측정  (0) 2015.09.18
Analogue to Digital Converter  (0) 2015.09.17
Posted by newind2000