July 22nd, 2017

Externe Interrupts mit dem AVR leicht gemacht3

Die Unterschiede zwischen Polling und Interrupt sind in einem älteren Beitrag schon aufgelistet. Theorie findet man jedoch sehr oft. Hier findet ihr ein einfaches Beispiel wie man einen Taster per Interrupt eine Aktion ausüben lässt. Das Beispiel ist für einen AT90CAN128 mit folgender Hardwarekonfiguration:

  • - Taster an PORT E, PIN 7
  • - LED an PORT E, PIN 6

Beim Initialisieren aktiviert man die Interrupts und konfiguriert wann dieser ausgelöst werden soll:

//  Init Taster
DDRE  &= ~_BV(7);    // PORT E, PIN 7 als Eingang definieren

EIMSK |= _BV(INT7);  // Interrupt fuer Pin 7 aktivieren
EICRB |= _BV(ISC50); // steigende Flanke erzeugt einen INT
EICRB |= _BV(ISC51);

//  Init LED
DDRE  |= _BV(6);     // PORT E, PIN 6 als Ausgang definieren

sei();    //activate global interrups

In der ISR für Signal 7 kann dann eine Aktion erfolgen oder ein selbst erstelltes Flag (in einer Variablen) gesetzt werden.

//  ISR Taster
SIGNAL(SIG_INTERRUPT7)
{
  // LED an
  PORTE |= _BV(6);

  // entprellen
  delay_ms(100);
}

Die beiden Dateien stehen hier zur Verfügung.

Tags: , , ,


Beispiel CAN Bus Testapplikation für AT90CAN1289

at90can128 Ich habe es in letzter Zeit oft erlebt, dass sich angehende Mikrocontrollerprogrammierer mit dem AT90CAN beschäftigen wollen oder müssen um eine CAN Anwendung zu entwickeln. Dabei stößt man immer auf folgendes Problem: Man wird in den Wald geworfen und weiß nicht welchen Baum man zuerst studieren soll. Wenn man nach einfachen Testanwendungen sucht, dann findet man meist ausgeklügelte Bibliotheken oder Anwendungen wo man zunächst nicht durchsieht. Außerdem sind die meist viel zu umfangreich und können auch beide CAN 2.0 Standards. Diesem Problem mache ich heute ein Ende, hier folgt eine einfache Anwendung für den AT90CAN und eine kleine Einführung in die Software. Es sind alle Derivate des AT90CAN verwendbar (32, 64, 128), man muss selbstverständlich beim Kompilieren darauf achten den Richtigen einzustellen.

Beginnen wir mit der Struktur der Software:

- main.c Hauptdatei, Aufruf der Funktionen
- at90can.c Sourcedatei für CAN-Funktionen, inkl. ISR
- at90can.h Headerdatei für CAN, Definition der Struktur, Geschwindigkeiten
- utils.h Korrekte Definitionen für True/False und nützliche Dinge

Für die Variablen in denen CAN-Nachrichten gespeichert werden sollen wurde eine Struktur CAN_messageType erstellt. Die im Datenblatt empfohlenen Einstellungen für die Geschwindigkeiten sind in einem Feld (array) in der at90can.h hinterlegt. Die Applikation besteht nun darin, dass in der main-Funktion zunächst die Initialisierung aufgerufen wird und anschließend eine CAN-Botschaft testweise gesendet wird. Die Empfangenen Nachrichten werden nur in der globalen Variable recMsg abgespeichert, jedoch nicht weiter verarbeitet. Bei jeder Operation mit MObs muss die CANPAGE auf das entsprechende gesetzt werden.

Wichtig ist zunächst die korrekte Initialisierung. Der CAN-Controller muss zum konfigurieren in den config-mode versetzt werden um Geschwindigkeit und Interrupteinstellungen zu ändern. Die globalen Interrupts sollte man erst nach der Konfiguration aktivieren, denn sonst könnte mitten in der Konfiguration beim aktivieren der einzelnen Interrupts ein kommender die Konfiguration verfälschen. Zur Initialisierung des CAN-Controllers gehört das aktivieren des config-mode, die Einstellungen der Interrupts und das Setzen der Busgeschwindigkeit. Die Konfiguration der einzelnen MObs kann auch in gesonderten Funktionen erledigt werden.

