Les 10: Seriele Communicatie

Spreekt de ATmega328p op een Arduino Nano rechtstreeks met een onze PC?

UART

  • Universal Asynchronous Receiver Transmitter
  • Asynchrone Interface
    • Geen gemeenschappelijke klok
    • Vereist wel een correcte instelling

  • Vereist 2 draden
    • Full Duplex mogelijk

  • Werkt op TTL levels
  • Simpel
  • Altijd aanwezig op een microcontroller

UART Frame

  • IDLE - Lijn in rust
  • St - Start bit
  • (n) - Data bits
  • P - Parity Bit
  • Sp - Stop Bits

UART Frame

  • IDLE
    • Lijn in rust
    • Altijd een logisch hoog signaal

  • St
    • Start Bits
    • Signaleert de start van een frame
    • Altijd een logisch laag signaal

UART Frame

  • (n)
    • Aantal data bits
    • Min 5 - Max 9
    • Meestal 8

  • P
    • Parity bits
    • Error controle
      • ≠ Error correctie
    • Meestal niet gebruikt

UART Frame

  • St
    • Stop Bits
    • Altijd een logisch hoog signaal
    • Min: 1 - Max: 2
      • Meestal 1
      • 2 Stop bits is een artifact
  • St/IDLE
    • Volgend frame of stoppen met verzenden

UART Configuratie

Uit opbouw van een UART Frame leiden we volgende configuratie mogelijkheden af:

  • Aantal data bits
  • Parity bit
  • Stop Bits
  • Baud rate

Baud Rate

  • Modulatie snelheid
    • Aantal symbool veranderingen per seconde
    • In digitale systemen = bits per second (bps)
  • Keuze afhankelijk van kloksnelheid

Vaak voorkomende waarden

  • 9600
  • 19200
  • 57600
  • 115200

UART Synchronisatie

  • Asynchroon
    • Geen klok
  • Afhankelijk van de correcte instellingen
  • Reciever moet weten wanneer te stoppen met sampelen
    • d.m.v. Stop Bit
  • Reciever moeten weten wanneer te sampelen
    • d.m.v. Start Bit
  • Er wordt meestal gesampeld op 16x de baud rate

USART I/O Data Register 0

  • Een register voor zowel TX als RX buffer
  • uSart
    • De USART module kan gebruikt worden voor zowel UART als SPI in master mode
  • Als UDRE0 == 0, dan is het register beveiligd tegen overschrijven

USART Control and Status Register 0 A

  • Interrupt Flags
    • RXC0 - Recieve Complete Interrupt
    • TXCO - Transmit Complete Interrupt
    • UDRE0 - Data Register Empty Interrupt

  • Nitro
    • U2X0 - Dubbele snelheid voor de UART communicatie

USART Control and Status Register 0 B

  • Interrupt Flags
    • RXCIE0 - Recieve Complete Interrupt Enable
    • TXCIEO - Transmit Complete Interrupt Enable
    • UDRIE0 - Data Register Empty Interrupt Enable

  • Enable
    • RXEN0
    • TXEN0

  • Aantal data bits
    • UCSZ02
    • Zie ook UCSR0C

USART Control and Status Register 0 C

  • USART Mode Select
    • UMSEL0[1:0]

  • Parity Mode Select
    • UPM0[1:0]
    • 0 - Off

  • USART Stop Bit Select
    • USBS0
    • 0 - 1 bit

  • Character Size Select
    • UCSZ[2:0]
    • 0b011 - 8 bits

USART Baud Rate 0 Register Low/High

  • BAUD 12 bits
    • UBRR0[11:8] - UBRR0H
    • UBRR0[7:0] - UBRR0L

Baud Rate Berekenen

  • Opvangen van fouten
    • AVR
    • Arduino
      • `UBR Rn = (((F_(CPU) / 4) / (baud)) - 1) / 2`

Baud Rate Error

  • Magic Frequency
    • Systeemklok is een veelvoud van 1.8432 MHz

  • Tolerantie
    • Alles onder de 2% is acceptabel

  • Fouten onstaan door afrondingen

Voorbeeld Simpel Echo Programma


#define BAUDRATE 9600
#define BUADVAL (F_CPU / 8 / BAUDRATE - 1) / 2

char ReceivedByte ;

void setup() {
  UCSR0B = (1 << RXEN0 ) | (1 << TXEN0 );
  UCSR0C = (1 << UCSZ00 ) | (1 << UCSZ01 );
  UBRR0H = ( BUADVAL >> 8) ;
  UBRR0L = BUADVAL;

}

void loop() {
  // put your main code here, to run repeatedly:
  while ( UCSR0A & (1 << RXC0));
  ReceivedByte = UDR0 ;
  while (UCSR0A & (1 << UDRE0));
  UDR0 = ReceivedByte ;
}  
  

Pointers

Wat is een pointer

