Depuis qqs temps , je bloque sur l'affichage des caractères sur LCD
Je travaille sur la réception de msg SMS via module GSM-808
Le format de la trame de reception SMS est de la forme:
CRLF
+CMT: "+336xxxxxxxx","","18/11/25,21:03:44+08"CRLF
le msg sms CRFL CRFL
Je fais une lecture UART sur l'ensemble de la trame que l'envoie dans 2 tableaux
le 1er-> pour le "msg" comprenant le numéro de l’émetteur, l'heure, la date....jusqu'au premier CR
le 2me->pour le corps du SMS recu ,dans le tableau SMS
Mon probleme etant de devoir connaitre le nombre de caractere du SMS pour pouvoir l'afficher sinon ça plante
dans mon code joint, mon SMS doit contenir STRICTEMENT 9 caractères ( de 50 à 58).
Si je reçois un SMS d'une longueur de caractere differents, j'ai des incoherences d'affichage (un decalage de caractère) et je suis obligé de reseter mon PIC.
Je souhaiterai pouvoir afficher l'ensemble du SMS reçu quelque soit sa longueur ( 16 caracteres max)
merci pour vos réponses.
Nota:
pour le moment je ne veux pas passer par l'inter UART
n'etant pas à l'aise avec les tableaux, je ne me suis pas risqué à utiliser les pointeurs...
apres compréhension, je m y attaquerai....etape par etape..
Mon code projet:
Code : Tout sélectionner
//******************************************************************************
// microcontroller : P16F877a
// Compilateur: hi-Tech
// IDE: MPLAB IDE-V8.92
// Programmateur: ICD3
//
// Project:GSM808_lcd_Gps_V1
/*
Protocole de com UART/
-Mode: Asynchro
-Bit: 8
-Parité: Aucune
-Vitesse:9600 Bauds
Ce projet consiste à:
--> envoyer un SMS via 16f877a: ok
--> Génération d'interruption uart: ok
---> Lire UART via une condition if '+' : ok
---> Envoyé la lecture selon condition sur LCD: ok
---> Présenter la lecture sur LCD dans bon ordre: ok
/* Les essais de reception sont visualisés sur RealTime*/
/* exemple de trame de reception SMS */
/*+CMT: "+336xxxxxxxx","","18/11/25,21:03:44+08"*/
/* Essai*/
//*****************************************************************
//--------------INCLUSION DES FICHIERS HEADER----------------------
//*****************************************************************
#include <htc.h> //chargement des en-tete issu du compilateur lors de la compilation
#include <pic16f877a.h> //chargement des en-tete issu du compilateur lors de la compilation
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//*****************************************************************
//-------------definition des registres Systemes-------------------
//*****************************************************************
//*****************************************************************
//------------definition des fichiers temporels--------------------
//*****************************************************************
// valeur du Quartz en Hz utilisé sur le pic
#define _XTAL_FREQ 20000000
// on pourra utilser les fonctions declarées dans <pic.h> pointé par <htc.h> apres compilation
// __delay_us(1)-> valeur imprecise verifiée à l'oscillo (tjrs +4µs mesuré)
// __delay_ms(1)-> valeur precise verifiée à l'oscillo
// __delay_s(1) -> valeur precise verifiée à l'oscillo
//*****************************************************************
//------------definition des fusibles de configuration-------------
// PIC16F876A Configuration Bit Settings
//*****************************************************************
__CONFIG(FOSC_HS & WDTE_OFF & PWRTE_OFF & BOREN_OFF & LVP_OFF & CPD_OFF & WRT_OFF & CP_OFF);
//*****************************************************************
//---------------------VARIABLES GENERALES-------------------------
//*****************************************************************
//---Définitions des Bits
#define LCD_RS RA0
#define LCD_E RA1
#define VERT RD0
#define RED RD1
#define ORANGE RD2
//---Définitions des Variables Tableaux
char MSG[80]="";
char SMS[80]="";
char Data_lue;
//---Définitions des Variables Compteurs
int j=0;
//*****************************************************************
//--------------PROTOTYPE DES FONCTIONS LOCALES--------------------
//*****************************************************************
//---Fct_UART---
void UART_Init();
char UART_Read(); // Fct lecture de caractere
void UART_Read_Text(char *Output, unsigned int length);
void UART_Write(char caractere);// Fct d'ecriture de caractere
void UART_Write_Text(char* text);
//---fct_LCD---
void LCD_Init(void);
void lcd_enable(void);
void lcd_write_4bit(unsigned char c);//Routine d'ecriture 4bit sur PORTB_DATA
void lcd_write_cmd(unsigned char c);// Ecriture d'une commande
void lcd_putch(char c); // Ecriture d'1 caractere
void lcd_puts(const unsigned char *chaine);// Ecriture d'1 chaine de caractere
void lcd_pos(unsigned char ligne,unsigned char pos);
//---fct_SMS---
void GSM_Init();
void SendSms();
//*****************************************************************
//-----------SOUS-PROGRAMME D INTERRUPTION-------------------------
//*****************************************************************
/* Fonction: Interruption UART
Si une Data est reçu dans le registre RCREG,
-->un Flag de reception RCIF==1 du registre PIR1 est positionné
-->Il faut imperativement faire une lecture UART du registre RCREG pour le vider
-->Apres lecture, ce flag est remis à 0 Automatiquement
*/
void interrupt UART() //Pas besoin de la prototyper puisque non utlisée dans le main
{
}
//*****************************************************************
//-------------DEBUT DU PROGRAMME PRINCIPAL Main()-----------------
//*****************************************************************
void main()
{
//---Déclartion des variables Locales
/**************INITIALISATION DES REGISTRES*****************/
ADCON1 = 0b00000110; // Tout PORTA en Numerique
CMCON = 0b00000111; // Désactivation du Module Comparateur
OPTION_REG= 0b10000000; // Resistances de tirage à +VCC du PORTB désactivées
// INTCON= 0b00000000; // Tout Interruption de controle déactivées
//---DIRECTION DES PORTS
TRISA = 0b00000000; // --RA5-RA4-RA3-RA2-RS-E
TRISB = 0b11000000; //PGM-PGC-RB5-RB4-D7-D6-D5-D4
TRISC = 0b10111111; // Configuration RX=RC7 en Entrée & TX=RC6 en Sortie
TRISD = 0b00000000; // Tout en Sortie
//---INITIALISATION DES PORTS
PORTA = 0b00000000;
PORTB = 0b00000000;
PORTD = 0b00000000;
//---INITIALISATION DES FONCTIONS
//--UART
UART_Init(); //Initialize UART
//--LCD
LCD_Init(); //Initialize LCD
//--GSM
GSM_Init(); //Initialize GSM
/****************************************************/
lcd_pos(0x00,0x03);
lcd_puts("GSM 808");
lcd_pos(0x01,0x00);
lcd_puts("Du:");
lcd_pos(0x02,0x00);
lcd_puts("Dte:");
lcd_pos(0x03,0x00);
lcd_puts("Msg:");
while (1)
{
//-------------------------Lecture du Numero & date----------
j=0;
do // boucle do
{
Data_lue = UART_Read();
MSG[j] = Data_lue;// ici on place dans NUM [j] la valeur de recept pour, j=2 jusqu'à j<14
} while( ++j<50);
//-------------------------Lecture du SMS----------
j=50;
do // boucle do
{
Data_lue = UART_Read();
SMS[j] = Data_lue;// ici on place dans NUM [j] la valeur de recept pour, j=2 jusqu'à j<14
} while( ++j<61); //TANT QUE N EST PAS EGALE A CR???
//**************************************AFFICHAGE SUR LCD**********************************************
//-------------------------Affichage du Numero----------
lcd_pos(0x01,0x03);
j=9;
do
{
Data_lue = MSG[j];
lcd_putch(Data_lue); //affichage sur LCD ou lcd_puts
}while( ++j<21);
//-------------------------Affichage de l'Heure----------
lcd_pos(0x02,0x04);
j=27;
do
{
Data_lue = MSG[j];
lcd_putch(Data_lue); //affichage sur LCD ou lcd_puts
}while( ++j<35);
//-------------------------Affichage du SMS----------lcd_putch
lcd_pos(0x03,0x04);
j=50;
do
{
Data_lue = SMS[j];
lcd_putch(Data_lue); //affichage de 9 caracteres sur LCD
}while( ++j<59);
}// fin du while
}// fin du main
/**************************************************************************************************
*--1-- Fonction: UART
**************************************************************************************************/
/*---ECRITURE---*/
// Ecriture d'un caractere
void UART_Write(char caractere)
{
while(!TXIF); //Reste ici, Tant que le buffer TXREG est
// RCIF=1---> signifie que le buffer de Transmission est vide (on peut le remplir)
// RCIF=0---> signifie que le buffer de Transmission est plein (on peut le remplir)
TXREG = caractere; //chargement du buffer avec la valeur TX reçue
}
// Ecriture d'une Chaine de caractere
void UART_Write_Text(char* text)
{
while(*text) //Si il y a un Char
UART_Write(*text++); //proceder comme une donnée d'octet
}
/**************************************************************************************************
* Fonction: Lecture d'un caractere et d'une chaine de caractere dans UART
**************************************************************************************************/
/*---LECTURE---*/
// Lecture d'un caractere
char UART_Read()
{
if(OERR==1) // Verification d'Erreur du registre de reception RCSTA avec OERR=1
//Si erreur, on procede à l'affacement du Bit OERR par le passage du Bit CREN de 0 à 1
{
CREN = 0;
CREN = 1;
}
while(RCIF==0); //Reste ici, Tant que le buffer RCREG est vide
// RCIF=1---> signifie que le buffer de reception est plein (donnée reçu)
// RCIF=0---> signifie que le buffer de Reception est vide (rien reçu)
return RCREG ; //Reception de la DATA et envoie à la fonction principale (main)
}
// Lecture d'une chaine de caractere
void UART_Read_Text(char *Output, unsigned int length)
{
int i;
for(int i=0;i<length;i++)
Output[i] = UART_Read();
}
//****************************************************************
//----------------FONCTIONS RELATIVES AU LCD 4X20----------------
//****************************************************************
//--------Fonction de validation de donnée du bus
void lcd_enable(void)
{
__delay_us(100);
LCD_E = 1;
__delay_us(100);
LCD_E = 0;
__delay_us(100);
}
// Procédure d'initialisation de l'afficheur LCD en mode 4 bits
void LCD_Init(void)
{
__delay_ms(15); // Attente après l'établissement de la tension d'alim
//-----------Initialisation du Mode 4bit------------
lcd_write_cmd(0x33);// envoi 2 fois le MSB du Mode 8bit
lcd_write_cmd(0x32);// envoi des MSB du Mode 8bit et MSB du Mode 4bit
lcd_write_cmd(0x28);// envoi des MSB et LSB du Mode 4bit
//-----------Initialisation des Parametres du LCD---
lcd_write_cmd(0x01);// effacer l'ecran
__delay_ms(5); // Attente
lcd_write_cmd(0x0c);//incre gauche vers droite
__delay_ms(5); // Attente
lcd_write_cmd(0x06);//incre sans decalage
__delay_ms(15); // Attente
}
// Ecriture d'un octet dans le LCD en mode 4 bits
void lcd_write_4bit(unsigned char c)
{
//---Trame d'envoi de MSB sur LCD
PORTB =(c>>4);// Msb de rb3à rb0
lcd_enable();
//---Trame d'envoi de LSB sur LCD
PORTB =(c);// lsb de rb3à rb0
lcd_enable();
}
// Ecrit une instruction dans LCD
void lcd_write_cmd(unsigned char c)
{
LCD_RS = 0; // Mode commande du lcd
lcd_write_4bit(c);
}
// Ecriture d'un caractere
void lcd_putch(char c)
{
LCD_RS = 1;// Mode affichage du lcd
lcd_write_4bit(c);
}
// Ecriture d'une chaine de caracteres
void lcd_puts(const unsigned char *chaine)
{
while(*chaine)
lcd_putch(*chaine++);
}
// Positionne le curseur ligne, position EN 4X20
// la premiere ligne est la ligne 0
void lcd_pos(unsigned char ligne,unsigned char pos)
{
if(ligne<=0x01)
{
lcd_write_cmd(((ligne * 0x40)+pos)+0x80);
}
else
{
lcd_write_cmd(((ligne * 0x40)+pos)+0x14);
}
}
/**************************************************************************************************
* Fonction: Initialisation UART: 8Bits/Asyn/9600Bds
**************************************************************************************************/
void UART_Init()
{
// Registre associé à l' emission (TX)
TXSTAbits.TX9 = 0; //9me Bit de la data transmise ou le bit de parité
TXSTAbits.TXEN = 1; //Validation de la transmission
TXSTAbits.SYNC = 0; //Selection du Mode Asynchrone
TXSTAbits.BRGH = 0; // choix de la vitesse du Baud rate
// Registre associé à la Reception (RX)
RCSTAbits.SPEN = 1; //Validation du port Serie
// RCSTAbits.RX9 = 1; //9me Bit Autorisé pour eviter l erreur de FERR
RCSTAbits.CREN = 1; //Validation de la Reception en Continue
// Registre de config transmission
SPBRG = 31; //Vitesse du Baudrate en fct de SPBRG= Fosc/[64(X+1)] ==>20000000/[64(4800+1)]=31 pour 9600bds et 65 pour 4800
//---------------------------------------------------------------------
// INTCONbits.GIE = 1; //Validation des Interruptions Générales
// INTCONbits.PEIE = 1; //Validation des Interruptions Péripheriques
// PIE1bits.RCIE = 1; //Validation de l'interruption sur Recepetion du Bit RC
// PIR1bits.RCIF = 0; //Effacement du Flag d'interruption sur Recption du Bit RC (par securité)
}
/**************************************************************************************************
* Fonction: Initialisation GSM_808
**************************************************************************************************/
void GSM_Init()
{
// __delay_ms(2000);
UART_Write_Text("ATE0"); // AT command for Echo OFF
UART_Write(13);
UART_Write(10);
__delay_ms(500);
UART_Write_Text("AT+CMGF = 1");
UART_Write(13);
UART_Write(10);
__delay_ms(500);
UART_Write_Text("AT+CNMI=1,2,0,0,0");// ("AT+CNMI=1,2,0,0,0")---> ça marche avec
UART_Write(13);
UART_Write(10);
__delay_ms(500);
}
/**************************************************************************************************
*--2-- Fonction: Module GSM_808
**************************************************************************************************/
//--- Envoi d'un SMS via la fct UART_Write_Text
void SendSms()
{
UART_Write_Text("AT+CMGS=");
UART_Write(0x22);// ouverture des guillements pour entrer le numero
UART_Write_Text("+336xxxxxxx");
UART_Write(0x22);// ouverture des guillements pour entrer le numero
UART_Write(0x0D);
__delay_ms(500);
UART_Write_Text("envoi Reussi");
UART_Write(26);// Ctrl+Z
}