Bei einem Empfang einer Nachricht wird in der entsprechenden Interrupt-Service-Routine (ISR) die CAN-Botschaft aus den Registern ausgelesen und in eine globale Variable gespeichert. Variablen die in einer ISR beschrieben werden sollen, müssen als volatile deklariert werden. Nach dem speichern der Daten muss der Interrupt durch readmodwrite resetet werden. Ebenso muss das Bit CONMOBn gesetzt werden, um erneut Empfangsbereitschaft zu signalisieren.

Zum Senden einer Nachricht werden die gewünschten Daten und ID in einer Variable gespeichert und die Funktion can_tx aufgerufen werden. Diese kopiert die Daten in die Register des Controllers und setzt das Bit CONMOBn des als Sender konfigurierten MOb.

Fragen, Anregungen oder Verbesserungsvorschläge können gerne als Kommentare erfolgen!

Tags: , , ,


Einstellungen im EEPROM eines AVR speichern2

Es gibt kaum eine Anwendung in der man keine Einstellungen speichern möchte. Doch wenn man sich schon den Aufwand macht Einstellungen zu speichern, sollten diese nach dem Reset auch wieder abrufbar sein. Daher wird so etwas im EEPROM gespeichert und ausgelesen. Wie man das ganz sinnvoll programmieren kann folgt hier:

Am sinnvollsten überlegt man sich vorher was zu speichern ist, dann erstellt man gesondert dafür eine Sourcedatei mit deren Header. Im Header erfolgt die Definition der Benötigten Bytes:

#define EEPROM_SECTION  __attribute__ ((section (".eeprom")))

/*
** this global variables are stored in EEPROM
*/
uint16_t  dummy          EEPROM_SECTION  = 0;  // avoid using lowest addresses

//——————————————————————————
// section 1: default settings
uint8_t   eeprom_def_brightness EEPROM_SECTION  = 1;  // EEPROM address 0002
uint16_t  eeprom_def_TempID     EEPROM_SECTION  = 2;  // EEPROM address 0003
uint8_t   eeprom_def_TempUnit   EEPROM_SECTION  = 3;  // EEPROM address 0005
uint16_t  eeprom_def_Filter     EEPROM_SECTION  = 4;  // EEPROM address 0006
uint8_t   eeprom_def_CANspeed   EEPROM_SECTION  = 5;  // EEPROM address 0008

// placeholder
uint16_t  eeprom_def_dummy1     EEPROM_SECTION  = 6;  // EEPROM address 0009
uint16_t  eeprom_def_dummy2     EEPROM_SECTION  = 7;  // EEPROM address 000B
uint8_t   eeprom_def_dummy3     EEPROM_SECTION  = 8;  // EEPROM address 000D
uint8_t   eeprom_def_dummy4     EEPROM_SECTION  = 9;  // EEPROM address 000E
uint8_t   eeprom_def_dummy5     EEPROM_SECTION  = 10; // EEPROM address 000F

//——————————————————————————
// section 2: user settings
uint8_t   eeprom_usr_brightness EEPROM_SECTION  = 11;  // EEPROM address 0010
uint16_t  eeprom_usr_TempID     EEPROM_SECTION  = 12;  // EEPROM address 0011
uint8_t   eeprom_usr_TempUnit   EEPROM_SECTION  = 13;  // EEPROM address 0013
uint16_t  eeprom_usr_Filter     EEPROM_SECTION  = 14;  // EEPROM address 0014
uint8_t   eeprom_usr_CANspeed   EEPROM_SECTION  = 15;  // EEPROM address 0016

// placeholder
uint16_t  eeprom_usr_dummy11    EEPROM_SECTION  = 16;  // EEPROM address 0017
uint16_t  eeprom_usr_dummy12    EEPROM_SECTION  = 17;  // EEPROM address 0019
uint8_t   eeprom_usr_dummy13    EEPROM_SECTION  = 18;  // EEPROM address 001B
uint8_t   eeprom_usr_dummy14    EEPROM_SECTION  = 19;  // EEPROM address 001C
uint8_t   eeprom_usr_dummy15    EEPROM_SECTION  = 20;  // EEPROM address 001D

Anschließend werden in der Sourcedatei die entsprechend der Reservierung benötigten Funktionen erstellt um die Werte zu lesen/schreiben.

#include <stdbool.h>
#include <stdint.h>
#include <avr/io.h>
#include <avr/eeprom.h>
#include "eeprom_access.h"

