Consolle M16C
CONSOLLE REMOTA p/n ESD070312-1
1.Finalidad
Cuantas veces utilizando un aparato pensamos Como serìa còmodo tener màs informaciones de aquel led che adquire 527 colores o parpadea en 6432 modos diferentes pero todos iguales. cuantas aplicaciones hoy emplean un mòdulo GSM? Telecontroles, teleactuadores, comandos de activaciòn remota ecc. pero si nos fijamos bien ¿ por què¨ no emplearlo para recibir o enviar SMS? Cierto que se tendrìa que trabajar en el firmware, pero por lo menos tendriamos el hardware a nuestra disposiciòn! Bien, si os sois encontrados en una de estas situaciones el proyecto de la consolle remota que sigue puede hacer a vuestro caso.
2.Descripciòn
La consolle permite visualizar en un display los datos ricibidos de otro sistema y enviar una cadena de datos, como por ejemplo en respuesta a una determinada peticiòn.
Los principales bloques funcionales que la componen son:
1)Display de visualizaciòn.
2)Teclado alfanumèrico.
3)Serial de comunicaciòn.
4)Unidad central de elaboraciòn.
Aquì seguido vamos a analizar en detalle cada uno de estos bloques.
3.Display De Visualizaciòn
Para poder visualizar los datos la elecciòn cayò en un clàsico display alfanumèrico 16x2 o sea un dispositivo que pueda visualizar 16 caràcteres estàndar ASCII en dos rayas. El interfaz con el microcontrolador ocurre mediante tres señales de control y ocho señales para la lìnea datos, claramente manejadas en el intierno del firmware.
4.Teclado alfanumèrico
Un teclado alfanumèrico de 14 teclas (0-9,RD,WR,SEND,UP DOWN) permite de escribir y de visualizar los datos ricibidos. El interfaz con el microcontrolador fue realizado aprovechando del mètodo a matriz; esto permite de diminuir el nùmero de I/O necesarios al la conexiòn elèctrica y simplifica la realizaciòn del driver firmware de gestiòn.
5.Serial De Comunicaciòn
La comunicaciòn con el mundo exterior està en las manos de un serial por medio de señales de TX, RX y GND. Un sencillo transceiver RS232 està insertado entre la unidad central y el exterior.
6.Unidad Central De Elaboraciòn
El control del sistema està encargado a un microcontrolador a 16bit Renesas de la serie M16C/62P que gracias a su firmware puede controlar y gestionar en tiempo real el correcto funcionamiento de la CONSOLLE. La redecciòn del programa fue realizada en C y se compone de los principales bloques funcionales:
gestiòn teclado.
gestiòn display.
gestiòn serial.
Estas rutinas vienen ejecutadas en manera cìclica en el interno del main program y permiten a el usuario de disfrutar de todas las funcionalidades de la CONSOLLE. Claramente estàn tambièn driver software con un nivel màs bajo para la gestiòn fisica de las perifericas (por ejemplo adquisiciòn teclado o inizializaciòn display. como ejemplo se ilustra la rutina que adquire la configuraciòn del teclado.
Gestiòn teclado
br>
//Title: gest_teclado_100.c
//Author: najro.prestado
//Date: 12/03/07
//Current Rev: 100
//Mod.Descr.: Mòdulo para adquisiciòn teclas
//
// ptastihi y ptastilo congelan el estado del teclado a la primera adquisiciòn.
// mtastihi y mtastilo congelan el estado del teclado a la siguiente adquisiciòn.
// tastihi y tastilo vienen empleados de manera que cada mòdulo del programma pueda acceder
// en tiempo real al estado del teclado.
// NB: tecla apretada bit=0
// tecla no apretada bit=1
//
// Ejemplo 1:
// ninguna tecla apretada
// tastilo=11111111b tastihi=11111111b
//
// Ejemplo 2:
// tecla 4 apretado por un tiempo NO aceptable
// ptastilo=11111110b (*) ptastihi=11111111b
// despuès x mS tecla no activa
// mtastilo=11111111b mtastihi=11111111b
// mtastilo es diferente de ptastilo por lo tanto no actualizo tastilo y tastihi que mantiene
// el valor precedente o sea la configuraciòn para ninguna tecla apretada (Ejemplo 1)
//
// Ejemplo 3:
// tecla 4 apretado por un tiempo aceptable
// ptastilo=11111110b(*) ptastihi=11111111b
// despuès x mS tecla activa
// mtastilo=11111110b(*) mtastihi=11111111b
// mtastilo es igual a ptastilo por lo tanto actualiza tastilo y tastihi con la nueva configu-
// -raciòn o sea:
// tastilo=11111110b(*) tastihi=11111111b
//
// (*) para el programa el bit 0 de tastilo representa la tecla 4 pero està configurable como se desea
//1: Directivas
#incluye "sfr62.h"
#incluye "global.h"
#incluye "gest_wdt.h"
#incluye "gest_tastiera.h"
//2: Variables locales
union registro tastilo,tastihi;
unsigned char ptastilo,ptastihi;
unsigned char mtastilo,mtastihi;
unsigned char estadoteclado,tmrari;
//3: Prototipos funciones locales
void gest_teclado(void);
//4: Mòdulo Gestiòn Teclado
void gest_teclado(void)
{
//NB: Tecla no apretada = 1 lògico
//
//Define registro temporal
uchar wkreg;
switch (statotastiera)
{
//Adquisiciòn configuraciòn teclado para la primer vez y activaciòn antirebote
case 0:
wkreg=0xFF;
//Adquire teclas raya 1 (1-2-3-4)
TR1=0;
wkreg=p3;
ptastilo=wkreg>>4;
TR1=1;
//Adquire teclas raya 2 (5-6-7-8)
TR2=0;
wkreg=p3 & 0xF0;
ptastilo=ptastilo+wkreg;
TR2=1;
//Adquire teclas raya 3 (9-0-U-D)
TR3=0;
wkreg=p3;
ptastihi=wkreg>>4;
TR3=1;
//Adquire teclas rayas 4 (S-W/R- - )
TR4=0;
wkreg=p3 & 0xF0;
ptastihi=ptastihi+wkreg;
TR4=1;
//Precarga timer antirebote
tmrari=cTMRARI;
//Pasa a la gestiòn antirebote
estadoteclado=01;
break;
//Espera fin antirebote y verifica configuraciòn teclado con eventual asignaciòn
case 1:
//Espera conclusiòn antirebote
if (tmrari==00)
{
wkreg=0xFF;
//Readquire teclas raya 1 (1-2-3-4)
TR1=0;
wkreg=p3;
mtastilo=wkreg>>4;
TR1=1;
//Readquire teclas raya 2 (5-6-7-8)
TR2=0;
wkreg=p3 & 0xF0;
mtastilo=mtastilo+wkreg;
TR2=1;
//Readquire teclas raya 3 (9-0-U-D)
TR3=0;
wkreg=p3;
mtastihi=wkreg>>4;
TR3=1;
//Readquire teclas raya 4 (S-W/R- - )
TR4=0;
wkreg=p3 & 0xF0;
mtastihi=mtastihi+wkreg;
TR4=1;
//Verifica si configuraciòn vàlida y eventual traslado en tastilo
//e tastihi nuova configurazione
if ((mtastilo==ptastilo) || (mtastihi==ptastihi))
{
tastilo.byte=mtastilo;
tastihi.byte=mtastihi;
}
//Reinit acquisizione
estadoteclado=00;
}
break;
//
default:
//En el caso de valores no previstos en estadoteclado vuelve a empezar ciclo.
estadoteclado=00;
break;
}
//Actualiza el registro gestiòn WDT
checkwdt+=cWDTRO;
}
En pràctica se adquiren (empleando unos registros de apoyo) a intervales regolares las configuraciones del teclado y despuès se confrontan; en el caso que sean iguales los registros tastilo e tastihi ; de esta manera os escabullais de eventuales problemas de spike, activaciones ràpidas etc.
Mientras estas son las funciones para gestir un display 16x2 con controller S6A0069 de la Samsung
br>
br>
//Title: DrvS6A0069_100.c
//Author: najro.prestato
//Date: 12/03/07
//Current Rev: 100
//Mod.Descr.: Gestione display LCD con controller tipo Samsung S6A0069
// Il formato di LCD e'gestito da LCD_ROWS e LCD_COLS
// La modalita' e' gestita da LCD_BUS.
// I pin di Controllo dello lcd dichiarati dalle seg. costanti:
// LCD_RS pin per Register selector
// LCD_RW pin per Read/Write
// LCD_EN pin per Enable
// LCD_IO_RS tris per Register selector
// LCD_IO_RW tris per Read/Write
// LCD_IO_EN tris per Enable
// I pin per DATA vanno tutti su una stessa porta.
// 8 bit: D0-D7 connessi a Portx0 - Portx7
// 4 bit: D4-D7 connessi a Portx4 - Portx7
// Il punto Top,Left è impostato a 1,1
// L'impostazione delle connessione avviene mediante:
// LCD_PORT_DATA pin port per Data
// LCD_IO_DATA tris per Data
// Per moficare le caratteristiche per altri LCD:
// accedere e modificare lcd.h
//Note: Size Char pos DDRAM addresses
// 2*16 00..15 00h..0Fh + 40h..4Fh
// 2*20 00..19 00h..13h + 40h..53h
//
//
//Funzioni disponibili per pilotaggio LCD:
//
// lcdinit(void) Inizializza LCD
// checkbf(void) Attende la fine dell'ultima operazione
// lcdclear(void) Invia comando Clear & Home
// lcdputch(char) Scrive un carattere nella pos. del cursore
// lcdputs(char *) Scrive una stringa di caratteri
// lcdwrite(char, char) Scrive un byte unsigned nella DD RAM
// lcdcommand(char) Scrive un comando
// lcdgetch(char) Legge il carattere nella pos. cursore
// lcdread(char) Legge un byte unsigned dalla DD RAM
// lcdsetcurs(char, char) Imposta il cursore a riga, colonna
// lcdgetcurs (char, char) Ritorna la riga, colonna attuale del cursore
//
//1: Direttive
#include "sfr62.h"
#include "global.h"
#include "S6A0069.h"
//2: Variabili locali
//3: Prototipi funzioni locali
void delayms(uchar dly_ms); //Routine di ritardo in mS (NB: realizzata con loop)
void delayus10(uchar dly_us); //Routine di ritatdo da 10uS (NB: realizzata con loop)
void lcdinit(void); //Inizializza LCD - chiamare prima di ogni cosa
void checkbf(void); //Attende la fine dell'ultima operazione
void lcdputch(uchar car); //Scrive un carattere nella posizione attuale del cursore
void lcdputs(uchar far *str); //Scrive una stringa di caratteri
//(NB: Si usa far per indirizzare eventuali messaggi allocati in flash)
void lcdcommand(uchar lcd_cmd); //Scrive un comando
void lcdwrite(uchar value, uchar modo); //Scrive un byte unsigned nella DD RAM
uchar lcdgetch(void); //Legge il carattere nella posizione attuale del cursore
uchar lcdread(unsigned char modo); //Legge un byte unsigned dalla DD RAM
void lcdsetcurs(uchar row, uchar col); //Imposta il cursore a riga, colonna
void lcdgetcurs(uchar *row,uchar *col); //Ritorna riga e colonna attuale del cursore
//4: driver LCD
void s6a0069(void)
{
;
}
//5: Codice delle funzioni locali
//
//
//5a) Routine generazione ritardo con BT 1mS (max 255mS)-
void delayms(unsigned char dly_ms)
{
unsigned char wkreg,wkreg1,wkreg2;
for (wkreg = dly_ms; wkreg ; --wkreg)
{
//ciclo di ritardo da 1000 uS
for (wkreg1 = 100; wkreg1 ; --wkreg1)
{
delayus10(DLY10US);
}
}
}
//
//5b) Routine generazione ritardo con BT 10us-
void delayus10(unsigned char dly_us)
{
#pragma asm
loop1us: adjnz.b #-1,R1L,loop1us
#pragma endasm
}
//
//5c) Inizializzazione LCD con controller S6A0069 Samsung
void lcdinit(void)
{
LCD_RS = LCD_CMD; //Imposta modalitàComando
LCD_RW = LCD_WRITE; //Imposta modalitàWrite
LCD_EN = LCD_DISABLE; //Disabilita lcd
LCD_IO_RS = 1; //Imposta pin come output
LCD_IO_RW = 1; //Imposta pin come output
LCD_IO_EN = 1; //Imposta pin come output
LCD_PORT_DATA = 0x00; //Imposta DB7-DB0 = 00000000
LCD_IO_DATA |= LCD_IO_DMASK; //Imposta data bus come output
//Sequenza inizializzazione per S6A0069 Samsung
//
//1-Attesa per stabilizzazione Vcc: minimo 40mS
delayms(60);
//2-Function set: Bus a 8 bit, 2 linee, font 5x8
LCD_PORT_DATA = (LCD_BUS_8BIT | LCD_LINE_MULTI | LCD_FONT_5x8);
//Strobe E
LCD_STROBE;
delayms(1);
//3-Display on
lcdcommand(LCD_DISPLAY_ON | LCD_CURSOR_OFF |LCD_BLINK_OFF);
delayms(1);
//4-Display clear
lcdcommand(LCD_CLEAR);
delayms(3);
//5-Default Entry Mode: Autoincrement right, Display shift off
lcdcommand(LCD_CURSOR_INC);
}
//
//5d) Verifica busy flag LCD
void checkbf(void)
{
unsigned char busy;
LCD_RS = LCD_CMD; // Imposta modalita' commando
LCD_RW = LCD_READ; // Imposta modalita' lettura
LCD_IO_DATA &= ~LCD_IO_DMASK; // Imposta porta come input
LCD_EN = LCD_ENABLE; // Attiva Lcd
do{
busy = LCD_PORT_DATA & LCD_BIT_BUSY; // DB7 = BF
}while (busy);
LCD_EN = LCD_DISABLE; // Disattiva lcd
LCD_RW = LCD_WRITE; // Imposta modalita' scrittura
LCD_IO_DATA |= LCD_IO_DMASK; // Imposta porta come output
}
//
//5e) Invia un commando a LCD
void lcdcommand(uchar lcd_cmd)
{
//Verifica busy flag display (nb: verifica effettuata con lettura BF in loop)
checkbf();
//Imposta modalita' comando su display
LCD_RS = LCD_CMD;
//Trasferisci a display (check prima se bus a 4 od 8 bit)
#if (LCD_BUS == 8 )
LCD_PORT_DATA = lcd_cmd;
#else
//Trasferisci high byte
LCD_PORT_DATA = (LCD_PORT_DATA & ~LCD_IO_DMASK) | (lcd_cmd & LCD_IO_DMASK);
LCD_STROBE;
//Trasferisci low byte
LCD_PORT_DATA = (LCD_PORT_DATA & ~LCD_IO_DMASK) | (lcd_cmd << 4);
#endif
LCD_STROBE;
}
//
//5f) Scrive un carattere sull'LCD
void lcdputch(uchar car)
{
//Verifica busy flag display (nb: verifica effettuata con lettura BF in loop)
checkbf();
//Imposta modalita' dati su display
LCD_RS = LCD_DATA;
//Trasferisci a display (check prima se bus a 4 od 8 bit)
#if (LCD_BUS == 8 )
LCD_PORT_DATA = car;
#else
//Trasferisci high byte
LCD_PORT_DATA = (LCD_PORT_DATA & ~LCD_IO_DMASK) | (car & LCD_IO_DMASK);
LCD_STROBE;
//Trasferisci low byte
LCD_PORT_DATA = (LCD_PORT_DATA & ~LCD_IO_DMASK) | (car << 4);
#endif
LCD_STROBE;
}
//
//5g) Scrive una stringa di caratteri sull'LCD
void lcdputs(uchar far *str)
{
while(*str)
lcdputch(*str++);
}
//
//5h) Scrive un 8 bit unsigned nella DDRAM
void lcdwrite(uchar value, uchar modo)
{
//Verifica busy flag display (nb: verifica effettuata con lettura BF in loop)
checkbf();
//Imposta modalita' display (CMD se modo=0 o DATA se modo=1)
if (modo==0)
LCD_RS = LCD_CMD;
else
LCD_RS = LCD_DATA;
//Trasferisci a display (check prima se bus a 4 od 8 bit)
#if (LCD_BUS == 8 )
LCD_PORT_DATA = value;
#else
//Trasferisci high byte
LCD_PORT_DATA = (LCD_PORT_DATA & ~LCD_IO_DMASK) | (value & LCD_IO_DMASK);
LCD_STROBE;
//Trasferisci low byte
LCD_PORT_DATA = (LCD_PORT_DATA & ~LCD_IO_DMASK) | (value << 4);
#endif
LCD_STROBE;
}
//
//5i) Legge il carattere nella posizione attuale del cursore
uchar lcdgetch (void)
{
return lcdread(LCD_DATA);
}
//
//5j) Legge un byte unsigned dalla DD RAM
uchar lcdread (uchar modo)
{
unsigned char byteDDRAM;
unsigned char highbits;
//Imposta DB7/DB0 come input
LCD_IO_DATA &= ~LCD_IO_DMASK;
//Imposta modalita' display (CMD se modo=0 o DATA se modo=1)
LCD_RS = (modo) ? LCD_DATA : LCD_CMD;
//Imposta su display operazione di Read
LCD_RW = LCD_READ;
delayus10(DLY10US);
//Abilita display
LCD_EN = LCD_ENABLE;
delayus10(DLY10US);
//Leggi da display (check prima se bus a 4 od 8 bit)
#if (LCD_BUS == 4 )
//Legge high byte
highbits = LCD_PORT_DATA & LCD_IO_DMASK;
LCD_EN = LCD_DISABLE;
delay_us(1);
LCD_EN = LCD_ENABLE;
//Legge low byte
byteDDRAM = ((LCD_PORT_DATA & LCD_IO_DMASK) >> 4);
byteDDRAM |= highbits;
#else
byteDDRAM = LCD_PORT_DATA;
#endif
LCD_EN = LCD_DISABLE;
LCD_RS = LCD_CMD;
LCD_IO_DATA &= ~LCD_IO_DMASK; //Imposta linee porta come output
return (byteDDRAM); //Ritorna il carattere letto
}
//
//5k) Imposta il cursore a riga e colonna indicati; l'indice inizia da 1
void lcdsetcurs(uchar row, uchar col)
{
unsigned char pos;
//Controlla correttezza valori di riga e colonna
if (row == 0)
row = 1;
if (col == 0)
col = 1;
if (row > LCD_ROWS)
row = LCD_ROWS;
if (col > LCD_COLS)
col = LCD_COLS;
//Imposta indirizzo base
switch (row)
{
case 1:
pos = LCD_ADDRESS_ROW1;
break;
case 2:
pos = LCD_ADDRESS_ROW2;
break;
case 3:
pos = LCD_ADDRESS_ROW3;
break;
case 4:
pos = LCD_ADDRESS_ROW4;
break;
}
lcdcommand(LCD_SET_ADDRESS | (pos+col-1));
}
//
//5l) Ritorna la posizione riga,colonna attuale del cursore
void lcdgetcurs (uchar *row, uchar *col)
{
unsigned char curAdd;
unsigned char pos;
//Legge indirizzo cursore
curAdd = lcdread(LCD_CMD);
//Mask per determinare indirizzo row questo può essere 00h, 10h, 40h, 50h
pos = (curAdd & 0x50);
switch(pos)
{
case LCD_ADDRESS_ROW1:
*row = 1;
*col = curAdd - LCD_ADDRESS_ROW1 + 1;
break;
case LCD_ADDRESS_ROW2:
*row = 2;
*col = curAdd - LCD_ADDRESS_ROW2 + 1;
break;
case LCD_ADDRESS_ROW3:
*row = 3;
*col = curAdd - LCD_ADDRESS_ROW3 + 1;
break;
case LCD_ADDRESS_ROW4:
*row = 4;
*col = curAdd - LCD_ADDRESS_ROW4 + 1;
break;
}
}
//Title: gest_seriale_100.c
//Author: najro.prestato
//Date: 12/03/07
//Current Rev: 100
//Mod.Descr.: Modulo gestione RS232:
// Protocollo di comunicazione -> STX CMD DATI ETX
// Comandi Gestiti -> MI: Visualiiza sul display stringa ASCII contenuta in DATI
// -> MA: invia sulla seriale una stringa ASCII contenuta in DATI
//
//1: Direttive per compilatore
#include "sfr62.h"
#include "global.h"
#include "gest_lcd.h"
#include "messaggi_I.h"
#include "gest_seriale.h"
//2: Variabili locali
union registro flagrx0;
union registro flagtx0;
unsigned char bufrx0[cBUFRX0];
unsigned char buftx0[cBUFTX0];
unsigned char pibufrx0,pubufrx0;
unsigned char bufpk0[cBUFPK0];
unsigned char lenpkrx0;
unsigned char statopkrx0;
unsigned char bytetx0,bytetxed0,tmrcmdmatx0;
unsigned char r0uart,r1uart,r2uart;
//3: Prototipi funzioni locali
void gest_seriale(void);
void check_bufrx0(void);
void ela_bufpk0(void);
void pktx0(void);
//4: Modulo Gestione Seriale
void gest_seriale(void)
{
//Verifica se arrivato un nuovo pacchetto dati su bufrx0
check_bufrx0();
//Elabora eventuale pacchetto estrapolato da buffer rx0(bufpk0)
ela_bufpk0();
//Invia dati/risposta tramite buftx0
pktx0();
}
//5: Codice funzioni locali
//
//5a)Funzione estrapolazione pacchetto da buffer RX0
void check_bufrx0(void)
{
unsigned char datorx;
//Verifica se ci sono dati da elaborare
while (pibufrx0 ^ pubufrx0)
{
//acquisisci dato da seriale
datorx=bufrx0[pubufrx0];
pubufrx0++;
//verifica se l'indice è da resettare (buffer circolare)
if (pubufrx0 > cBUFRX0-1)
pubufrx0 = 0;
//analizza dato acquisito
switch (datorx)
{
//ricerca cLF senza avere cSTX
//NB: Questa situazione si ha quando attendo l'echo di un comando
// da parte di un sistema remoto es: MA
case cLF:
//Se non ho ricevuto STX
if (!flagrx0.bit.FSTX)
{
if (lenpkrx0 > 2)
{
if ( (bufpk0[lenpkrx0-1]==cCR)
&& (bufpk0[lenpkrx0-2]>0x19)
&& (bufpk0[lenpkrx0-3]>0x19))
{
bufpk0[0]=bufpk0[lenpkrx0-3]; //
bufpk0[1]=bufpk0[lenpkrx0-2]; //
flagrx0.bit.FPKRX=1;//trovato identificato di fine pacchetto rx
lenpkrx0=0; //azzera contatore dati pacchetto
}
}
}
//Se si è un carattere non valido e da
//specifica si deve ricominciare il ciclo
else
{
lenpkrx0=0;
flagrx0.bit.FSTX=0;
}
break;
//ricerca inizio pacchetto
case cSTX:
flagrx0.bit.FSTX=1; //trovato identificato inizio pacchetto rx
lenpkrx0=0; //azzera contatore dati pacchetto
break;
//ricerca fine pacchetto
case cETX:
//se non ricevuto flag inizio pacchetto scarta questo ETX
if (flagrx0.bit.FSTX)
{
//verifica che siano stati trovati almeno 'cNUMRXVAL' dati tra STX ed ETX
if (lenpkrx0 < cNUMRXVAL)
{
flagrx0.bit.FSTX=0;//dichiara non trovato identificato inizio pacchetto rx
lenpkrx0=0; //azzera contatore dati pacchetto
}
else
{
flagrx0.bit.FPKRX=1; //trovato identificato di fine pacchetto rx
flagrx0.bit.FSTX=0; //reset flag identificato inizio pacchetto rx
}
}
break;
//Acquisizione dati
default:
//Se non ricevuto flag inizio pacchetto scarta questo ETX
if (flagrx0.bit.FSTX)
{
//Verifica se ricevuto un carattere non valido (<20h)
if (datorx > 0x19)
{
//memorizza pacchetto in buffer dedicato
bufpk0[lenpkrx0]=datorx;
lenpkrx0++;
if (lenpkrx0 > cBUFPK0-1)
lenpkrx0 = 0;
}
//Se no scarta tutto
else
{
lenpkrx0=0;
flagrx0.bit.FSTX=0;
}
}
else
{
//Memorizza dati che potrebbero essere di una eventuale
//risposta da parte del sistema remoto (vedi case cLF:)
bufpk0[lenpkrx0]=datorx;
lenpkrx0++;
}
break;
}
}
}
//
//5b)Funzione elaborazione pacchetto buffer RX0 (bufpk0)
void ela_bufpk0(void)
{
unsigned char wki,wkj;
switch(statopkrx0)
{
//Riconoscimento Comandi
case 0:
if (flagrx0.bit.FPKRX==1)
{
//Verifica per comandi Mx
if (bufpk0[0]=='M') //riconosciuto comando 'M'
statopkrx0=1;
//Reinit se nessun guruppo di comandi valido viene identificato
else
{
flagrx0.bit.FPKRX=0; //riabilita RX su RS232
statopkrx0=00; //torna a stato 0
}
}
break;
//Comandi Mx
case 1:
//Verifica per sottocomando MI
if (bufpk0[1]=='I')
{
statopkrx0=10;
break;
}
//Verifica per echo comando MA
else if (bufpk0[1]=='A')
{
statopkrx0=11;
break;
}
//Reinit se nessun sottocomando Mx valido identificato
else
{
flagrx0.bit.FPKRX=0; //riabilita RX su RS232
statopkrx0=00; //torna a stato 0
}
break;
//Elabora comando MI
case 10:
//Reinit indici buffer lcd rx se nuovo messaggio da acquisire
rowlcdrx=0;
cullcdrx=0;
prowlcdrx=00;
irowlcdrx=00;
//Pulisci buffer visualizzazione display
clearbuflcdrx();
//Abilita accensione retroilluminazione dislpay
tmronlcd=cTMRONLCD;
//Prepara buffer lcd rx. NB: sottraggo 2 a lenpkrx0 per tenere conto di 'MI'
for (wki=2; wki < (lenpkrx0); wki++)
{
//Carica dati nel buffer del LCD gia organizzati per riga/colonna
if ((bufpk0[wki] != '[') && (bufpk0[wki] != ']'))
{
//NB: Uso wki+2 per scartare 'MI' iniziale
buflcdrx[rowlcdrx][cullcdrx]= bufpk0[wki];
cullcdrx++;
if (cullcdrx >= cCULLCDRX)
{
cullcdrx=0;
rowlcdrx++;
if (rowlcdrx > cROWLCDRX)
rowlcdrx=0;
}
}
else
{
//Gestione stringa esadecimale
//Se [0D]:
if ( (bufpk0[wki] == '[')
&& (bufpk0[wki+1]=='0')
&& ((bufpk0[wki+2]=='D') || (bufpk0[wki+2]=='d'))
&& (bufpk0[wki+3]==']') )
{
unsigned char wkj;
if (cullcdrx < (cCULLCDRX-1))
{
for (wkj=cullcdrx; wkj < cCULLCDRX; wkj++)
buflcdrx[rowlcdrx][wkj] = ' ';
cullcdrx=0;
rowlcdrx++;
if (rowlcdrx > cROWLCDRX)
rowlcdrx=0;
}
wki+=2;
}
//Se [xx]:
else
{
if ( (bufpk0[wki] == '[') && (bufpk0[wki+3]==']') )
{
buflcdrx[rowlcdrx][cullcdrx] = ' ';
cullcdrx++;
if (cullcdrx > cCULLCDRX)
{
cullcdrx=0;
rowlcdrx++;
if (rowlcdrx > cROWLCDRX)
rowlcdrx=0;
}
wki+=2;
}
}
}
}
flaglcd.bit.FBLRX=1; //Dichiara messaggio per LCD disponibile
flagrx0.bit.FPKRX=0; //Libera seriale RX0
statopkrx0=00; //Attendi nuovo pacchetto
break;
//Ricezione echo comando MA
case 11:
flagrx0.bit.FPKRX=0; //Libera seriale RX0
statopkrx0=00; //Attendi nuovo pacchetto
flaglcd.bit.FBLTX=1; //Dichiara echo comando ricevuto
break;
//Nessun comando valido/riconosciuto
default:
flagrx0.bit.FPKRX=0; //riabilita RX0
statopkrx0=00; //torna a stato 0
break;
}
}
//
//5c)Funzione invio dati su buftx0
void pktx0(void)
{
//Verifica se pacchetto pronto && UART disponibile
if ((flagtx0.bit.FTXAT==1) && (ti_u0c1==1))
{
if (flagtx0.bit.FTXST==0)
{
flagtx0.bit.FTXST=1; //Dichiara STX inviato
u0tbl=cSTX; //Trasmettere STX (inizio pacchetto)
bytetxed0=00; //Azzera counter dati trasmessi su uart
}
else
{
if (flagtx0.bit.FTXDA==0)
{
u0tbl=buftx0[bytetxed0];
bytetxed0++;
if (bytetxed0==bytetx0)
{
flagtx0.bit.FTXDA=1; //dichiara tx dati
}
}
else
{
if (flagtx0.bit.FTXET==0)
{
flagtx0.bit.FTXET=1; //dichiara ETX inviato
u0tbl=cETX; //trasmettere ETX (fine pacchetto)
}
else
{
flagtx0.bit.FTXAT=0; //dichiara pacchetto non disponibile
}
}
}
}
}
Esto en cambio es el esquema elèctrico.
br>
br>

Lista componentes
Item Qty Reference Part ________________________________________________________ 1 8 C1,C4,C5,C6,C8, 1uF C9,C10,C13 2 3 C2,C3,C7 0,1uF 3 2 C11,C12 22pF 4 6 D1,D3,D4,D5,D6,D7 BYD17D 5 1 D2 LGR971 6 1 J1 CON8 7 1 J2 DISPLAY 16x2 8 1 J3 MOLEX 53261-1290 9 1 J4 MOLEX MICRO-FIT 10 1 Q1 BCX 54-16 11 1 Q2 MMBT2222 12 1 R1 2K2 13 4 R2,R3,R19,R21 4K7 14 4 R4,R5,R6,R7 100K 15 5 R8,R12,R13,R14,R15 1K 16 6 R9,R11,R16,R18,R20,R25 47K 17 2 R10,R24 10 18 1 R17 0 19 2 R22,R23 10K 20 1 U1 M30624FGPFP 21 1 U2 ST232BD 22 1 U3 DS1818 23 1 U4 24LC16 24 1 Y1 4 MHz
Descarga la Documentaciòn completa en PDF --->> DOWNLOAD
- Inicie sesión o regístrese para enviar comentarios
- %count lecturas

