Úprava programu "nf generátor" pro ATTiny25-20

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Zpráva
Autor
Uživatelský avatar
FHonza
Příspěvky: 1443
Registrován: 20 lis 2012, 01:00
Bydliště: Praha

#16 Příspěvek od FHonza »

No právě, to je to co sem se snažil dopočítat. Jakmile navíc "compare" bude menší než počet taktů potřebných pro vykonání přerušení od časovače (72 "nopů" + kód vygenerovaný překladačem), tak se to začne chovat úplně jinak.

A další věc je ošetření "debouncingu" tlačítek. Jestli není ošetřen zákmit hardwarově, tak je to taky špatně.

Poslední verzi nemáš ?

Uživatelský avatar
jade
Příspěvky: 962
Registrován: 28 pro 2004, 01:00
Bydliště: Brno

#17 Příspěvek od jade »

Mám tu ještě jednu verzi, ale ta je označena jako starší.

Kód: Vybrat vše

/*
 *
 * Created: 9.8.2012 20:02:00
 *  Author: Michal
 */ 


#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>

#define F_CPU 3800000UL
//	cas = x * (1 / 3.8E+6)
//	frekvence= 3.8E+6 / x

//	x = 3.8E+6 * pozadovany cas
//	x = 3.8E+6 / pozadovana frekvence (pul periody!!!!!)
char compare = 0x80;
int i;

int main(void)
{
	
	PORTB |= (0<<DDB2) | (1<<DDB1) | (1<<DDB0);	//nastaveni pull up
	DDRB |= (1<<DDB2) | (0<<DDB1) | (0<<DDB0);	//smerovz registr
	asm( "NOP");
	PCMSK |= (1<<PCINT1) | (1<<PCINT0);			//tlacitka povoleni pcint 1,0
	GIMSK |= (1<<PCIE);							//povoleni pcint
	asm("NOP");
	TIMSK |= (1<<TOIE0);						//citac  preruseni pri preteceni
	TCCR0B |= (0<<CS02) | (0<<CS01) | (1<<CS00);//preddelicka 0
	GTCCR |= (1<<TSM);							//zastaveni
	GTCCR |= (1<<PSR0);
	OCR0A = compare;							//zapsani komparacni hodnoty
	TCNT0 = 0x00;								//citac=0

	GTCCR &= 01111110;							//zapnuti
	sei();								//vsechna preruseni
	
    while(1)
    {}											//SMYCKA!!!!!!
      
	 
	  
	return(1);
}

ISR (PCINT0_vect)
{
	for (i=0;i<10;i++)
	{
		asm( "NOP");
	}
	
	if bit_is_clear(PINB,0) compare--;
	if bit_is_clear(PINB,1) compare++;
	
}



ISR (TIMER0_COMPA_vect)
{
	for (i=0;i<10;i++)
	{
		asm( "NOP");
	}
	PORTB ^= (1<<PORTB2);		//zmena vystupu
	GTCCR |= (1<<TSM);			//vypnuti
	GTCCR |= (1<<PSR0);
	OCR0A = compare;			//zapsani komparacni hodnoty
	TCNT0 = 0x00;				//citac=0
	GTCCR &= 10000000;			//zapnuti

}
Ta poslední se nejspíš nedochovala :?

Uživatelský avatar
FHonza
Příspěvky: 1443
Registrován: 20 lis 2012, 01:00
Bydliště: Praha

#18 Příspěvek od FHonza »

V principu se to chce vykašlat na dolaďování frekvence vkládáním instrukce "nop". Jestli ještě nemáš hotovou desku, tak by asi bylo nejlepší jako výstup použít PB0. Timer0 nastavit do režimu CTC a povolit "toggle" na vývodu OC0 (PB0). Pak jenom nastavit předděličku pro Timer0 a spočítat OCR0A. V případě že se musí použít PB2, tak Timer0 nastavit do režimu Overflow, spočítat počáteční hodnotu TCNT0. A v každém přerušení opět nastavit TCNT0 a překlopit PB2. Jestli dobře počítám, tak to vychazí pro uvedený krystal přesně: předdělička na 8, TCNT0 na 191. Frekvence přerušení je pak přesně 7560Hz. A hlavně přesnost bude dána jenom přesností krystalu.

Edit: druhá možnost bude lepší pro generování toho přerušení tónu. Do timeru pak stačí dodělat počítadlo a při dosažení zvoleného počtu "tiků" odstavit na daný počet "tiků" generování signálu. Jakmile počítadlo dosáhne hodnoty 756, tak přestat generovat signál. Po dosažení 945 začít generovat a počítadlo vynulovat.

Uživatelský avatar
jade
Příspěvky: 962
Registrován: 28 pro 2004, 01:00
Bydliště: Brno

#19 Příspěvek od jade »

Díky, sám to ale dohromady nedám. Pokud by se někdo uvolil, i nějakou tu kačku bych pustil.
V podstatě můžu výstup upravit, mám tam vyvedený ISP konektor, z něj můžu brát signál odkudkoliv.

