Časovač s ATmega16

C,C++,C#

Moderátori: psichac, Moderátori

Používateľov profilový obrázok
jirka.jirka.
Ultimate člen
Ultimate člen
Príspevky: 1537
Dátum registrácie: 17 Okt 2008, 00:00
Bydlisko: Uherské Hradiště
Kontaktovať používateľa:

Časovač s ATmega16

Príspevok od používateľa jirka.jirka. » 21 Apr 2013, 17:03

Ahoj.
Dělám si jednoduchou osvitku s možností přepnutí velikosti formátu. Nic neobvyklého. :-)
Ale mám menší problém, že když se ve svém programu dostanu do smyčku, kde nastavuji hodnotu minut, tak mi na displeji projedou nesmyslné znaky. (Vše se ale ustálí a program jede). Ale vadí mi to tam. Nesetkal se někdo s takovým problémem??

Používám ATmegu16, takt 16MHz. LCD-2x16 znaků. K nastavení používám rotační enkodér.

Funkce pro nastavení času je zde:

Kód: Vybrať všetko

void nastaveni_casu(void)
{
		//hodiny
		if (flag==2){
			lcd_gotoxy(0,0);
			lcd_puts("nastaveni hodin ");

			hodiny=encoder;
				if (hodiny>=24)
					{hodiny=0;
					encoder=0;
					}
			sprintf(buffer,"    %02d:%02d.%02d    ",hodiny,minuty,sekundy);
			lcd_gotoxy(0,1);
			lcd_puts(buffer);
		}
		//minuty
		if (flag==3){
			lcd_gotoxy(0,0);
			lcd_puts("nastaveni minut ");

			minuty=encoder;
					if (minuty>=60)
						{minuty=0;
						encoder=0;
						}
			sprintf(buffer,"    %02d:%02d.%02d    ",hodiny,minuty,sekundy);
			lcd_gotoxy(0,1);
			lcd_puts(buffer);
		}
		//sekundy
		if (flag==4){
			lcd_gotoxy(0,0);
			lcd_puts("nastaveni sekund");

			sekundy=encoder;
				if (sekundy>=60)
					{sekundy=0;
					encoder=0;
					}
			sprintf(buffer,"    %02d:%02d.%02d    ",hodiny,minuty,sekundy);
			lcd_gotoxy(0,1);
			lcd_puts(buffer);

			//ulozani hodnoty hodiny,minuty, sekundy
				pom_h=hodiny;
				pom_m=minuty;
				pom_s=sekundy;
			cas=( 3600 * (long)hodiny) + ( 60 * (long)minuty) + (long)sekundy;	//prevod hodnot hod, min, sek na CAS
		}
}
Kde FLAG je proměnná, kterou inkrementuji, při stisku tlačítka (v přerušení). Více uvidíte na videu.
Dík za jakoukoli radu
0

Používateľov profilový obrázok
jirka.jirka.
Ultimate člen
Ultimate člen
Príspevky: 1537
Dátum registrácie: 17 Okt 2008, 00:00
Bydlisko: Uherské Hradiště
Kontaktovať používateľa:

Re: Časovač s ATmega16

Príspevok od používateľa jirka.jirka. » 21 Apr 2013, 18:46

Tak jsem tuto fci ještě trošku zjednodušil, ale pořád nic.

Kód: Vybrať všetko

/****************************************************
***************fce pro nastaveni casu osvitu*********
****************************************************/
void nastaveni_casu(void)
{
		//hodiny
		if (flag==2){
			lcd_gotoxy(0,0);
			lcd_puts("nastaveni hodin ");
				//nastaveni hodin probiha v preruseni
			lcd_gotoxy(0,1);
			sprintf(buffer,"    %02d:%02d.%02d    ",hodiny,minuty,sekundy);
			lcd_puts(buffer);
		}
		//minuty
		if (flag==3){
			lcd_gotoxy(0,0);
			lcd_puts("nastaveni minut ");
				//nastaveni minut probiha v preruseni
			lcd_gotoxy(0,1);
			sprintf(buffer,"    %02d:%02d.%02d    ",hodiny,minuty,sekundy);
			lcd_puts(buffer);
		}
		//sekundy
		if (flag==4){
			lcd_gotoxy(0,0);
			lcd_puts("nastaveni sekund");
				//nastaveni sekund probiha v preruseni
			lcd_gotoxy(0,1);
			sprintf(buffer,"    %02d:%02d.%02d    ",hodiny,minuty,sekundy);
			lcd_puts(buffer);

			//ulozani hodnoty hodiny,minuty, sekundy
				pom_h=hodiny;
				pom_m=minuty;
				pom_s=sekundy;
			cas=( 3600 * (long)hodiny) + ( 60 * (long)minuty) + (long)sekundy;	//prevod hodnot hod, min, sek na CAS
		}
}
EDIT: a zjistil jsem, že mi to dělá pouze v této funkci.
0

