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


Pilotare LCD con compilatore XC8
     
Autore Messaggio opzioni
primok




una ogni 100 livelli
una ogni 10 livelli


postato il:
17.11.2017, alle ore 22:02



Più piccola è la mente più grande è la presunzione.
e.ferriani





postato il:
18.11.2017, alle ore 16:24
Più o meno quello che avevo scritto io, ma il mio si incartava su "itoa". Arrivava anche a 46000....
Poi ho risolto il problema alla luminosità dei primi tre led gialli così.

Prima impostavo le 4 soglie a cui accenderli, ma se non era raggiunta la soglia per il led successivo veniva azzerata tutta la porta:


if(trimmer>250) 
  RB0=1; 
else
  PORTB=0x00; 



In pratica era un pwm grossolano dipendete dalla velocità di scorrimento del ciclo.
Al raggiungimento della soglia per il 4 led tutti erano accesi a dovere.

Ora azzero solo il bit interessato ed ovviamente i led fanno luce al 100% sempre.


if(trimmer>250) 
  RB0=1; 
else
  RB0=0; 



Abbi pazienza, ma devo imparare ancora parecchio. E' facile andare ad un corso o fare una cosa per mestiere, lo dico con cognizione di causa. Faccio questo per gioco e quando riesco.

Qui il risultato.


Devo capire ora come allineare il risultato a destra e non a sinistra.



Enea Ferriani
e.ferriani





postato il:
18.11.2017, alle ore 16:28
Come si fa, se si può, per modificare un messaggio inserito nel forum? Il mio browser non mi fa vedere il link che ho inserito e volevo modificarlo con questo






Enea Ferriani
e.ferriani





postato il:
18.11.2017, alle ore 21:37
Eccoci, sto arrivando al dunque, almeno credo.
Regolo il pwm con il trimmer, e ne indico il valore 0÷1023 sul display, il led è collegato all'uscita PWM1. Il led si accende al massimo fino alla tensione impostata dal trimmer.
Nel programmino poco raffinato faccio resettare il pwm alla fine di ogni ciclo, quindi raggiunto il valore massimo il led di spegne.
In realtà la tensione impostata con il trimmer dovrà essere mantenuta dal treno e raggiunta dopo il segnale di start. In questo modo si da un effetto più realistico alla partenza ed alla fermata del treno.

https://youtu.be/-mhZFHtLYS8



Enea Ferriani
e.ferriani





postato il:
19.11.2017, alle ore 15:50
Ecco collegata la scheda di prova al circuito. è un programma di test, ma serve per valutare il comportamento del firmware, che comunque dovrà essere raffinato.

