LinkedIn YouTube Facebook
Szukaj

Wstecz
Artykuły

Bluetoothowy moduł BTM222 i STM32

List. 4

void USART2_IRQHandler(void) 
{ 
  extern char TxBuffer[]; 
  extern uint16_t TxCounter; 
  extern uint16_t TxLength; 
  extern char RxBuffer[]; 
  extern uint16_t RxCounter; 
  //odbiór danych 
  if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) 
  { 
    //odczyt odebranego znaku 
    RxBuffer[RxCounter] = (USART_ReceiveData(USART2) & 0x7F);
    //inkrementacja licznika danych 
    RxCounter++; 
    //zabezpieczenie przed wprowadzeniem zbyt dlugiego ciagiu znakow 
    if((RxBuffer[RxCounter - 2] != '\r') && (RxBuffer[RxCounter - 1] != '\n') && (RxCounter == 127)) 
      {RxCounter = 125;} 
  } 

  //wysylanie danych 
  if(USART_GetITStatus(USART2, USART_IT_TXE) != RESET) 
  { 
    //wysyłanie poszczególnych znaków z zadanego ciągu 
    if(TxCounter < TxLength) 
    { 
      USART_SendData(USART2, TxBuffer[TxCounter]); 
      TxCounter++; 
    } 
    else 
    { 
      //wylaczenie przerwania od TXE 
      USART_ITConfig(USART2, USART_IT_TXE, DISABLE); 
      //wyzerowanie licznika wysylanych danych 
      TxCounter = 0; 
      TxLength = 0; 
    } 
  } 
}

Samo dekodowanie przesłanych poleceń jest realizowane w pętli głównej programu. Rozpoczęcie dekodowania wymaga spełnienia warunku:
if((RxBuffer[RxCounter – 1] == '\n’) && (RxBuffer[RxCounter – 2] == '\r’))
informującego o fakcie wciśnięcia klawisza Enter, w wyniku czego są wysyłane dwa znaki: powrót karetki (CR) oraz znak nowej linii (LF). W przypadku wystąpienia powyższego, następuje sprawdzenie czy polecenie pasuje do jednego ze zdefiniowanych. Przykład takiego dekodowania (dla włączenia wskazanej diody LED) przedstawiono na listingu 5. Na początku następuje sprawdzenie ogólnego polecenia (z pominięciem numeru diody LED). W przypadku dopasowania polecenia następuje sprawdzenie znaku numeru diody przy wykorzystaniu polecenia switch. Na samym końcu jest wysłany komunikat o powodzeniu lub błędzie w dekodowaniu polecenia. Analogiczne działania występują w przypadku dekodowania pozostałych poleceń.

List. 5

//włączenie diody LED 
if( 
  (RxCounter == 10) && 
  ((RxBuffer[0] == 'L') || (RxBuffer[0] == 'l')) && 
  ((RxBuffer[1] == 'E') || (RxBuffer[1] == 'e')) && 
  ((RxBuffer[2] == 'D') || (RxBuffer[2] == 'd')) && 
  (RxBuffer[3] == '_') && 
  (RxBuffer[5] == '_') && 
  ((RxBuffer[6] == 'O') || (RxBuffer[6] == 'o')) && 
  ((RxBuffer[7] == 'N') || (RxBuffer[7] == 'n')) 
  ) 
  { 
    if((RxBuffer[4] >= 0x31) && (RxBuffer[4] <= 0x38))
    { 
      //sprawdzenie znaku numeru diody LED 
      switch(RxBuffer[4]) 
      { 
        case 0x31 : LED_1_ON; break; 
        case 0x32 : LED_2_ON; break; 
        case 0x33 : LED_3_ON; break; 
        case 0x34 : LED_4_ON; break; 
        case 0x35 : LED_5_ON; break; 
        case 0x36 : LED_6_ON; break; 
        case 0x37 : LED_7_ON; break; 
        default : LED_8_ON; break; 
      } 
      //wysłanie komunikatu o poprawnie zdekodowanym poleceniu 
      SendDataToBTM222("OK\r\n"); 
    } 
    //wysłanie komunikatu błędu 
    else 
    {SendDataToBTM222("ERROR\r\n");} 
    //wyzerowanie licznika danych odebranych 
    RxCounter = 0; 
  }

Wyjątkiem od wystąpienia znaków CR i EOL jest obsługa kodu klawisza Backspace, na listingu 6 przedstawiono obsługę takiego zdarzenia.

List. 6

  //znak backspace - znak BS 
  else if((RxBuffer[RxCounter - 1] == '\b')) 
  { 
    if(RxCounter > 1) 
    { 
      RxCounter--; 
      RxBuffer[RxCounter] = 0; 
      RxCounter--; 
      RxBuffer[RxCounter] = 0; 
    } 
    else 
    { 
      RxCounter = 0; 
    } 
  }

Wystąpienie znaku Backspace powoduje przesunięcie i wyzerowanie dwóch znaków (aktualnie wpisanego znaku BS oraz poprzedniego), kod realizuje także zabezpieczenie przed przekroczeniem zakresu tabeli.
W projekcie występuje dodatkowy plik macro.h, w którym zdefiniowano działania w celu sterowania diodami LED. Realizowane są one poprzez odpowiednie zapisy poszczególnych bitów do odpowiednich rejestrów. Dla przykładu, w sterowaniu diodą LED numer 1 mamy następujące definicje:

#define LED_1_ON GPIOB->BSRR |= GPIO_BSRR_BS8,

#define LED_1_OFF GPIOB->BSRR |= GPIO_BSRR_BR8,

#define LED_1_INV ((GPIOB->ODR & GPIO_ODR_ODR8)?(LED_1_OFF):(LED_1_ON)).

Pierwsze plecenie powoduje włączenie diody LED, drugie polecenie wyłącza ją, natomiast ostatnie prowadzi do przełączenia stanu diody LED. Analogiczne działania występują przy sterowaniu pozostałymi diodami LED.
Mariusz Dziębowski
m.dziebowski@interia.pl

Odnośniki: Pliki źródłowe projektu przygotowanego w środowisku Atollic TrueStudio dla STM32
Program terminala Hercules
Moduł Bluetooth KAmodBTM222
Zestaw uruchomieniowy ZL27ARM