Forum: Mikrocontroller und Digitale Elektronik Cortex M4E 16E Treiberprobleme


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Ferid M. (fried)


Bewertung
0 lesenswert
nicht lesenswert
Hallo allesamt,

ich habe in einem Projekt ein Problem mit den Atmel IO Treibern, die 
einem zur Verfügung gestellt werden. Es handelt sich um ein an der Uni 
entwickeltes Board, dass für studentische Projekte genutzt werden soll 
und das ich gerade teste. Es sind einige Peripherigeräte angeschlossen 
für Ethernet, SD, CAN, ein Motortreiber und für die IO gibt es Rotary 
Encoder, ein Display und eine Taster-Matrix. Das Board benutzt den 
SAM4E16C mit FreeRTOS fürs Task Management.
Es wird AVR Studio 6.2 genutzt und ein SAM-ICE als Schnittstelle 
verwendet .

Das Problem an dem ich gerade hänge liegt bei der Taster-Matrix. Bei 
dieser wird jede Spalte von Knöpfen normal auf ein High Signal gezogen 
und an jeder Reihe abwechselnd ein Low Signal vom uC angelegt. Wenn ein 
Knopf gedrückt wird, dann wird das Signal der Spalte auf das Niveau der 
Reihe gezogen und dort lässt sich für einen kurzen Interval das Low 
Signal der Reihe auslesen.
Wenn an einer Spalte ein Low Signal erkannt wird, dann kann die Nummer 
des Knopfes aus Reihe und Spalte berechnet werden. Das ist die 
Funktionsweise.

Zum Einarbeiten habe ich zunächst den Code von jemand anderes 
übernommen, der mit der Vorgängerversion von dem Board gearbeitet hat, 
und damit ein bisschen getestet. Leider konnte ich mit meinem Code nur 8 
von 12 Knöpfen erkennen und mit dem Oszilloskop an einer Reihe gar kein 
Signal abgreifen. Es stellte sich heraus, dass für das Projekt das Model 
SAM4E16E verwendet wurde und dieser ein 144-pin uC ist. Ein paar Pins 
sind dort anders belegt, sodass ich das Projekt neu angelegt habe für 
den SAM4E16C.

Der gleiche Code, der in dem vorherigen Projekt noch zum Teil 
funktionierte liefert hier leider andere Ergebnisse. Es lassen sich nun 
wie erwartet alle Reihen richtig ansprechen und die angelegten 
Signalverläufe entsprechen den Erwarnten (mit dem Oszilloskop getestet). 
Wenn die IO-Funktion "ioport_get_pin_level" benutzt wird liefert diese 
immer das gleiche (High Level) Ergebnis, obwohl beim direkten Messen der 
Leitung etwas anderes angezeigt wird.

Die genau Position des Problems wäre also die Abfrage: val_col = 
ioport_get_pin_level(BUTTON_COL1);   , da diese immer ein High Pegel 
ausgibt, auch wenn ein Low Pegel anliegt. Wenn der Pin als Ausgang 
geschaltet ist, lässt sich dort problemlos ein Low Pegel ansetzen.

Falls jemand eine Idee hat, wie sich das Verhalten erklären lässt, wäre 
ich sehr dankbar für Hinweise. Ich erkläre gerne weitere Punkte, falls 
noch etwas unklar ist.
 #include <asf.h>
#include <string.h>
#include <stdint.h>
#include "conf_board.h"
#include "IO_PINS.h"

/***************Defines for the tasks****************************/
xQueueHandle QueueButtons;

xTaskHandle task_buttonreaction ;
xTaskHandle task_buttons ;

void task_Buttons(void *pvParameters);
void task_ButtonReaction(void *pvParameters);


