PIC e ricezione telecomando infrarossi
Moderatore:
Paolino
35 messaggi
• Pagina 2 di 4 • 1, 2, 3, 4
0
voti
Ma non puoi usare interrupt on change?
"Houston, Tranquillity Base here. The Eagle has landed." - Neil A.Armstrong
-------------------------------------------------------------
PIC Experience - http://www.picexperience.it
-------------------------------------------------------------
PIC Experience - http://www.picexperience.it
-

Paolino
32,6k 8 12 13 - G.Master EY

- Messaggi: 4226
- Iscritto il: 20 gen 2006, 11:42
- Località: Vigevano (PV)
0
voti
Paolino ha scritto:Ma non puoi usare interrupt on change?
Quello che mi chiedevo anche io, visto che ha anche definito una interrupt service routine, ma vuole fare tutto nel main.

0
voti
Grazie per l'aiuto che mi state dando.
Ho modificato il codice usando l'interrupt sul gpio.f4 come da voi consigliato.
Il codice sopra ancora non è ottimizzato e finito quindi alcune righe sono per fare il debug.
Ora sto cercando di copiare il codice in un array per poi ritrasmetterlo su di un led (gpio.f5). Il fatto è che ora una volta acquisita la stringa il gpio.f5 rimane sempre acceso, è come se nella stringa non ci fosse neanche uno zero, cosa improbabile
Ho modificato il codice usando l'interrupt sul gpio.f4 come da voi consigliato.
- Codice: Seleziona tutto
signed short ricevo[20]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
unsigned bit flag_discesa; flag_salita; inizio_ricezione; alto; basso;
unsigned bit stop_tempo; leggi; stop; start;
unsigned short tempo_trascorso;
unsigned short incremento_byte;
void interrupt(void){
if(intcon.gpif){
if((gpio.f4==1)&&(alto==0))
{
gpio.f1=1;
INTCON.T0IE=1;
tmr0=0;
stop_tempo=0;
tempo_trascorso=0;
alto=1;
start=0;
intcon.gpif=0;
}
if((gpio.f4==0)&&(alto==1))
{
gpio.f1=0;
tempo_trascorso=tmr0;
INTCON.T0IE=0;
stop_tempo=1;
alto=0;
incremento_byte++;
start=1;
intcon.gpif=0;
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void main() { ///////
incremento_byte=0;
stop_tempo=0;
alto=0;
basso=0;
start=0;
stop=0;
flag_discesa=0;
leggi=0;
flag_salita=0;
inizio_ricezione=0;
tempo_trascorso=0;
CMCON = 7; //Disabilita comparatore
ADCON0 = 0b000000000; //Disabilita convertitore A/D
ANSEL = 0b00000000; //Tutte le porte in digitale
TRISIO = 0b00010000; //Tutti i pin in OUT tranne gpio3
OPTION_REG=0b00000101; //abilita presaler 1:64 in modo da avere un incremento del tmr0 ogni 64uS
ioc=0b010000;
INTCON.GPIE =1; //abilita interrupt generale
gpio.f5=0;
gpio.f3=0;
gpio.f2=0;
gpio.f1=0;
gpio.f0=0;
while(1){
////////////////////////////controlla impulso start di 13ms////////////////////////////////////////////////////////////
if(gpio.f4==0)
{
INTCON.T0IE=1;
tmr0=0;
flag_discesa=1;
}
if((gpio.f4==1)&&(flag_discesa==1))
{
flag_salita=1;
}
if((gpio.f4==0)&&(flag_salita==1))
{
tempo_trascorso=tmr0;
}
if(tempo_trascorso>200)
{
intcon.GIE=1;
inizio_ricezione=1;
flag_salita=0;
flag_discesa=0;
tempo_trascorso=0;
}
if((inizio_ricezione==1)&&(start==1)){
if((tempo_trascorso<25)&&(stop_tempo==1))
{
ricevo[incremento_byte]=0;
}
if((tempo_trascorso>25)&&(stop_tempo==1))
{
ricevo[incremento_byte]=1;
}
}
if(incremento_byte>20)
{
leggi=1;
incremento_byte=0;
intcon.gie=0;
}
if(leggi==1)
{
gpio.f2=1;
stop++;
gpio.f5=ricevo[incremento_byte];
delay_ms(500);
gpio.f2=0;
delay_ms(500);
incremento_byte++;
}
}
}
Il codice sopra ancora non è ottimizzato e finito quindi alcune righe sono per fare il debug.
Ora sto cercando di copiare il codice in un array per poi ritrasmetterlo su di un led (gpio.f5). Il fatto è che ora una volta acquisita la stringa il gpio.f5 rimane sempre acceso, è come se nella stringa non ci fosse neanche uno zero, cosa improbabile
0
voti
Prova questo, l'ho fatto su xc8 ma si traduce facilmente:
Come discriminante tra gli 0 e gli 1 ho usato
ed ho tolto di mezzo gli interrupt
- Codice: Seleziona tutto
/*
* File: main.c
* Author: sbusnelli
*
* Created on 6 ottobre 2015, 16.08
*/
#include <xc.h>
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
// CONFIG
#pragma config FOSC = INTRCIO // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = ON // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF // Power-Up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON // GP3/MCLR pin function select (GP3/MCLR pin function is MCLR)
#pragma config BOREN = ON // Brown-out Detect Enable bit (BOD enabled)
#pragma config CP = OFF // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)
typedef unsigned char uchar;
uchar samples[20];
int main(int argc, char** argv) {
uchar i_sample = 0;
uchar timer1 = 0;
uchar timer2 = 0;
// Interrupt disabilitati
INTCONbits.GIE = 0;
// GP4 come Input
TRISIObits.TRISIO4 = 1;
// GP5 come Output
TRISIObits.TRISIO5 = 0;
// Usiamo TMR0 in modalità TIMER
OPTION_REGbits.T0CS = 0; // Internal instruction cycle clock
OPTION_REGbits.PSA = 0; // Prescaler su TMR0
OPTION_REGbits.PS = 0b101; // Prescaler 1 : 64
// SKIP 1 iniziali
while ( GPIObits.GP4 == 1 )
{
;
}
// SKIP 0 successivi agli 1 iniziali
while ( GPIObits.GP4 == 0 )
{
;
}
for ( i_sample=0; i_sample<20; i_sample++ ) {
timer1 = TMR0;
// Misuro 1
while ( GPIObits.GP4 == 1 )
{
;
}
timer2 = TMR0;
samples[i_sample] = timer2-timer1;
// SKIP 0
while ( GPIObits.GP4 == 0 )
{
;
}
}
// Visualizzo i valori
for ( i_sample=0; i_sample<20; i_sample++ ) {
if ( samples[i_sample] < 12 ) {
// Se il periodo misurato è inferiore a 12*64us=768us ~800us è uno 0, altrimenti è un 1
GPIObits.GP5 = 0;
} else {
GPIObits.GP5 = 1;
}
_delay(1000000);
}
return 0;
}
Come discriminante tra gli 0 e gli 1 ho usato
ed ho tolto di mezzo gli interrupt
0
voti
Sto testando questo codice con oscilloscopio. Canale A oscilloscopio collegato all'uscita del ricevitore infrarossi, canale B collegato al pin GPIO.F1 del PIC, sono identiche, quindi il PIC riceve perfettamente il dato, il problema è la memorizzazione del dato in array
Come posso migliorare la memorizzazione del dato??
- Codice: Seleziona tutto
signed short ricevo[20]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
unsigned bit flag_discesa; flag_salita; inizio_ricezione; alto; basso;
unsigned bit stop_tempo; leggi; stop; start;
unsigned short tempo_trascorso;
unsigned short incremento_byte;
void interrupt(void){
if(intcon.gpif){
if((gpio.f4==1)&&(alto==0))
{
gpio.f1=1; //oscilloscopio canale B
INTCON.T0IE=1;
tmr0=0;
stop_tempo=0;
tempo_trascorso=0;
alto=1;
start=0;
intcon.gpif=0;
}
if((gpio.f4==0)&&(alto==1))
{
gpio.f1=0; //oscilloscopio canale B
tempo_trascorso=tmr0;
INTCON.T0IE=0;
stop_tempo=1;
alto=0;
incremento_byte++;
start=1;
intcon.gpif=0;
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void main() { ///////
incremento_byte=0;
stop_tempo=0;
alto=0;
basso=0;
start=0;
stop=0;
flag_discesa=0;
leggi=0;
flag_salita=0;
inizio_ricezione=0;
tempo_trascorso=0;
CMCON = 7; //Disabilita comparatore
ADCON0 = 0b000000000; //Disabilita convertitore A/D
ANSEL = 0b00000000; //Tutte le porte in digitale
TRISIO = 0b00010000; //Tutti i pin in OUT tranne gpio3
OPTION_REG=0b00000101; //abilita presaler 1:64 in modo da avere un incremento del tmr0 ogni 64uS
ioc=0b010000;
INTCON.GPIE =1; //abilita interrupt generale
gpio.f5=0;
gpio.f3=0;
gpio.f2=0;
gpio.f1=0;
gpio.f0=0;
while(1){
////////////////////////////controlla impulso start di 13ms////////////////////////////////////////////////////////////
if(gpio.f4==0)
{
INTCON.T0IE=1;
tmr0=0;
flag_discesa=1;
}
if((gpio.f4==1)&&(flag_discesa==1))
{
flag_salita=1;
}
if((gpio.f4==0)&&(flag_salita==1))
{
tempo_trascorso=tmr0;
}
if(tempo_trascorso>200)
{
intcon.GIE=1;
inizio_ricezione=1;
flag_salita=0;
flag_discesa=0;
tempo_trascorso=0;
}
}
}
Come posso migliorare la memorizzazione del dato??
0
voti
Secondo me c'è un po' di confusione.
Il controllo della polarità della porta lo devi fare solamente nell'interrupt. L'ho parzialmente modificata la ISR dell'interrupt:
Paolo
Il controllo della polarità della porta lo devi fare solamente nell'interrupt. L'ho parzialmente modificata la ISR dell'interrupt:
- Codice: Seleziona tutto
void interrupt(void)
{
if(intcon.gpif)
{
if((gpio.f4==1)&&(alto==0))
{
gpio.f1=1; //oscilloscopio canale B
INTCON.T0IE=1;
tmr0=0;
stop_tempo=0;
tempo_trascorso=0;
alto=1;
start=0;
} else if((gpio.f4==0)&&(alto==1))
{
gpio.f1=0; //oscilloscopio canale B
tempo_trascorso=tmr0;
INTCON.T0IE=0;
stop_tempo=1;
alto=0;
incremento_byte++;
start=1;
}
intcon.gpif=0;
}
}
Paolo
"Houston, Tranquillity Base here. The Eagle has landed." - Neil A.Armstrong
-------------------------------------------------------------
PIC Experience - http://www.picexperience.it
-------------------------------------------------------------
PIC Experience - http://www.picexperience.it
-

Paolino
32,6k 8 12 13 - G.Master EY

- Messaggi: 4226
- Iscritto il: 20 gen 2006, 11:42
- Località: Vigevano (PV)
0
voti
resetti il prescaler che quindi non divide più per 64 la frequenza con cui si incrementa il timer
0
voti
sorecaro ha scritto:impostando il tmr0 a 0 non resetti il prescaler
Scusami, il datasheet forse in merito è un po' ambiguo:
Capitolo 4, paragrafo 4.4 "Prescaler":
When assigned to the Timer0 module, all instructions writing to the TMR0 register (e.g., CLRF 1, MOVWF 1, BSF 1, x....etc.) will clear the prescaler.
A questo punto vorrei fare degli esperimenti in merito, non capisco se si resetta un contatore interno del prescaler, o proprio l'impostazione.

35 messaggi
• Pagina 2 di 4 • 1, 2, 3, 4
Torna a Firmware e programmazione
Chi c’è in linea
Visitano il forum: Nessuno e 16 ospiti

Elettrotecnica e non solo (admin)
Un gatto tra gli elettroni (IsidoroKZ)
Esperienza e simulazioni (g.schgor)
Moleskine di un idraulico (RenzoDF)
Il Blog di ElectroYou (webmaster)
Idee microcontrollate (TardoFreak)
PICcoli grandi PICMicro (Paolino)
Il blog elettrico di carloc (carloc)
DirtEYblooog (dirtydeeds)
Di tutto... un po' (jordan20)
AK47 (lillo)
Esperienze elettroniche (marco438)
Telecomunicazioni musicali (clavicordo)
Automazione ed Elettronica (gustavo)
Direttive per la sicurezza (ErnestoCappelletti)
EYnfo dall'Alaska (mir)
Apriamo il quadro! (attilio)
H7-25 (asdf)
Passione Elettrica (massimob)
Elettroni a spasso (guidob)
Bloguerra (guerra)

