Sari la conținut
ELFORUM - Forumul electronistilor

ceas cu pic


Vizitator H4cK3r

Postări Recomandate

Vizitator H4cK3r

Buna seara!

 

Pentru a invata cum functioneaza timer-ii si intreruperile, m-am decis sa-mi fac un ceas.

 

//microu config#pragma config PLLDIV = 5#pragma config CPUDIV = OSC1_PLL2#pragma config USBDIV = 2 #pragma config FOSC = INTOSCIO_EC#pragma config FCMEN = OFF#pragma config IESO = OFF#pragma config PWRT = OFF#pragma config BOR = OFF#pragma config BORV = 3#pragma config VREGEN = OFF#pragma config WDT = OFF#pragma config WDTPS = 32768#pragma config CCP2MX = ON#pragma config PBADEN = OFF#pragma config LPT1OSC = OFF#pragma config MCLRE = OFF#pragma config STVREN = ON#pragma config LVP = OFF#pragma config ICPRT = OFF#pragma config XINST = OFF#pragma config DEBUG = OFF#pragma config CP0 = OFF,CP1=OFF,CP2=OFF,CP3=OFF#pragma config CPB = OFF#pragma config CPD = OFF#pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF,WRT3 = OFF#pragma config WRTC = OFF#pragma config WRTB = OFF#pragma config WRTD = OFF#pragma config EBTR0 = OFF,EBTR1 = OFF,EBTR2 = OFF,EBTR3 = OFF#pragma config EBTRB = OFF//include#include<p18f4550.h>#include<timers.h>//cifreint catod[4]={14,13,11,7};int anod[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//prototipurivoid high_ISR(void);void interruptcode(void);void afisare(void);void time(void);////#pragma code HIGH_INTERRUPT_VECTOR = 0x000008	void high_ISR(void){	_asm goto interruptcode _endasm}#pragma code////////////////////////#pragma interrupt interruptcodevoid interruptcode(void){		if(PIR1bits.TMR2IF == 1){		//timer2 flag			PIR1bits.TMR2IF = 0;			afisare();				}		if(PIR2bits.TMR3IF == 1){		//timer3 flag			PIR2bits.TMR3IF = 0;			time();						}}#pragma code//varint i=0,count=0;int h=10,m=59;//mainvoid main(void){  	OSCCONbits.IRCF2 = 1; //seteaza ceasul la 1MHz  	OSCCONbits.IRCF1 = 0;  	OSCCONbits.IRCF0 = 0;	T2CONbits.TMR2ON = 0;	//opreste timer2	T3CONbits.TMR3ON = 0;	//opreste timer3	ADCON1bits.PCFG3 = 1;	//toate pin-urile digital	ADCON1bits.PCFG2 = 1;	ADCON1bits.PCFG1 = 1;	ADCON1bits.PCFG0 = 1;	RCONbits.IPEN = 1;	INTCONbits.GIE_GIEH = 1;		//timer2 config	T2CONbits.T2CKPS1 = 1;	//prescale 1:16	T2CONbits.T2CKPS0 = 1;	T2CONbits.T2OUTPS3 = 1;	//postscale 1:16	T2CONbits.T2OUTPS2 = 1;	T2CONbits.T2OUTPS1 = 1;	T2CONbits.T2OUTPS0 = 1;	PR2 = 2;  //registru periodic	PIE1bits.TMR2IE = 1;	//enable timer2	IPR1bits.TMR2IP = 1;	//end timer2 config	//timer3 config	PIE2bits.TMR3IE = 1;	IPR2bits.TMR3IP = 1;	T3CONbits.T3CKPS1 = 1; //1:4 prescale	T3CONbits.T3CKPS0 = 0;	T3CONbits.TMR3CS = 0; //fol clock-ul intern	//end timer3 config	TRISB = 0;	TRISD = 0;	T2CONbits.TMR2ON = 1;	//porneste timers	T3CONbits.TMR3ON = 1;	while(1){}	//loop infinit	}//functiivoid time(void){	if(i < 60)i++;		else i = 0;	if(i == 60)	 {	if(m < 60)m++;			else m=0;		i=0;	 }	if(m==60)	{  if(h<12)h++;			else h=0;		m=0;	}}void afisare(void){	if(count%4==0){		PORTD = catod[count%4];		PORTB = anod[m%10];	}	if(count%4==1){		PORTD = catod[count%4];		PORTB = anod[(m/10)%10];	}	if(count%4==2){		PORTD = catod[count%4];		PORTB = anod[h%10];	}	if(count%4==3){		PORTD = catod[count%4];		PORTB = anod[(h/10)%10];	}	count++;}
inca n-am pus butoane pentru minut/ora, insa am o problema cu afisarea cifrelor.

 