void task_Buttons(void *pvParameters){
  unsigned char val_col = 1;
  char butten_number=0, old_button1=0, old_button2=0, old_button3=0, old_button4=13, row=0;
  while(1){
    for (int col=0;col<=2;col++){
      val_col=1;
      switch (col){  
        case 0: val_col = ioport_get_pin_level(BUTTON_COL1);  break;
        case 1: val_col = ioport_get_pin_level(BUTTON_COL2);  break;
        case 2: val_col = ioport_get_pin_level(BUTTON_COL3);  break;
      }
      
      if(!(val_col==0)){                  // When val_col==0 a button was pressed
        butten_number=(row)*3+(col+1);          // Calculates the button number (1-12) by row+column
      }
    }
    
    // Resets the ROW-pins to "1"
    switch (row){
      case 0: ioport_set_pin_level(BUTTON_ROW1,IOPORT_PIN_LEVEL_HIGH); break;
      case 1: ioport_set_pin_level(BUTTON_ROW2,IOPORT_PIN_LEVEL_HIGH); break;
      case 2: ioport_set_pin_level(BUTTON_ROW3,IOPORT_PIN_LEVEL_HIGH); break;
      case 3: ioport_set_pin_level(BUTTON_ROW4,IOPORT_PIN_LEVEL_HIGH); break;
    }
    // Selects next row and sets the level of this row to "0"
    if (row==3)  { row=0; } else { row++; }
      
    switch (row){
      case 0: ioport_set_pin_level(BUTTON_ROW1,IOPORT_PIN_LEVEL_LOW); break;
      case 1: ioport_set_pin_level(BUTTON_ROW2,IOPORT_PIN_LEVEL_LOW); break;
      case 2: ioport_set_pin_level(BUTTON_ROW3,IOPORT_PIN_LEVEL_LOW); break;
      case 3: ioport_set_pin_level(BUTTON_ROW4,IOPORT_PIN_LEVEL_LOW); break;
    }
    vTaskDelay(1);
  }
}



von W.S. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ferid Mahdi schrieb:
> Wenn die IO-Funktion "ioport_get_pin_level"...

Könntest du eventuell mal versuchen, die benötigten HW-Ressourcen direkt 
anzusprechen und dir dabei zugleich einen Gedanken zu machen, wieviel 
Zeit zum Einschwingen der Signale von und zu den Tasten tatsächlich 
vonnöten ist, bevor man beim Abfragen den tatsächlichen Zustand 
herauskriegen kann?

Jedes Vorhaben - auch das Abfragen von Bedientasten - bedarf einer 
Strategie, also eines Gedanken, WIE zum Kuckuck man das 
bewerkstelligen will. Deine scheint nicht zu taugen, also bemühe deine 
grauen Zellen um eine bessere Strategie.

W.S.

von Gerhard (Gast)


Bewertung
0 lesenswert
nicht lesenswert

von Ferid M. (fried)


Bewertung
0 lesenswert
nicht lesenswert
Die Einschwingungszeit, wenn ein neuer Pegel angesetzt wird liegt 
zwischen 50-100ns (gemessen) und damit 4 Größenordnungen unter dem 
angesetzten Zeitraum von 1ms, der gewartet wird, bis das Signal 
abgegriffen wird. Nach Datenblatt werden nur minimale Werte für High und 
Low Level Pulse Rise/Fall-Time angegeben welche dort für die Pin Groups 
bei ~ 10-20ns liegen, also kommt das gut hin.

Der gleiche Code funktioniert in einem vorherig erstellten Projekt, auch 
wenn er nicht die unbedingt gut und schön ist, sollte er durch die 
Portierung nicht sein Verhalten komplett ändern... Es kann gut sein, 
dass der Fehler an einer ganz anderen Stelle ist und die Frage deswegen 
hier nichts zu suchen hat. Da ich es derzeit leider nicht genau weiß, 
wollte ich fragen, ob jemanden ein Problem mit den IO Funktionen 
geläufig ist.

von Ferid M. (fried)


Bewertung
0 lesenswert
nicht lesenswert
Das Problem ist jetzt wohl gelöst. Aus dem  Atmel Studio 6.1 Projekt 
waren noch configs für ein anderes Board (EK) vorhanden, wodurch die 
unterschiedliche Pinbelegung zustande kam. Mit angepasster 
Initialisierung hat es dann funktioniert. Auch wenn der Code für die 
Taster nicht der Beste ist, ging es nur darum rudimentale Funktionalität 
zu zeigen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.