Hallo zusammen! Ich arbeite gerade an einem Projekt, bei dem ich eine RTC (über I²C) und eine SD Karte (SPI) zeitgleich an einem 18F458 betreiben muss. Die RTC soll dabei in bestimmten Intervallen angesprochen werden und einen Timestamp auf die MMC schreiben. I²C und SPI werden bei diesem PIC von den gleichen PINs angeboten. Daher hab ich jetzt drei Möglichkeiten: - RTC über I²C und MMC über Soft-SPI - RTC über Soft-I²C und MMC über SPI - RTC über I²C und MMC über I²C-SPI Bridge Hat jemand von euch schon Erfahrungen damit gesammelt oder einen Tipp, welches die einfachste bzw. logischste Lösung ist? Vielen Dank schon mal im Voraus!
SD-Karten wuseln ja ordentlich Daten umher (FAT usw.), da würde ich das harte SPI nehmen. Für die paar Byte des RTC reicht weiches I2C völlig. Oder viele MCs erlauben direkt den Anschluß eines Uhrenquarzes im Stromsparmodus, dann ohne extra RTC-Chip. Peter
Das mit dem Quarz geht leider nicht, da der µC schon auf einer Embeddedplatine sitzt. Das mit dem Software-I²C lese ich mir jetzt schon die ganze Zeit durch. Aber da ich (noch) nicht soo viel Routine im C Programmieren hab, weiß ich nicht wirklich, wie ich da rangehen soll. Ein Beispiel in C auf PIC bezogen hab ich noch nicht gefunden.. Kenn vielleicht jemand einen guten Link oder hat selbst schon mal eine SW-I²C-Routine für PICs geschrieben?
http://www.sprut.de/electronic/pic/grund/i2c.htm http://www.sprut.de/electronic/pic/grund/i2c_soft.htm
Die Sprutseiten hab ich auch schon alles durch. Ich würde halt nur gerne in C bleiben, da ich mich da etwas "wohler" fühle :)
Ist fürn AVR, sollte aber leicht anzupassen sein. Beim PIC sind wohl die Directionbits anders rum.
1 | #define i2c_delay() _delay_us( 2.5 / 2 ) // 2.5us = 400kHz
|
2 | |
3 | |
4 | #define ssda_lo() SSDA_DDR = 1
|
5 | #define ssda_hi() SSDA_DDR = 0
|
6 | #define sscl_lo() SSCL = 0
|
7 | #define sscl_hi() SSCL = 1
|
8 | |
9 | |
10 | void si2c_start( void ) // input: SDA = 1, SCL = x |
11 | {
|
12 | SSCL_DDR = 1; // SCL = output |
13 | SSDA = 0; |
14 | SSDA_DDR = 0; // SDA = high (input) |
15 | sscl_hi(); |
16 | i2c_delay(); |
17 | ssda_lo(); |
18 | i2c_delay(); |
19 | sscl_lo(); |
20 | }
|
21 | |
22 | |
23 | void si2c_stop( void ) // input: SDA = 1, SCL = 0 |
24 | {
|
25 | ssda_lo(); |
26 | i2c_delay(); |
27 | sscl_hi(); |
28 | i2c_delay(); |
29 | ssda_hi(); |
30 | }
|
31 | |
32 | |
33 | static uint16_t si2c_rw( uint16_t val ) // input: SDA = x, SCL = 0 |
34 | {
|
35 | for( uint8_t i = 9; i; i-- ){ // data + ACK |
36 | if( val & 0x8000 ) |
37 | ssda_hi(); |
38 | else
|
39 | ssda_lo(); |
40 | i2c_delay(); |
41 | sscl_hi(); |
42 | i2c_delay(); |
43 | val <<= 1; |
44 | if( SSDA_PIN ) |
45 | val |= 0x80; |
46 | sscl_lo(); |
47 | }
|
48 | return val; |
49 | }
|
50 | |
51 | |
52 | uint8_t si2c_r( uint8_t nack ) // input NACK |
53 | {
|
54 | if( nack ) |
55 | nack = 0x80; // set only bit 7 ! |
56 | return si2c_rw( 0xFF00 | nack ) >> 8; // return data |
57 | }
|
58 | |
59 | |
60 | uint8_t si2c_w( uint8_t val ) // input data |
61 | {
|
62 | return si2c_rw( 0x00FF | (val<<8)) & 0xFF; // return NACK |
63 | }
|
Peter
Hier noch ein 8051-C-Code für Software I2C, dort sieht man sehr genau und auf den ersten Blick, wann welcher Pin welchen Zustand hat.
1 | //-----------------------------------------------------------------
|
2 | void delay(unsigned char warte_wert) |
3 | {
|
4 | do
|
5 | {
|
6 | warte_wert--; |
7 | }
|
8 | while(warte_wert != 0); |
9 | }
|
10 | //-----------------------------------------------------------------
|
11 | void i2c_bus_start() |
12 | {
|
13 | SCL = 0; |
14 | delay(1); |
15 | SDA = 1; |
16 | delay(1); |
17 | SCL = 1; |
18 | while(SCL==0); |
19 | delay(1); |
20 | SDA = 0; |
21 | delay(1); |
22 | SCL = 0; |
23 | delay(1); |
24 | SDA = 1; |
25 | delay(1); |
26 | }
|
27 | //-----------------------------------------------------------------
|
28 | |
29 | void i2c_bus_stop() |
30 | {
|
31 | SCL = 0; |
32 | delay(1); |
33 | SDA = 0; |
34 | delay(1); |
35 | SCL = 1; |
36 | while(SCL==0); |
37 | delay(1); |
38 | SDA = 1; |
39 | delay(1); |
40 | SCL = 0; |
41 | delay(1); |
42 | }
|
43 | |
44 | //-----------------------------------------------------------------
|
45 | void i2c_bit_write(bit bit_wert) |
46 | {
|
47 | SDA = bit_wert; |
48 | delay(1); |
49 | SCL = 1; |
50 | while(SCL==0); |
51 | delay(1); |
52 | SCL = 0; |
53 | delay(1); |
54 | }
|
55 | //-----------------------------------------------------------------
|
56 | /*
|
57 | bit i2c_bit_read()
|
58 | {
|
59 | bit bit_wert;
|
60 | SCL = 0;
|
61 | delay(1);
|
62 | SDA = 1;
|
63 | delay(1);
|
64 | SCL = 1;
|
65 | while(SCL==0);
|
66 | delay(1);
|
67 | bit_wert = SDA;
|
68 | SCL = 0;
|
69 | delay(1);
|
70 | SDA = 0;
|
71 | delay(1);
|
72 | return(bit_wert);
|
73 | }
|
74 | */
|
75 | //-----------------------------------------------------------------
|
76 | void i2c_ack_slave() |
77 | {
|
78 | SCL = 0; |
79 | delay(1); |
80 | SDA = 1; |
81 | delay(1); |
82 | SCL = 1; |
83 | while(SCL==0); |
84 | while(SDA==1); |
85 | delay(1); |
86 | SCL = 0; |
87 | delay(1); |
88 | }
|
89 | //-----------------------------------------------------------------
|
90 | /*
|
91 | void i2c_ack_master()
|
92 | {
|
93 | SCL = 0;
|
94 | delay(1);
|
95 | SDA = 0;
|
96 | delay(1);
|
97 | SCL = 1;
|
98 | while(SCL==0);
|
99 | delay(2);
|
100 | SCL = 0;
|
101 | delay(1);
|
102 | SDA = 1;
|
103 | delay(1);
|
104 | }
|
105 | */
|
106 | //-----------------------------------------------------------------
|
107 | void i2c_byte_write(unsigned char byte_wert) |
108 | {
|
109 | unsigned char i; |
110 | bit bit_wert; |
111 | for(i=0;i<=7;i++) |
112 | {
|
113 | bit_wert = (byte_wert&0x80)/128; |
114 | i2c_bit_write(bit_wert); |
115 | byte_wert=byte_wert<<1; |
116 | }
|
117 | }
|
118 | //-----------------------------------------------------------------
|
119 | /*
|
120 | unsigned char i2c_byte_read()
|
121 | {
|
122 | unsigned char i;
|
123 | unsigned char byte_wert=0;
|
124 | for(i=0;i<=7;i++)
|
125 | {
|
126 | byte_wert=(i2c_bit_read()<<(7-i))+byte_wert;
|
127 | }
|
128 | return(byte_wert);
|
129 | }
|
130 | */
|
Andre K. schrieb: > Die Sprutseiten hab ich auch schon alles durch. Ich würde halt nur gerne > in C bleiben, da ich mich da etwas "wohler" fühle :) Inline ASM ???
Microchip hat auch noch Funktions-Bibliotheken in denen Software und Hardware-Schnittstellen angesprochen werden können. Keine Ahnung ob die was taugen. http://ww1.microchip.com/downloads/en/devicedoc/MPLAB_C18_Libraries_51297f.pdf
Ich habe eine Steuerung gebaut, die I2C- und SPI-Slaves anspricht (und das mit 5V und 3,3V!). Mit einem Analog-Umschalter (4053?) schalte ich die SDA/SCL-Signale auf jeweils einen Bus (Pull-Ups bzw -downs intelligent gewählt). Läuft prima. Die Software aktiviert immer das benötigte Hardware-Modul und den Umschalter und spricht die Geräte an.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.