Пытаюсь разобраться в программировании этого контроллера и при попытке настроить USART для приема/передачи данных возникла проблема:
Пытаюсь принять байт и после нажатия кнопки отправить его обратно, но на выходе получается совсем не то что ожидаю.
При отправке 0 должно вернуть 0, но возвращает вот это. В чем может быть проблема?
ASCII BIN DEC HEX
Подозрения падают на настройку baud rate, но вроде всё как в мануалах.
Полный код:
#include "stm32f4xx.h"
#include "stm32f4xx_hal_gpio.h"
#include "stm32f4xx_hal_rcc.h"
#include "stm32f4xx_hal_cortex.h"
#include "stdint.h"
#include "math.h"
//define Internal RC frequencies
#define XTAL 16000000UL
//define busses prescalers
#define AHB_PRE 1
#define APB1_PRE 2
#define APB2_PRE 1
#define SysTicksClk 10000
//calculate peripheral frequencies
#define SYSCLK 84000000
#define AHB SYSCLK/AHB_PRE
#define APB1 AHB/APB1_PRE
#define APB1_TIM APB1*2
#define APB2 AHB/APB2_PRE
#define APB2_TIM APB2*1
#define SysTicks AHB/SysTicksClk
#define USART_BAUDRATE 19200
#define BUF_LEN 1
struct Data
{
char Msg[BUF_LEN];
} Message;
void USART2_IRQHandler(void)
{
if (!(USART2->SR & USART_SR_TXE))
{
if (Message.Msg[0] == (char)0x00)
GPIOA->ODR |= 1 << 1;
if (Message.Msg[0] == (char)0x01)
GPIOA->ODR |= 0 << 1;
}
if (USART2->SR & USART_SR_RXNE)
{
Message.Msg[0] = USART2->DR;
}
}
int main()
{
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN;
GPIOA->MODER |= 1 << 1*2; //Set GPIOA pins output mode
GPIOB->MODER |= 0 << 0*2;
GPIOA->MODER |= 0xA0;
GPIOA->AFR[0] |= 0x7700;
RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
USART2->CR1 |= USART_CR1_UE; //usart enable
USART2->CR1 |= USART_CR1_TE; //transmitter enable
USART2->CR1 |= USART_CR1_RE; //receiver enable
float div = (float)APB1 /(16*(float)USART_BAUDRATE);
int integer = APB1 / (16*USART_BAUDRATE);
float flo = (div - (float)integer)*16;
int floatt = round(flo);
USART2->BRR = (( integer << 4 ) + floatt);
NVIC_EnableIRQ(USART2_IRQn);
USART2->CR1 |= USART_CR1_TXEIE;
USART2->CR1 |= USART_CR1_RXNEIE;
int i;
while(1)
{
if (!(GPIOB->IDR & GPIO_IDR_ID0))
{
i = 1;
}
else
{
if(i == 1)
{
USART2->DR &= Message.Msg[0];
while(!(USART2->SR & USART_SR_TC));
i = 0;
}
}
}
}
Сама схема: