j'ai vraiment beaucoup de mal avec la fonction UART_Read () utilisée dans interrup:
j'ecume les tuto, les conseils, les exemples...je n'y arrive pas
j'ai bien compris l'utilisation de la fct : strchr(MSG, 13);
mais je ne sais où la placer dans mon code:
-->dans le main?, en dehors du main?
-->dans la fct UART_Read()?
--->dans l'interruption?
j'ai déclaré un tabeau de caractere char SMS[80]
Mon sms reçu traité par l'uart rempli bien ce tableau à partir de l'indice [50]
mais je n'arrive pas à afficher sur le Lcd l'ensemble du Message SMS reçu par le Module
Je n'arrive pas à lui faire detecter la fin du SMS se terminant par OD-OA
La seule façon pour afficher l'ensemble du sms et de connaitre à l'avance le nombre de caractere envoyer:
En dehors de ce nombre de caractere j'ai un decalage sur l'ensemble des lignes de l'afficheur.
Quelqu'un peut il modifier mon code source ci-joint,afin que je puisse comprendre comment cela fonctionne après compilation?
Par avance merci,..je galere vraiment
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
static 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
{
// mettre ici les declaration?
if(RCIF==1) // //test le buffer RCREG si plein
// 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)
{
//-------------------------Lecture du Numero date----------
j=0;
do // boucle do
{
Data_lue = UART_Read();
MSG[j] = Data_lue;// ici on place dans MSG [j] la valeur de Data_lue pour, j=0 jusqu'à j<50
} while( ++j<50);
//-------------------------Lecture du sms----------
j=50;
do // boucle do
{
Data_lue = UART_Read();
SMS[j] = Data_lue;// ici on place dans MSG [j] la valeur de Data_lue pour, j=0 jusqu'à j<57
// 57 car 5 caracteres + 2 autres (OD et OA)
} while(++j<57);
//----------------------FIN DU TRAITEMENT PAR UART??????----------------------------------------------------------
//----------------------AFFICHAGE SUR ECRAN 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<55);
}//Fin du 1er if
}// JE SORS DE L INTERRUPTION UART
//*****************************************************************
//-------------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)
{
VERT=1;
}// 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("+33612345678");
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
}