본문 바로가기

개발/embed

[CubeIDE] stm32 Uart 살리기 LoopBack, sample source

이전 

[CubeIDE] stm32 프로젝트 만들기  https://bahk33.tistory.com/45

 

[CubeIDE] stm32 프로젝트 만들기

1. 프로젝트 생성때 맨 처음 해야 할일 2가지 - SWD 설정 - 클럭 소스 및 동작 클럭을 설정 2. 프로젝트 만들기 - File => New => STM32 Project - Target Selection 에서 MCU/MPU Selector 탭에서 Part Number 에 CubeIDE 를

bahk33.tistory.com

에 이어 Uart 살리고, LoopBack 을 한다.

 

1. PinOut View 에서

  - PA9 : USART1_TX,   PA10: USART1_RX,  PA2:Usart2_Tx, PA3:Usart2_Rx  로 설정 하고,

 

 

2 Categories - Connectivity - USART1/ USART2  둘다 같이 설정 한

 - Mode : Asynchronous

 - Configuration - GPIO Settings - Parameter Settings - Baud Rate : 9600 Bits/s

 - Configuration - GPIO Settings - NVIC Interrupt Table - USART1 global interrupt 를 체크 한다

 

 

3. 다 했으면, 왼쪽 프로젝트명( 여기서는 AAClock_stm ) 에서 마우스 오른쪽 버튼 눌러 Buil Project 한다.

 

4. main.c 의 앞 부분

/* Private variables ---------------------------------------------------------*/

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
static void MX_TIM1_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */

 

와 같은 부분에 내가 만들 함수 정의 를 추가하여 아래와 같이 만듭니다. 

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c1;
TIM_HandleTypeDef htim1;

UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;

void Serial_Init(void);		 // serial port 초기화
void Serial_get1(void);		// serial port1 에서 읽기
void Serial_get2(void);		// serial port2 에서 읽기

unsigned char rBuf[100];  // 읽는 거 저장 할 곳

/* USER CODE BEGIN PV */
void MyTaskInit(){		// 초기화 할때 , 부를 함수 정의
    Serial_Init();
}

void MyTask(){
  Serial_get1();  // 처리 함수
  Serial_get2();
}
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
static void MX_TIM1_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */



 

5. main.c  의 main() 에 할일 정의

int main(void)
{
// 초기화 부분
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

/* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_TIM1_Init();
  MX_USART1_UART_Init();
  MX_USART2_UART_Init();

/* USER CODE BEGIN 2 */
  MyTaskInit();
  /* USER CODE END 2 */

// 무한 룹 부분
  /* Infinite loop */
  while (1)
  {
	  MyTask();
  }
}

 

 

 

6. MySerial.c 만들기

- Project 에서 마우스 오른쪽 버튼 눌러

- New -Source File - 하여 ~Core/Src Folder 에 MySerial.c - [Finish]

 - 아래 내용 입력

/*
 * MySerial.c
 *  Created on: 2023. 7. 13.
 *      Author: b
 */

#include "main.h"
#define RXBUFSIZE   1024

typedef struct {
  uint32_t head, tail;
  volatile uint32_t nBytes; // 이것은 int 안에서 , 밖에서 다 바뀌므로 , volatile 로 해 줘야..  그런데... 안해도 되는거 같은..
  uint8_t buf[RXBUFSIZE], d;
} QUart, *pQUart;

QUart q1uart,
QUart q2uart;

extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart2;

// printf 문을 쓰기 위해 설정 : __weak 로 설정된  __io_putchar 함수 재 정의
int __io_putchar(int ch)
{
  if(HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 10) != HAL_OK) return -1;
  return ch;
}

void InitUartQueue(pQUart pQueue) {    // 큐 초기화
  pQueue->nBytes = pQueue->head = pQueue->tail = 0;
}

void Serial_Init(void) {
  InitUartQueue(&q1uart);   // 큐 초기화
  InitUartQueue(&q2uart);
  HAL_UART_Receive_IT(&huart1, &q1uart.d, 1); // 이거 한번 먼저 해줘야 , 1개 들어오면 인터럽트 발생 시켜라
  HAL_UART_Receive_IT(&huart2, &q2uart.d, 1);
}

static void MinusByte1(pQUart pQueue) {   // 큐에서 1바이트 뺐다고 기록
  pQueue->tail = (pQueue->tail == (RXBUFSIZE - 1)) ? 0 : (pQueue->tail + 1);
  pQueue->nBytes--;
}

// 대문자로 바꾸기    보기 0x65 -> 0x45  ( 'e'  -> 'E' )
uint8_t toUpper(uint8_t d) { if ( d>0x60 && d<0x7B ) d &= ~0x20; return d;}   


void Serial_get1() {   // parsing COM1 packet
  uint8_t d;

  while (q1uart.nBytes) {  // 받은 문자 개수가 0보다 크면, 계속 빼줌
    d = q1uart.buf[q1uart.tail];	// 맨 먼저 받은거 저장
//  혹시 나중에 필요 하다면, 여기서 받은 스트링 처리 하면 된다. 

// 여기서는 대문자로 바꾸어 LoopBack
    d = toUpper(d);                 // 대문자로 바꾸고, 
    HAL_UART_Transmit(&huart1, &d, 1, 10);   //    printf("-%c", d);  보내기
    MinusByte1(&q1uart);            // 한글자 뺏다고 기록
  }
}

void Serial_get2() {   // parsing COM2 packet
  uint8_t d;

  while (q2uart.nBytes) {  // 계속 빼줌
    d = q2uart.buf[q2uart.tail];
    HAL_UART_Transmit(&huart2, &d, 1, 10);  //    printf("-%c", d);
    MinusByte1(&q2uart);
  }
}


void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {  // 이 함수 안에 print 문 절대넣지 말것.. 동작 잘 안됨.
  pQUart pQ;

  if (huart->Instance == USART1) {	// 뭐가 COM1로 왔으면 
    pQ = &q1uart;

    if (pQ->nBytes < RXBUFSIZE)   // 넘으면 버림.  빨리 0빼줘야 함.
    {
      pQ->buf[pQ->head] = pQ->d;  // 버퍼에 받은 1 byte 넣기..
      pQ->head = (pQ->head == (RXBUFSIZE - 1)) ? 0 : (pQ->head + 1);  // 넣을 위치 갱신
      pQ->nBytes++;    // 넣은 개수 1 추가
    }
    HAL_UART_Receive_IT(huart, &(pQ->d), 1);   // 1 byte receive  재설정
  }
  else if (huart->Instance == USART2) {
      pQ = &q2uart;

      if (pQ->nBytes < RXBUFSIZE)   // 넘으면 버림.  빨리 빼줘야 함.
      {
        pQ->buf[pQ->head] = pQ->d;  // 1 byte 넣기..
        pQ->head = (pQ->head == (RXBUFSIZE - 1)) ? 0 : (pQ->head + 1);
        pQ->nBytes++;
      }
      HAL_UART_Receive_IT(huart, &(pQ->d), 1);   // 1 byte receive
    }
}

 

 

7. Project - Build Project 하면 된다.

8. Down Load 하여 Uart 1 이 loopBack ( 받은거 되돌려 주기 , 소문자는 대문자로 바꿔서 ) 이 된다.

9. 설명이 좀 모자라지만, 첨부 소스 보시고 해보셔요.

stm32_uart.zip
0.67MB