Conexión de SIM900 a STM32F4 Núcleo

Estoy tratando de conectar Simcom SIM900 a Nucleo-F411RE usando la siguiente configuración para USART1 :

void MX_USART1_UART_Init(void)
{

  huart1.Instance = USART1;
  huart1.Init.BaudRate = 9600;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  HAL_UART_Init(&huart1);

}

También la inicialización de GPIO es la siguiente:

        GPIO_InitStruct.Pin       = GPIO_PIN_9 | GPIO_PIN_10;
        GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull      = GPIO_PULLUP;
        GPIO_InitStruct.Speed     = GPIO_SPEED_FAST;
        GPIO_InitStruct.Alternate = GPIO_AF7_USART1;

        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

Ahora estoy tratando de enviar "AT\r"un comando y recibir el "OK"o "ERROR"desde el módem, pero parece que no obtengo nada de él. Intenté enviar "AT\n" "AT\n\r"también pero tampoco estaba dando el resultado adecuado.

Uso el osciloscopio para ver si los bits binarios se transmiten al módem y funciona bien. ¿Cuál puede ser el problema potencial?

Creo que hay una discrepancia de configuración entre Nucleo y el módem, pero aún no pude resolverlo.

Editar: Mi función principal se ve así:

#define TXATMESSAGESIZE       (COUNTOF(Message) - 1)
#define RXBUFFERSIZE          10

#define COUNTOF(__BUFFER__)   (sizeof(__BUFFER__) / sizeof(*(__BUFFER__)))

uint8_t Message[] = "AT\r\n";
uint8_t aRxSIM900Buffer[RXBUFFERSIZE];
UART_HandleTypeDef huart1;

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_USART1_UART_Init();

  /* UART TX and RX */
  HAL_UART_Transmit(&huart1, (uint8_t*) Message, TXATMESSAGESIZE, 1);

  if( HAL_UART_Receive(&huart1, (uint8_t*) aRxSIM900Buffer, RXBUFFERSIZE, 10) != HAL_OK)
  {
      while(1){

      }
  }
}

Edición 2:

Cuando entro en la HAL_UART_Receivefunción en modo de depuración, veo que el programa está atascado dentro de static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout()la función. Para ser exactos, va dentro de este primer si y espera a que se reciba el siguiente carácter:

