EPRO1 AVR bord.

© Harry Broeders.

Deze pagina is bestemd voor studenten van de Haagse Hogeschool - TH Rijswijk/Academie voor Engineering groep EP2.1.

In het blok EP1.1 heb je bij het EPRO1 project een inbraakalarm gemaakt. Dit inbraakalarm bevat een AVR ATmega16 micorcontroller en kan dus ook voor heel andere zaken gebruikt worden door de AVR anders te programmeren. Je kunt dit bord prima gebruiken om de dingen die je bij PROS2 leert te oefenen. De klokfreqentie van de ATmega16 op het EPRO1 bord is 8 MHz. Het schema kun je hier vinden.

Als je een programma wilt draaien op het EPRO1 bord dan moet je het programma met AVR Studie bouwen en met PonyProg laden. Je kunt deze tools eenvoudig thuis installeren:

Practicumopdracht 1.

Practcicumopdracht 1 kun je prima op het EPRO1 bord maken:

Theorieles 1.

Het in de eerste theorieles behandelde programma kun je ook prima draaien op het EPRO1 bord. Vergeet niet om de CPU frequentie in te stellen bij de Project Options. Deze frequentie wordt namelijk gebruikt door de _delay_ms functie.

Kies de menuoptie Project, Configuration Options en stel de frequentie in op 8000000 Hz.

Knightrider by Night....De LEDs op het EPRO1 bord werken anders dan op het STK500 bord. De LEDs op het STK500 worden aangezet met een 0 en uitgezet met een 1. De LEDs op het EPRO1 bord worden aangezet met een 1 en uitgezet met een 0. Als je het voorbeeld programma uitvoert op het EPRO1 bord zijn er dus steeds 2 LEDs uit en 6 LEDs aan (de onderste 2 LEDs zijn niet aangesloten en dus ook altijd uit). Tip: Vergeet niet om de jumper (rechts boven de LEDs) te plaatsen!

Opdracht: Pas het programma aan zodat de LEDs op het EPRO1 bord op dezelfde manier "lopen" als op het STK500 bord. Dus steeds 2 LEDs aan.

Theorieles 2.

Opdracht: Pas de functie om 1 seconde te wachten (zie AVR boek pagina 44 t/m 46) aan zodat bij een klokfrequentie van 8 MHz 1 seconde wordt gewacht. Om deze functie te testen kun je in het programma uit les1 de functie wait vervangen door functie wacht1sec. Je kunt natuurlijk ook de in de les besproken alternatieve oplossing gebruiken (TCNT0 steeds resetten).

Theorieles 3.

De alternatieve implementatie van de functie wacht1sec met behulp van de TOV0 flag kan zonder problemen op het EPRO1 bord draaien. De 160 en 10 moeten natuurlijk wel aangepast worden omdat de frequentie 8 MHz is. De instructie om alle LEDs uit te schakelen moet ook worden aangepast omdat de LEDs op het EPRO1 bord worden uitgezet met een 0.

Opdracht: Pas het programma timer_counter0_overflow.c aan zodat LED7 1x per seconde knippert.

Het programma timer_counter0_interrupt.c dat gebruik maakt van de TIMER0_OVF_vect interrupt om LED7 te laten knipperen en dat in het hoofdprogramma SW6 inleest en kopieert naar LED6 kan met dezelfde aanpassingen als het vorige programma getest worden op het EPRO1 bord.

Practicumopdracht 2.

Practcicumopdracht 2 kun je prima op het EPRO1 bord maken.

LCD functies.

De LCD functies kun je prima op het EPRO1 bord gebruiken. Zie hier voor een stap voor stap handleiding.

Theorieles 4 en 5.

De programma's met de ADC kun je ook op je EPRO1 bord testen. Je moet dan wel zelf een potentiometer aansluiten. Pin PA0 is zoals je in het schema kunt zien aangesloten op header H3. Deze header is beschikbaar links onder het toetsenbord van het EPRO1 bord. De bovenste pin is pin 1 in het schema. De header is in het schema dus ondersteboven getekend:

Je kunt een potentiometer van bijvoorbeeld 10K als volgt aansluiten zodat je de spanning op PA0 kunt variëren:

Let op: PA0 is ook verbonden met SW0. Je moet er voor zorgen dat deze DIP switch open staat.

Het resultaat van het programma adc_epro1.c als PA0 verbonden is met VCC is hieronder te zien:

Mijn EPRO1 bord geeft overigens als PA0 verbonden is met GND de waarde 1 in plaats van de waarde 0.

In het programma adc_double_epro1.c wordt de 10 bits digitale waarde van de ADC omgerekend naar een voltage tussen 0.00 en 5.00 V.

Practicumopdracht 3.

Practcicumopdracht 3 kun je op het EPRO1 bord maken als je zelf een potentiometer aansluit op PA0 (zoals hierboven beschreven). Als je in plaats van pin PB6 de pin PD4 aanstuurt als de temperatuur te hoog wordt dan kun je via het relais een echt koelelement aansluiten op J3 van je EPRO1 bord. Helaas is er maar 1 relais aanwezig op het bord dus de verwarming kan niet echt worden geschakeld. Bij mijn EPRO1 bord wordt de schakelaar van het relais gesloten als PD4 0 wordt en geopend als PD4 1 wordt. Dat is net andersom als in het schema staat?