[URL=https://youtu.be/W25KiL1c0W0][/URL]

Se volessi fare in modo che il display mostri il valore del trimmer o del pwm in realtime e che io voglia far intervenire in realtime il trimmer sulla velocità massima, come dovrei fare secondo voi? Interrupt? Mai gestiti.

Questo il mio sorgente main. In lcd.c e lcd.h, che sono presenti nei post precedenti,ho solo scambiato PORTB con PORTC.

 

//**************************************************************
// CONFIGURATION
//**************************************************************

#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF// Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)




//**************************************************************
// INCLUDE
//**************************************************************


#include "xc.h"
#include "lcd.h" 
#include "stdio.h"
#include "string.h"
#include "stdlib.h"

//**************************************************************
//DEFINIZIONI (definitions)
//************************************************************** 

unsigned char p[]="    "; 
unsigned char messaggio[]="Trimmer";             //messaggio da scrivere
unsigned int trimmer; 

char lung; 
unsigned char string[]="";

unsigned int valorepwm;
int velocita;
int accelera;
int rallenta;


//**************************************************************
//ROUTINE INTERNE (subroutines)
//**************************************************************
 
void Settaggi(void);
void SettaggiPwm(void);
void IngressiAnalogici(void);

void ScriviTrimmerSuDisplay (void);

void PWM_1_Load (unsigned int);
void PWM_2_Load (unsigned int);
void TestAccelera(void);

 
//**************************************************************
//MAIN - (MAIN PROGRAM)
//**************************************************************
  
void main(void) 

  Settaggi();
  SettaggiPwm();
  IngressiAnalogici();
  
  

  LCD_INIT();                 //Inizializza display LCD 
  __delay_ms(10); 
  LCD_CLEAR(); 
  __delay_ms(100); 
  
  while(1)
  { 
    lcd_gotoxy(1,1); 
    lcd_puts(messaggio);

    ADCON0bits.GO = 1; 
    while (ADCON0bits.GO_DONE);
    trimmer =(unsigned int) (ADRESL + (ADRESH<<8));

    for(velocita=0;velocita<trimmer;velocita++)
    {
      PWM_1_Load( velocita );
      __delay_ms(3);
      
      itoa(string,trimmer, 10);           //dice che string 
      lcd_gotoxy (2,1);                   //vai a riga,colonna
      lcd_puts(string);                   //scrive la stringa "string" sul display
      lung=strlen(string);                //lung = calcola la lunghezza di "string"
      lung+=1;                            //somma 1 alla lunghezza calcolata "lung"
      lcd_gotoxy(2,lung);                 //vai a riga,colonna determinata da "lung"
      lcd_puts(p);                        //scrivi "    " (4 spazi) per cancellare gli 0 inutili)

      lung=0;
    }
    
    __delay_ms(4000);
    
        for(;velocita>0;velocita--)
    {
      PWM_1_Load( velocita );
      __delay_ms(2);

      itoa(string,trimmer, 10);           //dice che string 
      lcd_gotoxy (2,1);                   //vai a riga,colonna
      lcd_puts(string);                   //scrive la stringa "string" sul display
      lung=strlen(string);                //lung = calcola la lunghezza di "string"
      lung+=1;                            //somma 1 alla lunghezza calcolata "lung"
      lcd_gotoxy(2,lung);                 //vai a riga,colonna determinata da "lung"
      lcd_puts(p);                        //scrivi "    " (4 spazi) per cancellare gli 0 inutili)

      lung=0;
    }
    
    __delay_ms(4000);
       
  } 
return; 



//**************************************************************
//SETTAGGI - (SETTINGS)
//**************************************************************

void Settaggi(void)
{
  // 0= USCITA
  // 1= INGRESSO
  
  INTCON  = 0b00000000; 
  
  TRISA   = 0b00000001;   // solo PORTA0 Ã¨ un ingresso
  TRISB   = 0b00000000;   // PORTB tutti i bit in uscita 
  TRISC   = 0b00000000;   // PORTC tutti i bit in uscita 
  
  PORTA   = 0b00000000;   // clear PORTA 
  PORTB   = 0b00000000;   // clear PORTB 
  PORTC   = 0b00000000;   // clear PORTC  
}

void SettaggiPwm(void)
{
      //************************* IMPOSTAZIONI PWM *************************

  PR2     = 255;          //periodo pwm = 4.096 mS
  T2CKPS1  = 1;            //prescaler Timer2 1:16
  T2CKPS0  = 1;            //    "        "    "
  CCPR1L   = 0;            //valore iniziale di PWM pari a 0
  CCPR2L   = 0;            //valore iniziale di PWM pari a 0
  CCP1CON  = 0b00001100;               //modo PWM + valore iniziale PWM pari a 0
  CCP2CON  = 0b00001100;               //modo PWM + valore iniziale PWM pari a 0
  TMR2ON   = 1;            //Timer2 abilitato
    
}

void IngressiAnalogici (void)
{
ADCON1 = 0b10001110;           //bit7 -> 0 = Left justified. 6 Least Significant bits of ADRESL are read as ?0?.
                                //bit7 -> 1 = Right justified. 6 Most Significant bits of ADRESH are read as ?0?.
                                //bit6,5,4 -> Unimplemented: Read as '0'
                                //bit3,2,1,0 -> 1110 solo RA0 analogica

ADCON0 = 0b00000001;            //bit7,6 -> 00 = FOSC/2; 
                                //bit5,4,3 -> 000 = channel 0, (RA0/AN0);
                                //bit2 -> 0 = A/D conversion not in progress;
                                //bit1 -> Unimplemented: Read as '0'
                                //bit0 -> 1 = A/D converter module is operating
}


void ScriviTrimmerSuDisplay (void)
{
  itoa(string,trimmer, 10);           //dice che string 
  lcd_gotoxy (2,1);                   //vai a riga,colonna
  lcd_puts(string);                   //scrive la stringa "string" sul display
  lung=strlen(string);                //lung = calcola la lunghezza di "string"
  lung+=1;                            //somma 1 alla lunghezza calcolata "lung"
  lcd_gotoxy(2,lung);                 //vai a riga,colonna determinata da "lung"
  lcd_puts(p);                        //scrivi "    " (4 spazi) per cancellare gli 0 inutili)

  lung=0;
}


void PWM_1_Load (unsigned int PWM_1_Value)
{
CCP1CON = CCP1CON & 0b11001111;    //azzera CCP1CON <5:4> e lascia stare tutti gli altri
CCP1CON = CCP1CON | ((PWM_1_Value << 4) & 0b00110000);   //sposta in 4 a sx (per mettere i due bit meno significativi 
                                                              //(0 e 1) in posizione 4 e 5 e li scrive in CCP1CON<5:4>
CCPR1L = PWM_1_Value >> 2;                  //scrive in CCPR1L gli 8 bit piu' significativi di PWM
}

void PWM_2_Load (unsigned int PWM_2_Value)
{
CCP2CON = CCP2CON & 0b11001111;    //azzera CCP1CON <5:4> e lascia stare tutti gli altri
CCP2CON = CCP2CON | ((PWM_2_Value << 4) & 0b00110000);   //sposta in 4 a sx (per mettere i due bit meno significativi (0 e 1) 
                                                                //in posizione 4 e 5 e li scrive in CCP1CON<5:4>
CCPR2L = PWM_2_Value >> 2;                  //scrive in CCPR1L gli 8 bit piu' significativi di PWM
}

void TestAccelera(void)
{
  for(accelera=0;accelera<trimmer;accelera++)
  {
    PWM_1_Load( accelera );
    __delay_ms(5);
  }
}



Enea Ferriani
e.ferriani





postato il:
19.11.2017, alle ore 22:41
Per oggi basta, non vi disturbo più. Sono abbastanza soddisfatto del lavoro svolto, anche se ho ancora molto lavoro da fare.
Vedi il video con parlato descrittivo.

[URL=https://youtu.be/PBt5fu0X3D4][/URL]

Il codice lo metto poi più avanti, quando avrò aggiunto altre funzioni.

Una domanda però.
Secondo voi, se volessi collegare 4 micro fra loro magari in RS485 o Canbus, essendo distanti pochi centimetri uno dall'altro, è necessario interporre qualche line driver/receiver o simili o posso collegare rx e tx in cascata senza farmi troppi problemi?



Enea Ferriani
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