home | area personale         schemi | tutorial | robotica | pic micro | recensioni         forum | chat irc         faq | contatti         store | Ordina PCB
username
password
cerca

 
FORUM: Pic Micro
Tutto quanto riguarda questi microprocessori... progetti, suggerimenti, aiuti, discussioni...ecc


trasmissione seriale UART
     
Autore Messaggio opzioni
Atex





postato il:
15.01.2022, alle ore 14:10
trasmissione seriale UART 

Buongiorno a tutti, premetto che non sono esperto di programmazione dei PIC e infatti ho un problema su cui mi sto rompendo la testa senza arrivare a nulla. In pratica riesco bene a inviare un solo carattere al PIC tramite il terminale mikroC Pro, e lo vedo perchè invio il carattere al display LCD collegato al PIC. Di seguito ho messo il codice completo che ho scritto per inviare 5 caratteri al display, che però non funziona (sul display non arriva niente).
Se qualcuno può aiutarmi a capire dove sbaglio:

#define primo 0
#define num_caratteri 5

sbit LCD_RS at RD2_bit; // connessione LCD_PIC
sbit LCD_EN at RD3_bit; // connessione LCD_PIC
sbit LCD_D4 at RD4_bit; // connessione LCD_PIC
sbit LCD_D5 at RD5_bit; // connessione LCD_PIC
sbit LCD_D6 at RD6_bit; // connessione LCD_PIC
sbit LCD_D7 at RD7_bit; // connessione LCD_PIC

sbit LCD_RS_Direction at TRISD2_bit; // configurazione dei pin
sbit LCD_EN_Direction at TRISD3_bit; // configurazione dei pin
sbit LCD_D4_Direction at TRISD4_bit; // configurazione dei pin
sbit LCD_D5_Direction at TRISD5_bit; // configurazione dei pin
sbit LCD_D6_Direction at TRISD6_bit; // configurazione dei pin
sbit LCD_D7_Direction at TRISD7_bit; // configurazione dei pin

char buf[5], my_buf[5], i;

void main() {
Lcd_Init(); // inizializzazione LCD
Lcd_Cmd(_LCD_CLEAR); // pulizia schermo
Lcd_Cmd(_LCD_CURSOR_OFF); // cursore invisibile
TRISC = 0xBF; // pin RC6 = 0 TX, pin RC7 = 1 RX, gli altri pin = 1 per sicurezza
TRISD = 0x00; // PORTD output, RD0 e RD1 collegati a massa
UART1_Init(9600); // inizializzazione comunicazione seriale asincrona a 9600 bit /sec
Delay_ms(100);

i = 0;
while(1) {
if(UART1_Data_Ready()) {
buf[i] = UART1_Read();
i++;
}
}
memcpy(my_buf, buf + primo, num_caratteri);
my_buf[num_caratteri] = '\0';
Lcd_Out(1, 3, my_buf);
}

double_wrap




una ogni 100 livelli
una ogni 10 livelli una ogni 10 livelli una ogni 10 livelli una ogni 10 livelli una ogni 10 livelli una ogni 10 livelli una ogni 10 livelli


postato il:
15.01.2022, alle ore 14:29
forse sbaglio io, ma sembra che dal ciclo WHILE(1) non si esca mai e che non si raggiunga mai l'istruzione LcD_Out

while(1) {
 if(UART1_Data_Ready()) {
    buf[i] = UART1_Read();
    i++;
    }
 }







"se peso cado, ma se cado non peso"
adamatj.altervista.org
Atex





postato il:
15.01.2022, alle ore 14:53
si è vero, quindi dovrebbe essere così, è corretto ?

while(1) {
if(UART1_Data_Ready()) {
buf[i] = UART1_Read();
i++;
}
memcpy(my_buf, buf + primo, num_caratteri);
my_buf[num_caratteri] = '';
Lcd_Out(1, 3, my_buf);
}
}
Atex





postato il:
15.01.2022, alle ore 15:17
o meglio

while(1) {
if(UART1_Data_Ready()) {
buf[i] = UART1_Read();
i++;
}
memcpy(my_buf, buf[i] + primo, num_caratteri);
my_buf[num_caratteri] = ';
Lcd_Out(1, 3+i, my_buf);
}
}
Atex





postato il:
15.01.2022, alle ore 16:22
Ciao double_wrap, ho fatto girare il codice come mi hai suggerito, e funziona.

Però vorrei spiegare meglio il mio scopo:
vorrei salvare 5 caratteri (numeri XXXXX) inviati dal terminale al PIC per poter utilizzare il numero decimale XXX.XX in seguito.
Allo scopo ho pensato di scrivere questo codice (in cui switch(i) mi calcola la parte intera n e la parte decimale m a partire da my_buf). Ma purtroppo sul display leggo 3. 255.

Qualcuno :

#define primo 0
#define num_caratteri 5
sbit LCD_RS at RD2_bit; // connessione LCD_PIC
sbit LCD_EN at RD3_bit; // connessione LCD_PIC
sbit LCD_D4 at RD4_bit; // connessione LCD_PIC
sbit LCD_D5 at RD5_bit; // connessione LCD_PIC
sbit LCD_D6 at RD6_bit; // connessione LCD_PIC
sbit LCD_D7 at RD7_bit; // connessione LCD_PIC

