티스토리 뷰

목표

이번 시간에 진행한 실습은 UART 통신이다.
키보드로 입력한 값을 터미널에 띄우고 값에 해당하는 색을 LED로 표시하려고 한다.

main 함수가 있는 파일에서 아래와 같은 파일을 include 할 것이다.

#include "device_registers.h"           
#include "clocks_and_modes.h"
#include "LPUART.h"

LPUART.c 파일

LPUART.h 헤더파일에는 함수가 선언되어있고 함수들은 LPUART.c에 정의되어있고
UART를 초기화하고 터미널로 문자를 출력하는 함수가 있다.

LPUART1_init

clock 설정, BAUD rate 설정, CTRL 설정 등 UART를 사용하기 위한 초기 설정을 위한 함수

LPUART1_transmit_char

char 자료형을 받아 터미널에 출력하는 함수
stat과 tdre_mask를 shift 한 게 0이 아닐때만 출력하도록 조건

LPUART1_transmit_string

위의 문자 자료형 출력 함수를 이용해 문자열을 출력하도록 하는 함수
끝을 알리는 '\0' 이 나올때까지 char을 출력해 전제 문자열을 출력할 수 있게 했다.

LPUART1_receive_char

receive변수에 받고 반환하도록 한다. main에서는 받은 데이터를 변수에 저장하고 출력하도록 할 것이다.

LPUART1_receive_and_echo_char

받아서 출력해준다.


main 파일

/*
 * main.c       UART transmission simple example
 * 2016 Mar 17 O Romero - Initial version
 * 2016 Oct 31 SM: Clocks adjusted for 160 MHz SPLL
 *
 */

//#include "S32K144.h" /* include peripheral declarations S32K144 */
#include "device_registers.h"           // Device header
#include "clocks_and_modes.h"
#include "LPUART.h"

char data=0;
void PORT_init (void) {
  PCC->PCCn[PCC_PORTC_INDEX ]|=PCC_PCCn_CGC_MASK; /* Enable clock for PORTC */
  PORTC->PCR[6]|=PORT_PCR_MUX(2);           /* Port C6: MUX = ALT2,UART1 TX */
  PORTC->PCR[7]|=PORT_PCR_MUX(2);           /* Port C7: MUX = ALT2,UART1 RX */
	
	PCC->PCCn[PCC_PORTD_INDEX ]|=PCC_PCCn_CGC_MASK; /* Enable clock for PORTD */
	PTD->PDDR |= 1<<15|1<<16|1<<0;	/* Data Direction = output */
  PORTD->PCR[15]|=PORT_PCR_MUX(1);           /* Port D15: MUX = GPIO */
  PORTD->PCR[16]|=PORT_PCR_MUX(1);           /* Port D16: MUX = GPIO */
	PORTD->PCR[0]|=PORT_PCR_MUX(1);           /* Port D0: MUX = GPIO */
}

void WDOG_disable (void){
  WDOG->CNT=0xD928C520;     /* Unlock watchdog */
  WDOG->TOVAL=0x0000FFFF;   /* Maximum timeout value */
  WDOG->CS = 0x00002100;    /* Disable watchdog */
}

int main(void)
{
  WDOG_disable();        /* Disable WDGO*/
  SOSC_init_8MHz();      /* Initialize system oscilator for 8 MHz xtal */
  SPLL_init_160MHz();    /* Initialize SPLL to 160 MHz with 8 MHz SOSC */
  NormalRUNmode_80MHz(); /* Init clocks: 80 MHz sysclk & core, 40 MHz bus, 20 MHz flash */
  SystemCoreClockUpdate();
	
	PORT_init();           /* Configure ports */
  LPUART1_init();        /* Initialize LPUART @ 9600*/
  LPUART1_transmit_string("- Running LPUART example 2...\n\r");     /* Transmit char string */
  LPUART1_transmit_string("- Input character r, g or b to turn on BUILT-IN RED, GREEN, BLUE LED,\n\r  respectively and input x, y or z to turn on two of them...\n\r"); /* Transmit char string */
	
	PTD->PSOR |= 1<<15|1<<16|1<<0; /* turn off all LEDs */

  for(;;) {
	  LPUART1_transmit_char('>');  		/* Transmit prompt character */
	  data = LPUART1_receive_char();
		LPUART1_transmit_char(data);
		LPUART1_transmit_char('\n');
		LPUART1_transmit_char('\r');
		
		switch(data)
		{
			case 'r':
				PTD->PCOR |= 1<<15;
				PTD->PSOR |= 1<<16|1<<0;
				break;
			
			case 'g':
				PTD->PCOR |= 1<<16;
				PTD->PSOR |= 1<<15|1<<0;
				break;
			
			case 'b':
				PTD->PCOR |= 1<<0;
				PTD->PSOR |= 1<<15|1<<16;
				break;
			
			case 'x':										/* R, G LEDs turn on, B LED turn off */
				PTD->PCOR |= 1<<15;
				PTD->PCOR |= 1<<16;
				PTD->PSOR |= 1<<0;
				break;
			
			case 'y':										/* G, B LEDs turn on, R LED turn off */
				PTD->PCOR |= 1<<16;
				PTD->PCOR |= 1<<0;
				PTD->PSOR |= 1<<15;
				break;
			
			case 'z':										/* R, B LEDs turn on, G LED turn off */
				PTD->PCOR |= 1<<15;
				PTD->PCOR |= 1<<0;
				PTD->PSOR |= 1<<16;
				break;
			
			default:
				PTD->PSOR |= 1<<15|1<<16|1<<0;
		}
  }
}

