- 강의 질문
- AI TECH
part 9. 블루투스 연동 문제
안녕하세요. 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();
}
}

