- Messaggi: 91
- Ringraziamenti ricevuti 16
Libreria per emulare USART via software
8 Anni 10 Mesi fa #6
da permax1958
Risposta da permax1958 al topic Libreria per emulare USART via software
x lorix
su quale pic lavori?
io sto provando sul 16F1847 usando l'interrupt on change sul piedino RB0,con un clock di 32MHz e un bitrate di 19200 sono riuscito a farlo funzionare, altri Pic gestiscono l'interrupt in modo diverso,comunque ad ogni interrupt si riceve un solo carattere a meno che si abbia un clock molto basso e un bitrate alto allora la ricezione di un carattere alla volta diventa difficoltosa e conviene riceverli tutti in una volta con i suoi pro e oi suoi contro quindi bisogna gestire il tutto secondo le proprie esigenze in quel momento, in pratica bisogna sapere cosa arriva sulla seriale per poterlo gestire cioè se arrivano delle stringhe di uguale dimensione si gestisce in un modo se invece arrivano stringhe di dimensione variabile si gestisce in un altro modo ad esempio intercettando un carattere di fine stringa (\n \r \0).
Io ricevo stringhe di dimensione variabile ma col carattere finale '\n' quindi lascio ricevere tutti i caratteri via interrupt e quando ricevo '\n' allora passo alla gestione della stringa.
tu che esigenze hai?
così prima di postare il codice vedo di adattarlo.
saluti
su quale pic lavori?
io sto provando sul 16F1847 usando l'interrupt on change sul piedino RB0,con un clock di 32MHz e un bitrate di 19200 sono riuscito a farlo funzionare, altri Pic gestiscono l'interrupt in modo diverso,comunque ad ogni interrupt si riceve un solo carattere a meno che si abbia un clock molto basso e un bitrate alto allora la ricezione di un carattere alla volta diventa difficoltosa e conviene riceverli tutti in una volta con i suoi pro e oi suoi contro quindi bisogna gestire il tutto secondo le proprie esigenze in quel momento, in pratica bisogna sapere cosa arriva sulla seriale per poterlo gestire cioè se arrivano delle stringhe di uguale dimensione si gestisce in un modo se invece arrivano stringhe di dimensione variabile si gestisce in un altro modo ad esempio intercettando un carattere di fine stringa (\n \r \0).
Io ricevo stringhe di dimensione variabile ma col carattere finale '\n' quindi lascio ricevere tutti i caratteri via interrupt e quando ricevo '\n' allora passo alla gestione della stringa.
tu che esigenze hai?
così prima di postare il codice vedo di adattarlo.
saluti
Si prega Accedi o Crea un account a partecipare alla conversazione.
- permax1958
- Autore della discussione
- Premium Member
Riduci
Di più
8 Anni 10 Mesi fa #7
da lorix
Risposta da lorix al topic Libreria per emulare USART via software
stavo lavorando su un 12F1840, in rx pensavo che una volta che entro in interrupt, metto un time out attesa byte successivo
e poi salvo l'intero pacchetto indipendente dalla lunghezza, lo sto usando in mikroc con uart hard e funziona bene
per cui pensavo di adattare questo blocco
void interrupt () {
char i = 0;
unsigned timeOut = 0;
if (PIR1.RCIF == 1) {
Rx_cnt = 0;
while (timeOut < 1000){ // min 140 9600bps 16Mhz
if (UART1_Data_Ready() == 1) {
Rx_buff = UART1_Read();
i++;
Rx_cnt++; // conta byte ricevuti
timeOut = 0; // reset timeout
}
timeOut++;
}
if (Rx_buff[0] == ids) { // confronta id
rx_f = 1;
}
}
e poi salvo l'intero pacchetto indipendente dalla lunghezza, lo sto usando in mikroc con uart hard e funziona bene
per cui pensavo di adattare questo blocco
void interrupt () {
char i = 0;
unsigned timeOut = 0;
if (PIR1.RCIF == 1) {
Rx_cnt = 0;
while (timeOut < 1000){ // min 140 9600bps 16Mhz
if (UART1_Data_Ready() == 1) {
Rx_buff = UART1_Read();
i++;
Rx_cnt++; // conta byte ricevuti
timeOut = 0; // reset timeout
}
timeOut++;
}
if (Rx_buff[0] == ids) { // confronta id
rx_f = 1;
}
}
Si prega Accedi o Crea un account a partecipare alla conversazione.
- lorix
- New Member
Riduci
Di più
- Messaggi: 8
- Ringraziamenti ricevuti 0
8 Anni 10 Mesi fa #8
da permax1958
Risposta da permax1958 al topic Libreria per emulare USART via software
tu stai usando il modulo seriale che è all'interno del Pic, io invece sto cercando di usare una seconda porta seriale (emulata), perchè il modulo seriale del Pic lo sto usando per un'altra comunicazione, ed entrambe le comunicazioni seriali le gestisco via interrupt usando XC8:
void interrupt INTERRUPT_InterruptManager(void) {
unsigned char i = 8; // 8 data bits to receive
//********** quella del modulo interno la ho risolta così: *********
//******************************************************************
//Check which interrupt flag caused the interrupt is it USART?
if (PIR1bits.RCIF == 1 ) {
//Service the interrupt reciving byte
while (PIR1bits.RCIF) {
if (1 == RCSTAbits.OERR) {
// EUSART error - restart
RCSTAbits.CREN = 0;
RCSTAbits.CREN = 1;
}
data = RCREG;
buffer[chars] = data;
chars++;
}
}
//********** quella emulata la ho risolta così: *******************
//******************************************************************
// interrupt handler
// Check which interrupt flag caused the interrupt is it PORTB RB0 on Negative edge?
if (IOCBN0 == 1) {
TMR0 = (BAUD_CENTER); // load TMR0 value for ~1.5 baud
while(TMR0 > 0); // wait for baud
while(i) // receive 8 serial bits, LSB first
{
RxChr = (RxChr >> 1); // rotate right to store each bit
RxChr = RxChr | RxPin << 7; // save data bit
i--;
TMR0 -= SER_BAUD; // load corrected baud value
while(TMR0 > 0); // wait for baud
}
// store a valid char in buffer
rx_buffer[numChr] = RxChr;
numChr ++;
// clear interrupt-on-change flag
IOCBF0 = 0;
// clear global interrupt-on-change flag
INTCONbits.IOCIF = 0;
}
}
entrambe le routine ricevono un byte per volta, nelle variabili RxChr e data trovo l'ultimo byte ricevuto e nelle variabili numChr e chars trovo il numero di byte ricevuti così nel loop principale del main posso gestire qualsiasi messaggio.
void interrupt INTERRUPT_InterruptManager(void) {
unsigned char i = 8; // 8 data bits to receive
//********** quella del modulo interno la ho risolta così: *********
//******************************************************************
//Check which interrupt flag caused the interrupt is it USART?
if (PIR1bits.RCIF == 1 ) {
//Service the interrupt reciving byte
while (PIR1bits.RCIF) {
if (1 == RCSTAbits.OERR) {
// EUSART error - restart
RCSTAbits.CREN = 0;
RCSTAbits.CREN = 1;
}
data = RCREG;
buffer[chars] = data;
chars++;
}
}
//********** quella emulata la ho risolta così: *******************
//******************************************************************
// interrupt handler
// Check which interrupt flag caused the interrupt is it PORTB RB0 on Negative edge?
if (IOCBN0 == 1) {
TMR0 = (BAUD_CENTER); // load TMR0 value for ~1.5 baud
while(TMR0 > 0); // wait for baud
while(i) // receive 8 serial bits, LSB first
{
RxChr = (RxChr >> 1); // rotate right to store each bit
RxChr = RxChr | RxPin << 7; // save data bit
i--;
TMR0 -= SER_BAUD; // load corrected baud value
while(TMR0 > 0); // wait for baud
}
// store a valid char in buffer
rx_buffer[numChr] = RxChr;
numChr ++;
// clear interrupt-on-change flag
IOCBF0 = 0;
// clear global interrupt-on-change flag
INTCONbits.IOCIF = 0;
}
}
entrambe le routine ricevono un byte per volta, nelle variabili RxChr e data trovo l'ultimo byte ricevuto e nelle variabili numChr e chars trovo il numero di byte ricevuti così nel loop principale del main posso gestire qualsiasi messaggio.
Si prega Accedi o Crea un account a partecipare alla conversazione.
- permax1958
- Autore della discussione
- Premium Member
Riduci
Di più
- Messaggi: 91
- Ringraziamenti ricevuti 16
8 Anni 10 Mesi fa #9
da lorix
Risposta da lorix al topic Libreria per emulare USART via software
OK grazie
appena ho un attimo provo implementarla
uso il 12F840, ma devo fa re una soft uart
in quanto ho i pin impegnati
appena ho un attimo provo implementarla
uso il 12F840, ma devo fa re una soft uart
in quanto ho i pin impegnati
Si prega Accedi o Crea un account a partecipare alla conversazione.
- lorix
- New Member
Riduci
Di più
- Messaggi: 8
- Ringraziamenti ricevuti 0
Moderatori: Mauro Laurenti, Pinna, StefA, Matteo Garia
Registrati al sito
Accedi a tutte le risorse e articoli non visibili pubblicamente, puoi registrarti con pochi passi.