코드 분석 

PORT_init 함수

clock, 인풋, 아웃풋 설정을 위한 함수

포트C의 6번, 7번핀이 USB케이블을 통한 TX, RX 핀이므로 MUX(2)로 설정한다.
포트D의 0번, 15번, 16번 핀이 MCU의 내장 LED와 연결되어 있으므로 MUX(1)로 설정한다. (GPIO로 설정)

void PORT_init (void) {
  PCC->PCCn[PCC_PORTC_INDEX ]|=PCC_PCCn_CGC_MASK; /* Enable clock for PORTC */
  PORTC->PCR[6]|=PORT_PCR_MUX(2);           /* Port C6: MUX = ALT2,UART1 TX */
  PORTC->PCR[7]|=PORT_PCR_MUX(2);           /* Port C7: MUX = ALT2,UART1 RX */
	
	PCC->PCCn[PCC_PORTD_INDEX ]|=PCC_PCCn_CGC_MASK; /* Enable clock for PORTD */
	PTD->PDDR |= 1<<15|1<<16|1<<0;	/* Data Direction = output */
  PORTD->PCR[15]|=PORT_PCR_MUX(1);           /* Port D15: MUX = GPIO */
  PORTD->PCR[16]|=PORT_PCR_MUX(1);           /* Port D16: MUX = GPIO */
	PORTD->PCR[0]|=PORT_PCR_MUX(1);           /* Port D0: MUX = GPIO */
}

void WDOG_disable (void){
  WDOG->CNT=0xD928C520;     /* Unlock watchdog */
  WDOG->TOVAL=0x0000FFFF;   /* Maximum timeout value */
  WDOG->CS = 0x00002100;    /* Disable watchdog */
}

WDOG_disable 함수

WDOG는 시스템의 안정성을 위해 타이머를 설정해주는 기능을 제공합니다. 하지만 이 예제에서는 워치독 타이머를 비활성화하여, 프로그램이 종료되지 않도록 합니다. 라고 한다..

main

int main(void)
{
  WDOG_disable();        /* Disable WDGO*/
  SOSC_init_8MHz();      /* Initialize system oscilator for 8 MHz xtal */
  SPLL_init_160MHz();    /* Initialize SPLL to 160 MHz with 8 MHz SOSC */
  NormalRUNmode_80MHz(); /* Init clocks: 80 MHz sysclk & core, 40 MHz bus, 20 MHz flash */
  SystemCoreClockUpdate();
	
	PORT_init();           /* Configure ports */
  LPUART1_init();        /* Initialize LPUART @ 9600*/
  LPUART1_transmit_string("- Running LPUART example 2...\n\r");     /* Transmit char string */
  LPUART1_transmit_string("- Input character r, g or b to turn on BUILT-IN RED, GREEN, BLUE LED,\n\r  respectively and input x, y or z to turn on two of them...\n\r"); /* Transmit char string */
	
	PTD->PSOR |= 1<<15|1<<16|1<<0; /* turn off all LEDs */

  for(;;) {
	  LPUART1_transmit_char('>');  		/* Transmit prompt character */
	  data = LPUART1_receive_char();
		LPUART1_transmit_char(data);
		LPUART1_transmit_char('\n');
		LPUART1_transmit_char('\r');
		
		switch(data)
		{
			case 'r':
				PTD->PCOR |= 1<<15;
				PTD->PSOR |= 1<<16|1<<0;
				break;
			
			case 'g':
				PTD->PCOR |= 1<<16;
				PTD->PSOR |= 1<<15|1<<0;
				break;
			
			case 'b':
				PTD->PCOR |= 1<<0;
				PTD->PSOR |= 1<<15|1<<16;
				break;
			
			case 'x':										/* R, G LEDs turn on, B LED turn off */
				PTD->PCOR |= 1<<15;
				PTD->PCOR |= 1<<16;
				PTD->PSOR |= 1<<0;
				break;
			
			case 'y':										/* G, B LEDs turn on, R LED turn off */
				PTD->PCOR |= 1<<16;
				PTD->PCOR |= 1<<0;
				PTD->PSOR |= 1<<15;
				break;
			
			case 'z':										/* R, B LEDs turn on, G LED turn off */
				PTD->PCOR |= 1<<15;
				PTD->PCOR |= 1<<0;
				PTD->PSOR |= 1<<16;
				break;
			
			default:
				PTD->PSOR |= 1<<15|1<<16|1<<0;
		}
  }
}

WDOG를 비활성화한다. 
시스템 실행에 필요한 clock을 설정한다.

미리 만들어둔 PORT_init, LPUART1_init 함수로 사용하기 위한 초기 설정을 한다.

for문 (반복되도록)

  • 터미널에 > 를 띄운다.
  • data로 키보드 입력 값을 받아온다.
  • data를 터미널에 출력한다.
  • 터미널에서 다음 줄로 넘어간다.
  • 리턴 (MCU마다 \n으로 다음줄로 넘어가되 커서는 가장 앞으로 오지 않는 경우가 있다. 이런 호환성 문제를 없애기 위해 \r 로 커서가 앞쪽에 위치할 수 있도록 한다.)
  • switch문
    - 입력받은 데이터가 각 r, g, b, x, y, z, 이외일 때 PCOR, PSOR 레지스터를 이용해 어떤 색상을 나타나게 할지 설정한다.
    - pull-up 형태이기에 output clear를 해야 해당 led에 불이 들어온다.

 

반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함