Uživatelský avatar
FHonza
Příspěvky: 1443
Registrován: 20 lis 2012, 01:00
Bydliště: Praha

#20 Příspěvek od FHonza »

Když vydržíš do úterý, tak ti sem dám kód. Teď už jsem na odchodu a celé Velikonoce nezapnu počítač. Jenom ještě napiš jestli se má řešit debouncing tlačítek nebo jestli je vyřešen hardwarově.

Uživatelský avatar
jade
Příspěvky: 962
Registrován: 28 pro 2004, 01:00
Bydliště: Brno

#21 Příspěvek od jade »

Rád počkám! Kontakty spínačů jsou ošetřeny kondenzátory 100n, docela to funguje.
Díky!

Uživatelský avatar
AB1
Příspěvky: 312
Registrován: 23 lis 2009, 01:00

#22 Příspěvek od AB1 »

Ahoj,

Dolaďování pomocí změny OCR0A moc jemné není,
jak je vidět v kódu.

Jestli stačí pevná frekvence 3710,9 Hz tak zkus tento kód. (přikládám i hex)
Nemám tiny25, takže jsem ho nemohl vyzkoučet v reálu.

Kód: Vybrat vše

// Attiny25, AvrStudio4
// Na pinu PB0 je modulovaný signál 3711 Hz 

#define F_CPU 3800000UL 
#include <avr/io.h> 
#include <util/delay.h> 


int main(void) 
{ 
   TCCR0A = (1<<COM0A0)|(1<<WGM01); // mode CTC, toggle on compare
   TCCR0B = (0<<CS01);                // prescaler 8 
   OCR0A  = 63;                      // 3710,9 Hz
// OCR0A  = 62;                      // 3769,8 Hz
// OCR0A  = 64;                      // 3653,8 Hz


   while(1) 
   {
      DDRB |=  (1<<0);      // modulace:
      _delay_ms(160);       // impuls 160 ms 
      DDRB &= ~(1<<0);  
      _delay_ms(40);        //  mezera 40 ms 
   }                                  
}
Přílohy
test00.zip
(266 bajtů) Staženo 141 x
Naposledy upravil(a) AB1 dne 19 dub 2017, 14:03, celkem upraveno 1 x.

Uživatelský avatar
FHonza
Příspěvky: 1443
Registrován: 20 lis 2012, 01:00
Bydliště: Praha

#23 Příspěvek od FHonza »

Kód: Vybrat vše

#define F_CPU 3932160

#include <avr/io.h>
#include <avr/interrupt.h>

volatile unsigned char setOCR0A = 65; // F_CPU / 2 / 8 / 3720 
volatile unsigned char counterBr = 0;
volatile unsigned char pulse = 0;

#define prescBr 93 // frekvence pulzu -> frekvence preruseni / 47 = 80Hz
#define pulsePercent 8 // delka pulzu v desitkach procentech

ISR(TIM0_COMPA_vect)
{
   if (pulse < pulsePercent)
   {
     PORTB ^= (1 << PINB2);
   }
   counterBr++;
   if (counterBr == prescBr)
   {
      counterBr = 0;            
      pulse++;
      if (pulse > 9)
      {
	 pulse = 0;
      }
   }
}

void setup()
{
   DDRB = (1 << PINB2);            
   TCCR0A = (1 << WGM01); // rezim CTC
   TCCR0B = (1 << CS01); // // preddelicka 8
   OCR0A = setOCR0A;
   TIMSK |= (1 << OCIE0A); // preruseni 
      
   sei();
}

int main()
 { 
   setup();
   while (1) ;   
   return 0;
 }

S krystalem 3,932160 MHz je generovana frekvence 3723,63 Hz, pauza je generovaná s frekvencí 8Hz, délka "pulzu" je 80%. Výstup je na PB2

Uživatelský avatar
jade
Příspěvky: 962
Registrován: 28 pro 2004, 01:00
Bydliště: Brno

#24 Příspěvek od jade »

Díky moc pánové!
AB1: Těch 10hz níž by snad tolik nevadilo, pokud by se dalo dolaďovat v krocích 10hz nebo jemněji, ale vyžadovalo by to pokaždé doladit oscilátor, aby ladil s výstupním LC. Jelikož maják většinou zanáší na místo nějaká ta mírně poučená osoba, která se zrovna na místě namane, bude lepší, když bude jakékoliv manipulace na místě co nejméně, tedy i dolaďování.
Děkuji i tak, použiji kód ke studijním účelům :) , určitě vyzkouším!

FHonza: Jdu kompilovat a zkoušet!
Jeden dotázek: Pokud bych chtěl změnit frekvenci přerušování, tedy těch 8hz, nerozhodím si tím ten nf signál?

Ještě jednou děkuji!

Uživatelský avatar
jade
Příspěvky: 962
Registrován: 28 pro 2004, 01:00
Bydliště: Brno

#25 Příspěvek od jade »

