Forum: Compiler & IDEs I2C-Irq-Interupt für ARM-Microcontroller


von Alex T. (mikro_step)


Lesenswert?

Hallo,
ich möchte vom ARM-LPC2xxx-Mikrocontroller an LCD-Display über ein 
I2C-Bus Daten schicken, also "Bilder auf LCD-Display übertragen" und 
habe ein Beispiel für Datenübertrageung über ein I2C-Bus, aber nicht für 
LCD, bei NXP gefunden:
1
#include"LPC210x.h"
2
void Initialize(void);
3
/* I2C ISR */
4
__irq void I2C _ISR(void);
5
/* Master Transmitter states */
6
void ISR_8(void);
7
void ISR_18(void);
8
void ISR_28(void);
9
/*************************** MAIN ************************/
10
int main(){
11
   /* Initialize system */
12
   Initialize ();
13
   /* Send start bit */
14
   I2C ONSET=0x60;
15
   /* Do forever */
16
   while(1)
17
   {      IOCLR=0x40;
18
      IOSET=0x40;   }
19
}
20
/*************** System Initialization ***************/
21
void Initialize()
22
{
23
   /* Remap interrupt vectors to SRAM */
24
   MEMMAP=0x2;
25
   /* Initialize GPIO ports to be used as indicators */
26
   IODIR=0xF0;
27
   IOSET=0xF0;
28
   /* Initialize Pin Connect Block */
29
   PINSEL0=0x50;
30
   /* Initialize I2C */
31
   I2CONCLR=0x6c;/* clearing all flags */
32
   I2CONSET=0x40; /* enabling I2C */
33
   I2SCLH=0xC; /* 100 KHz */
34
   I2SCLL=0xD;
35
   /* Initialize VIC for I2C use */
36
   VICINTSEL=0x0; /* selecting IRQ */
37
   VICINTEN= 0x200; /* enabling I2C */   
38
   VICCNTL0= 0x29; /* highest priority and enabled */
39
   VICVADDR0=(unsigned long) I2C_ISR;   
40
   /* ISR address written to the respective address register*/
41
}
42
/********************** I2C ISR **************************/
43
__irq void I2C_ISR()
44
{
45
   int temp=0;
46
   temp=I2STAT;
47
   switch(temp)
48
   {
49
      case 8:
50
         ISR_8();
51
         break;
52
      case 24:
53
         ISR_18();
54
         break;
55
      case 40:
56
         ISR_28();
57
         break;
58
      default :
59
         break;
60
    }
61
VICVADDR=0xFF;
62
}
63
/* I2C states*/
64
/* Start condition transmitted */
65
void ISR_8()
66
{
67
   /* Port Indicator */
68
   IOCLR=0x10;
69
   /* Slave address + write */
70
   I2DAT=0x74;
71
   /* Clear SI and Start flag */
72
   I2CONCLR=0x28;
73
   /* Port Indicator */
74
   IOSET=0x10;
75
}
76
/* Acknowledgement received from slave for slave address */
77
void ISR_18()
78
{
79
   /* Port Indicator */
80
   IOCLR=0x20;
81
   /* Data to be transmitted */
82
   I2DAT=0x55;
83
   /* clear SI */
84
   I2CONCLR=0x8;
85
   /* Port Indicator */
86
   IOSET=0x20;
87
}
88
/* Acknowledgement received from slave for byte transmitted from master. Stopcondition is transmitted in this state signaling the end of transmission */
89
void ISR_28()
90
{
91
   /* Port Indicator */
92
   IOCLR=0x80;
93
   /* Transmit stop condition */
94
   I2CONSET=0x10;
95
   /* clear SI */
96
   I2CONCLR=0x8;
97
   /* Port Indicator */
98
   IOSET=0x80;
99
}
Ich bin ein Anfänger und meine Frage wäre: findet die vollstendige 
Datenübertragung(Startbit, Slaveadresse+W,Daten,Stopbit) nur ein mal 
statt oder die wiederholt sich regelmasig? Ich habe ein 
Versändnisproblemm und weiß nicht wie Interupt bei Datenübertragung in 
Hardware funktionirt :(
Danke im voraus.

von Tilo (Gast)


Lesenswert?

Handbuch lesen :)

