Stap 8: Code
Een heleboel mensen zoals Arduino voor deze codering en er is niets mis met het gebruik van, behalve ik voel dat het voegt een heleboel zwellen aan een normaal eenvoudig programma. Ook ik wist van C en Arduino weet niet. Misschien een dag, als er tijd is. :)
Code:
{{{
#include < avr/io.h >
Gebruik een pin om te schakelen de SPK
Typedefs / / /
typedef unsigned char u8;
int main(void)
{
U8-btnState0;
U8-btnState1;
U8-btnState2;
U8-btnState3;
U8-btnState4;
U8-btnState5;
U8-btnState6;
DDRB = (1 << DDB6); Set SPK voor uitvoer
PORTD = (1 << PD0) | (1 << PD1) | (1 << PD2) | (1 << PD3) | (1 << PD4); Stel hoge knop
PORTC = (1 << PC4) | (1 << PC6);
TCCR2B = (1 << CS21); Timer instellen
terwijl (1)
{
btnState0 = ~ PINC & (1 << PC5);
btnState1 = ~ PINC & (1 << PC4);
btnState2 = ~ PIND & (1 << PD0);
btnState3 = ~ PIND & (1 << PD1);
btnState4 = ~ PIND & (1 << PD2);
btnState5 = ~ PIND & (1 << PD3);
btnState6 = ~ PIND & (1 << PD4);
Als (btnState0)
{
Als (TCNT2 > = 190)
{
PORTB ^ = (1 << PD6); SPK Pin spiegelen
TCNT2 = 0;
}
}
Als (btnState1)
{
Als (TCNT2 > = 179)
{
PORTB ^ = (1 << PD6); SPK Pin spiegelen
TCNT2 = 0;
}
}
Als (btnState2)
{
Als (TCNT2 > = 159)
{
PORTB ^ = (1 << PD6); SPK Pin spiegelen
TCNT2 = 0;
}
}
Als (btnState3)
{
Als (TCNT2 > = 142)
{
PORTB ^ = (1 << PD6); SPK Pin spiegelen
TCNT2 = 0;
}
}
Als (btnState4)
{
Als (TCNT2 > = 126)
{
PORTB ^ = (1 << PD6); SPK Pin spiegelen
TCNT2 = 0;
}
}
Als (btnState5)
{
Als (TCNT2 > = 119)
{
PORTB ^ = (1 << PD6); SPK Pin spiegelen
TCNT2 = 0;
}
}
Als (btnState6)
{
Als (TCNT2 > = 106)
{
PORTB ^ = (1 << PD6); SPK Pin spiegelen
TCNT2 = 0;
}
}
}
}
}}}
Waar komen de standplaatsen vandaan? Een beetje wiskunde nodig was. De klok van de timer op de atmega 168 draait op 1MHz. Dat is veel te snel voor audio, dus we moeten de prescaler /8 gebruiken. Dan aangezien we spiegelen de uitgang-pins hoog dan laag moeten zodat 1 cyclus, we het antwoord door 2 deelt om te komen met de juiste toonhoogte moeten. De formule ziet er als volgt,
Worp om te zetten in code = (1000000/8) / (frequentie Target * 2)
Voor A(440) zou dit 125000/880 = 142.045- of 142 voor onze doeleinden, aangezien de waarde een geheel getal moet.
De frequenties van de doelgroep notities zowat overal online kunnen worden gevonden en zijn over het algemeen allemaal hetzelfde.
Ik wil nog toevoegen een case-statement in plaats van met behulp van een bos van Ifs en PWM gebruiken om betere controle van het volume en toonhoogte van de spreker, maar voor nu, dit werkt.