Generátor tónov: Rozdiel medzi revíziami
Zo stránky SensorWiki
| Riadok 37: | Riadok 37: | ||
<tabs> | <tabs> | ||
<tab name="AVR C-code"><syntaxhighlight lang="c++" style="background: LightYellow;"> | <tab name="AVR C-code"><syntaxhighlight lang="c++" style="background: LightYellow;"> | ||
/* | |||
* projekt.c | |||
* | |||
* Created: 5. 6. 2026 10:56:31 | |||
* Author: Oliver Szabo | |||
*/ | |||
#include <avr/io.h> | #include <avr/io.h> | ||
#include <util/delay.h> | |||
// Bzuciak na D6 = PD6, breadboard | |||
#define BUZZER_DDR DDRD | |||
#define BUZZER_PORT PORTD | |||
#define BUZZER_PIN PD6 | |||
// Generuje ton na pine D6 softwarovo - toggluje pin rucne | |||
// freq_hz = frekvencia, duration_ms = ako dlho bzuci (napr. 50) | |||
void tone_sw(uint16_t freq_hz, uint16_t duration_ms) { | |||
if (freq_hz == 0) { | |||
BUZZER_PORT &= ~(1 << BUZZER_PIN); // Ticho | |||
_delay_ms(50); | |||
return; | |||
} | |||
// Polovicna perioda v mikrosekundach | |||
// T = 1/f, polovica = 500000/f [us] | |||
uint16_t half_period_us = 500000UL / freq_hz; | |||
// Pocet toggleov za duration_ms | |||
// Jeden toggle = half_period_us mikrosekund | |||
// Celkovy cas = duration_ms * 1000 us | |||
uint16_t toggles = (uint32_t)duration_ms * 1000 / half_period_us; | |||
for (uint16_t i = 0; i < toggles; i++) { | |||
BUZZER_PORT ^= (1 << BUZZER_PIN); // Toggle pin | |||
// Cakaj half_period_us mikrosekund | |||
// _delay_us nevie premennu, musime pouzit loop | |||
uint16_t t = half_period_us; | |||
while (t--) { | |||
__asm__("nop"); // 1 nop = 1 cyklus = 62.5ns pri 16MHz | |||
__asm__("nop"); | |||
__asm__("nop"); | |||
__asm__("nop"); | |||
__asm__("nop"); | |||
__asm__("nop"); | |||
__asm__("nop"); | |||
__asm__("nop"); | |||
__asm__("nop"); | |||
__asm__("nop"); | |||
__asm__("nop"); | |||
__asm__("nop"); | |||
__asm__("nop"); | |||
__asm__("nop"); | |||
__asm__("nop"); | |||
__asm__("nop"); // 16 nop = ~1 mikrosekunda pri 16MHz | |||
} | |||
} | |||
} | |||
// Precita ADC hodnotu z kanala, vracia 0..1023 | |||
uint16_t read_adc(uint8_t channel) { | |||
ADMUX = (1 << REFS0) | (channel & 0x07); | |||
ADCSRA = (1 << ADEN) | (1 << ADSC) | |||
| (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); | |||
while (ADCSRA & (1 << ADSC)); | |||
return ADC; | |||
} | } | ||
int main(void) { | |||
BUZZER_DDR |= (1 << BUZZER_PIN); // D6 ako vystup | |||
while (1) { | |||
uint16_t adc = read_adc(4); // Citaj A4 - potenciometer | |||
if (adc < 10) { | |||
tone_sw(0, 50); // Ticho | |||
} else { | |||
// ADC 0..1023 -> 100..2000 Hz | |||
uint16_t freq = 100 + (uint32_t)adc * 1900 / 1023; | |||
tone_sw(freq, 50); // Bzuci 50ms na danej frekvencii | |||
} | |||
// Ziadny _delay_ms tu - tone_sw uz trva 50ms sama | |||
} | |||
} | |||
</syntaxhighlight ></tab> | </syntaxhighlight ></tab> | ||
<tab name="filename.h"><syntaxhighlight lang="c++" style="background: LightYellow;"> | <tab name="filename.h"><syntaxhighlight lang="c++" style="background: LightYellow;"> | ||
Verzia z 19:15, 6. jún 2026
Záverečný projekt predmetu MIPS / LS2026 - Oliver Szabo
Zadanie
Cieľom projektu bolo vytvoriť generátor tónov, ktorého frekvencia je riadená potenciometrom. Hodnota získaná z analógového vstupu mikrokontroléra pomocou A/D prevodníka sa spracuje programom a následne sa použije na generovanie zvukového signálu na bzučiaku.
Používateľ môže otáčaním potenciometra plynule meniť frekvenciu generovaného tónu.

