본문 바로가기
임베디드 개발/STM32 (ARM Cortex-M)

STM32 , UART 통신으로 4 digit 7 segment FND 실시간 제어하기 1편 ( 2가지 방법 )

by eteo 2022. 6. 3.

 

UART 수신 인터럽트를 통한 4자리의 FND 실시간 제어

 

명령어 예시

FND38 : 3번째 FND에 숫자 8을 켠다.

FNDA4 : 모든 FND를 4로 켠다.

FND4X : 0-9 값이 아닌 다른 값을 입력하면 4번째 FND가 꺼진다.

 

 

이 글에 나오는 다른 함수는 이전글과 동일하다.

 

이전글 :

2022.06.02 - [MCU/STM32 (ARM Cortex-M)] - STM32 , 74HC595 시프트 레지스터로 FND 제어하기 , 카운터 / 시계 ( SysTick 타이머 사용)

 

 

 

테라텀 설정

New connection으로 포트를 제대로 잡은 후 보드레이트 115200으로 잡아주고

Setup - Terminal 설정에서 new-line 시 라인피드(\n)가 전송될 수 있도록 하고 내가 터미널에 친 글자가 보이도록 Local echo를 체크한다.

 

 

 

 

 

첫번째 방법

UART 수신 인터럽트 콜백함수 내에서는 플래그만 바꾸고 while문 내에서는 플래그에 따른 행동을 정의해두는 방법

 

전역변수

/* USER CODE BEGIN PV */
uint8_t rx;
uint8_t bufindex=0;
uint8_t buf[10];
uint8_t fndnum;
uint8_t fndpos;
uint8_t Acommand=-1;
/* USER CODE END PV */

 

 

 

while문

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  while(Acommand==1){
		  DisplayFND(ttl7447(fndnum),1);
		  DisplayFND(ttl7447(fndnum),2);
		  DisplayFND(ttl7447(fndnum),3);
		  DisplayFND(ttl7447(fndnum),4);
		  DisplayFND(ttl7447('X'),1);
		  DisplayFND(ttl7447('X'),2);
		  DisplayFND(ttl7447('X'),3);
		  DisplayFND(ttl7447('X'),4);
	  }

	  while(Acommand==0){
		  DisplayFND(ttl7447(fndnum),fndpos);
	  }

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

 

 

 

HAL_UART_RxCpltCallback 함수

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance == USART3){

		if(rx=='\n'){
			buf[bufindex] = 0;
			char *p;

			if((p = strstr((char*)buf, "FND")) != NULL){
				fndnum = *(p+4)-'0';
				if(*(p+3) !='A'){
					Acommand=0;
					fndpos = *(p+3)-'0';
				}else {
					Acommand=1;
				}
			}
			bufindex=0;
		}else {
			if(bufindex <10){
				buf[bufindex++] = rx;
			}
		}
		HAL_UART_Receive_IT(&huart3, &rx, 1);
	}

}

/* USER CODE END 4 */

 

 

 

 

 

 

두번째 방법

 

 

while 문 내에서는 계속 같은 행동을 반복하게 하고 각 자릿수에 해당하는 숫자를 담을 fndnum 배열로 만들어두었다.

 

 

 

전역변수

/* USER CODE BEGIN PV */
uint8_t rx;
uint8_t bufindex=0;
uint8_t buf[10];
uint8_t fndnum[4]={'x','x','x','x'};
uint8_t fndpos=0;
uint8_t com[4]={0,};
/* USER CODE END PV */

 

 

 

while 문

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  DisplayFND(ttl7447(fndnum[0]),1);
	  DisplayFND(ttl7447(fndnum[1]),2);
	  DisplayFND(ttl7447(fndnum[2]),3);
	  DisplayFND(ttl7447(fndnum[3]),4);

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

 

 

 

 

 

HAL_UART_RxCpltCallback 함수

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance == USART3){

		if(rx=='\n'){
			buf[bufindex] = 0;
			char *p;
			if((p = strstr((char*)buf, "FND")) != NULL){
				if(*(p+3) !='A'){
					fndpos = (*(p+3)-'0')-1;
					fndnum[fndpos] = *(p+4)-'0';
				}else {
					for(int i=0; i<4; i++){
						fndnum[i] = *(p+4)-'0';
					}
				}
			}
			bufindex=0;
		}else {
			if(bufindex <10){
				buf[bufindex++] = rx;
			}
		}
		HAL_UART_Receive_IT(&huart3, &rx, 1);
	}

}

/* USER CODE END 4 */

 

사용자에게 받은 FND위치에 -1한 값을 fndpos에 담아서서 fndnum[fndpos] 인덱스에 접근해 해당자리에 사용자가 입력한 숫자를 넣는다.

 

A명령이 들어온 경우 모든 fndnum[i] 에 해당 숫자를 켠다.

 

사용자가 0-9사이의 숫자가 아닌 다른 숫자를 입력하면 함수를 거치면서 0xff값으로 리턴되어 해당 자리가 꺼진다.