ATMega328 Memories: Flash memory 32kB SRAM 2kB EEPROM 1kB
ISP programming
Bootloader programming The bootloader is basically a.hex file that runs when you turn on the board. It is very similar to the BIOS that runs on your PC. It does two things. First, it looks around to see if the computer is trying to program it. If it is, it grabs the program from the computer and uploads it into the ICs memory (in a specific location so as not to overwrite the bootloader). That is why when you try to upload code, the Arduino IDE resets the chip. This basically turns the IC off and back on again so the bootloader can start running again. If the computer isn t trying to upload code, it tells the chip to run the code that s already stored in memory. Once it locates and runs your program, the Arduino continuously loops through the program and does so as long as the board has power.
Arduino Uno board
USART Interface and USART connection to PC COM MAX 232 converts signals from an RS-232 serial port to signals suitable for use in TTL Asynchronous transmission
USART to USB adapter
Default Clock Source The device is shipped with internal RC oscillator at 8.0MHz and with the fuse CKDIV8 programmed, resulting in 1.0MHz system clock. The startup time is set to maximum and time-out period enabled. (CKSEL = "0010", SUT = "10", CKDIV8 = "0"). The default setting ensures that all users can make their desired clock source setting using any available programming interface. Other clock sources Low power crystal oscillator crystal External oscillator Low frequency crystal oscillator Used for real time clock
Clock systems
Linia DTR umożliwia resetowanie mikrokontrolera z komputera PC konieczne przed ładowaniem programu przez bootloader
Bitwise operators: & AND OR ~ NOT << SHIFT LEFT >> SHIFT RIGHT ^ EXCLUSIVE OR Example: Bitwise AND PORTD = 0b???????? Number= 0b11111011???????? unknown bits & 11111011 =?????0?? result: one bit cleared Example: Bitwise OR PORTD = 0b???????? Number= 0b00000100???????? unknown bits 00000100 =?????1?? result: one bit set
Bitwise operators: & AND OR ~ NOT << SHIFT LEFT >> SHIFT RIGHT ^ EXCLUSIVE OR Example: Bitwise NOT PORTD = 0b10101010 ~PORTD = 0b01010101 Example: Bitwise SHIFT PORTD = 0b10101010 PORTD<<1 = 0b01010100 Example: Exclusive OR PORTD = 0b10101010 Number = 0b110011 00 0b10101010 ^ 0b11001100 = 0b01100110
Hex numbers: 0b00000001 = 0x01 0b00000010 = 0x02 0b00000100 = 0x04 0b00001000 = 0x08 0b00001100 = 0x0C 0b11110001 = 0xF1 0b10001000 = 0x88 ~0x01 = 0xfe ~0x02 = 0xfd ~0x04 = 0xfb Makro _BV(x): _BV(0) = 0b00000001 _BV(1) = 0b00000010 _BV(2) = 0b00000100 _BV(3) = 0b00001000 _BV(4) = 0b00010000 _BV(5) = 0b00100000 _BV(6) = 0b01000000 _BV(7) = 0b10000000 ~_BV(0) = 0b11111110 ~_BV(0) = 0b11111101 ~_BV(0) = 0b11111011 ~_BV(0) = 0b11110111 ~_BV(0) = 0b11101111 ~_BV(0) = 0b11011111 ~_BV(0) = 0b10111111 ~_BV(0) = 0b01111111
Shifted numbers _BV(0) = 0b00000001 = (1<<0) _BV(1) = 0b00000010 = (1<<1) _BV(2) = 0b00000100 = (1<<2) _BV(3) = 0b00001000 = (1<<3) _BV(4) = 0b00010000 = (1<<4) _BV(5) = 0b00100000 = (1<<5) _BV(6) = 0b01000000 = (1<<6) _BV(7) = 0b10000000 = (1<<7) ~ (1<<0) = 0b11111110 ~ (1<<1) = 0b11111101 ~ (1<<2) = 0b11111011 ~ (1<<3) = 0b11110111 ~ (1<<4) = 0b11101111 ~ (1<<5) = 0b11011111 ~ (1<<6) = 0b10111111 ~ (1<<7) = 0b01111111 (1<<0) = (1<<PORTD0) (1<<1) = (1<<PORTD1) (1<<2) = (1<<PORTD2) (1<<3) = (1<<PORTD3) (1<<4) = (1<<PORTD4) (1<<5) = (1<<PORTD5) (1<<6) = (1<<PORTD6) (1<<7) = (1<<PORTD7)
General purpose input/output schematic Pullup transistor Output to pin Input from pin
Port D registers
Using Arduino library Using PORT names Pin 2 as input internally pulled up pin 2 = PORTD, 2 DDRD = DDRD & 0xFB; (input) pinmode(2, INPUT_PULLUP); PORTD = PORTD 0x04; (pullup) Pin 2 as input floating (high Z) pin 2 = PORTD, 2 DDRD = DDRD & 0xFB; (input) pinmode(2, INPUT); PORTD = PORTD & 0xFB; (floating) Pin 13 as output pin 13 = PORTB, 5 DDRB = DDRB 0x20; PORTB = PORTB 0x20; PORTB = PORTB & 0xDF; pinmode(13, OUTPUT); digitalwrite(13, HIGH); digitalwrite(13, LOW);
Using PORT names Using Arduino library Pin 2 as input internally pulled up pin 2 = PORTD, 2 (Uno) DDRD = DDRD & ~ _BV(2); (input) PORTD = PORTD _BV(2) ; (pullup) pinmode(2, INPUT_PULLUP); Pin 2 as input floating (high Z) pin 2 = PORTD, 2 (Uno) DDRD = DDRD & ~ _BV(2); (input) PORTD = PORTD & ~ _BV(2); (floating) pinmode(2, INPUT); Pin 13 as output pin 13 = PORTB, 5 (Uno) DDRB = DDRB _BV(5); PORTB = PORTB _BV(5); PORTB = PORTB & ~ _BV(5); pinmode(13, OUTPUT); digitalwrite(13, HIGH); digitalwrite(13, LOW);
Using PORT names Using Arduino library Pin 2 as input internally pulled up pin 2 = PORTD, 2 (Uno) DDRD = DDRD & ~ (1<<DDD2); (input) PORTD = PORTD (1<<PORTD2); (pullup) pinmode(2, INPUT_PULLUP); Pin 2 as input floating (high Z) pin 2 = PORTD, 2 (Uno) DDRD = DDRD & ~ (1<<DDD2); (input) PORTD = PORTD & ~ (1<<PORTD2); (floating) pinmode(2, INPUT); Pin 13 as output pin 13 = PORTB, 5 (Uno) DDRB = DDRB (1<<DDD5); PORTB = PORTB (1<<PORTD5); PORTB = PORTB & ~ (1<<PORTD5)); pinmode(13, OUTPUT); digitalwrite(13, HIGH); digitalwrite(13, LOW);
Cod in AtmelStudio: int main(void) { setup(); while (1) loop(); return 0; Cod in Arduino setup(); loop(); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// void setup (void) { // the setup function runs once when you press reset or power the board //funkcja setup jest wykonywana 1x po resecie lub podaniu zasilania void loop(void) { // the loop function runs over and over again forever //funkcja loop() jest wykonywana w kółko w nieskończonej pętli
Example: blinking LED Using Arduino library void setup() { pinmode(13, OUTPUT); void loop() { digitalwrite(13, HIGH); delay(1000); // wait for a second digitalwrite(13, LOW); delay(1000); Using PORT names void setup() { DDRB = DDRB 0x20; void loop() { PORTB = PORTB 0x20; delay(1000); // wait for a second PORTB = PORTB & 0xDF; delay(1000);
Example: button const int buttonpin = 2; const int ledpin = 13; int buttonstate = 0; // the number of the pushbutton pin // the number of the LED pin // variable for reading the pushbutton status void setup() { pinmode(ledpin, OUTPUT); pinmode(buttonpin, INPUT); // initialize the LED pin as an output: // initialize the pushbutton pin as an input: void loop() { buttonstate = digitalread(buttonpin); // read the state of the pushbutton value: if (buttonstate == HIGH) // check if the pushbutton is pressed. { // turn LED on: digitalwrite(ledpin, HIGH); else { // turn LED off: digitalwrite(ledpin, LOW);
Example: serial monitor Serial monitor is an application on PC connected to USART via USB int incomingbyte = 0; // for incoming serial data void setup() { Serial.begin(9600); // opens serial port, sets data rate to 9600 bps void loop() { // send data only when you receive data: if (Serial.available() > 0) { // read the incoming byte: incomingbyte = Serial.read(); // say what you got: Serial.print("I received: "); Serial.println(incomingByte, DEC);
Serial.write(33); Serial.write(33) gives!" Serial.print(33); Serial.print(33) gives 33" Serial.print(1.23456) gives "1.23" Serial.print('N') gives "N" Serial.print("Hello world.") gives "Hello world." Serial.print(78, BIN) gives "1001110" Serial.print(78, OCT) gives "116" Serial.print(78, DEC) gives "78" Serial.print(78, HEX) gives "4E" Serial.println(1.23456, 0) gives "1" Serial.println(1.23456, 2) gives "1.23" Serial.println(1.23456, 4) gives "1.2346"
void setup() { Serial.begin(9600); int thisbyte = 33; void loop() { Serial.write(thisByte); Serial.print(", dec: "); Serial.print(thisByte); Serial.print(", hex: "); Serial.print(thisByte, HEX); Serial.print(", oct: "); Serial.print(thisByte, OCT); Serial.print(", bin: "); Serial.println(thisByte, BIN); if (thisbyte == 126) { thisbyte = 33; // go on to the next character thisbyte++;
Interrupt vectors
Przerwania zewnętrzne INT0, INT1 INT0 PORTD2 linia nr 2 INT1 PORTD3 linia nr 3 Stan wysoki na linii jest stanem bezczynnym (IDLE state). Przerwanie może być wywołane przez: LOW level (poziom niski), FALLING edge (zbocze opadające), RISING edge (zbocze narastające), CHANGE (każda zmiana). ISR (INT0_vect) example LOW level void setup() { pinmode(13, OUTPUT); EIMSK = // zdjęcie maski interrupts(); void loop() { digitalwrite(13, LOW); ISR (INT0_vect){ digitalwrite(13, HIGH);
Przerwania zewnętrzne INT0, INT1 Funkcja biblioteczna attachinterrupt attachinterrupt (digitalpintointerrupt(pin), procedura przerwania, atrybut); Pin: 2 lub 3 numery przerwania INT0, INT1 Procedura: wykonywana w przerwaniu tu: blink() Atrybut: LOW (poziom niski), FALLING (zbocze opadające, RISING (zbocze narastające), CHANGE (każda zmiana). #define ledpin 13 void setup() { pinmode(ledpin, OUTPUT); attachinterrupt(digitalpintointerrupt(3), blink, FALLING); void loop() { Attachinterrupt void blink () { int state = digitalread(ledpin); digitalwrite (ledpin, state^1); //toggle state example
Przerwania zewnętrzne wybór źródła przerwania Przerwania zewnętrzne maska przerwania
Stany nieustalone przycisku Rejestr flagowy przerwań zewnętrznych
Program, który radzi sobie ze stanami nieustalonymi przycisku #define ledpin 13 #define buttonpin 3 void setup() { pinmode(ledpin, OUTPUT); pinmode(buttonpin, INPUT_PULLUP); attachinterrupt(digitalpintointerrupt(3), blink, CHANGE ); void loop() { void blink () { _delay_ms(30); if(digitalread(buttonpin)==1) { int state = digitalread(ledpin); digitalwrite (ledpin, state^1); _delay_ms(60); EIFR=0;
Przerwania zewnętrzne przykład ISR (INT0_vect) { // void setup() { DDRD &= ~_BV(x); PORTD = _BV(x); DDRB = _BV(y); PORTB &= ~_BV(y); EICRA = EIMSK = sei(); //linia x portu D jako wejście //podwieszenie wejścia // linia y portu C jako wyjście //wyjście w stan low //konfiguracja: poziomem lub zboczem // zdjęcie maski // lub interrupts() odblokowanie przerwań void loop() { ///
Przerwania zewnętrzne PCINT Przerwania zewnętrzne PCINT dostępne na pinach PCINT23 - PCINT0 są objęte 3-ma wektorami przerwań, po 8 linii na jeden wektor. W rejestrze PCICR leżą bity aktywacji grup przerwań: PCINT0-7 (bit PCIE0), PCINT8-14 (bit PCIE1), PCINT15-23 (bit PCIE2). W rejestrach PCMSK0, 1, 2 leżą maski indywidualne przerwań PCINT23-0. Przerwania PCINT23-0 są aktywowane każdą zmianą na pinach wejściowych.
Example: PCINT vectors #define switch z void setup() { pinmode (13, OUTPUT); digitalwrite(13, LOW); // z numer linii switcha w IDE //dioda PCICR = (1<<PCIEy); // wybór przerwania (są 3 wektory przerwań po 8 linii) PCMSKy = (1<<PCINTx); // wybór linii w ramach danego wektora przerwania sei(); // lub interrupts(); ISR(PCINTy_vect) { //wybór wektora przerwania (są 3 wektory przerwań) _delay_ms(50); digitalwrite(13, digitalread(13) ^ 1); while(digitalread(switch)==1); //lub while(digitalread(switch)==0); w zależności od montażu switch/rezystor _delay_ms(50); PCIFR = _BV(PCIFy); void loop() {
Example: Timer1 overflow vector Przerwanie wywołane przepełnieniem rejestru zliczania timera #define ledpin 13 void setup() { pinmode(ledpin, OUTPUT); nointerrupts(); TCCR1A = 0; TCCR1B = 0; TCCR1B = (1 << CS12); TIMSK1 = (1 << TOIE1); interrupts(); // disable all interrupts // w Arduino zerowania konieczne ze względu // na wpisy pre-konfiguracyjne IDE // 256 prescaler // enable timer overflow interrupt // enable all interrupts ISR(TIMER1_OVF_vect) { // timer compare interrupt service routine int state = digitalread(ledpin); digitalwrite(ledpin, state ^ 1); // toggle LED pin void loop() {
Example: Timer1 compare vector CTC mode - przerwanie wywołane zrównaniem zawartości rejestru zliczania TCNT1 z rejestrem Porównawczym OCR1, - tryb CTC - każde przerwanie powoduje zerowanie rejestru zliczania TCNT0 #define ledpin 13 void setup() { pinmode(ledpin, OUTPUT); nointerrupts(); // disable all interrupts TCCR1A = 0; TCCR1B = 0; OCR1A = 31250; // compare match register 16MHz/256/2Hz TCCR1B = (1 << WGM12); // CTC mode TCCR1B = (1 << CS12); // 256 prescaler TIMSK1 = (1 << OCIE1A); // enable timer compare interrupt interrupts(); // enable all interrupts ISR(TIMER1_COMPA_vect) { state = digitalread(ledpin); digitalwrite(ledpin, state ^ 1); // timer compare interrupt service routine void loop() {
The Arduino performs some initialization of the timers. The Arduino initializes the prescaler on all three timers to divide the clock by 64. Timer 0 is initialized to Fast PWM, while Timer 1 and Timer 2 is initialized to Phase Correct PWM. See the Arduino source file wiring.c for details.
Fast PWM with Timer0 PWM signal on OC0A or OC0B
Fast PWM with Timer0 int brig = 0; void setup() { TCCR0A = 0; TCCR0B = 0; TCCR0A = (1 << WGM00) (1 << WGM01) (1 << COM0A1); TCCR0B = (1 << CS00); pinmode(6, OUTPUT); OCR0A = 0; void loop() { //Now Loop with increasing brightness for (brig = 0; brig < 255; brig++) { OCR0A = brig; delay(500); //Now Loop with decreasing brightness for (brig = 255; brig > 0; brig--) { OCR0A = brig; delay(500);
ADC Analog-digital converter int analogread(uint8_t pin) { uint8_t low, high; ref= 1; pin -= 14; ADMUX = (ref<< 6) (pin & 0x07); sbi(adcsra, ADEN); sbi(adcsra, ADSC); while (bit_is_set(adcsra, ADSC)); low = ADCL; high = ADCH; return (high << 8) low; int mojadc() { char l, h; ADMUX = ((1<<REFS0)); ADCSRA = ((1<<ADEN) (1<<ADSC)); ADCSRA = ((1<<ADPS2) (1<<ADPS1)); while (! (ADCSRA & (1<<ADIF))); ADCSRA = (1<<ADIF); //zerowanie flagi adif lo = ADCL; hi = ADCH; return (hi << 8) lo;
Example: analog input void setup() { Serial.begin(9600); void loop() { int sensorvalue = analogread(a0); Serial.println(sensorValue); delay(1);
Podstawowe funkcje biblioteczne (makra) Rejestr danych portu D - PORTD Bit 7 6 5 4 3 2 1 0 Nazwa PORTD7 PORTD6 PORTD5 PORTD4 PORTD3 PORTD2 PORTD1 PORTD0 Odczyt/zapis R/W R/W R/W R/W R/W R/W R/W R/W Wartość początkowa 0 0 0 0 0 0 0 0 #define cbi(reg, bitmask) *reg &= ~bitmask #define sbi(reg, bitmask) *reg = bitmask Przykłady: cbi (PORTD, (1<<6)); PORTD &= ~(1<<6); cbi (PORTD, PORTD6); PORTD &= ~(1<< PORTD6); cbi (PORTD, _BV(6)); PORTD &= ~(1<<_BV(6)); sbi (PORTB, (1<<6)); PORTD = (1<<6); sbi (PORTD, PORTD6); PORTD = (1<< PORTD6); sbi (PORTD, _BV(6)); PORTD = (1<<_BV(6));
Podstawowe funkcje biblioteczne (makra) Rejestr wejściowy portu D - PIND Bit 7 6 5 4 3 2 1 0 Nazwa PIND7 PIND6 PIND5 PIND4 PIND3 PIND2 PIND1 PIND0 Odczyt/zapis R R R R R R R R Wartość początkowa N/A N/A N/A N/A N/A N/A N/A N/A N/A wartość nieustalona sfr = special function register #define bit_is_set(sfr, bit) (_SFR_BYTE(sfr) & _BV(bit)) while(bit_is_set(pind, PIND5)) { while(pind & (1<< PIND5)) { #define bit_is_clear(sfr, bit) (!(_SFR_BYTE(sfr) & _BV(bit))) while(bit_is_clear(pind, PIND5)) { while(!(pind & (1<< PIND5))) { #define loop_until_bit_is_set(sfr, bit) loop_until_bit_is_set(pind, PIND5); do { while (bit_is_set(pind, PIND5)); #define loop_until_bit_is_clear(sfr, bit) loop_until_bit_is_clear(pind, PIND5) ; do { while (bit_is_clear(pind, PIND5));
Universal Asynchronous Receiver-Transmitter USART Features Full Duplex Operation (Independent Serial Receive and Transmit Registers) Asynchronous or Synchronous Operation Master or Slave Clocked Synchronous Operation High Resolution Baud Rate Generator Supports Serial Frames with 5, 6, 7, 8, or 9 Data Bits and 1 or 2 Stop Bits Odd or Even Parity Generation and Parity Check Supported by Hardware Data OverRun Detection Framing Error Detection Noise Filtering Includes False Start Bit Detection and Digital Low Pass Filter Three Separate Interrupts on TX Complete, TX Data Register Empty and RX Complete Multi-processor Communication Mode Double Speed Asynchronous Communication Mode
USART BAUD rate (typical baurate: 1200, 2400, 4800, 9600, 19200, 38400 itd.)
USART frame format (typical 8n1)
USART0 rejestry: flagowy UCSR0A, kontrolny UCSR0B, kontrolny UCSR0C
USART0 rejestry: prędkości UBRR0L i UBRR0H, odbiorczy UDR0 i nadawczy UDR0 (dwa rejestry o tej samej nazwie zapewniające dupleksową transmisję danych
void setup() { #define FOSC 16000000 // Clock Speed #define BAUD 9600 #define ubrr FOSC/16/BAUD-1 UBRR0H = UBRR0L = UCSR0B = UCSR0C = void loop() //nadawanie { //nadaj bajt ascii ++ //poczekaj na flagę TXC0 //wyzeruj flagę TXC0 void loop() //odbiór { //poczekaj na flagę RXC0 { //odbierz //odeślij
#include <util/delay.h> includes _delay_us(80); _delay_ms(80); delaymicroseconds(480); Example: delay functions
Controlling sleep modes register description
Tryby uśpienia i sposób wybudzania