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


Timer0 su pic 18f4550
     
Autore Messaggio opzioni
graziano2000





postato il:
14.05.2018, alle ore 11:42
Timer0 su pic 18f4550 

salve a tutti ,
sto provando a far funzionare questo codice:

 #define _XTAL_FREQ 20000000
 
#include <xc.h>  
#include <delay.h>  
#include <delay.c>  
#define LCD_DEFAULT
#include <LCD_44780.h>
#include <LCD_44780.c>
#pragma config WDT = OFF  
#pragma config FOSC = HS 
unsigned int sensore1 = 0;  
unsigned int sensore2 = 0;  
unsigned int sensore3 = 0;  
unsigned int sensore4 = 0;
unsigned int sensore5 = 0;  
unsigned int Counter= 0;
 
void conversione1() //
{
 delay_ms (1);      
sensore1 = 0; 
ADCON0 = 0b00000011; 
    ADCON0bits.GO = 1;  
    while (ADCON0bits.GO);  
    sensore1 = (ADRESL+(ADRESH<<8)); 
    //converto il segnale di sensore 1 
}
void conversione2() //
{
delay_ms (1);    
    ADCON0 = 0b00000101;
    delay_ms (1);      
    sensore2 = 0;  
    ADCON0bits.GO = 1;        
    while (ADCON0bits.GO);  
    sensore2 = (ADRESL+(ADRESH<<8)) ; 
    //converto il segnale di sensore 2  
}
void conversione3() //
{
 delay_ms (1);    
    ADCON0 = 0b00001001;
    delay_ms (1);      
    sensore3 = 0;  
    ADCON0bits.GO = 1;        
    while (ADCON0bits.GO);  
    sensore3 = (ADRESL+(ADRESH<<8)) ; 
    //converto il segnale di sensore 3 
}
void conversione4() //
{
 delay_ms (1);    
    ADCON0 = 0b00001101;
    delay_ms (10);      
    sensore4 = 0;  
    ADCON0bits.GO = 1;        
    while (ADCON0bits.GO);  
    sensore4 = ((ADRESH<<8)+ADRESL)/0.0485 ; 
    //converto il segnale di sensore 4 
}
void conversione5() //
{
delay_ms (1);    
    ADCON0 = 0b00010001;
    delay_ms (1);      
    sensore5 = 0;  
    ADCON0bits.GO = 1;        
    while (ADCON0bits.GO);  
    sensore5 = ((ADRESH<<8)+ADRESL)/0.0485 ; 
    //converto il segnale di sensore 5 
}
void inizialtimer() //
{
    //************************************************************
// Abilito il Timer0 
//************************************************************
// Modalità a 16 bit
T0CONbits.T08BIT = 0;
   // Clock interno
T0CONbits.T0CS = 0;
// Abilito Prescaler
T0CONbits.PSA = 0;
// Prescaler 32
T0CONbits.T0PS0 = 0;
T0CONbits.T0PS1 = 0;
T0CONbits.T0PS2 = 1;
// Abilito le interruzioni del Timer0
INTCONbits.TMR0IE = 1;
// Abilito il Timer0
T0CONbits.TMR0ON = 1;
//************************************************************
// Abilito le interruzioni
//************************************************************
// disAbilito modalità interruzione a due livelli alta e bassa
RCONbits.IPEN = 0;
// Abilito gli interrupt
INTCONbits.GIE = 1;
 
   }
 
void interrupt ISR (void)
 { 
   if (INTCONbits.TMR0IF==1)
    { PORTCbits.RC0=~PORTCbits.RC0;
      INTCONbits.TMR0IF = 0; 
    }
}
 
