mw9501 Napisano Grudzień 9, 2019 Udostępnij Napisano Grudzień 9, 2019 Witajcie Realizuję komunikację pomiędzy mikroprocesorem STM32F411RE (NUCLEO) a modułem SIM800L. Wykorzystuję do tego interfejs UART. Inicjalizuję go poprzez bibliotekę HAL'a. Samą wymianę danych postanowiłem zrobić ręcznie, odwołując się bezpośrednio do rejestrów UART. Poniżej funkcja inicjalizacyjna: void uart_init(uint32_t baud) { uart_gpio.Pin = GPIO_PIN_9 | GPIO_PIN_10; //TX RX uart_gpio.Mode = GPIO_MODE_AF_PP; uart_gpio.Alternate = GPIO_AF7_USART1; uart_gpio.Speed = GPIO_SPEED_HIGH; uart_gpio.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOA,&uart_gpio); usart.Instance = USART1; usart.Init.BaudRate = baud; usart.Init.Parity = USART_PARITY_NONE; usart.Init.StopBits = USART_STOPBITS_1; usart.Init.WordLength = USART_WORDLENGTH_8B; usart.Init.Mode = USART_MODE_TX_RX; HAL_USART_Init(&usart); } Sama komunikacja odbywa się w funkcji "sim_reception", w przerwaniu od timera mikroprocesora. #define SIM_TX_BUF_SIZE 32 #define SIM_RX_BUF_SIZE 32 volatile unsigned char sim_tx_buf[SIM_TX_BUF_SIZE]; volatile unsigned char sim_rx_buf[SIM_RX_BUF_SIZE]; volatile unsigned char sim_tx_len = 0; volatile unsigned char sim_rx_len = 0; enum { handshake, hdsh_resp }; volatile uint8_t sim_states = handshake; #define SIM_HNDSHK "AT\r\n" void sim_reception(void) { //RX //if Receiver not empty flag is set and we have space in rx buffer, we read byte while(USART1 -> SR & USART_SR_RXNE) { if(sim_rx_len < SIM_RX_BUF_SIZE) sim_rx_buf[sim_rx_len++] = USART1 -> DR; //after reading byte we increment buffer length else break; } //TX //if Transmitter empty flag is set and we have data in tx buffer, we send byte while(USART1 -> SR & USART_SR_TXE) { if(sim_tx_len != 0) { USART1 -> DR = sim_tx_buf[0];//send one byte sim_byte_up(sim_tx_buf); //shift one byte up } else break; } switch(sim_states) { case handshake: sim_tx_buf_put(SIM_HNDSHK); sim_states = hdsh_resp; break; case hdsh_resp: break; default: sim_states = handshake; break; } } Na razie chcę wysłać tylko jedno polecenie i odczytać odpowiedź modułu SIM800L. Krótko opiszę nadawanie, które działa bez zarzutu. Wywołuję funkcję "sim_tx_buf_put", która napełnia bufor komendą "SIM_HNDSHK", zdefiniowaną wyżej za pomocą #define. Funkcja bada ile miejsca mamy w buforze i czy wystarczy go jeszcze dla nowego polecenia. Jeśli tak to wstawia je bajt po bajcie i zwiększa odpowiednio zmnienną "sim_tx_len". Nie będe wstawiał kodu tej funkcji, ponieważ działa ona bardzo dobrze, nie mam z nią problemu. Wyżej w kodzie widać, że jest badany stan flagi "Transmitter Empty", gdy się ona pojawi i w buforze Tx są dane przystępuje się do wysyłania danych bajt po bajcie. Po każdym wysłanym bajcie wywoływana jest funkcja "sim_byte_up", która przesuwa bajty bufora "o jeden w górę", czyli sim_tx_buf[0] = sim_tx_buf[1], sim_tx_buf[1] = sim_tx_buf[2] itd. oraz zmniejsza wartość "sim_tx_len" o jeden, następnie wysyłany jest kolejny bajt i tak do opróżnienia bufora. Nadajnik działa jak należy, co pokazuje screenshot z analizatora stanów logicznych. Po wysłaniu wiadomości "AT\r\n" moduł SIM800L odsyła odpowiedź. Zatem flaga "Receiver Not Empty" powinna zostać aktywowana, bufor Rx jest pusty, tak więc coś powinno zostać zapisane w buforze. Jednak nic takiego się nie dzieje. Screenshoty z debugowania. W buforze Rx pojawia się tylko jeden bajt o wartości 127. Dalszych procedur odbioru nawet nie opracowałem, bo skoro w buforze odbiorczym nic nie ma... Nie bardzo wiem z czym jest związany ten problem, próbowałem wyprowadzić Tx i Rx we wszystkich możliwych konfiguracjach, jednak zawsze jest tak samo, nadajnik wysyła bez żadnego problemu a odbiornik nie może nic odczytać. Jeśli ktoś ma jakiś pomysł co może być przyczyną problemu i jak to rozwiązać to byłbym bardzo wdzięczny za pomoc 😉 Pozdrawiam mw Cytuj Link do komentarza Share on other sites More sharing options...
Elvis Grudzień 10, 2019 Udostępnij Grudzień 10, 2019 @mw9501 nie udostępniłeś całego kodu, więc próba pomocy to niestety zgadywanie. Zacznę więc od najprostszego pytania - włączyłeś taktowanie portu z pinem RX? 1 Cytuj Link do komentarza Share on other sites More sharing options...
mw9501 Grudzień 11, 2019 Autor tematu Udostępnij Grudzień 11, 2019 @Elvis Tak, oczywiście. Taktowanie jest wszędzie włączone. int main(void) { HAL_Init(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_USART1_CLK_ENABLE(); __HAL_RCC_TIM5_CLK_ENABLE(); timers_init(); interrupt_init(); uart_init(9600); while(1) { } } Cytuj Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Dołącz do dyskusji, napisz odpowiedź!
Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!