Používateľov profilový obrázok
jirka.jirka.
Ultimate člen
Ultimate člen
Príspevky: 1537
Dátum registrácie: 17 Okt 2008, 00:00
Bydlisko: Uherské Hradiště
Kontaktovať používateľa:

Re: Časovač s ATmega16

Príspevok od používateľa jirka.jirka. » 21 Apr 2013, 23:41

Tak do toho čučím, ale chybu tam nevidím. Třeba když na to jukne někdo jiný, hned ji uvidí.

pro jistotu ještě jednou popis problému:
Při zadávání hodnoty hodiny,minuty,sekundy se mi na displeji zobrazuji chybne znaky. Vždy po chvilce odezní, ale obtěžuje to a nevypadá to dobře. A nový postřeh je ten, že tyto znaky se zobrazují vždy po stisku tlačítka, ale pouze v té funkci nastaveni_casu().

Kód: Vybrať všetko

#include <stdlib.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <util/delay.h>  

#include "lcd.h"

//DEsky
#define 	MALA_DPS		0
#define 	VETSI_DPS		1
#define		NEJVETSI_DPS	6
#define		OBOUSTRANA		7
#define		VIKO			6
#define		TLACITKO		3

//prednastaveni casu
volatile unsigned char  hodiny=0; 
volatile unsigned char  minuty=2; 
volatile unsigned char  sekundy=30;

//globalni a jiné proměnné
unsigned char temp;
char buffer[16];
int jednou=0;	//promenna pro zobrazeni upozorneni na nezavrene viko
volatile char encoder=0;		//hodnota enkoderu
volatile char rozmer_dps=0;
volatile char oboustr=0;

volatile unsigned char hod=0, min=0, sek=0, pom_h=0, pom_m=0, pom_s=0;

//============================================================================
//==============================INICIALIZACE==================================
//============================================================================
void inicializace()
{
	hod=hodiny; min=minuty; sek=sekundy;

	//nastaveni vstupnich pinu portu D
	DDRD &= ~(1 << PD0);	//enkoder	
	DDRD &= ~(1 << PD2);	//enkoder
	DDRD &= ~(1 << TLACITKO);	
	DDRD &= ~(1 << VIKO);
		//povoleni vnitřních pull-up odporu
	PORTD |= (1 << PD0);
	PORTD |= (1 << PD2);
	PORTD |= (1 << TLACITKO);
	PORTD |= (1 << VIKO);
		//zakazani vnitrnich pull-up odporu
	PORTC &= ~(1 << MALA_DPS);
	PORTC &= ~(1 << VETSI_DPS);	
	PORTC &= ~(1 << NEJVETSI_DPS);
	PORTC &= ~(1 << OBOUSTRANA);
		//nastaveni vystupnich pinu portu D
	DDRC |= (1 << MALA_DPS) | (1 << VETSI_DPS) | (1 << NEJVETSI_DPS) | (1 << OBOUSTRANA);
		//nastaveni PULL-UP odporu
	//PORTC |= (1 << MALA_DPS) | (1 << VETSI_DPS) | (1 << NEJVETSI_DPS) | (1 << OBOUSTRANA);
		//nastaveni preruseni od enkoderu
	MCUCR|=(1<<ISC01)|(1<<ISC00);   //Nastaveni INT0 na "rising" signal na pinu PD2
	GICR |=(1<<INT0 );				//povoleni preruseni
		//nastaveni preruseni od citace casovace 1 (cas)
	TCCR1B |= (1 << CS12); 			//preddelička 256 (16us)
	TIMSK  |= (1 << TOIE1); 		//prerušeni pri pretečení TCNT1    
		//nastaveni preruseni od citace casovace 0 (TLACITKO)
	TCCR0 |= (1<<WGM01)|(1<<CS02)|(1<<CS00); 	//CTC mode, preddelicka 1024 (64us)
	OCR0=255;						//cca 16,384ms pro kontrolu tlačítka
	TIMSK  |= (1 << OCIE0);
		//Nataveni displeje a prvni zobrazeni
	lcd_init(LCD_DISP_ON);            //Init LCD
	lcd_clrscr();

	//lcd_init(LCD_DISP_ON_CURSOR_BLINK);	//blikání kurzoru
	
	sei();    //povoleni přerušení
}