Posted Image

 

arata ca si cand cifra din urma este dublata pe urmatorul ecran, si nu inteleg de ce.aveti vreo idee ce-ar putea cauza asta?sa fie oare de vina metoda nu prea inteligenta de multiplexing?(acum afiseaza 10:59)

 

 

btw, g-ul de la 9 si 5 lumineaza ok, insa la b6 am conectat si g-ul dar si PGC-ul de la pic.daca scot mufa de la pickit2, g-ul se aprinde ok.

Link spre comentariu
  • Răspunsuri 5
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • 10vid

    1

Zile populare

Top autori în acest subiect

Baga un delay de 5 ms in functia 'afisare', dupa cele patru if-uri, inainte de count++.Acele imagini "fantoma" apar din cauza ca e imposibil sa se schimbe in acelasi timp si catodul si anodul de la afisaj (eventual cu un uC de 16 biti). Astfel ca pentru scurt timp intre instructiunile: PORTD = catod[count%4]; PORTB = anod[.....];afisajul e gresit, iar intensitatea acelei parti e data de timpul mai sus amintit, raportat la timpul total al buclei, adica undeva la 1/10 din intensitatea totala, ceea ce e enorm.Cu un delay de 5 ms, acea parte va avea undeva pe la 1/1000 din intensitatea totala, la 4 MHz (dar in functie si de codul generat de compilator). Existenta, dar practic invizibila.O alta metoda, pentru a elimina complet problema, e stingerea catodului curent, incarcarea noilor anozi si aprinderea catodului urmator. Delay-ul ramane valabil insa si aici, pentru ca altfel s-ar introduce o diminuare inutila a luminozitatii, cauzata de acele stingeri.

Link spre comentariu
Vizitator H4cK3r

am facut urmatoarele modificari:

 

//microu config

#pragma config PLLDIV = 5

#pragma config CPUDIV = OSC1_PLL2

#pragma config USBDIV = 2

 

#pragma config FOSC = INTOSCIO_EC

#pragma config FCMEN = OFF

#pragma config IESO = OFF

#pragma config PWRT = OFF

#pragma config BOR = OFF

#pragma config BORV = 3

#pragma config VREGEN = OFF

#pragma config WDT = OFF

#pragma config WDTPS = 32768

#pragma config CCP2MX = ON

#pragma config PBADEN = OFF

#pragma config LPT1OSC = OFF

#pragma config MCLRE = OFF

#pragma config STVREN = ON

#pragma config LVP = OFF

#pragma config ICPRT = OFF

#pragma config XINST = OFF

#pragma config DEBUG = OFF

#pragma config CP0 = OFF,CP1=OFF,CP2=OFF,CP3=OFF

#pragma config CPB = OFF

#pragma config CPD = OFF

#pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF,WRT3 = OFF

#pragma config WRTC = OFF

#pragma config WRTB = OFF

#pragma config WRTD = OFF

#pragma config EBTR0 = OFF,EBTR1 = OFF,EBTR2 = OFF,EBTR3 = OFF

#pragma config EBTRB = OFF

//include

#include

#include

 

//cifre

int catod[4]={14,13,11,7};