sbit LCD_RS_Direction at TRISD2_bit; // configurazione dei pin
sbit LCD_EN_Direction at TRISD3_bit; // configurazione dei pin
sbit LCD_D4_Direction at TRISD4_bit; // configurazione dei pin
sbit LCD_D5_Direction at TRISD5_bit; // configurazione dei pin
sbit LCD_D6_Direction at TRISD6_bit; // configurazione dei pin
sbit LCD_D7_Direction at TRISD7_bit; // configurazione dei pin

char buf[5], my_buf[5], i, Txt1[3], Txt2[2];
unsigned int n, m;

void main() {
Lcd_Init(); // inizializzazione LCD
Lcd_Cmd(_LCD_CLEAR); // pulizia schermo
Lcd_Cmd(_LCD_CURSOR_OFF); // cursore invisibile
TRISC = 0xBF; // pin RC6 = 0 TX, pin RC7 = 1 RX, gli altri pin = 1 per sicurezza
TRISD = 0x00; // PORTD output, RD0 e RD1 collegati a massa
UART1_Init(9600); // inizializzazione comunicazione seriale asincrona a 9600 bit /sec
Delay_ms(100);

i = 0;
while(i < 6) {
if(UART1_Data_Ready()) {
buf[i] = UART1_Read();
i++;
}
memcpy(my_buf, buf + primo, num_caratteri);
my_buf[num_caratteri] = '';
}
switch(i) {
case 1: n = 100*my_buf[1]; break;
case 2: n = 100*my_buf[1] + 10*my_buf[2]; break;
case 3: n = 100*my_buf[1] + 10*my_buf[2] + my_buf[3]; break;
case 4:
n = 100*my_buf[1] + 10*my_buf[2] + my_buf[3];
m = 10*my_buf[4];
break;
case 5:
n = 100*my_buf[1] + 10*my_buf[2] + my_buf[3];
m = 10*my_buf[4] + my_buf[5];
break;
}
IntToStr(n,Txt1);
Lcd_Out(1,3,Txt1);
Lcd_Chr(1,6,'.');
IntToStr(m,Txt2);
Lcd_Out(1,7,Txt2);
}
double_wrap




una ogni 100 livelli
una ogni 10 livelli una ogni 10 livelli una ogni 10 livelli una ogni 10 livelli una ogni 10 livelli una ogni 10 livelli una ogni 10 livelli


postato il:
15.01.2022, alle ore 18:51
Atex:
[CUT]Ma purtroppo sul display leggo 3. 255. [CUT]

Tu che caratteri hai inviato sulla seriale?
In <3. 255> che leggi sul display c'e' uno <spazio> fra <3.> e <255>?

Fra l'altro <buf> e' di tipo <char> mentre <n> ed <m> sembrano di tipo <int> visto che le moltiplichi x100, non e' che quando arriva il carattere <1> il codice lo vede come un >49> (valore ascci)? Ci pensa la <UART1_Read()> a fare la conversione da ascii a decimale? (magari dico una fesseria!)

Non conoscendo il tuo compilatore intuisco che <Lcd_out(1,7,Tx2)> scriva sulla prima riga a partire dalla posizione 7 e che <Lcd_Chr(1,6,'.')> scriva un puntino sulla riga 1 alla posizione 6. quindi se arriva NNNMM dovrebbe scrivere

0123456789
NNN.MM

e invece cosa scrive?

0123456789
??????????

E perchè una volta si usa <Lcd_Out> ed un'altra si usa <Lcd_Chr>?
Magari e' banale, ma non conosco il tuo compilatore e non so neppure i metodi della libreria Lcd.
Potresti dire che compilatore, micro e programmatore usi, ho come una premonizione...?



"se peso cado, ma se cado non peso"
adamatj.altervista.org
double_wrap




una ogni 100 livelli
una ogni 10 livelli una ogni 10 livelli una ogni 10 livelli una ogni 10 livelli una ogni 10 livelli una ogni 10 livelli una ogni 10 livelli


postato il:
15.01.2022, alle ore 18:53

0123456789
___NNN.MM



"se peso cado, ma se cado non peso"
adamatj.altervista.org
Atex





postato il:
15.01.2022, alle ore 19:53
Il compilatore è MikroC PRO.
Lcd_Chr si usa per spedire direttamente un carattere al display, mentre Lcd_Out manda una stringa.

Il mio problema è quello di trasformare una stringa numerica in un intero che poi posso utilizzare per fare dei calcoli.

La stringa numerica adesso arriva correttamente sul display, però la sua funzione my_buf non posso utilizzarla come intero
Atex





postato il:
16.01.2022, alle ore 00:40
Ciao Double_wrap, finalmente ho risolto con la funzione atoi:
n = atoi(my_buf);

poi ho sommato 1 a n e il risultato è stato confermato sul display.

segui questo thread con grixFC, per questa funzione devi aver installato il software grixFC

torna su
     

Come utente anonimo puoi leggere il contenuto di questo forum ma per aprire una discussione
o per partecipare ad una discussione esistente devi essere registrato ed accedere al sito




 







 
 
indietro | homepage | torna su copyright © 2004/2024 GRIX.IT - La community dell'elettronica Amatoriale