Как стать автором
Обновить

Комментарии 27

Это прикольно, но полезно или нет каждый решит еще до хабраката, голосование лучше убрать, мне кажется ;)
Ну да… убрал.
Я зашел под кат только для того что-бы посмотреть где-же тут Arduino :)
Основной код тут под Arduino.
И правильно что автор ушел от бояна-ардуино и осилил отдельный контроллер.
Осилил это слишком громко сказано, начал изучать только.
Да я же не против, я только поддерживаю.
Просто моё мнение в том что «Основной код тут под Arduino» != Arduino — в общем название не соответствует содержимому.
Почему? Предпоследний код у меня без особых проблем работает как на тини так и на ардуино.
На приход тёщи хорошо такую мелодию ставить.
А мне и так нравиться.
Мне — нет.
надоест, надоест.
Но можно неплохо украсить, если полезть немного дальше в степь звукоизвлечения — я о вейвтейблах.
Вот неплохая маленькая статейка (и исходники): elm-chan.org/works/mxb/report.html
Да чего накинулись на человека, вас помоему никто не заставляет себе такой звонок делать, а кому интересно — тот попробует. И как я понимаю, мелодию можно любую, так что кому не нравится эта — делайте свою (Лично я все пытаюсь Slayer — Raining Blood заставить ардуину пропищать).
Arduino может гораздо более интересный звук выдавать, а не просто «пропищать». Вот к примеру что у меня получилось
Афигеть! Респект и уважуха!
Прослушал и вспомнил Scream Tracker и коллекцию .stm файлов (на полторы 5-дюймовых дискеты), попавшую ко мне через флоппинет в начале 90-х. Я до сих пор помню свое удивление и восхищение, когда обыкновенная пищалка компьютера начала играть МУЗЫКУ… Это было лучшим подтверждением прочитанного чуть ранее в «Серой книге» (к сожалению, уже не помню ни автора, ни название, только размер (очень толстая, формата А4) и содержание — подробнейшее по-компонентное описание IBM XT) факта, что пищалка в ПК подключена к собственному ЦАП и может играть довольно сложные звуки (но в то время этим редко кто пользовался).
З.Ы. А коллекция у меня до сих пор сохранилась, изредка слушаю Winamp-ом.
Не было там ЦАП. Было управление динамиком через один бит уже не помню какого порта.
В Scream Tracker и соответствующих DOS проигрывателях звук на внутренний динамик выводился с помощью ШИМ.
Очень напомнило чипофон — тоже вроде бы на атмеле сделан.
НЛО прилетело и опубликовало эту надпись здесь
Почему украли?
Я ведь в статье написал что основной код взят из видеоролика на ютюбе, точней из ссылки в описании.
Но я решил немного доработать его под свои нужды.

Хотя сама идея у меня уже жила давно, ещё до знакомства с с миром микроконтроллеров.
НЛО прилетело и опубликовало эту надпись здесь
Тот же самый лунапарк, но с использованием аппаратного таймера, прерываний и режима энергосбережения
/*
Attiny13 Star Wars melody
*/

#define F_CPU 1200000UL
#include <avr/io.h>  
#include <avr/pgmspace.h> 
#include <util/delay.h> 
#include <avr/interrupt.h>
#include <avr/sleep.h>

#define COUNT_NOTES 39

//частоты ноты
const uint16_t frequences[COUNT_NOTES] PROGMEM = {
	392, 392, 392, 311, 466, 392, 311, 466, 392,
	587, 587, 587, 622, 466, 369, 311, 466, 392,
	784, 392, 392, 784, 739, 698, 659, 622, 659,
	415, 554, 523, 493, 466, 440, 466,
	311, 369, 311, 466, 392 };

//длительность нот
const uint16_t durations[COUNT_NOTES] PROGMEM = {
	350, 350, 350, 250, 100, 350, 250, 100, 700,
	350, 350, 350, 250, 100, 350, 250, 100, 700,
	350, 250, 100, 350, 250, 100, 100, 100, 450,
	150, 350, 250, 100, 100, 100, 450,
	150, 350, 250, 100, 750 };

int main( void )
{
	/*
	вход от кнопки (фиксирован) = PB1 , т.к. от этого порта 
	срабатывает прерывание INT0 - единственное внешнее прерывание,
	которое может пробудить контроллер из режима максимального 
	энергосбережения Power-down
	
	выход на пищалку (фиксирован) = PB0, т.к. таймер может управлять
	только пинами PB0 и PB1, последний из которых уже занят кнопкой
	*/
	
	DDRB = (1 << DDB0);		//переключить PB0 на выход
	
	/*
	по-хорошему, даже от вывода мелодии по прерыванию INT0 можно отказаться,
	если подключить кнопку на RESET: после сброса контроллер будет выполнять инициализацию,
	затем тут же проигрывать мелодию и ...уходить в режим максимального
	энергосбережения до следующего сброса
	*/
	
	PORTB = (1 << PORTB1);	//включить подтяжку на PB1
	GIMSK = (1 << INT0);	//разрешить прерывание INT0 (PB1)
	
	set_sleep_mode(SLEEP_MODE_PWR_DOWN);	//настроить энергосберегающий режим Power-down
	
	sei();				//включить прерывания
	
	while(1)
		sleep_mode();	//войти в режим энергосбережения
} 

// вывод мелодии
static inline void doSound(void)
{
	//включить и настроить таймер
	TCCR0A = (1 << COM0A0) | (1 << WGM01);	//Toggle OC0A (PB0) on Compare Match ; mode = CTC
	TCCR0B = (1 << CS01) | (1 << CS00);		//Clock Select = F_CPU/64
	
	//поочередно проигрываем ноты
	for (uint8_t i = 0; i < COUNT_NOTES; i++)
	{
		//получить данные из памяти
		int16_t freq = pgm_read_word(&(frequences[i]));
		int16_t dur = pgm_read_word(&(durations[i]));
		
		//увеличиваем длительность в 1.5 раза
		dur *= 3;
		dur /= 2;
		
		//задаем частоту на выходе PB0
		OCR0A = (F_CPU / (2UL * 64UL * freq)) - 1;
		
		//ожидаем, пока играет нота
		while (dur > 0)
		{
			_delay_ms(10);
			dur -= 10;
		}
	}
	
	//отключить таймер
	TCCR0A = 0;
	TCCR0B = 0;
}

// обработчик прерывания INT0
ISR(INT0_vect)
{
	doSound();
}
Спасибо, добавил.
Всё заработало с первого раза:

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории