Bufor cykliczny UART – jak odbierać długie stringi z modułu GSM i je przechowywać?

0

witam,

Jestem początkującym, robię projekcik związany z komunikacją uC Atmega i modułu GSM i przetwarzaniem danych otrzymanych z modułu GSM i z tym największy problem.
Wiem jak przesyłać i odbierać pojedyncze ramki, ale nie wiem jak zorganizować w programie tą komunikację, docelowo chciałbym odczytywać i porównywać SMS zapisane na karcie SIM w module GSM a następnie je z czymś porównywać, na razie mam coś takiego i nie mam pomysłu jak odbierać długie stringi z modułu i przechowywać je w programie do momentu porównania.

Widziałem wiele przykładów implementacji bufora cyklicznego ale żadnego nie udało mi się z sukcesem zaimplementować...
Może ktoś zaproponować jakiś najprostszy sposób odbiór danych po UART i przechowanie go w programie, tak aby był nieblokujący.

#define F_CPU 18432000L
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/io.h>
#include <stdio.h>
#include <string.h>
#define BAUD 115200
#define __UBRR ((F_CPU+BAUD*8UL) / (16UL*BAUD)-1) 
#define ROZMIAR 16

volatile char znak = 0;

void USART_Init( uint16_t ubrr );
void USART_Transmit( char data );
char USART_Receive( void );
void GSM_Init( void );
void USART_Write_Word( char *dana );
void USART_Read_Word( void );

int main(void){
	//Ustawienie portów
	DDRD |= (1<<PD5); //debug dioda
	DDRD |= (1<<PD7); //boot input gsm
	PORTD = (0<<PD7); //gsm on

	//Deklaracja zmiennych lokalnych
	
	//Wywołanie funkcji inicjaizujących
	USART_Init(__UBRR);
	sei();
	
	while (1){		
		
		
		}
}
/*DEFINICJE FUNKCJI*/
ISR(USART_RXC_vect){		//przerwanie od odbioru danej
	znak = UDR;	
	UDR = znak;
}
void USART_Init( uint16_t ubrr){
	/*Set baud rate */
	UBRRH = (uint8_t)(ubrr>>8);
	UBRRL = (uint8_t)ubrr;
	/*Enable receiver and transmitter and receiver interrupt */
	UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
	/* Set frame format: 8data, 1stop bit, none parity */
	UCSRC = (1<<URSEL)|(3<<UCSZ0);
}
void USART_Transmit( char data ){
	/* Wait for empty transmit buffer */
	while ( !( UCSRA & (1<<UDRE)) );
	/* Put data into buffer, sends the data */
	UDR = data;
}
char USART_Receive( void ){
	/* Wait for data to be received */
	while ( !(UCSRA & (1<<RXC)) );
	/* Get and return received data from buffer */
	return UDR;
}
void GSM_Init( void ){
	
}	
void USART_Write_Word( char *dana){
	int length; //długość stringa
	int k=0; //zmienna licznikowa
	
	length=strlen(dana);
	
	for(k=0; k<length; k++){
		USART_Transmit(dana[k]);
	}
	
}
void USART_Read_Word(void){

}
0

Próba implementacji bufora cyklicznego, efekt jest taki, że po podłączeniu modułu GSM, uC powinien odebrać "MODEM STARTUP" a następnie go wysłać na terminal putty, a tak się nie dzieje.

/*
 * RS232.c
 *
 * Created: 29.09.2018 15:16:13
 * Author : Łukasz
*/
#define F_CPU 18432000L
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/io.h>
#include <stdio.h>
#include <string.h>
#define BAUD 115200
#define __UBRR ((F_CPU+BAUD*8UL) / (16UL*BAUD)-1) 
#define ROZMIAR 16

typedef struct{
	char tablica[ROZMIAR];
	char poczatek;
	char koniec;
	}bufor_cykliczny;
	
volatile bufor_cykliczny bufor = {.poczatek = 0, .koniec = 0};
//volatile char znak = 0;

void USART_Init( uint16_t ubrr );
void USART_Transmit( char data );
char USART_Receive( void );
void GSM_Init( void );
void USART_Write_Word( char *dana );
void USART_Read_Word( void );
void bufor_dopisz(char data);
void bufor_wyslij(void);

int main(void){
	//Ustawienie portów
	DDRD |= (1<<PD5);
	DDRD |= (1<<PD7);
	PORTD = (0<<PD7); //gsm on

	//Deklaracja zmiennych lokalnych
	
	//Wywołanie funkcji inicjaizujących
	USART_Init(__UBRR);
	sei();
	
	while (1){		
		
		
		}
}
/*DEFINICJE FUNKCJI*/
ISR(USART_RXC_vect){		//przerwanie od odbioru danej
	bufor_dopisz(UDR);
	if(bufor.poczatek + 1 == bufor.koniec){
		bufor_wyslij();
	}	
}
ISR(USART_UDRE_vect){
	bufor_wyslij();
}
void USART_Init( uint16_t ubrr){
	/*Set baud rate */
	UBRRH = (uint8_t)(ubrr>>8);
	UBRRL = (uint8_t)ubrr;
	/*Enable receiver and transmitter and receiver interrupt */
	UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(1<<UDRE);
	/* Set frame format: 8data, 1stop bit, none parity */
	UCSRC = (1<<URSEL)|(3<<UCSZ0);
}
void USART_Transmit( char data ){
	/* Wait for empty transmit buffer */
	while ( !( UCSRA & (1<<UDRE)) );
	/* Put data into buffer, sends the data */
	UDR = data;
}
char USART_Receive( void ){
	/* Wait for data to be received */
	while ( !(UCSRA & (1<<RXC)) );
	/* Get and return received data from buffer */
	return UDR;
}
void GSM_Init( void ){
	
}	
void USART_Write_Word( char *dana){
	int length; //długość stringa
	int k=0; //zmienna licznikowa
	
	length=strlen(dana);
	
	for(k=0; k<length; k++){
		USART_Transmit(dana[k]);
	}
	
}
void USART_Read_Word(void){
}
void bufor_dopisz(char data){
	if(bufor.koniec+1 < ROZMIAR) //standardowy przypadek
	{
		if(bufor.koniec+1 != bufor.poczatek){
			bufor.tablica[bufor.koniec++] = data;
			} //jeżeli jest miejsce w buforze to zapisz, aktualizuj koniec, jeżeli nie ma miejsca to nic nie rób
	}
	else //przypadek gdy trzeba wrócić do 0
	{
		if(bufor.poczatek != 0){
			bufor.tablica[ROZMIAR-1] = data; 
			bufor.koniec=0;
			}
	}
}
void bufor_wyslij(void){
	if(bufor.poczatek != bufor.koniec) //jeżeli bufor nie jest pusty
	{
		UDR = bufor.tablica[bufor.poczatek++]; //wyślij daną z początku i zwiększ wskaźnik
	}
}


1 użytkowników online, w tym zalogowanych: 0, gości: 1