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


risposta a Tatopower
     
Autore Messaggio opzioni
primok




una ogni 100 livelli
una ogni 10 livelli


postato il:
24.02.2022, alle ore 21:29
risposta a Tatopower 

#include <built_in.h>

// LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB6_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB6_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD module connections
// Lcd pinout settings
sbit OUT at RA2_bit;
// Pin direction
sbit OUT_Direction at TRISA2_bit;

#define NMeasure 4
#define const2 4
#define kappa 1440 //360* 4 usec
#define const1 250

//dichiarazioni globali:

unsigned char tnum6[6],tnum7[5],tnum8[5];
unsigned long Ngiri=0;
bit ready; // bit variable
unsigned char edge=0,measure=0;
unsigned long MaxPulse=0,LastMaxPulse=0;
unsigned long LoadPr2,LoadPr=0;
unsigned int alfa=0;
unsigned char INC=0;

void interrupt() {

if (INTCON.TMR0IF) { //1 msec

INTCON.TMR0IF = 0;
TMR0 =6;
}

if(INTCON.INTF){ //Su RB0


if(LoadPr>const1){
PR2=const1;
INC=(LoadPr/const1);
}else{
PR2=LoadPr/const2;
INC=0;
}



T2CON.TMR2ON=1;
PIE1.TMR2IE=1;


++edge;

if(edge==1){


TMR1H=0;
TMR1L=0;
T1CON.TMR1ON=1;
}

if(edge==2){

T1CON.TMR1ON=0;
MaxPulse=TMR1H*256+ TMR1L;

LoadPr= ((MaxPulse/kappa)*alfa) ;//Carica PR2 in funzione di alfa per il ritardo dell'impulso

TMR1H=0;
TMR1L=0;
edge=0;
ready=1;
}
INTCON.INTF=0;
}

if(PIR1.TMR1IF){
PIR1.TMR1IF=0;
}

if(PIR1.TMR2IF){

if(OUT==1){
T2CON.TMR2ON=0;
OUT=0;
PIE1.TMR2IE=0;
}

else if(OUT==0){

if(INC>0){

if(--INC==0){

OUT=1;
}

} else{

OUT=1;
}
}
PIR1.TMR2IF=0;
}
}



void main() {

int i=0;
CMCON=0b00000111;
PORTB=0b00000000;
PORTA=0b00000000;
TRISB=0b00000001;
TRISA=0b00000000;
///Abilito LCD
Lcd_Init();
Lcd_Cmd (_LCD_CURSOR_OFF);
Lcd_Cmd (_LCD_CLEAR);

INTCON.PEIE=1;
INTCON.GIE=1;
INTCON.T0IE=1;
INTCON.INTE=1;

OPTION_REG=0b01000011; //4 usec
TMR0 =6;
T1CON.TMR1IE=0;
T1CON.TMR1ON=0;
T1CON.T1CKPS0=0;//1:4
T1CON.T1CKPS1=1;
ready=0;
T2CON=0b00000010; // 16MHz/4 1:16 --> 250KHz -->4usec
T2CON.TMR2ON=0;
alfa=270;

while(1){

if(ready){

ready=0;
LCD_Out(1,1,"RPM=");
Ngiri=(60*1000000)/MaxPulse ;
WordToStr(Ngiri, tnum6);
LCD_Out(1,5,tnum6); //visualizza Numero giri al minuto
IntToStr(alfa, tnum7);
LCD_Out(2,1,"AN=");
LCD_Out(2,4,tnum7);
LCD_chr(2,10,223);
LCD_Out(2,12,"Rit");
}

}

}



Più piccola è la mente più grande è la presunzione.
tatopower




una ogni 10 livelli una ogni 10 livelli


postato il:
25.02.2022, alle ore 14:59
Grazie, mi studio il codice che mi hai inviato e prodo ad adattarlo alle mie esigenze.
primok




una ogni 100 livelli
una ogni 10 livelli


postato il:
25.02.2022, alle ore 15:52
tatopower:
Grazie, mi studio il codice che mi hai inviato e prodo ad adattarlo alle mie esigenze.


Alcune indicazioni.

Su Rb0 deve essere collegato un sensore ottico in corrispondenza della tacca.

Se il numero di giri sono 3000 rpm vuol dire che il disco sta ruotando a 50Hz.

Sul primo fronte (impulso del sensore in corrispondenza della tacca) viene azzerato il timer1 e viene abilitato il conteggio.

Il clock è quello interno al micro 16MHz/4 diviso per 4 dal prescaler.

Quindi il timer 1 avanzerà ogni 1 usec. Dopo un giro completo verranno contati 20000 impulsi che ho chiamato MaxPulse.

Una volta noto il numero degli impulsi massimi, viene calcolato il valore da caricare nel timer2 e che ho chiamato LOADPR2. Quest'ultimo timer si incrementa ogn 4 usec.

Per avere ad esempio un interrupt dopo 5msec(90°) con un incremento ogni 4usec

dovrei caricare 1250 nel registro PR2 (4usec*1250=5msec).

Però il registro del pic16f628A è di 8 bit, quindi dovrò usare una variabile che ho chiamato INC e assegnare a questa un valore opportuno.

Se carico PR2=250 avrò il primo interrupt dopo 4usec*250=1msec . Per arrivare a 5 msec devo assegnare a INC il valore 5.

Con questi 2 valori PR2=250 e INC=5 avrò il primo interrupt dopo 5 msec.

Ovviamente il timer 2 lo sincronizzerò col il primo fronte di salita del segnale a 50Hz.

La durata dell'impulso la deciderò dopo che sono passati i 5 msec e in questo esempio è pari a 1 msec.

Al secondo interrupt che arriverà prima del secondo fronte del segnale dei 50 Hz, spegnerò il timer 2 e lo riaccenderò di nuovo al primo fronte e così via.

La formula LoadPr= ((MaxPulse/kappa)*alfa) deriva da una semplice proporzione:

20000*10^-6/360°=(4*10^-6 * LOADPR2)/alfa.

La precisione del ritardo/anticipo dipende dall'approssimazione del rapporto, dalla risoluzione con la quale si incrementa il contatore (Timer2), in questo caso 4 usec, e dalla velocità del micro.

Per eseguire le istruzioni il micro perde del tempo. Con un timer 2 a 16 bit si possono ottenere risultati migliori.

Se avrò tempo pubblicherò un esempio completo sul mio sito.

Saluti Primok







Più piccola è la mente più grande è la presunzione.
tatopower




una ogni 10 livelli una ogni 10 livelli


postato il:
15.03.2022, alle ore 19:06
Grazie Primok, ho provato il codice, ho trovato alcune problematiche con il timer a sfasamenti elevati. Faccio alcune prove e poi ti contatto.
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