Hallo zusammen,
ich bin z.Z. dabei mir eine TWI Libary für mein XMega256A3BU Board zu
schreiben.
Im Moment habe ich einen PCF8574 Portexpander an dem Board angeschlossen
und versuche ihn über TWI auszulesen.
Meine Lib sieht bisher so aus:
1 | /*
|
2 | * I2C.h
|
3 | *
|
4 | * Created: 20.10.2014 17:17:12
|
5 | * Author: Daniel
|
6 | */
|
7 |
|
8 |
|
9 | #ifndef I2C_H_
|
10 | #define I2C_H_
|
11 |
|
12 | #define Takt_TWI 400000
|
13 | #define TWI_BAUD(F_SYS, F_TWI) ((F_SYS / (2 * F_TWI)) - 5)
|
14 | #define TWI_BAUDRATE TWI_BAUD(F_CPU, Takt_TWI)
|
15 |
|
16 | #define PCF8574 0x20
|
17 |
|
18 | void I2C_Master_Init(TWI_t *I2C);
|
19 | void Send_Address(TWI_t *I2C, int Adresse, int RW);
|
20 | void PCF8574_send_byte(TWI_t *I2C, int Adresse, int byte);
|
21 | int PCF8574_read_byte(TWI_t *I2C, int Adresse);
|
22 |
|
23 |
|
24 | void I2C_Master_Init(TWI_t *I2C)
|
25 | {
|
26 | PORTC.DIRSET |= PIN0_bm;
|
27 | PORTC.DIRSET |= PIN1_bm;
|
28 | I2C->MASTER.BAUD = TWI_BAUDRATE;
|
29 | I2C->MASTER.CTRLA = TWI_MASTER_ENABLE_bm | TWI_MASTER_INTLVL_HI_gc | TWI_MASTER_RIEN_bm | TWI_MASTER_WIEN_bm;
|
30 | I2C->MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc;
|
31 | return;
|
32 | }
|
33 |
|
34 | void Send_Address(TWI_t *I2C, int Adresse, int RW)
|
35 | {
|
36 | I2C->MASTER.ADDR = (Adresse << 1) + RW;
|
37 | while(!(I2C->MASTER.STATUS & TWI_MASTER_WIF_bm));
|
38 | return;
|
39 | }
|
40 |
|
41 | void PCF8574_send_byte(TWI_t *I2C, int Adresse, int byte)
|
42 | {
|
43 | Send_Address(I2C, Adresse, 0);
|
44 | I2C->MASTER.DATA = byte;
|
45 | while(!(I2C->MASTER.STATUS & TWI_MASTER_WIF_bm));
|
46 | }
|
47 |
|
48 | int PCF8574_read_byte(TWI_t *I2C, int Adresse)
|
49 | {
|
50 | Send_Address(I2C, Adresse, 1);
|
51 | while(!(I2C->MASTER.STATUS&TWI_MASTER_WIF_bm));
|
52 | return I2C->MASTER.DATA;
|
53 | }
|
54 |
|
55 | #endif /* I2C_H_ */
|
Und mein Hauptprogramm so:
1 | /*
|
2 | * Atmel.c
|
3 | *
|
4 | * Created: 12.10.2014 12:33:42
|
5 | * Author: Daniel
|
6 | */
|
7 |
|
8 | #define F_CPU 32000000UL
|
9 | #define Baudrate 9600UL
|
10 |
|
11 | #include <avr/io.h>
|
12 |
|
13 | #include <string.h>
|
14 | #include "Chip.h"
|
15 | #include "UART.h"
|
16 | #include "ADC.h"
|
17 | #include "Display.h"
|
18 | #include <util/delay.h>
|
19 | #include "I2C.h"
|
20 |
|
21 | int main(void)
|
22 | {
|
23 | Enable_32MHz_Clock();
|
24 | Enable_Interrupt();
|
25 | UART_Init(&USARTE0);
|
26 | ADC_Init(&ADCA);
|
27 | I2C_Master_Init(&TWIC);
|
28 |
|
29 | Send_UART("Programmstart\n\r", &USARTE0);
|
30 |
|
31 | int Input;
|
32 | char Buffer[] = "";
|
33 |
|
34 | while(1)
|
35 | {
|
36 | Input = PCF8574_read_byte(&TWIC, 0x20);
|
37 | sprintf(Buffer, "%i", Input);
|
38 | Send_UART("Status: ", &USARTE0);
|
39 | Send_UART(Buffer, &USARTE0);
|
40 | Send_UART("\n\r", &USARTE0);
|
41 | _delay_ms(1000);
|
42 | }
|
43 | }
|
Wenn ich das Programm nun starte, bleibt es an dieser Stelle
while(!(I2C->MASTER.STATUS & TWI_MASTER_WIF_bm));
stehen. Wenn ich die Zeile auskommentiere bekomme ich auf dem Terminal
als Ergebnis "65" angezeigt und nicht den aktuellen Pinstatus des PCF.
Woran liegt das?
Danke für die Hilfe!