Stránka 2 z 3
Napsal: 13 dub 2017, 14:29
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áš ?
Napsal: 13 dub 2017, 14:35
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
![Confused :?](./images/smilies/icon_confused.gif)
Napsal: 13 dub 2017, 15:32
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.
Napsal: 13 dub 2017, 15:42
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.
Napsal: 13 dub 2017, 15:45
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ě.
Napsal: 13 dub 2017, 20:02
od jade
Rád počkám! Kontakty spínačů jsou ošetřeny kondenzátory 100n, docela to funguje.
Díky!
Napsal: 19 dub 2017, 09:03
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
}
}
Napsal: 19 dub 2017, 10:56
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
Napsal: 19 dub 2017, 19:09
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
![Smile :)](./images/smilies/icon_smile.gif)
, 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!
Napsal: 19 dub 2017, 20:20
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
![Sad :(](./images/smilies/icon_sad.gif)
[/b]
Napsal: 19 dub 2017, 22:17
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
}
}
Napsal: 19 dub 2017, 23:26
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ší...
Napsal: 20 dub 2017, 07:49
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é.
Napsal: 20 dub 2017, 11:11
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
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.
Napsal: 20 dub 2017, 18:25
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í
![Sad :(](./images/smilies/icon_sad.gif)
... 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!