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.
1 | #include <asf.h>
|
2 | #include <string.h>
|
3 | #include <stdint.h>
|
4 | #include "conf_board.h"
|
5 | #include "IO_PINS.h"
|
6 |
|
7 | /***************Defines for the tasks****************************/
|
8 | xQueueHandle QueueButtons;
|
9 |
|
10 | xTaskHandle task_buttonreaction ;
|
11 | xTaskHandle task_buttons ;
|
12 |
|
13 | void task_Buttons(void *pvParameters);
|
14 | void task_ButtonReaction(void *pvParameters);
|
15 |
|
16 |
|
17 | void task_Buttons(void *pvParameters){
|
18 | unsigned char val_col = 1;
|
19 | char butten_number=0, old_button1=0, old_button2=0, old_button3=0, old_button4=13, row=0;
|
20 | while(1){
|
21 | for (int col=0;col<=2;col++){
|
22 | val_col=1;
|
23 | switch (col){
|
24 | case 0: val_col = ioport_get_pin_level(BUTTON_COL1); break;
|
25 | case 1: val_col = ioport_get_pin_level(BUTTON_COL2); break;
|
26 | case 2: val_col = ioport_get_pin_level(BUTTON_COL3); break;
|
27 | }
|
28 |
|
29 | if(!(val_col==0)){ // When val_col==0 a button was pressed
|
30 | butten_number=(row)*3+(col+1); // Calculates the button number (1-12) by row+column
|
31 | }
|
32 | }
|
33 |
|
34 | // Resets the ROW-pins to "1"
|
35 | switch (row){
|
36 | case 0: ioport_set_pin_level(BUTTON_ROW1,IOPORT_PIN_LEVEL_HIGH); break;
|
37 | case 1: ioport_set_pin_level(BUTTON_ROW2,IOPORT_PIN_LEVEL_HIGH); break;
|
38 | case 2: ioport_set_pin_level(BUTTON_ROW3,IOPORT_PIN_LEVEL_HIGH); break;
|
39 | case 3: ioport_set_pin_level(BUTTON_ROW4,IOPORT_PIN_LEVEL_HIGH); break;
|
40 | }
|
41 | // Selects next row and sets the level of this row to "0"
|
42 | if (row==3) { row=0; } else { row++; }
|
43 |
|
44 | switch (row){
|
45 | case 0: ioport_set_pin_level(BUTTON_ROW1,IOPORT_PIN_LEVEL_LOW); break;
|
46 | case 1: ioport_set_pin_level(BUTTON_ROW2,IOPORT_PIN_LEVEL_LOW); break;
|
47 | case 2: ioport_set_pin_level(BUTTON_ROW3,IOPORT_PIN_LEVEL_LOW); break;
|
48 | case 3: ioport_set_pin_level(BUTTON_ROW4,IOPORT_PIN_LEVEL_LOW); break;
|
49 | }
|
50 | vTaskDelay(1);
|
51 | }
|
52 | }
|