Autor Tema: stm32f4 Discovery y USART2 caracter raros  (Leído 4556 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado japifer_22

  • PIC18
  • ****
  • Mensajes: 405
stm32f4 Discovery y USART2 caracter raros
« en: 18 de Mayo de 2014, 04:56:59 »
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.

Código: [Seleccionar]
#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

Desconectado Dédalo

  • PIC10
  • *
  • Mensajes: 2
Re: stm32f4 Discovery y USART2 caracter raros
« Respuesta #1 en: 30 de Mayo de 2014, 14:51:57 »
Hola
Hace tiempo tuve un problema parecido al final lo resolví, en mi caso era un problema de reloj,
me olvidé cambiar la variable HSE_VALUE a 8Mhz que es el cristal que monta la STM32F4 discovery,
te copio el siguiente texto:
" HSE_VALUE is a constant defined in stm32f4xx.h file (default value
  *              25 MHz), user has to ensure that HSE_VALUE is same as the real
  *              frequency of the crystal used. Otherwise, this function may
  *              have wrong result."
Si es por temas de reloj "un truco" fácil es falsear el valor de USART_InitStruct.USART_BaudRate = 9900 o 10.200,
si de esa manera los carácteres ya no son basura entonces corrije los parámetros del reloj y retorna baudrate a 9600.

Saludos.

Desconectado japifer_22

  • PIC18
  • ****
  • Mensajes: 405
Re: stm32f4 Discovery y USART2 caracter raros
« Respuesta #2 en: 02 de Junio de 2014, 15:14:20 »
Hola Dédalo, mira tengo la misma tincada que es un tema de velocidad. lo que estoy haciendo es:

Citar
//#define HSE_VALUE    ((uint32_t)8000000)
//#define PLL_M 8
//#define OS_CLOCK 168000000
#include "stm32f4xx.h"                  // Device header
#include "stm32f4xx_gpio.h"
#include <misc.h>          // I recommend you have a look at these in the ST firmware folder
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_usart.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
int flag = 0;

void init(USART_TypeDef* USARTx, uint32_t baudrate) {
    
      GPIO_InitTypeDef GPIO_InitStruct;
      USART_InitTypeDef USART_InitStruct;
      NVIC_InitTypeDef NVIC_InitStructure;    

      //General settings of pins TX/RX
      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_UP;

   if(USARTx == USART1){       
      
         RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

         GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // Pins B6 (TX) and B7 (RX)
         GPIO_Init(GPIOB, &GPIO_InitStruct);

         GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1);
         GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);

         NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
   }
   else if(USARTx == USART2){
      flag =1;
      
         RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

         GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; // Pins A2 (TX) and A3 (RX)
         GPIO_Init(GPIOA, &GPIO_InitStruct);

         GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
         GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);

         NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
   }
   else if(USARTx == USART3){   
      
         RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

         GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; // Pins D8 (TX) and D9 (RX)
         GPIO_Init(GPIOD, &GPIO_InitStruct);

         GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_USART3);
         GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_USART3);

         NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
   }
   else if(USARTx == UART4){      
      
         RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

         GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; // Pins C10 (TX) and C11 (RX)
         GPIO_Init(GPIOC, &GPIO_InitStruct);

         GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_UART4);
         GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_UART4);

         NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
   }
   else if(USARTx == UART5){
      
         RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);
         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

         GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12; // Pin C12 (TX)
         GPIO_Init(GPIOC, &GPIO_InitStruct);
         GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2; // Pin D2 (RX)
         GPIO_Init(GPIOD, &GPIO_InitStruct);

         GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_UART5);
         GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_UART5);

         NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;
   }
   else if(USARTx == USART6){
      
         RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE);
         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

         GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // Pins C6 (TX) and C7 (RX)
         GPIO_Init(GPIOC, &GPIO_InitStruct);

         GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_USART6);
         GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_USART6);

         NVIC_InitStructure.NVIC_IRQChannel = USART6_IRQn;
      }

      //UART setting
      USART_InitStruct.USART_BaudRate            = baudrate;
      USART_InitStruct.USART_WordLength          = USART_WordLength_8b; // octet comme taille élémentaore (standard)
      USART_InitStruct.USART_StopBits            = USART_StopBits_1; // bit de stop = 1 (standard)
      USART_InitStruct.USART_Parity              = USART_Parity_No; // pas de bit de parité (standard)
      USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // pas de controle de flux (standard)
      USART_InitStruct.USART_Mode                = USART_Mode_Tx | USART_Mode_Rx;
      USART_Init(USARTx, &USART_InitStruct);

      USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE);

      //Setting of interrupt
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
      NVIC_Init(&NVIC_InitStructure);

      //Enable UART
      USART_Cmd(USARTx, ENABLE);
   }

void send_char(USART_TypeDef* USARTx, unsigned char c) {
      USART_SendData(USARTx, c);
      while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET) {
      }
   }

void send_string(USART_TypeDef* USARTx, char *s){
   while(*s)
   {
      while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
      USART_SendData(USARTx, *s++);
   }
}   

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()

    init(USART2,9600);
    Delay(0x5FFFFF);
   LED();   
    send_char(USART2, '1');
    Delay(0x5FFFFF);
    send_char(USART2, '2');
    Delay(0x5FFFFF);
    send_char(USART2, '3');
    Delay(0x5FFFFF);
    send_string(USART2, "Hola");
    Delay(0x5FFFFF);
   
  while(1)
   {
      if (flag ==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);
      }            
   }
}

como vez cambie un poco el código, pero sigo teniendo el mismo problema. estoy intentando cambiar el clock, como lo refleja el código en su cabecera, pero no tengo buen resultado todavía. si me pudieses indicar como configurar el clock, te lo agradecería.

Saludos

Desconectado cristian_elect

  • PIC18
  • ****
  • Mensajes: 453
Re: stm32f4 Discovery y USART2 caracter raros
« Respuesta #3 en: 03 de Julio de 2014, 23:10:54 »
Bájate el STMCubeMX te ayuda bastante con el inicio de configuración del micro ya que estos micros necesitan bastante código para configurarlos.