// returns the dataset from eeprom
uint16_t get_eeprom_word(uint8_t setting)
{
  uint16_t   eeprom_word;

  switch (setting)
  {
    case 12:
      eeprom_word = eeprom_read_word( &eeprom_usr_TempID );
      break;
    case 14:
      eeprom_word = eeprom_read_word( &eeprom_usr_Filter );
      break;
    default:
      break;
  }
  return eeprom_word;
}

// save data to eeprom
void set_eeprom_word( uint16_t eeprom_word, uint8_t setting )
{
  switch (setting)
  {
    case 12:
      eeprom_write_word( &eeprom_usr_TempID, eeprom_word );
        break;
    case 14:
      eeprom_write_word( &eeprom_usr_Filter, eeprom_word );
        break;
    default:
      break;
  }
}

// returns the dataset from eeprom
uint8_t get_eeprom_byte(uint8_t setting)
{
  uint8_t   eeprom_byte;

  switch (setting)
  {
    case 15:
      eeprom_byte = eeprom_read_byte( &eeprom_usr_CANspeed );
        break;
    default:
      break;
  }

  return eeprom_byte;
}

// save data to eeprom
void set_eeprom_byte( uint8_t eeprom_byte, uint8_t setting )
{
  switch (setting)
  {
    case 15:
      eeprom_write_byte( &eeprom_usr_CANspeed, eeprom_byte );
        break;
    default:
      break;
  }
}

In der main-Datei (oder wo man die Funktion aufrufen möchte) muss anschließend definiert werden wie die Einstellungen heißen und die externen Funktionen deklariert werden.

//——–
// EEPROM
//——–
// settings
#define CAN_Speed 15
#define CAN_Filter 14
#define Temp_ID 12

extern void set_eeprom_byte( uint8_t eeprom_byte, uint8_t setting );
extern uint8_t get_eeprom_byte(uint8_t setting);
extern void set_eeprom_word( uint16_t eeprom_word, uint8_t setting );
extern uint16_t get_eeprom_word(uint8_t setting);

Der Aufruf aus der main-Datei könnte dann wie folgt aussehen:

CANspeed = get_eeprom_byte(CAN_Speed);

set_eeprom_byte(CANspeed, CAN_Speed);

Tags: , ,


Alientech Powergate im Check4

Ich hatte neulich mal die Gelegenheit ein ECU-flasher (Programmiergerät für Motorsteuergerät) zu testen. Das Gerät kam aus dem Hause Alientech und nennt sich Powergate Pro. Interessant zu sehen fand ich, dass auch hier ein AT90CAN128 als Controller verwendet wurde, ein recht bekannter Chip mit integriertem CAN Controller und einigen mächtigen Features. Daneben platzierte man die üblichen Verdächtigen wie FT245BL, M6636B, 7805C, PCA82C250 und vier Flashbausteine a 16MB AT45DB161.

powergate

Zu sagen ist, dass die Komponenten recht gut verlötet sind und sehr sauber platziert. Die Leiterbahnverlegung und Anordnung der Controller halte ich allerdings für fragwürdig. Negativ anzumerken ist, dass ein Fahrzeug nur einmal geflasht werden kann.

Tags: , ,


CANlogger mit Temperaturmessung0

Vor einiger Zeit hatte ich das Konzept der Projektarbeit schon einmal vorgestellt. Nun wurde Version 1.0 fertig gestellt.

Features:

  • - Temperaturmessung mit Thermoelement und MAX6675
  • - ISP Stecker nach ATMEL Standard
  • - Schutz zum CAN durch DC-DC und Optokoppler
  • - CAN Stecker ist CAN-CiA konform
  • - Stromversorgung wählbar zwischen CAN und extern
  • - zusätzlich I²C EEPROM auflötbar für große Bilder
  • - Einstellmöglichkeit mit Drehgeber für CAN-Speed, ID und Filter
  • - Anzeige von empfangenen CAN-Nachrichten auf dem TFT
  • - 65k Farb-TFT mit 176×132 Pixel von display3000

Hier eine kleine Demo des Moduls:

Tags: , , , , ,


Fehler bei AVR ISP Parallel-Programmieradapter0

Ich habe bereits zweimal den scheinbar unerklärlichen Fehler gehabt, dass bei einem Flashvorgang der AVR plötzlich nicht mehr antwortet. Nach viel Kontakt mit Atmel und einigen Profis konnte ich den Fehler trotzdem nicht lokalisieren.

