CubeIDE 에서 STM32 Uart 통신 관련 주요 부분..
main.c
===========================================
void MyTaskInit(){
Serial_Init();
}
void MyTask(){
Serial_get1(); // 처리 함수
Serial_get6();
}
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_DMA_Init();
MX_ADC1_Init();
MX_FSMC_Init();
MX_TIM1_Init();
MX_TIM2_Init();
MX_TIM8_Init();
MX_TIM10_Init();
MX_USART1_UART_Init();
MX_USART6_UART_Init();
MyTaskInit();
/* USER CODE BEGIN WHILE */
while (1)
{
MyTask();
}
}
; 생략
;
===========================================
Serial.c
===========================================
#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 q6uart;
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart6;
// printf 문을 쓰기 위해 설정 : __weak 로 설정된 __io_putchar 함수 재 정의
int __io_putchar(int ch)
{
if(HAL_UART_Transmit(&huart6, (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(&q6uart);
HAL_UART_Receive_IT(&huart1, &q1uart.d, 1); // 이거 한번 먼저 해줘야 , 1개 들어오면 인터럽트 발생 시켜라
HAL_UART_Receive_IT(&huart6, &q6uart.d, 1);
}
static void MinusByte1(pQUart pQueue) { // 큐에서 1바이트 뺐다고 기록
pQueue->tail = (pQueue->tail == (RXBUFSIZE - 1)) ? 0 : (pQueue->tail + 1);
pQueue->nBytes--;
}
void Serial_get6() { // parsing packet
uint8_t d;
while (q6uart.nBytes) { // 계속 빼줌
d = q6uart.buf[q6uart.tail];
HAL_UART_Transmit(&huart6, &d, 1, 10); // printf("-%c", d);
MinusByte1(&q6uart);
// 여기서 받은 스트링 처리 하면 된다.
}
}
void Serial_get1() { // parsing packet
uint8_t d;
while (q1uart.nBytes) { // 계속 빼줌
d = q1uart.buf[q1uart.tail];
HAL_UART_Transmit(&huart1, &d, 1, 10); // printf("-%c", d);
MinusByte1(&q1uart);
// 여기서 받은 스트링 처리 하면 된다.
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { // 이거 안네 print 문 넣지 말것.. 동작 잘 안됨.
pQUart pQ;
if (huart->Instance == USART1) {
pQ = &q1uart;
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
}
else if (huart->Instance == USART6) {
pQ = &q6uart;
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
}
}
}
===========================================
그리고, 자동 생성되는 코드 serial uart 부
usart.c
===========================================
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart6;
void MX_USART1_UART_Init(void) // 초기화 9600n81 로 설정
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
}
void MX_USART6_UART_Init(void)
{
huart6.Instance = USART6;
huart6.Init.BaudRate = 57600;
huart6.Init.WordLength = UART_WORDLENGTH_8B;
huart6.Init.StopBits = UART_STOPBITS_1;
huart6.Init.Parity = UART_PARITY_NONE;
huart6.Init.Mode = UART_MODE_TX_RX;
huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart6.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart6) != HAL_OK)
{
Error_Handler();
}
}
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(uartHandle->Instance==USART1) // PA9, PA10 을 uart 로 쓰겠다 라고 설
{
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
}
else if(uartHandle->Instance==USART6)
{
__HAL_RCC_USART6_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/**USART6 GPIO Configuration
PC6 ------> USART6_TX
PC7 ------> USART6_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_USART6;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* USART6 interrupt Init */
HAL_NVIC_SetPriority(USART6_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART6_IRQn);
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspDeInit 0 */
/* USER CODE END USART1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART1_CLK_DISABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
/* USART1 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART1_IRQn);
}
else if(uartHandle->Instance==USART6)
{
/* Peripheral clock disable */
__HAL_RCC_USART6_CLK_DISABLE();
/**USART6 GPIO Configuration
PC6 ------> USART6_TX
PC7 ------> USART6_RX
*/
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_6|GPIO_PIN_7);
/* USART6 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART6_IRQn);
}
}
===========================================
stm32f2xx_it.c
===========================================
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart6;
void My_UART_IRQHandler(UART_HandleTypeDef *huart);
void USART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&huart1);
// My_UART_IRQHandler(&huart1);
}
void USART6_IRQHandler(void)
{
// My_UART_IRQHandler(&huart6);
HAL_UART_IRQHandler(&huart6);
}
===========================================
이렇게 하면 송신은 그냥 보내고
수신은 interrupt 로 받는 거를 기본으로 사용 하는 거 이다.
===========================================
===========================================
===========================================
그런데, 혹시 안되면 수신 IRQHandler 를 변경 하는 다음 사항을 해 보셔요..
먼저 Serial.c 에 IRQHandler 추가
===========================================
void My_UART_IRQHandler(UART_HandleTypeDef *huart) { // 최대한 간결하게 Quue 에 넣음.
pQUart pQ = (huart->Instance == USART1 ? &q1uart : &q6uart);
if ((__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE) != RESET)) {
if (pQ->nBytes < RXBUFSIZE) // 넘으면 버림. 빨리 빼줘야 함.
{
pQ->buf[pQ->head] = (uint8_t) (huart->Instance->DR & (uint8_t) 0x00FF); // 1 byte 넣기..
// HAL_UART_Transmit(&huart6, &c, 1, 10); // 여기(int 안)에서 이문장 쓰면 이빨 빠짐
pQ->head = (pQ->head == (RXBUFSIZE - 1)) ? 0 : (pQ->head + 1);
pQ->nBytes++;
}
}
__HAL_UART_CLEAR_PEFLAG(huart); /* clear event flag */
// HAL_UART_Receive_IT(&huart6, &g_u8rx6a[0], 1); // 1 byte receive 하라는거 여기서 필요 없어서 막음.
}
===========================================
그리고, 수신 IRQHandler 를 내가 만든 함수를 사용 하도록 변경 입니다.
stm32f2xx_it.c
===========================================
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart6;
void My_UART_IRQHandler(UART_HandleTypeDef *huart);
void USART1_IRQHandler(void)
{
// HAL_UART_IRQHandler(&huart1); 기본 제공 막고
My_UART_IRQHandler(&huart1);
}
void USART6_IRQHandler(void)
{
My_UART_IRQHandler(&huart6);
// HAL_UART_IRQHandler(&huart6);
}
===========================================
'개발 > 통신' 카테고리의 다른 글
nuvoton-M483 PWM 으로 Nec 방식 IrDA 수신기, example source (0) | 2023.11.09 |
---|---|
CH9121 시리얼(ttl) 이더넷 모듈 (CH9121 Serial Ethernet Module) (0) | 2023.10.30 |
com(serial rs232) port data plot chart 화면에 그림 그리기 (0) | 2023.04.04 |
serial(rs232, rs485), LAN(tcp, udp)통신 Terminal 모음 (0) | 2023.01.09 |
Win TCP (UDP) Client ,Server , example Source code (0) | 2023.01.09 |