int anod[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

//prototipuri

void high_ISR(void);

void interruptcode(void);

void afisare(void);

void time(void);

////

#pragma code HIGH_INTERRUPT_VECTOR = 0x000008

void high_ISR(void){

 

_asm goto interruptcode _endasm

 

}

#pragma code

 

////////////////////////

#pragma interrupt interruptcode

void interruptcode(void){

 

if(PIR1bits.TMR2IF == 1){ //timer2 flag

PIR1bits.TMR2IF = 0;

afisare();

 

}

 

if(INTCONbits.TMR0IF == 1){ //timer0 flag

INTCONbits.TMR0IF = 0;

time();

 

 

}

 

 

}

#pragma code

//var

int i=0,count=0;

int h=0,m=50;

 

//main

void main(void){

OSCCONbits.IRCF2 = 1; //seteaza ceasul la 8MHz

OSCCONbits.IRCF1 = 1;

OSCCONbits.IRCF0 = 1;

 

T2CONbits.TMR2ON = 0; //opreste timer2

T0CONbits.TMR0ON = 0; //opreste timer0

 

ADCON1bits.PCFG3 = 1; //toate pin-urile digital

ADCON1bits.PCFG2 = 1;

ADCON1bits.PCFG1 = 1;

ADCON1bits.PCFG0 = 1;

 

RCONbits.IPEN = 1;

INTCONbits.GIE_GIEH = 1;

 

//timer2 config

T2CONbits.T2CKPS1 = 1; //prescale 1:16

T2CONbits.T2CKPS0 = 1;

 

T2CONbits.T2OUTPS3 = 1; //postscale 1:16

T2CONbits.T2OUTPS2 = 1;

T2CONbits.T2OUTPS1 = 1;

T2CONbits.T2OUTPS0 = 1;

 

PR2 = 0; //registru periodic

 

PIE1bits.TMR2IE = 1; //enable timer2

IPR1bits.TMR2IP = 1;

//end timer2 config

 

//timer0 config

 

INTCONbits.TMR0IE = 1;

INTCON2bits.TMR0IP = 1;

T0CONbits.T08BIT = 0; //16 bits

 

T0CONbits.T0CS = 0; //fol clock-ul intern

T0CONbits.PSA = 0; //fol prescale

 

T0CONbits.T0PS2 = 1;

T0CONbits.T0PS1 = 0;

T0CONbits.T0PS0 = 0;

 

//end timer0 config

 

TRISB = 0;

TRISD = 0;

 

T2CONbits.TMR2ON = 1; //porneste timers

T0CONbits.TMR0ON = 1;

while(1){} //loop infinit

 

}

 

//functii

 

void time(void){

 

if(i < 60)i++;

else i = 0;

if(i == 60)

{ if(m < 60)m++;

else m=0;

i=0;

}

if(m==60)

{ if(h<12)h++;

else h=0;

 

m=0;

}

}

void afisare(void){

 

if(count%4==0){

PORTD = catod[count%4];

PORTB = anod[m%10];

}

if(count%4==1){

PORTD = catod[count%4];

PORTB = anod[(m/10)%10];

}

if(count%4==2){

PORTD = catod[count%4];

PORTB = anod[h%10];

}

if(count%4==3){

PORTD = catod[count%4];

PORTB = anod[(h/10)%10];

}

Delay100TCYx(50);

 

PORTD = 0;

PORTB = 0;

 

count++;

 

}

 

insa acum, dupa ce trec 2 minute, ramane aprins doar primul display, celelalte se inchid de tot.ai putea te rog sa-mi explici de ce?

Link spre comentariu
Vizitator H4cK3r

oricum, mersi mult 10vid pentru ajutor, nu stiu cum faci dar tot timpul ai o explicatie pentru orice :)).cu modificarile facute, display-ul este luminos si afiseaza cum trebuie, mai trebuie insa sa rezolv bug-ul cu disparitia cifrelor dupa 2 minute.

Link spre comentariu
Vizitator H4cK3r

am depistat problema.am uitat ca acel count e un int si are si el o valoare maxima, care dupa doua minute trecea de valoarea aia si avea niste valori aiurea(negative cel probabil)

 

if(count<4)count++;		else count=0;
codul de sus a remediat problema.
Link spre comentariu
  • 3 săptămâni mai târziu...

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări