Skocz do zawartości

Przycisk włączający dźwięk


Pomocna odpowiedź

Napisano

Witam.

Siedzę już nad tym 3 godziny i nadal nie mogę tego zrobić. Przeczytałem już cały kurs, szukałem odpowiedzi na to banalne pytanie na forum i nic.

Otóż mam przycisk podłączony do PC0 i głośnik do portu PD0. I chciałbym żęby po włączeniu przycisku obojętnie jaki dźwięk wydobywał się z głośnika. (wszystko jest podłączone do ATmega8 )

próbowałem przerobić kod z kursu (ten z melodią koziołka) dodając

if(!(PINC & 0x01))

ale nic to nie dało

Z góry dzięki za pomoc.

Nikt na tym forum w myślach Twoich nie przeczyta. Jeśli (!(PINC & 0x01)) to co? wiesz czym w ogóle jest PINC? Gdzie masz podłączony ten przycisk? Gdzie głośnik? Gdzie jest schemat? Gdzie reszta kodu?

Gdzie masz podłączony ten przycisk? Gdzie głośnik?
Otóż mam przycisk podłączony do PC0 i głośnik do portu PD0
Gdzie jest schemat?

schematu nie robiłem bo jest to na płytce uniwersalnej:

jeden kabel od głośnika jest podłączony rezystora 680 a ten zaś do PD0, drugi do GND.

a przycisk do PC0 i do GND

uC to ATmega8

Gdzie reszta kodu?
/*
KURS AVR-GCC cz.4
Program, z pomocą  buzzera (przetwornika piezo),
odgrywa krótką melodyjkę.

układ atmega 1MHz
PB0 -> R(330Ohm) -> BUZZER -> PB1 
*/

#define F_CPU 1000000L
#include <avr/io.h>
#include <util/delay.h>

/**** ZMIENNE GLOBALNE ****/
/* 
Tablica dzwięków:
częstotliwść(Hz), czas_trwania(ms), częstotliwość, ... 
*/
int koziolek[][2]={
                   523,125,
                   587,125,
                   659,250,
                   698,125,
                   659,125,
                   587,250,
                   523,250,
                   1047,250,
                   784,250,
                   523,250,
                   1047,250,
                   784,250,
                   523,250,
                   1047,250,
                   784,1000 };

/**** DEFINICJE WŁASNYCH FUNKCJI ****/

/* Konfiguruje porty we/wy uC */
void init(void)
{
 /* PB0,PB1 - wyścia */
 DDRD  = 0x03;
 PORTD = 0x00;

 DDRC  = 0x00;
 PORTC = 0x03;
}

/*
Funkcja generuje sygnał prostokątny na wyprowadzeniach PB0 i PB1,
gdzie przyłączony jest  buzzer. Funkcja przyjmuje argumenty: 
częstotliwość(Hz) sygnału i dułgość czasu trwania sygnału (ms).
*/
void beep(unsigned int frequency, unsigned int duration)
{  
 unsigned int i,t,n;  
 t = 125000/frequency;  
 n = (250UL*duration)/t;

 PORTD |= 0x01;
 PORTD &= ~0x02;
 for(i=0; i < n; i++) 
 {
   PORTD ^= 0x01;  
   PORTD ^= 0X02;  
   _delay_loop_2(t);
 } 
}
/*
Odgrywa melodyjkę dzwięk po dzwięku. Jako argumentów funkcja 
oczekuje tablicy dzwięków oraz numerów pierwszego i ostatniego
dzwięku. Elementami tablicy dźwięków  są tablice o dwóch elementach
typu int (częstotliwość w Hz i długość trwania dzwięku w ms).
*/

void play(int nots[][2], unsigned int start, unsigned int stop)
{
  int n;

  for(n=start; n <= stop; n++)
       beep(nots[n][0], nots[n][1]);
}            

/**** POCZĄTEK PROGRAMU ****/            

/* Definicja głównej funkcji */
int main(void)
{
  /* Konfiguracja sprzętu */
  init();

  /* Nieskończona pętla */
  if(!(PINC & 0x01))
  {
     /* Gra dwukrotnie ten sam "kawałek" */
     play(koziolek,0,14);
     play(koziolek,0,14);
 }

}
schematu nie robiłem bo jest to na płytce uniwersalnej: jeden kabel od głośnika jest podłączony rezystora 680 a ten zaś do PD0, drugi do GND. a przycisk do PC0 i do GND

to go zrób, by w na pierwszym stopniu Piekła Początkujących byt długo nie stać.

Przepraszam za złe oznaczenie rezystorów, L1 to fotorezystor który pełni funkcję przycisku

__________

Komentarz dodany przez: Treker

Jeśli został zastosowany fotorezystor jako "przycisk", to jakie jest napięcie jeśli jest "naciśnięty", "nie naciśnięty". Przeczytaj w datasheecie jak procesor interpretuje napięcie na 1/0.

Kolejna rzecz jak z pustego może się tam jakiekolwiek napięcie pokazać?

Niema pullup sprzętowego, niema pullup programowego.

small-man wszystko jest podłączone, zasilanie jak i programator itp bo testowałem przykładowymi programami

riddyk opór przy " niewciśniętym to około 7 - 100K a przy wciśniętym 1800K.

fotorezystor działa jako przycisk, gdyż testowałem go już z diodami

Nie zmienia to faktu, że pin czyta napięcie a nie rezystancję. Musisz zrobić pullup jeśli chcesz żeby to działało.

No tak ale żeby dioda świeciła to nie trzeba było robić pullup.

