Tengo algunos problemas con la comunicación UART. Mi plataforma es STM32f4 Discovery Board con STM32f407VG.
Primero la configuración de mi sistema:
void clock_setup(void)
{
RCC->PLLCFGR = (uint32_t)0x27412A04;
RCC->CFGR = (uint32_t)0x00081000;
RCC->CR |= (uint32_t)0x00010000;
while((RCC->CR & 0x00020000) != 0x00020000);
RCC->CR |= (uint32_t)0x01000000;
while((RCC->CR & 0x02000000) != 0x02000000);
FLASH->ACR = (uint32_t)0x00000702;
RCC->CFGR |= (uint32_t)0x00000002;
while(!(RCC->CFGR & 0x00000008));
}
void system_setup(void)
{
SCB->CPACR |= 0x00f00000; //fpu can be configured
clock_setup();
}
Controlador de interrupción principal y de botón:
int main(void)
{
int i = 0;
__enable_irq();
NVIC_SetPriority(EXTI0_IRQn,0x31);
NVIC_EnableIRQ(EXTI0_IRQn);
SYSCFG->EXTICR[0] = 1;
EXTI->IMR = 0x00000001;
EXTI->RTSR = 0x00000001; //rising edge on
EXTI->FTSR = 0x00000000; //falling edge off
RCC->AHB1ENR |= (uint32_t)0x00000009;
GPIOD->MODER = (uint32_t)0x55000000;
GPIOD->OTYPER = (uint32_t)0x0000000;
USART1_Config();
while(1){
}
return 1;
}
void EXTI0_IRQHandler(void)
{
if(EXTI->PR & (1<<0))
{
USART1_puts("Test\n");
enableBlink = !enableBlink;
}
EXTI->PR |= (1<<0);
}
Configuración y funciones de USART:
void USART1_puts(volatile char* s)
{
while(*s)
{
while(!(USART1->SR & 0x00000040)){
}
USART_SendData(USART1,*s);
*s++;
}
}
void USART1_Config(void)
{
USART_InitTypeDef USART_InitStruct;
GPIO_InitTypeDef GPIO_InitStruct, GPIO_InitStruct2;
NVIC_InitTypeDef NVIC_InitStruct;
/* Enable clocks */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;//GPIO_PuPd_UP;
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_BaudRate = 9600;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USART1,&USART_InitStruct);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
USART_Cmd(USART1,ENABLE);
}
void USART1_IRQHandler(void)
{
int i = 0;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
static uint8_t cnt = 0;
char t = USART_ReceiveData(USART1);
USART1_putch(t);
if((t!='n')&&(cnt < MAX_STRLEN))
{
received_string[cnt] = t;
cnt++;
}
else
{
cnt = 0;
USART1_puts(received_string);
for (i = 0; i <= MAX_STRLEN+1; i++) // flush buffer
received_string[i] = 'void clock_setup(void)
{
RCC->PLLCFGR = (uint32_t)0x27412A04;
RCC->CFGR = (uint32_t)0x00081000;
RCC->CR |= (uint32_t)0x00010000;
while((RCC->CR & 0x00020000) != 0x00020000);
RCC->CR |= (uint32_t)0x01000000;
while((RCC->CR & 0x02000000) != 0x02000000);
FLASH->ACR = (uint32_t)0x00000702;
RCC->CFGR |= (uint32_t)0x00000002;
while(!(RCC->CFGR & 0x00000008));
}
void system_setup(void)
{
SCB->CPACR |= 0x00f00000; //fpu can be configured
clock_setup();
}
';
}
}
}
El primer problema es cuando envío Test
a la terminal, muestra ˙ţ‡đ˙ţř
Segundo problema cuando se dispara la interrupción USART, solo lee un carácter de la entrada. Durante la depuración, el código ASCII es el mismo que se envía desde el terminal. Pero el resto de la cadena de la terminal no se lee. Y la función USART1_putch
le da al terminal diferentes caracteres como entrada.
¿Cuál puede ser el problema? Tal vez sea algo relacionado con los relojes? El código se basa principalmente en este tutorial.