void main (void){    
    PORTC = 0;  
    TRISC = 0; 
    TRISD = 0;    
    LATB = 0;  
    TRISB = 0b00100000;  
 
 
    ADCON1 = 0b00001010; 
    //imposto AN0-AN1-AN2 AN3/4/5 come ingressi analogici
    ADCON2 = 0b10111101;  
    //imposto frequenza di clok del modulo adc  
    //e giustificazione a DEStra
    ADCON0 = 0b00000001;
    //attivo il modulo adc
   void inizialtimer();
 
 
    while(1) {
 
 
    conversione1();
    conversione2();
    conversione3();
    conversione4();
    conversione5();
 
 
    LCD_initialize (20);
    LCD_write_message(\"sen4:\");
    LCD_write_integer (sensore4,6,LCD_ZERO_CLEANING_ON);
    LCD_goto_xy(1,13);
    LCD_write_message(\"mV\");
    LCD_goto_line(2);
    LCD_write_message(\"sen2:\");
     LCD_write_integer (sensore2,6,LCD_ZERO_CLEANING_ON);
     LCD_goto_xy(2,13);
    LCD_write_message(\"mV\");    
}
}


per quando riguarda ADC e LCD nessun problema (solo qualche aggiustamento che farò in seguito )
ma il timer 0 non ne vuole proprio sapere , per il momento gli chiedo solo di far lampeggiare un led (in seguito sostituirò con un codice un po più complesso)
ma le sto provando tutte ma non va ....
dove sbaglio ?? :) :) :) :)



La vita potrebbe essere divisa in tre fasi: Rivoluzione, Riflessione e Televisione.Si comincia con il voler cambiare il mondo e si finisce col cambiare i canali.
http://graziano-page.simplesite.com/
elektorplus




una ogni 10 livelli una ogni 10 livelli


postato il:
14.05.2018, alle ore 17:27
Aggiungi l'abilitazione all'interrupt periferico dopo il GIE = 1.

INTCONbits.PEIE = 1;



http://elektor.altervista.org/
graziano2000





postato il:
14.05.2018, alle ore 17:40
ti ringrazio per l'aiuto ..
ho provato con la modifica che mi hai suggerito , ma non va :
 void inizialtimer() //
{
    //************************************************************
// Abilito il Timer0 
//************************************************************
// Modalità a 16 bit
T0CONbits.T08BIT = 0;
   // Clock interno
T0CONbits.T0CS = 0;
// Abilito Prescaler
T0CONbits.PSA = 0;
// Prescaler 32
T0CONbits.T0PS0 = 0;
T0CONbits.T0PS1 = 0;
T0CONbits.T0PS2 = 1;
// Abilito le interruzioni del Timer0
INTCONbits.TMR0IE = 1;
// Abilito il Timer0
T0CONbits.TMR0ON = 1;
//************************************************************
// Abilito le interruzioni
//************************************************************
// disAbilito modalità interruzione a due livelli alta e bassa
RCONbits.IPEN = 0;
// Abilito gli interrupt
INTCONbits.GIE = 1;
INTCONbits.PEIE = 1;
   } 



La vita potrebbe essere divisa in tre fasi: Rivoluzione, Riflessione e Televisione.Si comincia con il voler cambiare il mondo e si finisce col cambiare i canali.
http://graziano-page.simplesite.com/
picmicro675




una ogni 10 livelli


postato il:
14.05.2018, alle ore 21:22
Ho stringato il tuo programma
 #define _XTAL_FREQ 20000000

#include <xc.h>
#include <delay.h>
#include <delay.c>
#define LCD_DEFAULT
#include <LCD_44780.h>
#include <LCD_44780.c>
#pragma config WDT = OFF
#pragma config FOSC = HS
unsigned int sensore1 = 0;
unsigned int sensore2 = 0;
unsigned int sensore3 = 0;
unsigned int sensore4 = 0;
unsigned int sensore5 = 0;
unsigned int Counter = 0;
unsigned char flags

#define flip flags.0

unsigned int conversione(unsigned char adcon_setting)
{
/* Convertitore ACD che funziona a secondo dell' impostazione entrante
   Il valore ritornato e' il risultato della conversione
*/
    delay_ms (1);
    sensore1 = 0;
    ADCON0 = adcon_setting;
    ADCON0bits.GO = 1;
    while (ADCON0bits.GO);
    return (ADRESL+(ADRESH<<8));
}

void interrupt ISR (void)
{
    if (TMR0IF) {             // basta e avanza
        if (flip) {
            flip = 0;
            RC0 =  0;
        }
        else {
            flip = 1
            RC0 = 1;
        }
        TMR0IF = 0;
    }
}