Een pointer is een variabele dat een geheugen locatie bevat van andere elementen in de code. Een pointer de adressen van volgende elementen bevatten

  • Een adres
  • Variabelen
  • Functies
  • Pointers

Geheugen is adresseerbare blok bits!

Wat is een pointer

  • Zorgt voor efficiëntere code
  • Verhoogt de complexiteit
  • Pointers hangen nauw samen met arrays
  • Pointer hangt vast aan een datatype

Wat is een pointer

Pointers Declaren


  int number = 10;
  int *pointer = &number;
    
Je wijst een adres toe aan een pointer

Pointer Operators

  • Adres &
    • Met & vraag je het adres op van een variable
  • Dereferencing *
    • Met * vraag je de achterliggende data op, * ook de indirection operator genoemd.

Pointer Voorbeelden

Declaratie Value Adres
int Val = 2 2 54428
int *pVal = &Val 54428 97880
int secVal = *pVal 2 97932
*pVal = 5 5 54428
pVal = pVal + 1 54444 (+16) 97880

Dus ...

  • int *p = &c
    • De pointer p wijst naar het locatie van c
  • int k = *p
    • k is gelijk aan de achterliggende data van p
  • *p = 0
    • De achterliggende data = 0
  • *j = *p
    • De achterliggende data van j is gelijk aan de achterliggende data van p

Oefening

  • Declareer 3 integers x, y en z met de respectievelijke waardes 1, 5, 155
  • Declareer 3 pointers p_x, p_y, p_z die verwijzen naar de geheugen locaties van x,y,z
  • Print de waardes af van de achterliggende data van de pointers als ook de locaties

Volgorde van bewerkingen

  • * en & hebben voorrang op rekenkundige operators
  • *, &, ++ en -- hebben dezelfde priorieit
  • * en & worden van rechts naar links geëvalueerd
  • *p++ en (*p)++ zijn verschillend
    • *p++ verhoogt het adres opgeslagen in p en haalt daarna de achterliggende data van het nieuwe adres op
    • (*p)++ verhoogte de achterliggende data op adres p

Volgorde van bewerkingen

Veronderstel dat

  • char c = 5
  • char *p
  • p = &c

Swap Functie

  • Het volgende stuk code swap de variabelen niet
  • Er word een lokale kopie gemaakt
  • Dit noemt Pass By Value
  • De originele data word beschermt

void swap(int x, int y){
int tmp;
tmp = x
x = y;
y = tmp;
}
void main(void){
int a = 10;
int b = 13;

swap (a, b);
}
/*y == ? && z == ?*/
      

Pass By Reference

  • De data wisselt tussen de variabelen
  • Toegang tot de variabele is mogelijk door indirecte toegang
  • Data moet niet gedupliceerd worden
  • Pass By Reference
  • Concept bestaat ook in andere programmeer talen

void swap(int *x, int *y){
int tmp;
tmp = *x
*x = *y;
*y = tmp;
}
void main(void){
int a = 10;
int b = 13;

swap (&a, &b);
}
/*y == ? && z == ?*/
      

Oefening

  • Declareer 3 integers x, y en z met de respectievelijke waardes 1, 5, 155
  • Schuif vanuit een functie de waarde x naar y, y naar z en z naar x

Pointers & Arrays

  • Arrays is een blok van dezelfde data types
  • Een array kan beschouwd worden als een pointer van hetzelfde type
  • Een pointer kan een startpunt zijn voor een array

int *p
int a[1O]

p = &(a[2]);

/*Dan klopt het volgende*/
*p = a[2];
*(p+ 1) = a[3];
    

Gevaren van pointers

  • Rechtstreekse manipulatie van het geheugen
  • Kent geen out of bounds
    • 
      int a[1O]
      int *p = &(a[0]);
      int i = a[11] //error
      int j = *(p + 15) //mogelijk
            
  • Datatypes zijn niet belangrijk (void *pointer)

Null Terminated C String

  • In C worden alle char arrays getermineerd door '\O'
    • char *x = "hello" == "hello\0"
    • char x[4] = "hello" == "hello\0"
  • Dit maakt het mogelijk om simpels char arrays te kunnen manipuleren

nt strlen(char *s) /* added by RJH; source: K&R p99 */
{
int n;

for(n = 0; *s != '\0'; s++)
{
  n++;
}
return n;
}
  

Lengte van een object

  • Pointer is een adres
  • Pointers geven niet altijd een lengte mee
  • Functies mbt tot buffers hebben meestal beide nodig
  • 
    void RF24::read(void *buf, uint8_t  len)
    bool RF24::write(const void *buf, uint8_t len)
        
  • De groote van een element - sizeof()

int data[10]="Hello World"
for (int i = 0; i < sizeof(data)/sizof(int); i++){
//dosomething
}
  

int data[10]="Hello World"
write(data, sizeof(data));
  

Oefening

Schrijf een functie met pointers waar je een 2 arrays aan elkaar rijgt (concat)