root layout

패스트캠퍼스

  1. 강의 질문
  2. AI TECH

part 9. 블루투스 연동 문제

2026.03.30 00:33 수정

안녕하세요. UART를 구현하는 과정에서 시리얼 출력이 깨지는 문제가 발생하여 문의드립니다. 어떤 부분을 우선적으로 점검해야 할지 판단이 어려워 질문드립니다. 코드 일부분과 사진 참고자료로 보내드립니다.


UART.c 코드

#include "UART.h"

static FILE uart_stdout = FDEV_SETUP_STREAM(UART_putchar, NULL, _FDEV_SETUP_WRITE);

volatile char received_char;

char response[100];

uint8_t idx = 0;


void UART_init(uint32_t baud) {

uint16_t ubrr = (F_CPU / 16 / baud) - 1;

if (USE_2X) {

UCSR0A |= (1 << U2X0);

ubrr = (F_CPU / 8 / baud) - 1;

} else {

UCSR0A &= ~(1 << U2X0);

}

UBRR0H = (ubrr >> 8);

UBRR0L = ubrr;

UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0); // 수신/송신 및 RX 인터럽트 활성화

UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); // 비동기, 패리티 없음, 1 스톱 비트, 8 비트 데이터

stdout = &uart_stdout;

sei(); // 전역 인터럽트 활성화

}


int UART_putchar(char c, FILE *stream) {

if (c == '\n') {

UART_putchar('\r', stream);

}

while (!(UCSR0A & (1 << UDRE0))); // 송신 가능 대기

UDR0 = c;

return 0;

}


ISR(USART_RX_vect)

{

received_char = UDR0;

response[idx++] = received_char; // Store received character in response array

if (received_char == '\n') {

parse_bluetooth_message(response);

idx = 0; // Reset index if newline received

}

}


void UART_transmit(unsigned char data) {

while (!(UCSR0A & (1 << UDRE0))); // 송신 가능 대기

UDR0 = data;

}

unsigned char UART_receive(void) {

while (!(UCSR0A & (1 << RXC0))); // 데이터 수신 대기

return UDR0;

}


void UART_send_string(const char *str) {

while (*str) {

UART_transmit(*str++);

}

}



UART.h 코드

#include "../def.h"

#include "../sysconfig.h"

// 원하는 보드레이트 설정

#define BAUD_9600 9600

#define BAUD_38400 38400

#define BAUD_57600 57600

#define USE_2X 1 // 2배 속도 모드 사용 여부 (높은 보드레이트에서 유용)

#if USE_2X

#define UBRR_VALUE ((F_CPU / (BAUD * 8UL)) - 1)

#else

#define UBRR_VALUE ((F_CPU / (BAUD * 16UL)) - 1)

#endif

extern void UART_init(uint32_t baud);

extern int UART_putchar(char c, FILE *stream);

extern void UART_transmit(unsigned char data);

extern unsigned char UART_receive(void);

extern void UART_send_string(const char *str);


main.c 코드

int main(void)

{

UART_init(BAUD_9600);

printf("UART Init Ok\n");

GPIO_Init();

printf("GPIO Init Ok\n");

PWM_Init();

printf("PWM Init Ok\n");

L298N_Driver_Init();

printf("L298N Driver Init Ok\n");

I2C_Init();

printf("I2C Init Ok\n");


mpu6050_success_ret = MPU6050_start();


if(mpu6050_success_ret)

{

PD3_High();

_delay_ms(1000);

PD4_High();

printf("MPU6050 Enable\n");

}

else

{

printf("MPU6050 Disable\n");

}


MPU6050_Init();

printf("MPU6050 Init OK\n");


start_calibration();


PD3_Low();

PD4_Low();


balance_pid.setpoint = TARGET_ANGLE;

rotate_pid.setpoint = TARGET_ANGLE;


if(EEPROM_read((EEPROM_SAVE_FLAG_ADDRESS)))

{

printf("EEPROM READ\n");

EEPROM_PID_READ();

printf("BP = %0.2f, BI = %0.2f, BD = %0.2f\n",balance_pid.kp, balance_pid.ki, balance_pid.kd);

}

else

{

PID_Init(&balance_pid, KP, KI, KD);

PID_Init(&rotate_pid, KP_YAW, KI_YAW, KD_YAW);

printf("BP = %0.2f, BI = %0.2f, BD = %0.2f\n",balance_pid.kp, balance_pid.ki, balance_pid.kd);

}


/* Replace with your application code */

while (1)

{

Roll_Pitch_Yaw_Calculation();

//printf("phi_est(Roll) = %0.2f, theta_est(Pitch) = %0.2f, psi_est(Yaw) = %0.2f\n", phi_est, theta_est, psi_est);

//printf("theta_est(Pitch) = %0.2f, theta_est_kalman(Pitch) = %0.2f\n", theta_est, theta_est_kalman);

//_delay_ms(50);


if(eeprom_save == EEPROM_SAVE)

{

EEPROM_PID_SAVE();

eeprom_save = EEPROM_NONE;

}


if(motorState == MOTOR_ON)

{

PID_Compute(&balance_pid, theta_est_kalman, DT);

PID_Compute(&rotate_pid, psi_est, DT);

BalancingControl(balance_pid.output, rotate_pid.output, 0);

}

else// MOTOR_OFF

{

Left_Motor_Stop();

Right_Motor_Stop();

}


}


part 9.png참고자료 1.png


답변 

연관 질문

커뮤니티 질문보기