void main (void)
{
    PORTC = 0;
    TRISC = 0;
    TRISD = 0;
    LATB = 0;
    TRISB = 0b00100000;

    ADCON1 = 0b00001010;
    //imposto AN0-AN1-AN2 AN3/4/5 come ingressi analogici
    ADCON2 = 0b10111101;
    //imposto frequenza di clock del modulo adc
    //e giustificazione a destra
    ADCON0 = 0b00000001;
    //attivo il modulo adc
    // Abilito T0CON in una sola istruzione :-P
    T0CON = 0b01000100DS39632C-page 98
 
    IPEN = 0;
    // Abilito gli interrupt
    GIE = 1;
    LCD_initialize (20);

    while(1) {
        sensore1 = conversione(0b00000011);
        sensore2 = conversione(0b00000101);
        sensore3 = conversione(0b00001001);
        sensore4 = conversione(0b00001101);
        sensore5 = conversione(0b00010001);
        LCD_write_message("sen4:");
        LCD_write_integer (sensore4,6,LCD_ZERO_CLEANING_ON);
        LCD_goto_xy(1,13);
        LCD_write_message("mV");
        LCD_goto_line(2);
        LCD_write_message("sen2:");
        LCD_write_integer (sensore2,6,LCD_ZERO_CLEANING_ON);
        LCD_goto_xy(2,13);
        LCD_write_message("mV");
    }
}

Non avendo le librerie che s'ha da includere non posso simulare e provare il programma.
Non ho grande esperienze coi 18F, ma per il timer0 penso non sia poi tante cose da impostare per poterlo usare.
Comunque, mi sorge una domanda.... Da come giudichi che il timer0 non funziona ?
Se vuoi una frequenza da 156 kHz su RC0, come puoi verificarlo ?

Comunque la tabella 11.1 DS39632C-page 127, descrive tutte le locazioni di memoria implicate col timer0. Per capire come sono organizzati gli inteerupts vedi la Figura 9.1 DS39632C-page 98.
Poi a secondo la priorità dell' interrupt, dovresti configurare INCON2.TMR0IP. Che da come hai impostato il tuo interrupt dovrebbe essere quello a bassa priorità.

Per ultimo, sono rimasto anch'io sorpreso dal fatto che non sia possibile fare la negazione del bit della porta. Meglio usare un bit di appoggio.

Anche il display in quel modo di usarlo non penso sia ottimale. Specialmente perché richiede qualche millisecondo per aggiornare le scritte. Addirittura inizializzare l'LCD ripetutamente non è affatto consigliabile.
harpefalcata





postato il:
15.05.2018, alle ore 11:46
Non riesco a trovare alcuna parte, nel tuo codice, dove vai a scrivere l'intervallo che il timer deve contare, nei relativi registri. Forse me lo sono perso io? Con queste impostazioni, se non mi sbaglio, al primo tick del timer, questo va già in overflow.

Il tutto si risolve in un unico tick del timer, in base a quanto è il clock primario, potrebbe essere dopo appena una manciata di nanosecondi.



Il tempo è il miglior maestro, purtroppo uccide tutti i suoi allievi
graziano2000





postato il:
15.05.2018, alle ore 12:23
grazie a tutti per l'aiuto, sempre gentili !!!!
in ogni caso ho provato a snellire un po il codice e aggiungere le modifiche suggerite ma sia il led e sia l'oscilloscopio: calma piatta.......

#define _XTAL_FREQ 20000000 

#include <xc.h> 
#include <delay.h> 
#include <delay.c> 
#define LCD_DEFAULT 
#include <LCD_44780.h> 
#include <LCD_44780.c> 
#pragma config WDT = OFF 
#pragma config FOSC = HS 
unsigned int sensore1 = 0; 
unsigned int sensore2 = 0; 
unsigned int sensore3 = 0; 
unsigned int sensore4 = 0; 
unsigned int sensore5 = 0; 
unsigned int Counter = 0; 
unsigned char flags = 0;

#define flip flags



void interrupt ISR (void) 

    
    if (TMR0IF) {             // basta e avanza 
        if (flip) { 
            flip = 0; 
            RC0 =  0; 
        } 
        else { 
            flip = 1;
            RC0 = 1; 
        } 
        TMR0=61; 
        TMR0IF = 0; 
        
    } 


