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/로봇제어2015. 10. 30. 16:25

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

BCM 라이브러리

PWM LED Dimming

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

 

p/441

 

BCM 라이브러리

 

주소를 가상화 시키는 이유는 메모리를 효율적으로 사용하기 위해서이다.

‘[그림 16-18] BCM 2835의 버스 주소와 물리 주소의 대응관계에서 MMU가 버스의 주소를 가상화시키는 것을 알 수 있다.

 

핀의 기능이 한 가지 이상인 경우는 핀에 여러 가지 신호가 물려 있고 사용자의 조작에 따라 스위치가 동작하여 원하는 기능을 사용할 수 있다.

 

//‘SPI’는 시리얼로 분류된다.

 

 

우선 BCM라이브러리를 다운로드 받는다. Pi2bcm2836이 가능한 파일을 설치한다.

 

 

기존의 라이브러리 제공 사이트에서 제공하는 최신버전인 1.39버전부터는 bcm2836을 지원한다.

 

아래 링크를 통해서 설치 할 수 있다.

 

http://www.airspayce.com/mikem/bcm2835/bcm2835-1.39.tar.gz

 

ssh를 통해서 터미널로 접근 및 설치 해보도록 한다.

 

설치 절차는 다음과 같다.

 

1. wget을 사용하여 라이브러리 다운로드

 

wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.39.tar.gz


2. 다운받은 파일 압축해제

 

tar xvzf bcm-2835-1.39.tar.gz

3. 압축 해제한 폴더로 이동 후 설정을 적용한다.

 

cd bcm2835-1.39/

./configure

4. 설정이 올바르게 적용 되었는지 확인한다.

make check

 

 

5. 설치한다.

make install

 

 

라즈베리파이2의 경우는 라이브러리를 사용하기 위해 디바이스 트리를 활성화시켜야 한다.





다음 'reboot'명령어를 사용하여 재부팅한다.

 

PWM LED Dimming

 

교재 p/449에 있는 [PWM제어 예제]를 사용하여 PWM 코딩을 한다.

/*** 소스 ***/

[PWM_test.c]


 #include <bcm2835.h>
 #include <stdio.h>

 #define PIN 18
 #define PWM_CHANNEL 0
 #define RANGE       1024

 int main(int argc, char **argv)
 {
     int direction = 1;
     int data = 1;
     if ( 0 == bcm2835_init() )
         return 1;

     bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_OUTP);
     bcm2835_gpio_write(PIN, LOW);
     bcm2835_delay(1000);

     bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_ALT5);

     bcm2835_pwm_set_clock(BCM2835_PWM_CLOCK_DIVIDER_2);

     bcm2835_pwm_set_mode(PWM_CHANNEL, 11);

     bcm2835_pwm_set_range(0, RANGE);

     while(1)
     {
         if(data == 1)
             direction = 1;
         else if(data == RANGE-1)
             direction = -1;

         data += direction;

         bcm2835_pwm_set_data(PWM_CHANNEL, data);
         bcm2835_delay(20);
     }
     bcm2835_close();
     return 0;
 }



반응형
Posted by newind2000
Busan IT/Assembly2015. 10. 29. 17:35

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

String Operation

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

 

String Operation

 

교재 p/232

 

문자열과 관련된 명령어는 5개가 있다.

 

movs(move string)

cmps(compare string)

scas(scan string)

stos(store string)

lods(load string)

 

1byte 단위로 명령어를 내릴 때는 뒤에 첨자 'b'가 붙고, 2byte‘w', 4byte’d'가 붙는다.

 

어셈블리에서의 string은 문자열이 아닌 배열을 뜻한다.

문자열을 사용할 때는 레지스터 'ESI'와 'EDI'가 사용된다.

 

ESI = Extended Source Index

EDI = Extended Destination Index

 

'movs'명령어는 메모리에서 메모리로 데이터를 복사함으로 4사이클이 소모된다.

  

 

 

'movs' 명령어는 한 번에 한 단위 원소만을 조작시키고 명령어가 수행되고 나면 'esi'‘edi'는 조작 단위만큼 이동하게 되는데 이 때 ’EFL‘레지스에 ’DF‘ 플래그가 0일 때는 주소 값이 증가하고 1일 때는 주소 값이 감소하게 되는데 'DF'플래그의 값은 'cld', 'std'명령어로 조작할 수 있다.

문자열을 복사하는 함수를 만들어보자.

 

//함수를 사용하고 나서는 사용하기전의 레지스터 상태로 원상복구 시켜 주어야 한다.

 

교재 p/234


[strcpy.asm]

.386
.MODEL FLAT
ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD
INCLUDE io.h
cr  equ   0dh
Lf  equ   0ah

.STACK 4096

.DATA
prompt    BYTE  cr, Lf, "Original string? ",0
stringIn  BYTE  80 DUP (?)
display    BYTE  cr, Lf, "Your string was...", cr, Lf
stringOut  BYTE  80 DUP  (?)

.CODE
_start:  output   prompt
  input  stringIn,   80
  lea  eax,    stringOut
  push  eax
  lea  eax, stringIn
  push  eax
  call   strcopy
  output  display
  INVOKE  ExitProcess,  0

PUBLIC  _start

strcopy    PROC NEAR32

  push  ebp
  mov  ebp, esp

  push edi
  push esi
  pushf

  mov  esi, [ebp+8]
  mov  edi, [ebp+12]
  cld

whileNoNull:
  cmp  BYTE PTR [esi],  0
  je  endWhileNoNull
  movsb
  jmp  whileNoNull

endWhileNoNull:
  mov BYTE PTR [edi], 0

  popf
  pop  esi
  pop  edi
  pop  ebp
  ret  8

strcopy  ENDP

  END

 

 


반응형
Posted by newind2000