//============================================================================
//==================================PRERUSENI=================================
//============================================================================
volatile unsigned char 	tlac_prodleva,tlac_present;
volatile long int cas=0;
volatile unsigned int pomoc=5, pomoc_2=0;
volatile unsigned char flag=0, hotovo=0, zadej_cas=0;	//stisk tlacitka


ISR (INT0_vect)		//ratační enkoder (vlevo/vpravo) ======= PD0 & PD2
    {
		cli();
	if (((PIND&0x01)==0x00)&&(encoder<9999)) encoder=encoder+1;      //inc
	if (((PIND&0x01)==0x01)&&(encoder > 0 )) encoder=encoder-1;      //dec 
		sei();
    }

ISR (TIMER1_OVF_vect){ 
	TCNT1 = 3036;	//preteceni kazdou 1s
	if ( ((PIND & (1 << VIKO))==0) && (flag>=5)){
		if (cas!=0){cas--;} 
			else {
				void (*fn_ptr) (void) = (void (*) (void)) 0;	//reset MCU
				fn_ptr();
			}
	}
}

ISR(TIMER0_COMP_vect){ 		//přerušení od čítače časovače 0
	//ošetření tlačítka a jeho zákmitů
	  if((PIND & (1 << TLACITKO))){
	  	if(tlac_prodleva<20) tlac_prodleva++;
	    if(tlac_prodleva==19) tlac_present=1;  
      }
      else{	
	    if(tlac_prodleva==20){		//sem se dostane pouze pri stisku tlacitka
			if (flag==0){rozmer_dps=encoder;encoder=0;}	//ulozeni rozmeru DPS
			if (flag==1){oboustr=encoder;encoder=hodiny;}	//ulozeni oboustrane DPS		
			if (flag==2){encoder=minuty;}					//resetuje hodnotu v enkoderu
			if (flag==3){encoder=sekundy;}
			if (flag==4){encoder=0;}

			flag++;		//zvyseni pri stisku tlacitka
        }       
	 tlac_prodleva=0;
				
     }
			
			//nastaveni casu
		if (flag==2){	//nastaveni hodin
			hodiny=encoder;
			if (hodiny>=24){hodiny=0;encoder=0;}
		}
		if (flag==3){	//nastaveni minut
			minuty=encoder;
			if (minuty>=60){minuty=0;encoder=0;}
		}
		if (flag==4){	//nastaveni sekund
			sekundy=encoder;
			if (sekundy>=60){sekundy=0;encoder=0;}
		}
}

//============================================================================
//==================================FUNKCE====================================
//============================================================================