void main (void) 

    PORTC = 0; 
    TRISC = 0; 
    TRISD = 0; 
    LATB = 0; 
    TRISB = 0b00100000; 

    
    T0CON = 0b01000111;
//    DS39632C-page 98 
  
    IPEN = 0; 
    // Abilito gli interrupt 
    GIE = 1; 
    

    while(1) { 
        TMR0=61;
       LCD_initialize (20); 
        LCD_write_message("TEST:"); 
        
    } 
}
 



La vita potrebbe essere divisa in tre fasi: Rivoluzione, Riflessione e Televisione.Si comincia con il voler cambiare il mondo e si finisce col cambiare i canali.
http://graziano-page.simplesite.com/
picmicro675




una ogni 10 livelli


postato il:
15.05.2018, alle ore 23:45
Ho cercato una possibile soluzione, ma non ho trovato molto.
Forse trovi un modo facilitato con MCC
http://www.microchip.com/mplab/mplab-code-configurator
picmicro675




una ogni 10 livelli


postato il:
16.05.2018, alle ore 04:55
 /*  Processor: PIC18F4550
 * Compiler:  MPLAB XC8
 */

#include <xc.h>
#include <pic18f4550.h>

#define _XTAL_FREQ 20000000
#pragma config MCLRE = OFF       // MCLR Disabled
#pragma config XINST = OFF       // Extended instruction set disabled
#pragma config PWRT = ON       // Power up timer enabled
#pragma config PLLDIV = 4
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator (HS))

 void main (void)
{                   
    TRISA = 0;
    TRISC = 0;
    TRISB = 0;
    TRISD = 0x00;
    LATC = 0;
    T0CON = 0b11000100;
    IPEN       = 1;    //Enable Interrupt Priorities
    INTCON = 0b11100000;
    TMR0IP  = 0;    //TMR0 set to low Priority Interrupt
    while(1) {;}
}
void interrupt low_priority ISR(void)
{
    if(TMR0IF && TMR0IE){
        TMR0IF = 0;
       LATC0 = ~LATC0;
    }
}

Ho dovuto studiarmi qualche pagina web. Ma tanto un giorno, anch' io tirerò fuori quel 18F4550 che ho nei cassettini.
Provato al simulatore, frequenza 305 Hz.
picmicro675




una ogni 10 livelli


postato il:
16.05.2018, alle ore 05:06
Ma per quello che ho notato la chiave per aver una routine assegnata come interrupt bisogna scrivere
"void __interrupt (low_priority) Nome_Arbitrario(void)"
"void __interrupt (high_priority) Nome_Arbitrario(void)"

DS52053A-page 32.
Sebbene anche quello scritto nel codice sopra non dia problemi. Deduco che la parola chiave si low_priority o high_priority a secondo di quale priorità si voglia usare e quale sia quella in pratica impostata.

graziano2000





postato il:
16.05.2018, alle ore 18:26
dopo tanta fatica funziona !!!!


 
define _XTAL_FREQ 20000000 
 
#include <xc.h> 
#include <delay.h> 
#include <delay.c> 
#define LCD_DEFAULT 
#include <LCD_44780.h> 
#include <LCD_44780.c> 
#pragma config WDT = OFF 
#pragma config FOSC = HS 
unsigned int sensore1 = 0; 
unsigned int sensore2 = 0; 
unsigned int sensore3 = 0; 
unsigned int sensore4 = 0; 
unsigned int sensore5 = 0; 
unsigned int Counter = 0; 
 