Vor einigen Tagen nun habe ich mich mit einem Elektroniker unterhalten, der diesen Fehler auch hatte und genauer nachgeforscht hat. Es wurde in beiden Fällen der Programmieradapter von Robotikhardware verwendet. Hier wurde allerdings ein einfacher Schaltplan von früher verwendet, der sich damals weit verbreitet hatte. Hier fehlt eine Diode um die Spannung auf 5V zu begrenzen, denn RS232 hat ja einen höheren Pegel als 5V. Bei einer bestimmten Kombination von Code wird der Massepegel des AVR abgesenkt und daher der Spannungspegel über 5V angehoben. Das passiert nur wenn die Pegel zweier aufeinanderfolgenden Befehle die maximale Differenz haben. Da ist der Port nicht schnell genug und durch die fehlende Diode entsteht kurzzeitig ein Peak von mehr als 5V. Das ist der Grund warum der AVR unvorhergesehen kaputt geht.

Tags: , ,


Inkrementalgeber Auswertung6

Die Zeit der Taster oder sogar Bedienkreuze ist schon lange vorbei. IMG_5950Seit vielen Jahren werden in Radios, Navis, Handys,etc. so genannte Inkrementalgeber (encoder) eingesetzt. Mit Knopf oder ohne (Taste). Immer öfter werden diese kleinen Dinger auch im Hobbybereich interessant und verwendet. Die Ansteuerung in der Firmware ist zwar recht einfach, jedoch möchte ich euch den Weg erleichtern, so dass keiner das Rad zweimal erfinden muss.

Es ist empfehlenswert die im Datenblatt angegebene Beschaltung mit Entprellung und Strombegrenzung aufzubauen, falls keine vorhanden ist: 10k gegen Vcc, 10k zum µC-Pin und 100nF gegen GND. Die Abfrage gestaltet sich per Interrupt am sinnvollsten, denn wenn man den Flankenwechsel detektiert hat sollte sofort der Level des anderen Signals abgefragt werden. Meist bekommt man vom Hersteller nur so ein winziges Diagramm:

phase_diag

Es ist ja schon aussagekräftig, allerdings dauert es ein paar Minuten bis man mit der richtigen Sichtweise darauf schaut. Es gibt vier Fälle, je zwei pro Drehrichtung. Man lässt Signal A per Levelchange Interrupt Triggern und fragt danach Signal B ab. Hier ein Beispiel: Signal A steigende Flanke. Wenn dann Signal B low ist, dann war es eine ClockWise Rotation. (Zeitpunkt zwischen T2 und T3, C.W.) Hier die ISR:

code_a Immer daran denken: Variablen auf die in der ISR zugegriffen werden soll als volatile deklarieren!

Tags: , ,


CAN Spezifikation2

Mit der Zeit kommen bei mir so die Projekte zusammen, in letzter Zeit gehäuft mit CAN. Temperatureinheit, Grafikeinheit, CANtoRS232 oder Mainboard für den Jugend forscht Truck. Aktuellestes Projekt ist ein CAN-/Temperaturlogger.

Gerne greift man später mal in den Schrank und möchte ein Modul mit einem Anderen zu Testzwecken verbinden. Damit das möglich ist, müssen alle mindestens eine bestimmte CAN-Baudratenkonfiguration unterstützen die bei allen gleich ist. Mehrere Geschwindigkeiten sind natürlich möglich, aber prinzipiell nicht erforderlich. Um das zu gewährleisten, damit man in 3 Jahren nicht ein Modul nur deswegen neu flashen muss habe ich eine CAN-Spezifikation definiert. Sie ist in erster Linie für mich, jedoch möchte ich sie euch nicht vorenthalten. Man muss ja nicht jedes Rad neu erfinden.

can_spezifikation

Tags: , ,


Zweiter Test des 2,1″TFT0

Wiedereinmal muss ich euch mit dem Display nerven. Aber ihr werden sehen..es hat seinen Grund!

Ich habe nach dem erfolgreichen Test1 mit Linien nun eine Vollgrafik in den Controller geladen und dargestellt. Das Ergebnis ist….ja, mir fehlen die Worte! Einfach unglaublich, seht selbst!

Nochwas: Es steht nicht umsonst in dem Programmierhandbuch, man solle es unbedingt komplett lesen bevor man anfängt. Der Grafikkonverter ist zwar sehr hilfreich, aber die Ausgabe dessen muss hinterher angepasst werden!

Tags: , , ,


Evaluationboard für AT90CAN TQFP641

