Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
To get 8 bit melodies you're going to need more than a pin toggle..... If a crappy sound is needed then yes!!I'm not sure why you think you need a PWM to do music, other than they are good for frequencies, but so are timers. PWM give you the ability to adjust the duty cycle of the frequency, but we aren't worried about that on such a simple scale.
Basically, a note is a frequency. Use your timer to produce a 1/2 cycle time period and toggle the output when the timer times out. You may even be able to use the timer overflow pin instead of toggling a port pin. This will give a square wave, which to the untrained ear, would be good enough to run into an audio amp.
Now, I can see where you'd want to use the PWM function for controlling 6 notes at once. Use the PWM to set up the frequency, and set the duty cycle at 50%.
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#define C1 15288
#define C1d 14431
#define D1 13621
#define D1d 12856
#define E1 12134
#define F1 11453
#define F1d 10811
#define G1 10204
#define G1d 9631
#define A1 9090
#define A1d 8580
#define H1 8099
#define C2 7648
#define C2d 7220
#define D2 6814
#define D2d 6430
#define E2 6069
#define F2 5730
#define G2 5102
#define G2d 4815
#define A2 4545
#define A2d 4291
#define H2 4049
#define C3 3822
#define P 0
#define End 1
#define N32 125.000
#define N16 250.000
#define N8 500.000
#define N4 1000.000
#define N2 2000.000
#define N1 4000.000
volatile int track=0;
volatile int NoteLong = 250;
volatile int loaded=0;
volatile int i = 1;
volatile int Bit = 0x00;
volatile char flag;
volatile int count=0;
volatile char status = 1;
int tanki[] PROGMEM={160.000,P,N32,C2,N32,D2,N32,D2d,N32,C2,N32,D2,N32,D2d,N32,D2d,N32,F2,N32,G2,N32,D2d,N32,F2,N32,G2,N32,F2,N32,G2,N32,A2,N32,F2,
N32,G2,N32,A2,N32,G2d,N32,A2d,N32,C3,N32,G2d,N32,A2d,N32,C3,N32,C3,N32,P,N32,C3,N32,C3,N32,C3,N32,C3,N32,End}; //мелодия танчиков
int mario[] PROGMEM={100.000,P,N16,E2,N32,E2,N32,P,N32,E2,N16,P,N32,C2,N32,E2,N32,P,N32,G2,N32,P,N32,P,N16,G1,N32,P,N16,P,N16,
C2,N32,P,N16,G1,N32,P,N16,E1,N16,P,N16,P,N32,A1,N32,P,N32,H1,N32,P,N32,A1d,N32,A1,N32,P,N32,
G1,N32,E2,N32,G2,N32,A2,N32,P,N32,F2,N32,G2,N32,P,N32,E2,N32,P,N32,C2,N32,D2,N32,H1,N32,End}; //мелодия марио
int miniPolka[] PROGMEM={120.000,P,N16,C2,N16,E2,N16,G2,N16,E2,N16,G2,N16,F2,N16,D2,N8,G2,N16,F2,N16,D2,N8,G2,N16,E2,N16,C2,N8,
C2,N16,E2,N16,G2,N16,E2,N16,A2,N16,G2,N16,F2,N8,G2,N16,F2,N16,E2,N16,D2,N16,C2,N8,End};
int bumer[] PROGMEM={170.000,P,N16,E2,N16,G2,N8,P,N8,P,N8,G2,N16,E2,N8,P,N8,P,N8,A2,N16,G2,N16,A2,N16,G2,N16,A2,N16,G2,N16,A2,N16,G2,N16,A2,N16,H2,N8,P,N8,End};
int nokia[30] PROGMEM={120.000,P,N16,E2,N16,D2,N16,F1d,N8,G1d,N8,C2d,N16,H1,N16,D1,N8,E1,N8,H1,N16,A1,N16,C1d,N8,E1,N8,A1,N8,End};
int mortal[66] PROGMEM={140.000,A1,N16,A1,N16,C2,N16,A1,N16,D2,N16,A1,N16,E2,N16,D2,N16,C2,N16,C2,N16,E2,N16,C2,N16,G2,N16,C2,N16,E2,N16,C2,N16,
G1,N16,G1,N16,H1,N16,G1,N16,C2,N16,G1,N16,D2,N16,C2,N16,F1,N16,F1,N16,A1,N16,F1,N16,C2,N16,F1,N16,C2,N16,H1,N16,End};
int kuznechik[] PROGMEM={130.000,P,N16,A2,N8,E2,N8,A2,N8,E2,N8,A2,N8,G2d,N8,G2,N8,P,N8,G2d,N8,E2,N8,G2d,N8,E2,N8,G2d,N8,A2,N8,End};
int *playlist[]={
kuznechik,
tanki,
mario,
mortal,
nokia,
miniPolka,
bumer
};
//interrupt [TIM1_COMPA] void timer1_compa_isr(void)
ISR (TIMER1_COMPA_vect)
{
PORTC^=(1<<1);
}
// Timer 2 overflow interrupt service routine
ISR (TIMER2_OVF_vect)
{
if(count)count--;
}
void play()
{
OCR1AH = (char) (Bit >> 8); //записываем новую ноту в OCR1A
OCR1AL = (char) Bit;
TIMSK |= 1 << OCIE1A; // начали воспроизведение
_delay_ms(NoteLong); // длина ноты
TIMSK &= ~(1 << OCIE1A); //закончилась нота
_delay_ms(40);
i = i + 2;
}
void pause()
{
TIMSK &= ~(1<<OCIE1A); // запрещаем прерывания
_delay_ms(NoteLong);
TIMSK |= 1<<OCIE1A; // разрешаем прерывания
i+=2;
}
void stop()
{
TIMSK &= ~(1<<OCIE1A); // запрещаем прерывания
Bit=0x00;
PORTC&=~(1<<1);
i=1;
_delay_ms(200);
if(++track>=7) //если последний, то начать заново
{
track=0;
}
}
//void Loading_melody()
//{
// i=1;
// while(playlist[track][i]!=1)
// {
// playlist[track][i+1]=playlist[track][i+1]/(playlist[track][0]/60.000);
// // playlist[track][i+1]=pgm_read_word(playlist[track][i+1])/(pgm_read_word(playlist[track][0])/60.000);
// i++;
// if(playlist[track][i]!=1)
// {
// i++;
// }
// }
// i=1;
//}
int main(void)
{
PORTC=0x00;
DDRC=0b000000011;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 8000,000 kHz
// Mode: CTC top=OCR1A
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
//TCCR1A=0x00;
//TCCR1B=0x09;
TCCR1B |=1<<WGM12 | 1<<CS10;
//TCNT1H=0x00;
//TCNT1L=0x00;
//ICR1H=0x00;
//ICR1L=0x00;
//OCR1AH=0x00;
OCR1AL=0xFB;
//OCR1BH=0x00;
//OCR1BL=0x00;
// Timer/Counter 2 initialization
ASSR=0x00;
TCCR2|= 1 << WGM20 | 1 << WGM21; // Fast PWM mode
TCCR2|= 1 << CS22; // clk/256 - делим основную частоту МК на 256 (предделидель для таймера)
TCNT2=0x00;
OCR2=0x00;
//TIMSK=0x10;
TIMSK |= 1<<TOIE2 | 1<<OCIE1A; // разрешаем прерываемя по совпадению А от теймера/счетчика Т1
sei();
while (1)
{
while (pgm_read_word(&(playlist[track][i])) != 1) //читаем данные с массива мелодии до тех пор
{ //пока не увидим признак окончания мелодии
Bit = pgm_read_word(&(playlist[track][i])); //считываю ноту
NoteLong = pgm_read_word(&(playlist[track][i+1])); //считываю длительность ноты
if (Bit == 0)
{
pause();
}
else
{
play();
}
}
stop();
}
}
I don't know how to convert the notes into the array ringtones
#include <mega32.h>
#include <delay.h>
#include "data.c"
//#include "data1.c"
//#include "data2.c"
#define flashport PORTB.0
//Pointer für die PWM Soundtabelle
volatile unsigned int ui_soundpointer=0;
//Interruptzähler um eine Abtastrate von 15625 bei 8MHz zu erhalten
volatile unsigned char uc_intcounter=0;
...
...
/ Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
uc_intcounter++;
if (uc_intcounter>2) //Bei jedem 2ten Durchlauf wird der nächste Wert verwendet
{
uc_intcounter=0;
OCR0=Jakobsleiter8s_wav[ui_soundpointer]; //Tabelle auslesen und ins Comparematch- register tun
ui_soundpointer++;
if(ui_soundpointer>Jakobsleiter8s_wav_len) //Ende der Tabelle feststellen
{
ui_soundpointer=0;
}
}
}
// Declare your global variables here
void main(void)
{
// Declare your local variables here
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=Out Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=0 State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x09;
// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;
// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 16000,000 kHz
// Mode: Fast PWM top=FFh
// OC0 output: Non-Inverted PWM
TCCR0=0x69;
TCNT0=0x00;
OCR0=0x80;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// Global enable interrupts
#asm("sei")
while (1)
{
//Thats only for a flashing light. The Soud Generation is in the Timer Interrupt Routine
//Blitzen wird nachgebildet
flashport=1;
delay_ms(uc_lighttable[uc_sparkpointer]);
flashport=0;
delay_ms(uc_pausetable[uc_sparkpointer]);
uc_sparkpointer++;
};
flash unsigned char Jakobsleiter8s_wav[] = {
0x8c, 0x81, 0x87, 0x87, 0x84, 0x84, 0x82, 0x7a, 0x7a, 0x89, 0x6f, 0x92,
0x8c, 0x73, 0x7d, 0x84, 0x8d, 0x7d, 0x77, 0x78, 0x8a, 0x7f, 0x91,
...
...
0x63, 0x70, 0x72
};
#define Jakobsleiter8s_wav_len 20727
I wanna play NotesDo You wanna play Notes or complete Samples?
I understand thisThe array... contains the note..
Look at the table...
C4 ( middle C ) = 261.63 hz = time 3822 uS if you load the ICR you need to divide by 2 ie.. 1922