void conversione1() //
{
 delay_ms (1);      
sensore1 = 0; 
ADCON0 = 0b00000011; 
    ADCON0bits.GO = 1;  
    while (ADCON0bits.GO);  
    sensore1 = (ADRESL+(ADRESH<<8)); 
    //converto il segnale di sensore 1 
}
void conversione2() //
{
delay_ms (1);    
    ADCON0 = 0b00000101;
    delay_ms (1);      
    sensore2 = 0;  
    ADCON0bits.GO = 1;        
    while (ADCON0bits.GO);  
    sensore2 = (ADRESL+(ADRESH<<8)) ; 
    //converto il segnale di sensore 2  
}
void conversione3() //
{
 delay_ms (1);    
    ADCON0 = 0b00001001;
    delay_ms (1);      
    sensore3 = 0;  
    ADCON0bits.GO = 1;        
    while (ADCON0bits.GO);  
    sensore3 = (ADRESL+(ADRESH<<8)) ; 
    //converto il segnale di sensore 3 
}
void conversione4() //
{
 delay_ms (1);    
    ADCON0 = 0b00001101;
    delay_ms (10);      
    sensore4 = 0;  
    ADCON0bits.GO = 1;        
    while (ADCON0bits.GO);  
    sensore4 = ((ADRESH<<8)+ADRESL)/0.0485 ; 
    //converto il segnale di sensore 4 
}
void conversione5() //
{
delay_ms (1);    
    ADCON0 = 0b00010001;
    delay_ms (1);      
    sensore5 = 0;  
    ADCON0bits.GO = 1;        
    while (ADCON0bits.GO);  
    sensore5 = ((ADRESH<<8)+ADRESL)/0.0485 ; 
    //converto il segnale di sensore 5 
}
 
 
__interrupt (low_priority) void ISR_bassa (void)
{
// Controllo che l'interrupt sia stato generato dal Timer0
if (INTCONbits.TMR0IF == 1 )
    {
    Counter++;//INCREMENTA IL COUNTER
    if(Counter<30){ //Se vale meno di 30 ( 1counter => circa 2 secondi)
    Counter++;//INCREMENTA IL COUNTER    
    }
    else//Se vale piu di 30
    { 
    Counter=0;  //azzera il counter
    PORTCbits.RC0=~PORTCbits.RC0;
 
    }
// Resetto il flag dell interrupt per permettere nuove interruzioni
    INTCONbits.TMR0IF = 0;
    }
 

 
 
void main (void) 

    PORTC = 0; 
    TRISC = 0; 
    TRISD = 0; 
    LATB = 0; 
    TRISB = 0b00100000; 
 
        ADCON1 = 0b00001010; 
        //imposto AN0-AN1-AN2 AN3/4 come ingressi analogici
        ADCON2 = 0b10111101;  
        //imposto frequenza di clok del modulo adc  
        //e giustificazione a DEStra
        ADCON0 = 0b00000001;
        //attivo il modulo adc
 
        //************************************************************
        // Abilito il Timer0 per funzionare a bassa priorità
        //************************************************************
 
    // Modalità a 16 bit
    T0CONbits.T08BIT = 0;
    // Clock interno
    T0CONbits.T0CS = 0;
    // Abilito Prescaler
    T0CONbits.PSA = 0;
    // Prescaler 256
    T0CONbits.T0PS0 = 1;
    T0CONbits.T0PS1 = 1;
    T0CONbits.T0PS2 = 1;
    // Abilito le interruzioni del Timer0
    INTCONbits.TMR0IE = 1;
    // Abilito le interruzioni del Timer0 come bassa priorità
    INTCON2bits.TMR0IP = 0;
    // Abilito il Timer0
    T0CONbits.TMR0ON = 1;
 
    //************************************************************
    // Abilito le interruzioni
    //************************************************************
 
    // Abilito modalità interruzione a due livelli alta e bassa
    RCONbits.IPEN = 1;
    // Abilito gli interrupt ad alta priorità
    INTCONbits.GIEH = 1;
    // Abilito gli interrupt a bassa priorità
    INTCONbits.GIEL = 1 ;
 
    while(1) { 
 
 
    conversione1();
    conversione2();
    conversione3();
    conversione4();
    conversione5();
  LCD_initialize (20);
 
    LCD_write_message("sen4:");
    LCD_write_integer (sensore4,6,LCD_ZERO_CLEANING_ON);
    LCD_goto_xy(1,13);
    LCD_write_message("mV");
    LCD_goto_line(2);
    LCD_write_message("sen5:");
     LCD_write_integer (sensore5,6,LCD_ZERO_CLEANING_ON);
     LCD_goto_xy(2,13);
    LCD_write_message("mV");    
    } 
}
 
 
 
 



La vita potrebbe essere divisa in tre fasi: Rivoluzione, Riflessione e Televisione.Si comincia con il voler cambiare il mondo e si finisce col cambiare i canali.
http://graziano-page.simplesite.com/
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/2018 GRIX.IT - La community dell'elettronica Amatoriale