hola estimados,
les cuento que ya hace algún tiempo tengo en mis manos una tarjeta STM32F4 Discovery, y la estoy programando con Keil 5, anda todo bien, pero ahora que quiero comunicarla con una Xbee, me esta dando problema el USART2 del GPIOA. resulta que me arroja carácter raros. en un principio pensé que pudo ser los Xbee, pero no, andan bien a 9600 Baud. estos los tengo conectado uno a la tarjeta y el otro al PC, si junto el TX y RX del Xbee que está en la tarjeta me da un eco al mandar datos desde el PC, así que todo bien con la comunicación. pero al momento que la tarjeta le envía caracteres al Xbee del PC no pasa nada o arroja vasura. y bueno tras liar varios días con esto, acudo a ustedes para ver si me pueden echar una mano con mi código.
#include "stm32f4xx.h" // Device header
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"
#include <misc.h> // I recommend you have a look at these in the ST firmware folder
#include "stm32f4xx_usart.h"
#include "stm32f4xx_dma.h"
#include <stdio.h>
__IO uint8_t Buffer[10]; //Variable donde la DMA almacenara los datos del USART_Rx automaticamente
void testLoop(void)
{
/* Creamos estructuras de datos para la configuracion de los perifericos -----------------*/
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;// Inicializar la estructura del DMA
USART_DeInit(USART2);
/* Activa los relojes de los perifericos: ------------------------------------------------*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);/* Activar reloj UART */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);/* Activar reloj GPIOA */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); /* Activar reloj DMA1 */
/* Configuracion NVIC Prioridades Interrupciones-----------------------------------------*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //(NVIC_PriorityGroup_2)
/* Activa la interrupcion USART2 RX DMA */
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Configuracion GPIO--------------------------------------------------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Conectar los pins de USART con Alternative Functions */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
/*Configuracion UART---------------------------------------------------------------------*/
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART2, &USART_InitStructure);
USART_Cmd(USART2, ENABLE);
DMA_DeInit(DMA1_Stream5);//Buscamos en la tabla 20 y 21 UART1_RX y localizamos el canal y el stream
DMA_InitStructure.DMA_Channel = DMA_Channel_4; // Canal 4 -> Consultar tabla 20 y 21
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; // Del periferico a la memoria
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)Buffer; // Asociamos la variable donde vamos a guardar los datos recibidos del UART
DMA_InitStructure.DMA_BufferSize = (uint16_t)sizeof(Buffer); // Reservar en memoria el tamaño del buffer 32bytes
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART2->DR; // Especifica la direccion base periferica de DMA y Streamx.
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // Especifica si el registro de direccion periferica no debe ser incrementado o no
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // Especifica si el registro de direcciones de memoria debe ser incrementado o no.
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; // Especifica el tamaño de datos del perifericos [8 bits]
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // Especifica el tamaaño de datos de la memoria. [8 bits]
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // Especifica el modo de funcionamiento de la DMAy Streamx
DMA_InitStructure.DMA_Priority = DMA_Priority_High; // Especifica la prioridad de software para el DMAy Streamx
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; // Especifica si el modo FIFO o el modo directo se utilizaran para la secuencia especificada
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; // Especifica el nivel del umbral FIFO.
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; // Se especifica la cantidad de datos a transferir en una sola transaccion no interrumpible
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; // Especifica la configuracion de transferencia de rafaga para los traslados perifericos
DMA_Init(DMA1_Stream5, &DMA_InitStructure);
/* Activa la solicitud DMA desde USART-----------------------------------------------*/
USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE);
/* Activa las interrupciones de buufer completo y medio buffer-----------------------*/
DMA_ITConfig(DMA1_Stream5, DMA_IT_TC, ENABLE);
DMA_ITConfig(DMA1_Stream5, DMA_IT_HT, ENABLE);
/* Activa DMA RX Stream -------------------------------------------------------------*/
DMA_Cmd(DMA1_Stream5, ENABLE);
}
/**************************************************************************************/
//Codigo de la interrupcion
/**************************************************************************************/
void DMA1_Stream5_IRQHandler(void)
{
/* Comprobacion de buffer completo */
if (DMA_GetITStatus(DMA1_Stream5, DMA_IT_TCIF5))
{
/* Borrar la interrupcion del DMA*/
DMA_ClearITPendingBit(DMA1_Stream5, DMA_IT_TCIF5);
//Manda un caracter
USART_SendData(USART2, 'C');
//AQUI PROCESARIAMOS EL MENSAJE
}
/* Comprobacion de buffer completo */
if (DMA_GetITStatus(DMA1_Stream5, DMA_IT_HTIF5))
{
/* Borrar la interrupcion del DMA*/
DMA_ClearITPendingBit(DMA1_Stream5, DMA_IT_HTIF5);
//Manda un caracter
USART_SendData(USART2, 'H');
//AQUI PROCESARIAMOS EL MENSAJE
}
}
void Delay(__IO uint32_t nCount)
{
while(nCount--) {}
}
void LED()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOD, &GPIO_InitStructure);
}
int main()
{
Delay(0x5FFFFF);
testLoop ();
LED();
// Mientras el flag de la transmision no este vacio__(inicializacion)
while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
// Enviamos un caracter de prueba
USART_SendData(USART2, '@');
// La interrupcion se encarga de llenar el buffer y cuando este lleno o a mitad enviara caracteres de informacion
// Podemos utilizar en cualquier momento el buffer desde la variable Buffer[32]
while(1)
{
GPIO_SetBits(GPIOD, GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);
Delay(0x5FFFFF);
GPIO_ResetBits(GPIOD, GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);
Delay(0x5FFFFF);
}
}
Saludos