/****************************************************
****************fce pro zadani velikosti DPS*********
****************************************************/
void velikost_DPS(void)
{
	if (flag==0){	
	lcd_gotoxy(0,0);
	lcd_puts("  vyber rozmer  ");

		if(encoder==0){
			lcd_gotoxy(0,1);
			lcd_puts("1: 10x10 cm");
			}
		if(encoder==1){
			lcd_gotoxy(0,1);
			lcd_puts("2: 21x10 cm");
			}
		if(encoder==2){
			lcd_gotoxy(0,1);
			lcd_puts("3: 30x21 cm");
			}
		if(encoder>=3){
			encoder=0;
			}
	}
}
/****************************************************
****************fce pro vyber oboustrane DPS*********
****************************************************/
void oboustrana_DPS(void)
{
	if (flag==1){
	lcd_gotoxy(0,0);
	lcd_puts("oboustranou DPS?");
	
		if (encoder==0){
			lcd_gotoxy(0,1);
			lcd_puts("       NE       ");
			}
		if (encoder==1){
			lcd_gotoxy(0,1);
			lcd_puts("       ANO      ");
			}
		if(encoder>=2){
			encoder=0;
			}
	}
}
/****************************************************
***************fce pro nastaveni casu osvitu*********
****************************************************/
void nastaveni_casu(void)
{
		//hodiny
		if (flag==2){
			lcd_gotoxy(0,0);
			lcd_puts("nastaveni hodin ");
				//nastaveni sekund probiha v preruseni
			lcd_gotoxy(0,1);
			sprintf(buffer,"    %02d:%02d.%02d    ",hodiny,minuty,sekundy);
			lcd_puts(buffer);
		}
		//minuty
		if (flag==3){
			lcd_gotoxy(0,0);
			lcd_puts("nastaveni minut ");
				//nastaveni sekund probiha v preruseni
			lcd_gotoxy(0,1);
			sprintf(buffer,"    %02d:%02d.%02d    ",hodiny,minuty,sekundy);
			lcd_puts(buffer);
		}
			//sekundy
		if (flag==4){
			lcd_gotoxy(0,0);
			lcd_puts("nastaveni sekund");
				//nastaveni sekund probiha v preruseni
			lcd_gotoxy(0,1);
			sprintf(buffer,"    %02d:%02d.%02d    ",hodiny,minuty,sekundy);
			lcd_puts(buffer);

			//ulozani hodnoty hodiny,minuty, sekundy pro pozdejsi praci
				pom_h=hodiny;
				pom_m=minuty;
				pom_s=sekundy;
			//ulozani hodnoty hodiny,minuty, sekundy pro pozdejsi praci	
				hod=hodiny;
				min=minuty;
				sek=sekundy;

			cas=( 3600 * (long)hodiny) + ( 60 * (long)minuty) + (long)sekundy;	//prevod hodnot hod, min, sek na CAS
		}
}


/****************************************************
*****************fce pro rozsviceni DPS**************
****************************************************/
void rosviceni_DPS(void)
{
	if (oboustr==0){
		if (rozmer_dps==0){ 
			PORTC |= (1 << MALA_DPS);
			PORTC &= ~(1 << VETSI_DPS);	
			PORTC &= ~(1 << NEJVETSI_DPS);	
		}
	
		if (rozmer_dps==1){ 
			PORTC |= (1 << MALA_DPS);
			PORTC |= (1 << VETSI_DPS);	
			PORTC &= ~(1 << NEJVETSI_DPS);	
		}
	
		if (rozmer_dps==2){ 
			PORTC |= (1 << MALA_DPS);
			PORTC |= (1 << VETSI_DPS);	
			PORTC |= (1 << NEJVETSI_DPS);	
		}
	}
	else{
	PORTC |= (1 << OBOUSTRANA);
		if (rozmer_dps==0){ 
			PORTC |= (1 << MALA_DPS);
			PORTC &= ~(1 << VETSI_DPS);	
			PORTC &= ~(1 << NEJVETSI_DPS);	
		}

		if (rozmer_dps==1){ 
			PORTC |= (1 << MALA_DPS);
			PORTC |= (1 << VETSI_DPS);	
			PORTC &= ~(1 << NEJVETSI_DPS);	
		}
	
		if (rozmer_dps==2){ 
			PORTC |= (1 << MALA_DPS);
			PORTC |= (1 << VETSI_DPS);	
			PORTC |= (1 << NEJVETSI_DPS);	
		}
	}
}

/****************************************************
******************fce pro odpocitaveni***************
****************************************************/
void odpocet(void)
{
	if (flag==5){
			if ((PIND & (1 << VIKO))==0){
				rosviceni_DPS();
				sprintf(buffer,"nast:  %02d:%02d.%02d ",pom_h,pom_m,pom_s);
				lcd_gotoxy(0,0);
				lcd_puts(buffer);

				hod=cas/3600;
				min=(cas-((long)hod*3600))/60; 
				sek=cas%60;
				sprintf(buffer,"zbyva: %02d:%02d.%02d",hod,min,sek);	//zde
				lcd_gotoxy(0,1);
				lcd_puts(buffer);

				PORTC |= (1 << MALA_DPS);	//rozsviceni male DPSky
			}
			else{
				PORTC &= ~(1 << MALA_DPS);	//zhasnuti male DPSky	
				PORTC &= ~(1 << VETSI_DPS);	//zhasnuti male DPSky
				PORTC &= ~(1 << NEJVETSI_DPS);	//zhasnuti male DPSky
				PORTC &= ~(1 << OBOUSTRANA);	//zhasnuti male DPSky
				
				lcd_gotoxy(0,0);
				lcd_puts("  otevrene viko ");
				lcd_gotoxy(0,1);
				sprintf(buffer,"zbyva: %02d:%02d.%02d",hod,min,sek);	//zde;
				lcd_puts(buffer);
			}
		}
}
/****************************************************
*******************Restart MCU***********************
****************************************************/
void reboot(void) 
{
   void (*fn_ptr) (void) = (void (*) (void)) 0;
   fn_ptr();
}