FHonza: Něco jsem asi neudělal dobře, dává to 478hz. Pojistky jsem dal jako "EXT Crystal Osc. Frequency 3-8Mhz, Start-up time PWRDWN/RESET 1K CK/14CK+4.1ms [cksel=1100 SUT=11]"
Parametry PWRDWN/RESET nevím, co vlastně nastavují, možná jsem to dal blbě.
EDIT: Ještě kouknu, jestli jsem omylem nezapnul CKDIV8
EDIT2: Tak už chodí! Moje chyba. Momentálně mi ale došla baterka v měřáku a osciloskopem jen zhruba něco kolem 3700hz ( cca 270us)

AB1: Tvůj jsem nerozchodil vůbec :([/b]
Naposledy upravil(a) jade dne 19 dub 2017, 23:55, celkem upraveno 3 x.

Uživatelský avatar
AB1
Příspěvky: 312
Registrován: 23 lis 2009, 01:00

#26 Příspěvek od AB1 »

Pardon, měl jsem tam chybu.

Napiš do řádku #define F_CPU skutečnou frekvenci krystalu
a měř na PB0.

Kód: Vybrat vše

// Attiny25, AvrStudio4
// Na pinu PB0 je modulovaný signál 3711 Hz 

#define F_CPU 3800000UL  // frekvence krystalu [Hz]
#include <avr/io.h> 
#include <util/delay.h> 



int main(void) 
{ 
   CLKPR = (1<<CLKPCE);     // disable CKDIV8
   CLKPR = 0;
   
   DDRB = (1<<0);           // PB0 výstup
   
   TCCR0A = (1<<COM0A0)|(1<<WGM01); // mode CTC, toggle on compare
   TCCR0B = (1<<CS01);              // prescaler 8 
   OCR0A  = F_CPU / 2 / 8 / 3720;                     // 3710,9 Hz


   while(1) 
   {
      DDRB |=  (1<<0);      // modulace:
      _delay_ms(160);       // impuls 160 ms 
      DDRB &= ~(1<<0);  
      _delay_ms(40);        //  mezera 40 ms 
   }                                  
}

Uživatelský avatar
jade
Příspěvky: 962
Registrován: 28 pro 2004, 01:00
Bydliště: Brno

#27 Příspěvek od jade »

Tohle se rozběhlo, ale na frekvenci cca 3400 ? hz (zhruba podle osciloskopu, v měřáku mi došly baterky)
Než PB0 by mi lépe vyhovoval PB2, ale s tím bych se i smířil :)
Jak je to tam s těmi tlačítky?
Děkuji !

Edit: Vypadá to, že jsem rozchodil program od Honzy, zítra změřím frekvenci a ozkouším tlačítka. Už je zase půlnoc. Ten čas běží, když člověk něco řeší...

Uživatelský avatar
AB1
Příspěvky: 312
Registrován: 23 lis 2009, 01:00

#28 Příspěvek od AB1 »

Tohle se rozběhlo, ale na frekvenci cca 3400 ? hz (zhruba podle osciloskopu, v měřáku mi došly baterky)
Potom asi nesouhlasí skutečný kmitočet krystalu s tím co jsi napsal do #define F_CPU.
Jak je to tam s těmi tlačítky?
Žádné tam nejsou.
Dolaďování tlačítkama o +- 10 Hz tady nepůjde.
K tomu by byl třeba jiný procesor, s 16-bitovým čítačem.
Tiny25 má jenom 8-bitové.

Uživatelský avatar
FHonza
Příspěvky: 1443
Registrován: 20 lis 2012, 01:00
Bydliště: Praha

#29 Příspěvek od FHonza »

jade píše: Jeden dotázek: Pokud bych chtěl změnit frekvenci přerušování, tedy těch 8hz, nerozhodím si tím ten nf signál?
Nerozhodíš, ta konstanta

Kód: Vybrat vše

#define prescBr 93
určuje, kolikrát proběhne přerušení čítače než se zvýší hodnota pro určení šířky "pulzu". Šířka "pulzu" je rozdělená na deset částí, v které části se má přestat generovat výstupní signál určuje konstanta

Kód: Vybrat vše

#define pulsePercent 8[-code].

Vlastně je to celé PWM s frekvencí 8Hz, střídou 80% modulovaná frekvencí 3723.63 Hz.

Uživatelský avatar
jade
Příspěvky: 962
Registrován: 28 pro 2004, 01:00
Bydliště: Brno

#30 Příspěvek od jade »

Nejprve musím poděkovat za odpovědi :)

FHonza: Frekvence sedí, musel jsem měřit záznějovou metodou, protože měřák nepobral to přerušování. Vyšlo mi 3724hz, což je paráda.
Tlačítka nereagují :( ... Opravdu by nešlo nějak dodělat aspoň nějaké doladění?

AB1: Nechci se hádat, ale původní program na začátku tématu dolaďování tlačítky obsahuje a funguje to na ATtiny 25. Je to dáno jiným způsobem tvorby signálu?
Děkuji!

Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“