Úprava programu "nf generátor" pro ATTiny25-20
Moderátor: Moderátoři
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áš ?
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
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.
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 232 x
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
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
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!
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
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
}
}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ší...
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é.
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 93urč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
[code]#define pulsePercent 8[-code].
Vlastně je to celé PWM s frekvencí 8Hz, střídou 80% modulovaná frekvencí 3723.63 Hz.
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í
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!