/****************************************************
*************fce pro kontrolu tlacitka***************
****************************************************/
void kotrola(void)
{
	if (flag>=6){reboot();}
}
 
//============================================================================
//=====================================MAIN===================================
//============================================================================
int main(void)
{
    inicializace();           
	

while(1){	//nekonecnik
		
	//výběr velikosti DPSky
	velikost_DPS();
	
	//vyber oboustrane DPS
	oboustrana_DPS();

	//nastaveni casu osvitu
	nastaveni_casu();

	//nastaveni odpocitavani
	odpocet();

	//kontrola odpoctu (dokonceni osvitu)
	kotrola();

}//while
return 1;
}//main



0

stefanSK
Pokročilý člen
Pokročilý člen
Príspevky: 752
Dátum registrácie: 24 Jún 2010, 00:00
Bydlisko: Trnava
Vek: 68

Re: Časovač s ATmega16

Príspevok od používateľa stefanSK » 22 Apr 2013, 00:30

ešte som to celé nepreštudoval, ale premennú buffer[16] treba dimenzovať min. na buffer[17], pretože nemáš miesto pre koncový znak reťazca(16+1)
0
S.K.

Používateľov profilový obrázok
jirka.jirka.
Ultimate člen
Ultimate člen
Príspevky: 1537
Dátum registrácie: 17 Okt 2008, 00:00
Bydlisko: Uherské Hradiště
Kontaktovať používateľa:

Re: Časovač s ATmega16

Príspevok od používateľa jirka.jirka. » 22 Apr 2013, 00:44

uáááááááááááááá uáááááááááááááá. Mě z toho asi trefí šlak. :D
opavil jsem hodnotu buffer[16] na buffer[17] a už to vypadá lépe. Ještě to musím pořádně protestovat. No každopádně jsem si myslel, že to bude nějaká prkotina. Dík moc
0

Používateľov profilový obrázok
boraicho
Ultimate člen
Ultimate člen
Príspevky: 12406
Dátum registrácie: 03 Feb 2007, 00:00
Bydlisko: Prešov
Vek: 35
Kontaktovať používateľa:

Re: Časovač s ATmega16

Príspevok od používateľa boraicho » 22 Apr 2013, 07:08

aha to je logicke, mna by zaujimalo prečo si tam nedal na začiatku hned 20 a hotovo, stane sa dačo ked daš o par čisel viac?
0
"Aj nevinne vyzerajúca súčiastka, môže byť príčinou nefunkčnosti zariadenia a tou kondenzator 100% je"
3D REBEL II + PLA + PETG
CNC 1810 na DPS

Používateľov profilový obrázok
jirka.jirka.
Ultimate člen
Ultimate člen
Príspevky: 1537
Dátum registrácie: 17 Okt 2008, 00:00
Bydlisko: Uherské Hradiště
Kontaktovať používateľa:

Re: Časovač s ATmega16

Príspevok od používateľa jirka.jirka. » 22 Apr 2013, 08:31

No buffer[16] jsem dal proto, že jsem mymslel, že je to počítáno jako: 0,1,2,.....16. Ale jak vidno tak je to bráno 1,2,3....17.
0

Používateľov profilový obrázok
Andy99
Stály člen
Stály člen
Príspevky: 339
Dátum registrácie: 05 Mar 2008, 00:00
Bydlisko: BA
Vek: 35

Re: Časovač s ATmega16

Príspevok od používateľa Andy99 » 23 Apr 2013, 08:15

jirka.jirka. napísal:No buffer[16] jsem dal proto, že jsem mymslel, že je to počítáno jako: 0,1,2,.....16. Ale jak vidno tak je to bráno 1,2,3....17.
Ono to ide od 0, ale ak mas buffer[16], tak to ide 0, 1, 2... 15.
0

Napísať odpoveď
  • Podobné témy
    Odpovedí
    Zobrazení
    Posledný príspevok