Theorieles 6.

Het EPRO1 bord is ook voorzien van een speaker. Deze is aangesloten op PD5 = OC1A.

Opdracht: Pas het programma timer_counter0_kamertoon.c dat een kamertoon (440 Hz) genereert op PB3 = OC0 aan zodat de toon op PD5 wordt gegenereerd. Let op: T/C1 is een 16 bits telller/counter en OC1A is dus ook 16 bits. Je kunt in dit geval dus een prescaler waarde van 1 gebruiken om de frequentie zo nauwkeurig mogelijk te genereren. De registers OCR1A, TCCR1A, TCCR1B en DDRD moeten van een waarde worden voorzien. Maak gebruik van tabel 44, tabel 47 en tabel 48 uit de ATmega16 datasheets. De klokfrequentie op pin PD5 = OC1A kan berekend worden met de formule:

 

n = 1, fclk_I/O = 8 MHz en N = de prescale factor (zie tabel 48).

Theorieles 7.

Het programma om met PWM een LED te dimmen timer_counter0_PWM_low_25.c kun je prima testen op het EPRO1 bord.

Practicumopdracht 4a.

Practcicumopdracht 4a kun je prima op het EPRO1 bord maken. Je moet wel rekening houden met het verschil in klokfrequentie.

Practicumopdracht 4b.

Practcicumopdracht 4b kun je prima op het EPRO1 bord maken. Je moet wel rekening houden met het verschil in klokfrequentie.

Practicumopdracht 4c.

Practicumopdracht 4c kun je alleen op het EPRO1 bord maken als je zelf een potentiometer hebt aangesloten, zoals hierboven besproken is.

Practicumopdracht 5a en 5b.

Practicumopdracht 5a en practicumopdracht 5b kunnen helaas niet op het EPRO1 AVR bord getest worden omdat er geen 555 Timer op het EPRO1 bord aanwezig is.

Theorieles 8.

Het programma dat Timer/Counter0 gebruikt om na 24 neergaande flanken een interrupt op te wekken timer_counter0_counter_interrupt.c kan goed getest worden op het EPRO1 bord. Als uitgang PD6 hoog gemaakt wordt dan wordt geteld hoe vaak de 0 toets van het toetsenbord is ingedrukt en weer losgelaten.

Theorieles 9, 10 en 12.

Het USART programma's USART_echoput.c, USART_echoput_interrupt.c en avrserial.c kunnen prima op het EPRO1 bord getest worden. Je moet wel rekening houden met het verschil in klokfrequentie (8 in plaats van 3,6864 MHz) bij het bereken van de juiste waarde van het UBRR register.

Practicumopdracht 6a.

Practicumopdracht 6a kun je op het EPRO1 AVR bord testen als je zelf een potentiometer aansluit op PA0, zoals hierboven besproken is.

Practicumopdracht 6b.

Practicumopdracht 6b kun je helaas niet op het EPRO1 AVR bord testen omdat er geen 555 Timer op het EPRO1 bord aanwezig is.

Extra.

Hier is een functie om het toetsenbord van het EPRO1 bord in te lezen keypad.c.

#include <avr/io.h>
#include <stdint.h>
#define F_CPU 8000000UL
#include <util/delay.h>

/* char scankey()
 *  Deze functie geeft de op dit moment ingedrukte toets van het keyboard
 *  in ASCII code terug. Als er geen toets is ingedrukt wordt het NUL karakter
 *  '\0' teruggegeven.
 *  Rij-signalen PB3, PB2, PB1 en PB0 (van boven naar beneden).
 *  Kolom-signalen PD7, PD6 en PC0 (van links naar rechts).
 *  Deze functie stuurt de rij-signalen en leest de kolom-signalen.
 */

char scankey() {
    static const char keys[]={'\0','1','2','3','4','5','6','7','8','9','*','0','#'};
    uint8_t keyindex, teller;

    DDRD&=~0xc0;
    PORTD|=0xc0;
    DDRC&=~0x01;
    PORTC|=0x01;
    DDRB|=0x0f;
    PORTB=0x00;
    _delay_ms(1);
    keyindex=0;
    if ((PIND&0xc0)!=0xc0||(PINC&0x01)!=0x01) {
        // key found start scan:
        PORTB=0x07;
        _delay_ms(1);
        for (teller=0; teller<4; ++teller) {
            if ((PIND&0xc0)!=0xc0||(PINC&0x01)!=0x01) {
                // key found
                if ((PIND&0x80)!=0x80) keyindex+=1;
                else if ((PIND&0x40)!=0x40) keyindex+=2;
                else if ((PINC&0x01)!=0x01) keyindex+=3;
                break;
            }
            if (teller!=3) {
                PORTB>>=1;
                _delay_ms(1);
                keyindex+=3;
            }
            else
                keyindex=0;
        }
    }
    return keys[keyindex];
}

int main() {
    while (1) {
        char c=scankey(); // use debugger to test
    }
    return 0;
}