LinkedIn YouTube Facebook
Szukaj

Wstecz
Artykuły

Przykład obsługi modemu GSM Quectel M10 w systemie z mikrokontrolerem STM32

Przykład obsługi modemu GPS w systemie z mikrokontrolerem STM32

W przykładowej aplikacji pokażemy jak wysłać wiadomość SMS korzystając z modemu Quectel M10 (w prezentowanym przykładzie w module EB-M10 z oferty firmy Soyter) sterowanego przez mikrokontroler STM32. W przykładzie wykorzystano zestaw uruchomieniowy STM32Butterfly2 oraz moduł EB-M10, połączenia pokazane są na rysunku 1. Należy pamiętać, aby zasilacz systemu dysponował odpowienią wydajnością (moduł M10 potrzebuje do 2 A).

 

Rys. 1. Sposób połączenia modułu EB-M10 i zestawu startowego STM32Butterfly2

Rys. 1. Sposób połączenia modułu EB-M10 i zestawu startowego STM32Butterfly2

 

 

Komunikacja z modemem

Do komunikacji z modemem wystarczy jeden interfejs UART oraz jedna linia GPIO służąca do włączania modemu. Po dołączeniu zasilania do modemu należy odczekać 2 sekundy, następnie można uruchomić modem podając stan wysoki na linię PWRKEY. Od tej pory możemy komunikować się z modemem przez UART. Modem nie wymaga użycia konkretnej prędkości interfejsu UART, ponieważ automatycznie ją rozpozna (zakres prędkości to 4800…115 200 bps), należy tylko wysłać trzykrotnie sekwecję AT\x0D. W przykładowym zestawie uruchomieniowym procesor STM32 taktowany jest kwarcem o częstotliwości 14,7456 MHz, a szyna APB1 zegarem o częstotliwości 58,9824 MHz, stąd funkcja konfigurująca USART2 wygląda następująco:

void USART2_Init (void) 
{
  int i;

  // Enable AFIO, GPIOD clocks
  RCC->APB2ENR |= RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPDEN;
  
  // Remap USART2 to PD5, PD6
  AFIO->MAPR |= AFIO_MAPR_USART2_REMAP;
  
  // PD5 - tx, PD6 - rx
  GPIOD->CRL   &= ~(0xFF <<  20);
  GPIOD->CRL   |=  (0xB <<  20) | (0x4 << 24) | (0x3 <<  28);
  
  // Enable USART2 clk
  RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
  
  
  // Set baudrate to 115200 (NOTE: 14.7456 MHz resonator is used!!!)
  USART2->BRR   = 0x200;                 
  
  // Configure USART2
  USART2->CR1   = ((   1UL <<  2) |       // Enable RX
                   (   1UL <<  3) |       // Enable TX
                   (   0UL << 12) );      // 1 start bit, 8 data bits
  USART2->CR2   = 0x0000;                 // 1 stop bit
  USART2->CR3   = 0x0000;                 // No flow control
  for (i = 0; i < 0x1000; i++) __NOP();   // Avoid unwanted output

  USART2->CR1 |= USART_CR1_UE;            // Enable USART
}

Wysyłając rozkaz do modemu musimy zakończyć go znakiem CR (0x0D), odpowiedź modemu będzie rozpoczęta i zakończona sekwencją CRLF (0x0D, 0x0A), przykładowo:

wysyłamy: ATE0<CR>

odbieramy: <CR><LF>OK<CR><LF>

Jeśli karta SIM wymaga podania kodu PIN wysyłamy go rozkazem AT+CPIN=xxxx, gdzie w miejsce znaków ‘xxxx’ wprowadzamy numer PIN. W przykładzie użyto startera SIM, który nie wymaga kodu PIN. Funkcja inicjalizująca modem:

void M10_Init()
{
    unsigned int i;
    char res[128];
    
    // PWRON = 1
    del(60);  
    GPIOD->ODR |= (1 << 7);
  
    // LED on
    GPIOB->ODR &= ~1;
  
    // Wait for Quectel M10 to start
    del(60);
    
    for (i=0; i < 3; i++)
    {
        M10_SendCmd("AT\x0D", &res[0]);  
        del(3);
    }
    
           // LED off
    GPIOB->ODR |= 1;
    
    // Echo off
    M10_SendCmd("ATE0\x0D", 0);
}

Teraz możemy przystąpić do wysłania wiadomości. Przykładowy program czeka w nieskończonej pętli na naciśnięcie joysticka, po naciśnięciu wysyłana jest wiadomość SMS (w przykładzie użyto numeru +48123123123, oczywiście przy uruchamianiu przykładu należy wstawić tam właściwy numer odbiorcy).

int main()
{
  USART2_Init();
  M10_Init();
  while(1)
  {
      if ((GPIOC->IDR & (1 << 7)) == 0 )
      {
          M10_SendSMS("+48123123123", "Quectel M10 test...");
      }
  }
}

Funkcja wysysłająca wiadomość:

void M10_SendSMS(char * telephone, char * message)
{
    char res[128], cmd[256];
  
    // LED on
    GPIOB->ODR &= ~1;
  
    // Set text mode
    M10_SendCmd("AT+CMGF=1\x0D", &res[0]);
  
    // Send SMS message
    sprintf(cmd, "AT+CMGS=\"%s\"\x0D", telephone);
    M10_SendCmd(cmd, 0);    
    sprintf(cmd, "%s\x1A", message);
    M10_SendCmd(cmd, &res[0]);
    
    // LED off
    GPIOB->ODR |= 1;
}

W tej funkcji wysyłamy najpierw polecenie AT+CMGF=1, które określa format wysyłanej wiadomości jako tekstowy, następnie wysyłamy polecenie AT+CMGS=”+48xxxxxxxxx”\0x0D po którym wysyłamy treść wiadomości, na koniec wysyłamy znak Ctrl+Z, czyli 0x1A (26 dziesiętnie). Po chwili wiadomość powinna dotrzeć do odbiorcy.

W powyższym przykładzie założono optymistyczny wariant, czyli mamy zasięg, komunikacja przebiega bez problemów itd. W rzeczywistych aplikacjach koniecznie należy uwzględnić wszelkie możliwe problemy, czyli m.in. trzeba sprawdzać odpowiedzi modemu i reagować na ewentualne błędy!