/* Wait until flag is set */
  if(Status == RESET)
  {
    while(__HAL_UART_GET_FLAG(huart, Flag) == RESET)
    {
      /* Check for the Timeout */
      if(Timeout != HAL_MAX_DELAY)
      {
        if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
        ...(otherstuff)
  }
También conecté el pin Tx de SIM900 (Pin08) al osciloscopio. Cuando apago el módem, no veo ningún bit en la pantalla del osciloscopio, lo que significa que el módem no envía el mensaje "DESCONEXIÓN NORMAL". Estoy realmente confundido al respecto. Cualquier ayuda será apreciada.
Supongo que tiene la conexión de hardware correcta, es decir, Rx (Nucleo) -Tx (SIM900) y viceversa. Veo que tiene una var de sobremuestreo en la estructura. ¿Te importaría explicar por qué? y para limpiar un poco su código en GPIO init. Inicializaría ambos pines así. GPIO_InitStruct.Pin= GPIO_Pin_9|GPIO_Pin_10; y elimine las últimas 3 líneas del código.
y otra cosa, revisaste que PA9 y PA10 esten multiplexados para USART1 en el hardware?. Por si acaso. Un buen comienzo hacia la depuración.
Otro pensamiento; Puede ser un problema de circuito, ya que su SIM900 parece no responder. Desde mi experiencia, el mayor problema con los módulos SIM es la fuente de alimentación. ¿Puedes compartir un poco más? Además, ¿el módulo sim se usó antes? Tal vez se haya cambiado la velocidad de transmisión predeterminada. Pero esto no explica el hecho de que no responda mientras se apaga. Aún así, intente enviar AT+IPR=9600 por si acaso.
Edité el código y agregué algunas partes más. Sin embargo, eliminar el sobremuestreo no ayudó.
Gracias por los comentarios. El problema no puede estar en la velocidad de transmisión, creo. Probé el módem con Arduino y funcionó bien. También establezca la velocidad en baudios a 9600 con el comando AT+IPR=9600 y guárdelo con AT&W. Así que creo que debe haber algo más.
¿Dónde está el controlador USART1?
Se agregó a los códigos anteriores.
¿Tu suelo es común? Tarjeta SIM900 y ST?
Sí, los terrenos son comunes. Déjame mirar el código que compartiste.
¿Cómo sabes que no responde? Su código no hace nada cuando la recepción está bien o mal. Si usa la depuración, debe saber qué tipo de error ocurre durante la recepción de UART.
Uso la depuración y entro en el modo de recepción UART, esperando que se reciba algo del módem. Cuando apago el módem, ni siquiera recibo el mensaje "DESCONEXIÓN NORMAL". @BenceKaulics
¿Y qué ve cuando ingresa a la HAL_UART_Receivefunción durante la depuración?
He agregado los resultados en la pregunta anterior (en Edición 2). @BenceKaulics
El problema tal vez sea que su búfer RX tenga 10 bytes de largo, por lo que la recepción de UART está esperando 10 bytes, intente configurarlo en 3 para que se OK\rllene por completo. Aunque no sé por qué no Normal Power Downse recibe el mensaje. No tengo mejor idea en este momento.

Respuestas (3)

Yo mismo estoy usando un SIM900 con una MCU diferente. No puedo comentar sobre su código como tal, pero como otros han mencionado, el SIM900 es muy exigente con la fuente de alimentación. Asegúrate de que estás dando 4.5V. Agregue algunos condensadores de derivación por si acaso. Tuvimos un inductor en la potencia de entrada que causó algunos problemas. No estoy muy seguro de lo que estaba pasando, pero una vez que se reemplazó el inductor con un cortocircuito, obtuvimos resultados mucho mejores.

¿Está monitoreando las luces de estado del SIM900? Está diseñado para tener dos LED, uno en el pin 66 - STATUSy otro en el pin 52 - NETLIGHT. La luz de estado debe estar encendida continuamente y el LED de la luz de red debe parpadear (lentamente si hay red, rápido si no la hay). Si no está encendiendo correctamente el SIM900, no obtendrá nada a cambio (excepto quizás algún galimatías de vez en cuando).

Primero quiero agradecer todas las contribuciones para encontrar la respuesta correcta y probé todas las soluciones que sugirieron.

Después de pasar mucho tiempo leyendo la documentación del SIM900, descubrí que el problema está en los pines de E/S del módem. Estaba usando el escudo Arduino GSM con placa Nucleo y el pin 07 del módem SIM900 resultó ser el pin Tx. Pensé que el pin 08 debería usarse para Tx, pero es todo lo contrario.

En otras palabras, (Rx) 07 en el módem significa que 07 es un pin de transmisión y debe conectarse al pin de recepción del otro dispositivo.

Bueno. Este es el código que usé para el modo de solo recepción de USART a una velocidad de 9600 baudios. Asegúrate de que tus motivos sean comunes, o de lo contrario no funcionará.

void USART1_Init(void)
{



RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE);

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB , ENABLE);


  /* Configure USART1 pins:  Rx * - PB7 Alternative as TIM1 uses 4 channel PWM generation */

  GPIO_RX_Pin.GPIO_Pin =  GPIO_Pin_7;
  GPIO_RX_Pin.GPIO_Speed = GPIO_Speed_Level_1;
  GPIO_RX_Pin.GPIO_Mode = GPIO_Mode_AF;
  GPIO_RX_Pin.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOB, &GPIO_RX_Pin);

  GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_0);
    /* Configure USART1 */

UART1_BT.USART_BaudRate = 9600;
UART1_BT.USART_WordLength = USART_WordLength_8b;
UART1_BT.USART_StopBits = USART_StopBits_1;
UART1_BT.USART_Parity = USART_Parity_No ;
UART1_BT.USART_Mode = USART_Mode_Rx;
UART1_BT.USART_HardwareFlowControl = USART_HardwareFlowControl_None;


USART_Init(USART1, &UART1_BT);

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);  // ONLY RX mode config
NVIC_EnableIRQ(USART1_IRQn);    //NVIC enables the IRQ
USART_Cmd(USART1, ENABLE);


}

Aquí estoy usando CooCox con bibliotecas integradas para una implementación rápida de código. Estaba usando la placa Discovery STM32F0, por lo que los pines y las funciones son diferentes. Especialmente la asignación de funciones alternativas. Usé un controlador para recibir del pin RX. Aquí va.

void USART1_IRQHandler(void)
{

if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) /* RXNE if set, then data is received in DR register.*/
{
    USART_ClearITPendingBit(USART1, USART_IT_RXNE);
    char a;


    a = USART_ReceiveData(USART1);
}