Het eerste programma, dat een LED ingeschakeld die u hebt geschreven. Ja, dat spectaculair was! Nou, niet echt, maar laten we introduceren een beetje gekte op de LED. We geven het een "bi-polaire" persoonlijkheid doordat het knipperen. Toen we het intensiveren van een inkeping en maken het echt snel knipperen. Het programma is verrassend beknopt en eenvoudig te implementeren.
Zie voor jezelf:
#include <avr/io.h>#include <util/delay.h> int main(void){DDRB | = 1 << PINB0;
terwijl (1)
{
PORTB ^ = 1 << PINB0;
_delay_ms(100);
}
01001011 &10001101equals00001001
HEY!! Wat betekenen de crazy symbolen! Gek lijkt te zijn een gemeenschappelijk thema hier. Nou, ik zal uitleggen. Maar, ik beloof, het is vrij gemakkelijk. Je hoeft alleen te onthouden van een paar dingen. Ik zal krijgen in een klein beetje van detail, maar als je het niet krijgen, geen zorgen, gewoon onthouden wat de gehele verklaring volbrengt en u zal zitten schoon. Ik zal u een hint langs de weg. Hier komt het detail van bitsgewijze bewerkingen:
Er zijn logische operatoren AND, OR, niet genoemd en XOR die we bezorgd zijn met op dit moment. Zij werkelijk betekenen wat ze zeggen. Dit is allemaal omwille van het vergelijken van twee bits, "1" en "0". Zie je wel? Hoe gewoon het vergelijken van twee getallen moeilijk kan zijn! "1" en "1" is True of "1". En ja, je raadt het al, "0" en "0" is vals of "0". Maar wat is "0" en "1" en vice versa? Nou, False of "0", uiteraard. Die jongens zijn anders, dus echt, ze zijn vals.
Voorbeeld van de AND-bewerking voor binaire getal (de "&" wordt gebruikt in C programmeren voor en):
01001011 |10001101equals11001111
Makkelijk, toch? Goed, of is het nog gemakkelijker! "1" of "1" is "1", uiteraard. "0" of "0" wordt ook "0". Het begint te kijken zeer gelijkaardig aan en, maar hier het verschil is. Als de twee getallen verschillen, zal het resulteren in '1'. Ja, "1" of "0" is "1".
Laten we gebruik maken van het binaire getal dat hetzelfde voorbeeld (dat grappig karakter "|" is de OR, soms boven de "\" op het toetsenbord):
01001011 ^10001101equals11000110
Hmm, die draaide op alle plaatsen waar er ontbraken degenen! Dit is waar de magie gebeurt. Ja, het degene in het eerste nummer gehouden en waar er in de tweede binair getal, maar niet de eerste, het degenen die veranderd. Heel eenvoudig. NIET alleen neemt alle van de bits en draait ze. Bijvoorbeeld, voor dit binaire getal: 01001101 zal veranderen in 10110010. Bleek van de 0 in 1's en 1 in de 0, maar krijg dit verward met de XOR.
XOR is vergelijkbaar met OR maar de "1" XOR "1" is eigenlijk "0". Ik zal gewoon laten zien in het voorbeeld en u kunt achterhalen welke happenes.
#include <util/delay.h>
Yep, u raadt het al, de "^" boven de "6" is de XOR-symbool. Hmmm... De "|" en de "^" zijn in het programma. Cool. Nou, omdat wij denken programma, laten we disect het materiaal weten we nog niet!
DDRB = 0b00000001;
Je weet al wat het < avr/io.h > doet, dus ik zal niet verspil je tijd met die ene, maar er is een nieuwe instructie #include. De delay.h geeft ons een paar handige methoden voor ons om te gebruiken. Net zoals de naam al impliceert, zal de delay.h ons voorzien van een manier om vertragingen in ons programma.
Negeer de "main" omdat we dat al weten, zien we de DDRB veranderd. Wees niet bang! Hier is het proces van waar we waren tot waar we zijn:
Dit is wat we voorheen. Dit is niet een zeer goede manier van de pinnen omdat we net allemaal veranderd van de pinnen van 1 tot en met 7 als input, maar "what if" we hadden een groter programma dat deze pinnen voor andere dingen gebruikt, zoals bijvoorbeeld minipulating, pin 2 allpies rem drukregeling voor het antiblokkeer-remsysteem. U zou niet willen gewoon willekeurig instellen die als input. Dat zou betekenen dat uw remmen nutteloos (die echt slecht zou zijn).
DDRB = DDRB | 0b00000001;
We moeten een manier om alleen van invloed op beet, de PIN-code 0-bits. Nou, als je kijkt naar boven de "OR", kunnen we dit doen met een masker (niet de carnaval masker die je denkt, maar een binair masker.
DDRB |= 0b00000001;
Dit zal neemt haar vroegere zelf en "OR" om een masker. Het masker is: 0b00000001. Ja dit ziet eruit als de werkelijke binair getal, maar als de vorige DDRB, zeggen was, 0b01001010, dan doet een of dat het met onze masker zou zijn: 0b01001010 | 0b00000001 = 0b01001011. Wat is het verschil in het resultaat. Dat klopt, alleen de pin 0-bits is veranderd!
Dit statememt kan verder worden gecomprimeerd in C++:
PORTB |= 1 << PINB0;_delay_ms(100);PORTB &= ~(1 << PINB0);_delay_ms(100);
Maar dat is niet wat in het programma. Hoewel dit perfect geldig is, waarom niet we profiteren van een aantal van de definities in het headerbestand io.h. Ik bedoel, het is er voor ons gemak, nietwaar? Let op mijn gebruik van weeën! Dit is hetzelfde in C++: "it's" is echt "it's", net als "DDRB | 0b00000001 =" is hetzelfde als "DDRB = DDRB | 0b00000001 ". Ik dalen in mijn stoel met die slechte analogie. Whataver, helpt!
Dus waarom "DDRB | = 1 << PINB0"?
1 << PINB0 is de handeling van het creëren van het masker. De "1" staat voor wat wordt ingevoegd in het masker, de << is een linker shift-operator. Het doet precies wat het zegt, en PINB0 is een aantal functies die de "1" links zal verschuiven. PINB0 is in wezen gewoon gelijk aan 0. Dus, u start met een 0b00000000, en u een "1" zodat 0b00000001 en dan u het verliet 0 posities verschuiven. Zo heeft u nog 0b00000001, hetzelfde nummer van bovenaf. Dus, wat als het was PINB4? De verklaring zou zijn: 1 << PINB4. De "1" links zou worden verschoven resulterende 4 keer in: 0b00010000. Vergeet niet, we zijn met behulp van een nul index, dus er is vier 0s na de 1.
Laten we verhuizen naar de While lus. Je hebt gelijk, we hadden niet om het even wat in de "oneindige lus" voor. Nou, nu moeten we de microcontroller te tonen wat actie. Dit is alleen mogelijk binnen de lus. De lus is waar de actie wordt herhaald over en voorbij. Als de actie zich bevond voordat de lus, zou vervolgens de actie alleen gebeuren eens, zoals het opzetten van de richting van de pin, die geschikt is voor dit programma. Maar als u wilt maken voor eeuwig knipperen, we moeten om te zetten van de PINB0 in- en uitschakelen in de for-lus. Hier is ook waar de vertragingen komen. Als we geen vertragingen, zouden we de LED knippert helemaal niet zien, het zou uitzien als het is net op, aangezien het knipperen sneller dan het oog waarnemen, ontstaat kan dus we moeten langzaam naar beneden.
We weten hoe u een specifieke bit in de binaire getal, maar we weten niet hoe maak je een specifieke bit "0" als het nog een "1" is. De volgende code doet precies dit, maar u zult merken dat het is niet wat het programma toont. De eerste paar lijnen draait het bit op '1' (5 volt, licht), en pauzeert voor 100 miliseconden (door de manier, u kunt microseconden door het veranderen van de "ms" "ons"). De laatste twee regels verandert de PINB0-bit op "0" (0 volt, geen licht). Nee, de vergelijking en kan niet enkel maken een "0" van het bit, maar als je niet "~" het binaire getal masker, zal het weer alle de 0s aan 1s en alle van de 1s aan 0s. Dit zal toestaan dat u alleen invloed op de PINB0-bit en zet hem in een "0". Ik voegde het haakje gewoon om te bevatten van de maskerende werking, zodat het niet kon niet de hele maks en niet alleen de '1' vóór de linker shift "<<".
PORTB ^= 1 << PINB0;_delay_ms(100);
Als de vertraging is gonna be hetzelfde voor in- en uitschakelen, kunnen we verkorten de vorige vier lijnen naar slechts twee en te profiteren van de XOR bewerking. Vergeet niet, de XOR zal onze specifieke pin naar een 1 veranderen als er 0 en vice versa. Deze instructie zal alleen van invloed op de PINB0. Elke keer dat de instructie wordt uitgevoerd, zal het wegknippen de bit met het tegenovergestelde.
Thats it. Zie dat was helemaal niet pijnlijk.