Comandi AT e C18
- Login o registrati per inviare commenti
Salve a tutti. Ho un modulo GSM interfacciato con un PIC18F4520 e in parallelo ho collegato un convertitore seriale-usb per leggere su hyperterminal tutto ciò che il programma invia e riceve. Io devo leggere il testo di un SMS solo che la risposta a questo comando AT+CMGR=3 (ossia quello per leggere il messaggio) è questa:
+CMGR: "REC READ","+85291234567",,"07/02/18,00:12:05+32"
Hello, welcome to our SMS tutorial.
OK
E il PIC è come se ricevesse solo OK e tutto il resto non viene ricevuto (o magari sbaglio io). Vorrei sapere se c'è un modo per ricevere solo il testo o se c'è un modo per poterlo leggere in qualche modo.
Grazie in anticipo.
e quindi come dovrei fare?
Senza schema ne codice davanti è un po difficile.....
Se posti la parte di schema elettrico e di codice relativa vedo di darci un'occhiata.
Innanzitutto grazie dell'aiuto. Lo schema mi diventa difficile postartelo perchè non ne ho uno nemmeno io per il programma invece te lo posto qui sotto:
#include
#include
#include
#include
#include
#include
#pragma config OSC = INTIO7, WDT=OFF, MCLRE = OFF,DEBUG = OFF,LVP = OFF
#pragma config PBADEN = OFF
void arraytostring(void);
void getbyte(void);
void message(void);
char j=0;
char inbyte[50];
char x = 0;
char y = 0;
void getbyte(void)
{
char x = 0;
char y = 0;
if(RCSTAbits.OERR)
{
RCSTAbits.CREN=0;
Nop();
RCSTAbits.CREN=1;
}
while(x !=10 )
{
while (!DataRdyUSART());
if(RCSTAbits.OERR)
{
RCSTAbits.CREN=0;
Nop();
RCSTAbits.CREN=1;
}
x = getcUSART( );
if (x == 'O')
{
while (!DataRdyUSART());
x = getcUSART( );
if (x == 'K')
{
PORTAbits.RA0=1;
Delay10KTCYx(255);
PORTAbits.RA0=0;
Delay10KTCYx(200); // hai ricevuto il comando OK
}
}
}
}
void message(void)
{
char x,a,b,c,d,i = 0;
char y = 0;
for (i=0;i<20;i++)
{
if(RCSTAbits.OERR)
{
RCSTAbits.CREN=0;
Nop();
RCSTAbits.CREN=1;
}
while (!DataRdyUSART());
if(RCSTAbits.OERR)
{
RCSTAbits.CREN=0;
Nop();
RCSTAbits.CREN=1;
}
a = getcUSART( );
}
a = getcUSART( );
i=i+1;
}
void main(void)
{
OSCCON = 0b01110110;
ADCON1 = 0b00001111;
// Imposto PORTA tutti uscite
LATA = 0x00;
TRISA = 0x00;
// Imposto PORTB tutti uscite
LATB = 0x00;
TRISB = 0x00;
// Imposto PORTC tutti ingressi
LATC = 0x00;
TRISC = 0xFF;
// Imposto PORTD tutte uscite
LATD = 0x00;
TRISD = 0x00;
// Imposto PORTE tutti ingressi
LATE = 0x00;
TRISE = 0x07;
RCSTAbits.SPEN=1;
LATC=0;
TRISC=255;
TRISB=0b01000000;
PORTBbits.RB6=1;
Delay10KTCYx(255);
PORTBbits.RB6=0;
Delay10KTCYx(240);
PORTBbits.RB6=1;
PORTAbits.RA0=1;
Delay10KTCYx(255);
PORTAbits.RA0=0;
Delay10KTCYx(200);
// Quarzo 8MHz
// Formato 8 bit
// 1 bit di stop
// Baud rate 9600bit/s
// Interruzioni disattive
OpenUSART( USART_TX_INT_OFF &
USART_RX_INT_OFF &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH,
51);
while (1)
{
const unsigned char corretto[3]={'O','K','\0'};
unsigned char i=0;
char inbyte[50];
Delay10KTCYx(40);
putrsUSART((const far rom char *)"AT\r\n");// AT command test
while(!BusyUSART());
getbyte();
Delay10KTCYx(200);
// arraytostring();
putrsUSART((const far rom char *)"AT+CPIN=1017\r\n");// AT command test
while(!BusyUSART());
Delay10KTCYx(200);
putrsUSART ((const far rom char *)"AT+CMGF=1\n\r"); // SMS format type; 1=text
while(!BusyUSART());
putrsUSART((const far rom char *)"AT+CMGR=4\r\n");
while(!BusyUSART());
message();
Delay10KTCYx(200);
Infatti... non vedo la gestione del buffer FIFO.
la funzione getbyte dopo aver gestito l'overrun fa solo il confronto con OK ma i dati dove li salva?
Ma a me serve per forza salvarli? e come dovrei fare per salvarli?
La seriale dei PIC ha un buffer di 3 byte, poi sovrascrive. Se tu leggi solo il byte di ricezione come fai a leggere tutto il messaggio?
Immagino che se elimini il controllo overrun ti da errore...
Si esatto mi da errore..come posso fare per salvare ogni carattere?
Attiva un puntatore di memoria che incrementi ogni volta che ricevi un byte e ce lo scrivi. Puoi fare tutto da interrupt, viene un lavoro piu 'pulito'.
Allora:
-attiva l'interrupt sulla ricezione del byte da uart
-sotto interrupt trasferisci il byte ricevuto nella locazione di memoria puntata dal pointer che incrementerai
-fai una verifica con l'ultimo byte o con OK ed attiva una flag di fine messaggio
- se messaggio ricevuto azzera pointer
Non è difficile in C :)
mi sembra ci sia un esempio anche sul manuale del C18 ;)
Grazie mille per la risposta :)
ma non credo di essere in grado di fare tutto ciò... di questo link l'esempio è il numero 6? http://ww1.microchip.com/downloads/en/devicedoc/51295e.pdf
Salve a tutti, come metodo è molto valido quello di usare un interrupt....cmq potresti fare cosi quando ricevi via seriale le lettere le devi salvare su una cella libera della ram e andare avanti cosi....per fare cio devi usare la cella fsr
un piccol listato può essere:
FSR = 0x40;
appena ricevo un dato via seriale
INDEF = RCREG; <--INDEF è la cella con indirizzo 0x40 (dal contenuto di FSR)
FSR++;
finota la ricezione dati
mi salvo l'ultimo valore dell fsr in una cella e poi invio da 0x40 a 0xXX i dati al PC così da visualizzarli alla fine risetto l'FSR a 0x40 e riattendo i dati dalla seriale
- Login o registrati per inviare commenti

















18 min 44 sec fa
Non è per caso che stai riscrivendo nel buffer della uart?
(e quindi leggi solo gli ultimi 3 byte ' OK')