Mit freundlicher Unterstützung von Mark C. konnte ich am Wochenende ein sehr praktisches Evaluationboard für den AT90CANxx aufbauen. Ursprünglich wollte ich einen Adapter für den Chip bauen um ihn auf mein Steckbrett stecken zu können, das erwies sich allerdings schnell als unhandlich.

Da der AT90CANxx einer der wenigen AVRs ist, die per PDI und PDO programmiert werden (siehe hier), ist das Board speziell für diesen TQFP64 AVR entwickelt. Wenn man diese Pininkompabilität ausmärzt kann man theoretisch jeden AVR damit betreiben. Jedoch muss er aufgrund der Bauform direkt aufgelötet werden.

Features:

ISP Programmierung, CAN treiber onboard, MAX208 onboard, zwischen 5,0V und 3,3V Betriebsspannung (AVR und Ports getrennt) wählbar, Betriebsspannungen an extra klemmen abgreifbar, an jedem Port-Wannenstecker Port-Betriebsspannung und GND verfügbar, RTS und CTS lines per Jumper trennbar, 2 RS232 Schnittstellen

Schaltplan evboard_tqfp64

Tags: , ,


Unterschiede bei ISP-Programmierung von AVRs2

Normalerweise wird ein AVR über ISP immer durch MOSI und MISO programmiert, dass sind die SPI Input und Output Anschlüsse. Wer jedoch den AT90CANxx zum ersten mal anfasst wird schnell eine Überraschung erleben.

Denn wie im Datenblatt Seite 345 unter “Signal Names” beschrieben sind bei dem Chip und sicher auch bei wenigen weiteren die MOSI und MISO Pins auf PDI und PDO gemappt. Also, immer genau hinschauen!

Tags: , ,


AVR Programmer für USB0

Viele kennen das Problem…kein Serialport mehr mit D-SUB9, kein Parallelport mehr. Also muss ein Gerät für USB her. Da bieten sich viele an, USBprog, USBasp, MKII, usw.

Alle funktioniern sicherlich unterschiedlich schnell und unterschiedlich komfortabel. Einen AVR können sie alle flashen. Wer sich einen einfachen Brenner mit nur einem Atmel und nur einem Layer auf der Platine nachbauen möchte ist mit dem USBASP von Thomas Fischl am besten beraten. Einfach Platine herstellen, bestücken, Mega8 flashen und USB Treiber auf dem PC installieren. Dann kann man bequem mit Batchdatei oder Burn-O-mat für AVRdude arbeiten.

Wer das Layout noch ein bisschen komprimiert bekommt es sogar in eine Schachtel für Büroklammern.

Tags: , ,


JuFo wir kommen4

Ein neues Projekt ist geschaffen und damit haben wir uns gleich mal bei Jugend Forscht 2008 angemeldet. Zunächst bestand die Idee ein ferngesteuertes Auto energiesparend zu machen und das mithilfe von Solarzellen. Das Projekt “LET”- low energy truck - ist geboren. Inzwischen hat sich die Idee so weiterentwickelt, das wir einen 90cm langen Truck ausgesucht haben, auf den wir 5 Solarzellen basteln wollen. Die Elektronik kommt ins Innere des Hängers. Außen wird ein LCD-Display angebracht, das durch einen Mikrocontroller gesteuert wird. Die bereits vorhandene Elektronik wird um einen Akku erweitert, der die Solarenergie speichert. Außerdem wird die Elektronik von uns umgebaut, sodass auch diese noch stromsparender ist. Diese Energieersparnis wird auf dem Display angezeigt. Da wir es jedoch nicht selber finanzieren wollten beschlossen wir an diesem Wettbewerb teilzunehmen und den Föderverein meiner Schule um Unterstützung zu bitten. Dieser lässt sich jedoch Zeit, also haben wir die Solarzellen und den Truck bereits bestellt. Da Conrad sehr schnell liefert liegen die Solarzellen bereits auf dem Schreibtisch, während der Truck noch sehnsüchtig auf sich warten lässt. Auch das LCD-Display ist schon vorhanden und ich übe fleißig das programmieren des Mikrocontrollers, da dies mein Debütprojekt in diesem Bereich ist. Damit sind die ersten Schritte auf dem Weg zum Wettbewerb gemeistert.

Tags: , , , , , , , ,


Imhotep theme designed by Chris Lin. Proudly powered by Wordpress.
XHTML | CSS | RSS | Kommentare-RSS