Dort steht normalerweise drin, wodurch der IRQ ausgelöst wird. Pauschal 
lässt sich deine Frage nicht beantworten.
Vermutlich wird es so sein, dass der IRQ ausgelöst wird, wenn das 
TX-Register gerade am leer werden ist und neu befüllt werden darf.

Es ist irreleveant, ob an I2C ein LCD oder etwas anderes angeschlossen 
ist. Wichtig sit für dich, wie die Daten kodiert werden müssen. Das 
steht im Handbuch des LCD drin.

von Alex T. (mikro_step)


Lesenswert?

Tilo, danke für die Antwort,

wie die Daten kodiert werden habe ich rausgefunden. So wie ich verstehe, 
brauche ich die Daten regelmäßig in einen bestimten Zeitabstand an 
LCD-Display zu schicken. Kann man so was mit Interupt machen? Geht das 
nur mit Hilfe des Timers? Kann man das auch ohne Timer machen? Z.B. in 
diesem Fall(das Programm oben)? Werden die Daten hier nur ein mal 
abgeschickt und dann läuft die while-Schleife oder die Übertragung wird 
wiederholt?

von Peter D. (peda)


Lesenswert?

Ich würde das I2C erstmal in Software machen, also ganz einfach mit 
Portpin wackeln.
Und erst, wenn das LCD damit funktioniert, kann man über Interrupts 
nachdenken.

Wenn das LCD anderen Modies kann (8Bit, UART, SPI), würde ich die 
erstmal nehmen.

Denn I2C ist nicht gerade das einfachste Interface, wenn man noch nie 
damit gearbeitet hat.
Daher würde ich I2C erstmal mit einfachen ICs anfangen, z.B. PCF8574(A) 
PIO oder LM75 Sensor.


Peter

von Tilo (Gast)


Lesenswert?

Peters Tip mit den einfachen ICs ist nicht schlecht.
Bei deinem LCD kommen noch Timings ins Spiel. Wenn der Bus nicht läuft, 
wird das eklig zum debuggen.
Auf Software-SPI würde ich verzichten, aber das ist geschmackssache. Bei 
Hardware muss man sich darüber im klaren sein, wie Start und Stop Bits 
erzeugt werden. Ich hab I2C bei einem ADUC7000 verwendet. Der generiert 
die Bits automatisch. So bald der TX-Fifo leer läuft, wird das Stop-Bit 
automatisch erzeugt. Werden die Daten nicht rechtzeitig nachgelifert, 
geht das böse aus.

Ansonsten: Wenn Daten mit festen Timing gesendet werden sollen brauchst 
du einen Timer oder eine andere Zeitquelle.

von Alex T. (mikro_step)


Lesenswert?

Danke für die Tipps,
ich kann aber nicht auf IC verzichten, es geht einfach nicht:( So ist 
die Aufgabe. Mein LCD hat nur I2C-Bus. Ich habe jedoch schon ein paar 
Beispiele gefunden, für mein Mikrocontroller und für mein LCD.. jetzt 
möchte ich die für meine Aufgabestellung anpassen

Tilo schrieb:
> Ansonsten: Wenn Daten mit festen Timing gesendet werden sollen brauchst
>
> du einen Timer oder eine andere Zeitquelle.

Danke für den Tipp, also ich werde ein Zähler für Timer implementiren. 
So wie ich jetzt verstanden habe, die Übertragung aus dem obengenannten 
Beispiel wird nur einmal ausgeführt. Ich möcht aber die Bilder an 
LCD-Display regelmäßig schicken..

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.