Literatúra:
Analýza a opis riešenia
Opíšte sem čo a ako ste spravili, ak treba, doplňte obrázkami... Podrobne opíšte použité komponenty (okrem základnej dosky s ATmega328P procesorom), pridajte linky na datasheety alebo opis obvodu.

Nezabudnite doplniť schému zapojenia! V texte by ste mali opísať základné veci zo zapojenia, samotná schéma nie je dostačujúci opis.

Algoritmus a program
Algoritmus programu využíva toto a toto, základné funkcie sú takéto a voláma ich tuto... Výpis kódu je nižšie...
/*
* projekt.c
*
* Created: 5. 6. 2026 10:56:31
* Author: Oliver Szabo
*/
#include <avr/io.h>
#include <util/delay.h>
// Bzuciak na D6 = PD6, breadboard
#define BUZZER_DDR DDRD
#define BUZZER_PORT PORTD
#define BUZZER_PIN PD6
// Generuje ton na pine D6 softwarovo - toggluje pin rucne
// freq_hz = frekvencia, duration_ms = ako dlho bzuci (napr. 50)
void tone_sw(uint16_t freq_hz, uint16_t duration_ms) {
if (freq_hz == 0) {
BUZZER_PORT &= ~(1 << BUZZER_PIN); // Ticho
_delay_ms(50);
return;
}
// Polovicna perioda v mikrosekundach
// T = 1/f, polovica = 500000/f [us]
uint16_t half_period_us = 500000UL / freq_hz;
// Pocet toggleov za duration_ms
// Jeden toggle = half_period_us mikrosekund
// Celkovy cas = duration_ms * 1000 us
uint16_t toggles = (uint32_t)duration_ms * 1000 / half_period_us;
for (uint16_t i = 0; i < toggles; i++) {
BUZZER_PORT ^= (1 << BUZZER_PIN); // Toggle pin
// Cakaj half_period_us mikrosekund
// _delay_us nevie premennu, musime pouzit loop
uint16_t t = half_period_us;
while (t--) {
__asm__("nop"); // 1 nop = 1 cyklus = 62.5ns pri 16MHz
__asm__("nop");
__asm__("nop");
__asm__("nop");
__asm__("nop");
__asm__("nop");
__asm__("nop");
__asm__("nop");
__asm__("nop");
__asm__("nop");
__asm__("nop");
__asm__("nop");
__asm__("nop");
__asm__("nop");
__asm__("nop");
__asm__("nop"); // 16 nop = ~1 mikrosekunda pri 16MHz
}
}
}
// Precita ADC hodnotu z kanala, vracia 0..1023
uint16_t read_adc(uint8_t channel) {
ADMUX = (1 << REFS0) | (channel & 0x07);
ADCSRA = (1 << ADEN) | (1 << ADSC)
| (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
while (ADCSRA & (1 << ADSC));
return ADC;
}
int main(void) {
BUZZER_DDR |= (1 << BUZZER_PIN); // D6 ako vystup
while (1) {
uint16_t adc = read_adc(4); // Citaj A4 - potenciometer
if (adc < 10) {
tone_sw(0, 50); // Ticho
} else {
// ADC 0..1023 -> 100..2000 Hz
uint16_t freq = 100 + (uint32_t)adc * 1900 / 1023;
tone_sw(freq, 50); // Bzuci 50ms na danej frekvencii
}
// Ziadny _delay_ms tu - tone_sw uz trva 50ms sama
}
}
#include <avr/io.h>
void adc_init(void); // A/D converter initialization
unsigned int adc_read(char a_pin);
Pridajte sem aj zbalený kompletný projekt, napríklad takto (použite jednoznačné pomenovanie, nemôžeme mať na serveri 10x zdrojaky.zip:
Zdrojový kód: zdrojaky.zip
Overenie
Ako ste overili funkciu, napríklad... Na používanie našej aplikácie stačia dve tlačítka a postup používania je opísaný v sekcii popis riešenia. Na konci uvádzame fotku hotového zariadenia.

Video:
Čo by som urobil inak
Zamyslite sa spätne nad problémom, ktorý ste riešili a napíšte, čo sa vám nepodarilo a nabudúce by ste spravili inak.
Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.