Mógłby ktoś pomóc w napisaniu kodu, żeby właśnie po naciśnięciu przycisku (nawet zwykłego) to żeby jakiś dźwięk odtwarzał głośnik? Przeczytałem kolejny raz kurs i nadal nie umiem tego napisać...

Żeby dioda świeciła to trzeba było zrobić inny układ. Czy zmierzyłeś napięcie pomiędzy pinem uP, a masą ? Przy wciśniętym i nie naciśniętym?

Musisz wymusić stan wysoki jeśli nie jest naciśnięty, albo rezystorem rzędu 47k-100k lub programowo wewnętrznym rezystorem uP i po naciśnięciu musi być stan niski. Dopiero po tym może zacząć to działać.

Program który pokazałeś generuje dźwięk na liniach PD0 i PD1 - to tam musisz podłączyć swój głośnik. Jeden koniec do PD0 a drugi do PD1, nie do masy. Tak jak zrobiłeś też coś będzie słychać, ale ciszej. Najpierw jednak sprawdź, czy przez tak duży opornik w ogóle coś usłyszysz. Podłącz głośnik (lub cokolwiek to jest) jedną nóżką do masy a drugą przez opornik do +5V. Czy dotykając/przerywając obwód słyszysz jakieś stuki i trzaski w głośniku? Bo jeśli nie, to procesor też nic nie wskóra. Zmniejszaj opornik aż do chwili (np. do 100 omów albo nawet mniej) gdy stuki będą wyraźnie słyszalne. Wtedy podłącz do PD0 i PD1, i odpal program. Ten komentarz "Nieskończona pętla" jest Twój? Bo na razie to tylko takie pobożne życzenie. Program po włączeniu zasilania tylko raz sprawdzi stan na wejściu PC0 i jeśli będzie tam wtedy zero, odegra (być może) "koziołka" ale jeśli przycisk nie będzie wcześniej wciśnięty, funkcja main zakończy się i możesz już tylko wyłączyć zasilanie.

Co to za numer z tymi diodami? Czy zapalałeś je programowo, "przez procesor", bo jakoś tego jasno nie opisałeś. Jeśli tak, to i z melodyjką powinno być OK - oczywiście po zmianach w programie...

Może zamiast tego foto-cośtam wstaw na chwilę zwykły przycisk albo zwieraj nóżkę do masy drutem? Przynajmniej jeden problem odpadnie.

Wielkie dzięki wszystkim za odpowiedź.

Już wszystko działa.

A oto program:


#define F_CPU 1000000L 
#include <avr/io.h> 
#include <util/delay.h> 

/**** ZMIENNE GLOBALNE ****/ 
/* 
Tablica dzwięków: 
częstotliwść(Hz), czas_trwania(ms), częstotliwość, ... 
*/ 
int koziolek[][2]={ 
                   523,125, 
                   587,125, 
                   659,250, 
                   698,125, 
                   659,125, 
                   587,250, 
                   523,250, 
                   1047,250, 
                   784,250, 
                   523,250, 
                   1047,250, 
                   784,250, 
                   523,250, 
                   1047,250, 
                   784,1000 }; 

/**** DEFINICJE WŁASNYCH FUNKCJI ****/ 

/* Konfiguruje porty we/wy uC */ 
void init(void) 
{ 
 /* PB0,PB1 - wyścia */ 
 DDRD  = 0x03; 
 PORTD = 0x00; 

 DDRC  = 0x00; 
 PORTC = 0x03; 


} 

/* 
Funkcja generuje sygnał prostokątny na wyprowadzeniach PB0 i PB1, 
gdzie przyłączony jest  buzzer. Funkcja przyjmuje argumenty: 
częstotliwość(Hz) sygnału i dułgość czasu trwania sygnału (ms). 
*/ 
void beep(unsigned int frequency, unsigned int duration) 
{  
 unsigned int i,t,n;  
 t = 125000/frequency;  
 n = (250UL*duration)/t; 

 PORTD |= 0x01; 
 PORTD &= ~0x02; 
 for(i=0; i < n; i++) 
 { 
   PORTD ^= 0x01;  
   PORTD ^= 0X02;  
   _delay_loop_2(t); 
 } 
} 
/* 
Odgrywa melodyjkę dzwięk po dzwięku. Jako argumentów funkcja 
oczekuje tablicy dzwięków oraz numerów pierwszego i ostatniego 
dzwięku. Elementami tablicy dźwięków  są tablice o dwóch elementach 
typu int (częstotliwość w Hz i długość trwania dzwięku w ms). 
*/ 

void play(int nots[][2], unsigned int start, unsigned int stop) 
{ 
  int n; 

  for(n=start; n <= stop; n++) 
       beep(nots[n][0], nots[n][1]); 
}            

/**** POCZĄTEK PROGRAMU ****/            

/* Definicja głównej funkcji */ 
int main(void) 
{ 
  /* Konfiguracja sprzętu */ 
  init(); 
while(1)
{
  /* Nieskończona pętla */ 
  if(!(PINC & 0x01)) 
{
}   

else
{ 
 /* Gra dwukrotnie ten sam "kawałek" */ 
     play(koziolek,0,14); 
     play(koziolek,0,14); 
}


}
}
  • 8 lat(a) później...

Witam wszystkich !

Zastanawiam się cały czas na tym fragmentem kodu:

t = 125000/frequency; n = (250UL*duration)/t;

 

Może mi ktoś wytłumaczyć skąd dokładnie wzięły się te wartości 125000 oraz 250 oraz wzory ?

Z góry dziękuję !

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...