Bienvenue aux nouveaux arrivants sur FantasPic !
- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.
--- L’équipe FantasPic ---
- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.
--- L’équipe FantasPic ---
Modérateur : Jérémy
Pbm d'affichage de caractere sur LCD
Bonsoir à tous,
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
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
}
Pbm d'affichage de caractere sur LCD
-
Jérémy
Administrateur du site- Messages : 2725
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Hello,
Plusieurs problèmes .
Tu ne peux pas faire de boucle dans une interruption ! Ton interruption doit être le plus court possible !
Ton interruption se déclenche à chaque caractère reçus tu dois enregistrer ce caractère et ressortir !
dans ton Interruption tu récupérer et stocker ton message . Une fois que c'est finis! tu léves un Flag pour qui signaler a ton Main que tu as un message un afficher.
Attention un chaine de caractère doit ce terminer un terminateur de chaine un zéro "/0 " si tu veux utilsier des fonctions traitant des chaines de caractères.
Juste en faisant des copier/coller , un verrais plus un truc dans ce genre !
Un truc du genre
Plusieurs problèmes .
Tu ne peux pas faire de boucle dans une interruption ! Ton interruption doit être le plus court possible !
Ton interruption se déclenche à chaque caractère reçus tu dois enregistrer ce caractère et ressortir !
dans ton Interruption tu récupérer et stocker ton message . Une fois que c'est finis! tu léves un Flag pour qui signaler a ton Main que tu as un message un afficher.
Attention un chaine de caractère doit ce terminer un terminateur de chaine un zéro "/0 " si tu veux utilsier des fonctions traitant des chaines de caractères.
Juste en faisant des copier/coller , un verrais plus un truc dans ce genre !
Code : Tout sélectionner
void interrupt UART() //Pas besoin de la prototyper puisque non utlisée dans le main
{
// mettre ici les declaration? ---> surtout pas
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)
{
DATA_LUE = UART_READ();
//-------------------------LECTURE DU NUMERO DATE----------
if J < 50
MSG[J] = DATA_LUE;// ICI ON PLACE DANS MSG [J] LA VALEUR DE DATA_LUE POUR, J=0 JUSQU'À J<50
++J;
//-------------------------LECTURE DU SMS----------
if j > 50
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)
++J
if j > 57 ---> fin du message je leve un drapeau et je RAZ JE
DRAPEAU = 1 ;
J = 0
}// JE SORS DE L INTERRUPTION UART
MAIN {
if drapeau == 1{ -----> MAJ de l'écran
//----------------------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
Un truc du genre
Pbm d'affichage de caractere sur LCD
Bonsoir à tous,
Je profite d'un peu de temps pour réactualiser mon programme par la richesse et l'utilité de vos conseils.
J'ai enfin réussi à afficher les chaines de caractère provenant de ma réception UART via l'interruption UART.
Avant de poursuivre mon projet (emission d'un SMS....),
A/Question sur la déclaration du tableau MSG[80]
j'ai compris le mecanisque: on pointe vers une adresse qui contient la valeur,etc...
- mais j'ai beaucoup de mal à le mettre en œuvre pour comprendre concrètement son fonctionnement:
comment le déclarer?
où le déclarer?
comment initialiser?
etc...
En attendant je vous mets le code de réception SMS qui fonctionne à merveille en y mettant un Max de commentaire
Je profite d'un peu de temps pour réactualiser mon programme par la richesse et l'utilité de vos conseils.
J'ai enfin réussi à afficher les chaines de caractère provenant de ma réception UART via l'interruption UART.
Avant de poursuivre mon projet (emission d'un SMS....),
j'ai toujours la fameuse question...
A/Question sur la déclaration du tableau MSG[80]
- 1- J'ai déclaré ce tableau de caractère dans les variables Globales par : unsigned char MSG[80];
j'ai compris le mecanisque: on pointe vers une adresse qui contient la valeur,etc...
- mais j'ai beaucoup de mal à le mettre en œuvre pour comprendre concrètement son fonctionnement:
comment le déclarer?
où le déclarer?
comment initialiser?
etc...
En attendant je vous mets le code de réception SMS qui fonctionne à merveille en y mettant un Max de commentaire
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
les caracteres et correspondances/
CR=0x0D=13=\r
LF=0x0A=10=\n
Ce projet consiste à:
A/Configuration du Module GSM SIM808/
-Config Protocole UART:Ok (via QNavigator et doc)
-Désactivation du Mode Echo: Ok
-Selection du Mode Texte: Ok
-Selection du Format des SMS: Ok
B/RECEPTION SMS
--> Recevoir un SMS via 16f877a: ok
--> Génération d'interruption uart: ok
---> Lire le MSG reçu via UART : ok
---> Envoyé le MSG reçu sur LCD
via une Boucle (Flag)de Condition (CR et LF): ok
---> Mise à jour du LCD entre chaque lecture: ok
C/EMISSION SMS
--> Envoyer un SMS via 16f877a: en cours et à verifier
*/
//********************************************************************************************************************************
//--------------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 du PIC---------------------------------------------------------------------
//********************************************************************************************************************************
__CONFIG(FOSC_HS & WDTE_OFF & PWRTE_OFF & BOREN_OFF & LVP_OFF & CPD_OFF & WRT_OFF & CP_OFF);
//********************************************************************************************************************************
//---------------------VARIABLES GLOBALES-----------------------------------------------------------------------------------------
//********************************************************************************************************************************
//---Définitions des Bits
//PORTA:
#define LCD_RS RA0
#define LCD_E RA1
#define Inter RA5
//PORTD:
#define VERT RD0
#define RED RD1
#define ORANGE RD2
//---Définitions des Variables Tableaux
unsigned char MSG[80];
//---Définitions des Variables & Compteurs
int j=0;
int flag=0;
int Drapeau=0;
//********************************************************************************************************************************
//--------------PROTOTYPE DES FONCTIONS LOCALES-----------------------------------------------------------------------------------
//********************************************************************************************************************************
//---Fct_UART---
void UART_Init();
char UART_Read();
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);
void lcd_write_cmd(unsigned char c);
void lcd_putch(char c);
void lcd_puts(const unsigned char *chaine);
void lcd_pos(unsigned char ligne,unsigned char pos);
//---fct_SMS---
void GSM_Init();
void SendSms();
//********************************************************************************************************************************
//-----------SOUS-PROGRAMME D INTERRUPTION----------------------------------------------------------------------------------------
//********************************************************************************************************************************
/* Fonction: Interruption UART*/
void interrupt UART() //Pas besoin de la prototyper puisque non utlisée dans le main
{
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 MSG---------------
/* Trame du MSG Reçu: CrLf+CMT: "+336xxxxxxxx","","18/11/25,21:03:44+08"CrLf12345CrLf */
while (flag!=3) // Tant que la valeur du compteur FLAG est different de 3 faire la boucle
{
MSG[j]= UART_Read(); // ici on place dans MSG [j] la valeur lue par UART
if ((MSG[j]=='\n')) // Si le caractere \n de la trame est détecté
{
flag++ ; // j'incremente le compteur de Flag à +1
}
j++; // j'incremente le compteur d'indice de Lecture de MSG[j]
} // le compteur Flag est egale à 3
flag=0; // Je remets le compteur Flag à 0
Drapeau=1; // Mise à 1 du Drapeau conditionnel
//----------------------AFFICHAGE SUR ECRAN LCD---------
// Routine permettant de visuliser l'arrivée d'un SMS
RED=~RED;
__delay_ms(50);
RED=~RED;
__delay_ms(50);
RED=~RED;
__delay_ms(50);
RED=~RED;
// Effacement des lignes du LCD
lcd_pos(0x03,0x04);
lcd_puts(" ");
}
}
//********************************************************************************************************************************
//-------------DEBUT DU PROGRAMME PRINCIPAL Main()--------------------------------------------------------------------------------
//********************************************************************************************************************************
void main()
{
//*********************Début des Déclaration 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 = 0b00100000; // --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
//*********************Fin des Déclarations des variables Locales*********************//
lcd_pos(0x00,0x03);
lcd_puts("GSM 808");
lcd_pos(0x01,0x00);
lcd_puts("Du:");
lcd_pos(0x02,0x00);
lcd_puts("Hrs:");
lcd_pos(0x03,0x00);
lcd_puts("Msg:");
while (1)
{
switch (Drapeau)
{
case 0: // Si la valeur du Drapeau conditionnel est à 0
VERT=1;
break;
case 1:// Si la valeur du Drapeau conditionnel est à 1
//------------------------Affichage du Numero-----------
lcd_pos(0x01,0x03);
j=9; // A partir l'indice de MSG[9]
do
{
lcd_putch(MSG[j]); // Affichage sur LCD
}while( ++j<21); // J'incremente le compteur d'indice de MSG[j] tant que celui-ci est inferieur à 21--> MSG[20]
//-------------------------Affichage de l'Heure----------
lcd_pos(0x02,0x04);
j=36;
do
{
lcd_putch(MSG[j]);
}while( ++j<44);
//-------------------------Affichage du SMS--------------
lcd_pos(0x03,0x04);
j=50; // A partir l'indice de MSG[50]--> Debut du SMS (voir trame)
while((MSG[j]!='\r')) // Tant que le contenu de MSG[j] est different de \r --> Fin du SMS (voir trame)
{
lcd_putch(MSG[j]); // Affichage sur LCD
j++; // J'incremente le compteur d'indice de MSG[j]
}
j=0; // Je remets le compteur à 0
Drapeau=0; // Mise à 0 du Drapeau conditionnel
break;
}
}// fin du while
}// fin du main
//********************************************************************************************************************************
// Fonction: Ecriture dans UART---------------------------------------------------------------------------------------------------
//********************************************************************************************************************************
// Fonction d'écriture 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
}
// Fonction d'écriture 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 dans UART----------------------------------------------------------------------------------------------------
//********************************************************************************************************************************
// Fonction de 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); // ou bien while(!RCIF) 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)
}
// Fonction de 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 sur bus
void lcd_enable(void)
{
__delay_us(100);
LCD_E = 1;
__delay_us(100);
LCD_E = 0;
__delay_us(100);
}
// Fonction 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
}
// Fonction d'écriture 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();
}
// Fonction d'écriture d'une Commande dans LCD
void lcd_write_cmd(unsigned char c)
{
LCD_RS = 0; // Mode commande du lcd
lcd_write_4bit(c);
}
// Fonction d'écriture d'un caractere
void lcd_putch(char c)
{
LCD_RS = 1;// Mode affichage du lcd
lcd_write_4bit(c);
}
// Fonction d'écriture d'une chaine de caracteres
void lcd_puts(const unsigned char *chaine)
{
while(*chaine)
lcd_putch(*chaine++);
}
// Fonction de Positionnement du curseur: ligne, position
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 = 0; //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
// Controle des Interrptions
INTCONbits.PEIE = 1; //Validation des Interruptions Péripheriques
INTCONbits.GIE = 1; //Validation des Interruptions Générales
PIR1bits.RCIF = 0; //Effacement du Flag d'interruption sur Recption du Bit RC (par securité)
PIE1bits.RCIE = 1; //Validation de l'interruption sur Recepetion du Bit RC
}
//********************************************************************************************************************************
// 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"); // Mode Texte
UART_Write(13);
UART_Write(10);
__delay_ms(500);
UART_Write_Text("AT+CNMI=1,2,0,0,0"); // Format des SMS
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("+336xxxxxxxxx");
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
}
Pbm d'affichage de caractere sur LCD
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
francknvs a écrit : ... J'ai déclaré ce tableau de caractère dans les variables Globales par : unsigned char MSG[80];
là aussi, ce n'est pas tres propre, je devrai le déclarer comme pointer pour des raisons de stabilité et de facilité
....
l'emploi de pointeur n'est pas INDISPENSABLE ..
comment le déclarer?
le tableau est declaré comme d'habitude, pour reserver l'espace RAM
unsigned char MSG[80];
on declare un pointeur p1 sur type charactere
unsigned char * p1;
comment initialiser?
et dans le main on l'initialise pour pointer sur le 1er caractere du tableau
p1=&MSG[0];
ou p1=MSG; // mais pour ma part, je préfere la précedente init, plus explicite.
Code : Tout sélectionner
while (flag!=3) // Tant que la valeur du compteur FLAG est different de 3 faire la boucle
{
*(p1+j)= UART_Read(); // ici on place dans MSG [j] la valeur lue par UART
if ((*(p1+j)=='\n')) // Si le caractere \n de la trame est détecté
{
flag++ ; // j'incremente le compteur de Flag à +1
}
j++; // j'incremente le compteur d'indice de Lecture de MSG[j]
}
l'avantage d'utiliser un pointeur n'est pas evident dans cet exemple precis..
mais plus utile dans le cas de comparaison de chaine :
exemple , tiré d'une trame compteur EDF contenant "IINST 007"
pour extirper la valeur AMps
Code : Tout sélectionner
// buffer_Analyse = buffer de reception UART
char * p3; // déclaré,mais non initialisé
p3=strstr(Buffer_Analyse,"IINST"); // affectation du pointeur
if (p3>0)
{ p3=p3+6; // se positionne apres "IINST "
*(p3+9)=0; // un zero terminateur de string pour ne pas prendre ce qui suit
Amps=atoi(p3);
WordToStrWithZeros(Amps,CRam1);
// Gauge ronde (0-30 Amps) et Text I.Instant (Amps)
UART1_Write('*'); UART1_Write('A');
UART1_Write_Text(CRam1); UART1_Write('*');UART1_Write(',') ;
}
******* remarques sur le code **************
ce que j'aurais fait ... mais ce n'est pas une référence en soi !
mettre plutot cette partie là, dans le main,
Tempo et traitement LCD à eviter dans l'interrupt
Code : Tout sélectionner
//----------------------AFFICHAGE SUR ECRAN LCD---------
// Routine permettant de visuliser l'arrivée d'un SMS
RED=~RED;
__delay_ms(50);
RED=~RED;
__delay_ms(50);
RED=~RED;
__delay_ms(50);
RED=~RED;
// Effacement des lignes du LCD
lcd_pos(0x03,0x04);
lcd_puts(" ");
dans le main :
Code : Tout sélectionner
........
case 1:// Si la valeur du Drapeau conditionnel est à 1
//----------------------AFFICHAGE SUR ECRAN LCD---------
// Routine permettant de visuliser l'arrivée d'un SMS
RED=~RED;
__delay_ms(50);
RED=~RED;
__delay_ms(50);
RED=~RED;
__delay_ms(50);
RED=~RED;
// Effacement des lignes du LCD
lcd_pos(0x03,0x04);
lcd_puts(" ");
//------------------------Affichage du Numero-----------
.......
on pourrait aussi , des que le flag DRAPEAU est monté dans l'interruption,
interdire toute nouvelle modification du buffer de reception MSG
en attendant que son contenu soit traité dans le main
Code : Tout sélectionner
flag=0; // Je remets le compteur Flag à 0
Drapeau=1; // Mise à 1 du Drapeau conditionnel
PIE1bits.RCIE = 0; // on a notre TAF de caracteres , STOP
et donc, dans le main , en fin de traitement case,
remettre PIE1bits.RCIE = 1;
Code : Tout sélectionner
//declarations
char Cx;
....
....... main .....
Drapeau=0; // Mise à 0 du Drapeau conditionnel
Cx=RCREG; // une lecture registre reception pour effacer un eventuel flag RCIF
PIE1bits.RCIE = 1;
break;
}
} //fin du while
Pbm d'affichage de caractere sur LCD
Bonsoir Paul,
Un grand merci pour avoir répondu aux questions que je me posais.
de plus, tes exemples sont adaptés à mon programme, je pourrai ainsi comprendre concrètement le mécanisme.
effectivement, le traitement de l'affichage,etc ....dans l'interrup n'est pas genial, (je l'avais laissé ici pour verifier l'entrée et la sortie de l'interruption)
je vais donc l’insérer dans le main à présent.
Encore Merci...et joyeuses fêtes de fin d'année
Un grand merci pour avoir répondu aux questions que je me posais.
de plus, tes exemples sont adaptés à mon programme, je pourrai ainsi comprendre concrètement le mécanisme.
effectivement, le traitement de l'affichage,etc ....dans l'interrup n'est pas genial, (je l'avais laissé ici pour verifier l'entrée et la sortie de l'interruption)
je vais donc l’insérer dans le main à présent.
Encore Merci...et joyeuses fêtes de fin d'année
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 135 invités