Hallo zusammen Ich bin Anfänger im C programmieren. Ich wollter das TWI Interface des ATmega64L ausprobieren und in Betrieb nehmen. Dabei schrieb ich mit Hilfe der Programmbesipiele von Atmel (auch andere Bsp.) den Source code im Anhang. Dies funktioniert aber in keiner Weise! Der Chip sendet nicht einmal eine Start Condition! Ich habe meinen Code mit vielen verschiedenen Bsp. codes verglichen und finde keinen Fehler. Vieleicht wais jo jemand von euch was ich falsch mache! Mit freundlichen Grüssen Beat
Öööhhhh.... Musst du vielleicht noch das Interrupt System aktivieren?! Will selber bald mit WI anfangen. Also mal an sei() einhacken.
Du solltest vielleicht noch abfragen, ob die Stop-Condition auch erfolgreich war.
Ja da gebe ich dir recht! Aber er sendet sie ja gar nicht! Das konnte ich messen! Und wenn er sie gar nicht sendet, nützt es auch nicht viel wenn ich abfrag ob die Start Condition gesendet wurde.. Ist halt meine erste Programmversion für TWI und nur zum ausprobieren gedacht...
Also funkioniert TWI ohne Interrupt-Conditions gar nicht?! Egal wie?! Auch wenn ich nur ein Display ansteuern will, welches ja selber keine Signale zurückgibt?! Gruß der Praktikant
Also mit dem TWI Interface habe ich damals auch etwas länger rumgeknobelt und es ist nicht gerade meine Lieblingsübertragungsart ;) Schließlich hats dann funktioniert. Folgender Code ist für eine Datenübertragung zwischen einem Atmega8 (Master; 4 MHz) und einem LM75 Tempfühler. das ganze wurde mit einem Timer ausgelöst, der alle 4 Sekunden die Temperatur erneut abgefragt hat. Du solltest darauf achten, zwischen den TWI Durchläufen ein paar ms pause einzulegen. Zwar steht in der TWI Anleitung, dass der Slave die Datenübertragung verlangsamen kann, indem er einfach den clock gegen Masse zieht aber in meiner Anwendung hat das nicht so super geklappt und mein Tempfühler hat sich aufgehängt, somit hing auch das Programm, da ich keinen Schutzmechanismus mit Watchdogtimer oder sonstwas eingebaut habe. [AVRSAM] ;LM75 data .EQU LM75_1_T_HYST = 57 ; 57 centigrade .EQU LM75_1_T_OS = 60 ; 60 centigrade .EQU LM75_1_WRITE = 0b10010000 ; Write address for first LM75 .EQU LM75_1_READ = 0b10010001 ; Read address for first LM75 ; TWI data .EQU TWI_BIT_RATE = 48 ; Bit-Rate (1...255) .EQU TWI_PRESCALER = $1 ; Prescaler: 0=1 1=4 2=16 3=64 ;***************************************************************** ; TWI ROUTINES ;***************************************************************** ; SET POINTER ON LM75 TEMP_READ_POINTER: rcall TWI_START ; ...jump ; STATUSKONTROLLE rcall TWI_LM75_1_WRITE ; ...jump ; STATUSKONTROLLE ldi r16,$00 ; r16 = 0 out TWDR,r16 ; TWI data register on AT8 = 0 rcall TWI_DATA ; send data to LM75, pointer on LM75 = 0 ; STATUSKONTROLLE ; READ TEMPERATURE ON LM75, POINTER MUST BE SET! TEMP_READ: rcall TWI_START ; ...jump ; STATUSKONTROLLE rcall TWI_LM75_1_READ ; ...jump ; STATUSKONTROLLE ldi r16,(1<<TWINT) | (1<<TWEA) | (1<<TWEN) ; start Transfer, ; send ACK after communication out TWCR,r16 rcall CHECK_TWINT ; ...jump in r15,TWDR ; TEMPERATURE NOW IN r15 (HIGHBYTE) ; STATUSKONTROLLE ldi r16, (1<<TWINT) | (0<<TWEA) | (1<<TWEN); start transfer, ; send NACK after communication out TWCR, r16 ; ...jump rcall CHECK_TWINT ; ...jump in r14,TWDR ; TEMPERATURE NOW IN r15 (LOWBYTE) ; STATUSKONTROLLE rcall TWI_STOP ; ...jump ; STATUSKONTROLLE ret ; go back ; CHECK TWINT bit @AT8 (transfer complete?) CHECK_TWINT: in r16,TWCR ; r16 = TWCR (two wire control register) sbrs r16,TWINT ; check if bit 7 (TWINT) = 1 rjmp CHECK_TWINT ; yes: go back, no: loop ret ; LOAD LM75 address and readbit in TW data register TWI_LM75_1_READ: ldi r16,LM75_1_READ out TWDR,r16 rcall TWI_DATA ret ; LOAD LM75 address and writebit in TW data register TWI_LM75_1_WRITE: ldi r16,LM75_1_WRITE out TWDR,r16 rcall TWI_DATA ret ; START TWI COMMUNICATION (address must be in TWDR) TWI_START: ldi r16,(1<<TWINT) | (1<<TWSTA) | (1<<TWEN) out TWCR,r16 rcall CHECK_TWINT ret ; STOP TWI COMMUNICATION TWI_STOP: ldi r16,(1<<TWINT) | (1<<TWSTO) | (1<<TWEN) out TWCR,r16 ; send STOP ret ; SEND DATA TWI_DATA: ldi r16,(1<<TWINT) | (1<<TWEN) out TWCR,r16 rcall CHECK_TWINT ret ; initialise TWI TWI_INIT: ldi r16,TWI_BIT_RATE out TWBR,r16 ldi r16,TWI_PRESCALER out TWSR,r16 ;set T_hyst rcall TWI_START ;STATUSKONTROLLE rcall TWI_LM75_1_WRITE ;STATUSKONTROLLE ldi r16,0b00000010 ; r16 = LM75 pointeraddress out TWDR,r16 rcall TWI_DATA ; set pointer = T_HYST ;STATUSKONTROLLE ldi r16,LM75_1_T_HYST out TWDR,r16 rcall TWI_DATA ; send MS databyte ;STATUSKONTROLLE out TWDR,r17 rcall TWI_DATA ; send LS databyte ;STATUSKONTROLLE rcall TWI_STOP ; STOP TWI ;read T_hyst (pointer is set) rcall WAIT_5ms ; wait for TW BUS rcall TWI_START ; START TWI rcall TWI_LM75_1_READ ; ...jump ldi r16,(1<<TWINT) | (1<<TWEA) | (1<<TWEN) ; receive data and send ACK out TWCR,r16 rcall CHECK_TWINT in r15,TWDR ; T_hyst (highbyte) now on r15 ; STATUSKONTROLLE ldi r16, (1<<TWINT) | (0<<TWEA) | (1<<TWEN) out TWCR, r16 rcall CHECK_TWINT ; T_hyst lowbyte not needed but received ; !!! required !!! ; STATUSKONTROLLE rcall TWI_STOP ; STATUSKONTROLLE mov r16,r15 rcall BCD_start ; start BCD ; write T_hyst (fan stop) on LCD ldi r16,193 mov r22,r18 rcall LCD_TEST ldi r16,194 mov r22,r19 rcall LCD_TEST ldi r16,195 ldi r22,254 ; write . rcall LCD_TEST ldi r16,196 ldi r22,0 rcall LCD_TEST ldi r22,'C'-48 ldi r16,198 rcall LCD_TEST ; write T_os rcall TWI_START ;STATUSKONTROLLE rcall TWI_LM75_1_WRITE ;STATUSKONTROLLE ldi r16,0b00000011 out TWDR,r16 rcall TWI_DATA ; set pointer = T_OS ;STATUSKONTROLLE ldi r16,LM75_1_T_OS out TWDR,r16 rcall TWI_DATA ;STATUSKONTROLLE out TWDR,r17 rcall TWI_DATA ;STATUSKONTROLLE rcall TWI_STOP rcall WAIT_5ms ; read T_os (pointer is set) rcall TWI_START rcall TWI_LM75_1_READ ldi r16,(1<<TWINT) | (1<<TWEA) | (1<<TWEN) out TWCR,r16 rcall CHECK_TWINT in r15,TWDR ; STATUSKONTROLLE ldi r16, (1<<TWINT) | (0<<TWEA) | (1<<TWEN) out TWCR, r16 rcall CHECK_TWINT ; STATUSKONTROLLE rcall TWI_STOP ; STATUSKONTROLLE mov r16,r15 rcall BCD_start ; write T_os (fan start) on LCD ldi r16,173 mov r22,r18 rcall LCD_TEST ldi r16,174 mov r22,r19 rcall LCD_TEST ldi r16,175 ldi r22,254 ; write . rcall LCD_TEST ldi r16,176 ldi r22,0 rcall LCD_TEST ldi r22,'C'-48 ldi r16,178 rcall LCD_TEST ret [/AVRASM]
Sorry jetzt nochmal richtig den code:
1 | ;LM75 data |
2 | .EQU LM75_1_T_HYST = 57 ; 57 centigrade |
3 | .EQU LM75_1_T_OS = 60 ; 60 centigrade |
4 | .EQU LM75_1_WRITE = 0b10010000 ; Write address for first LM75 |
5 | .EQU LM75_1_READ = 0b10010001 ; Read address for first LM75 |
6 | |
7 | ; TWI data |
8 | .EQU TWI_BIT_RATE = 48 ; Bit-Rate (1...255) |
9 | .EQU TWI_PRESCALER = $1 ; Prescaler: 0=1 1=4 2=16 3=64 |
10 | |
11 | ;***************************************************************** |
12 | |
13 | ; TWI ROUTINES |
14 | |
15 | ;***************************************************************** |
16 | |
17 | ; SET POINTER ON LM75 |
18 | TEMP_READ_POINTER: |
19 | rcall TWI_START ; ...jump |
20 | ; STATUSKONTROLLE |
21 | rcall TWI_LM75_1_WRITE ; ...jump |
22 | ; STATUSKONTROLLE |
23 | ldi r16,$00 ; r16 = 0 |
24 | out TWDR,r16 ; TWI data register on AT8 = 0 |
25 | rcall TWI_DATA ; send data to LM75, pointer on LM75 = 0 |
26 | ; STATUSKONTROLLE |
27 | ; READ TEMPERATURE ON LM75, POINTER MUST BE SET! |
28 | TEMP_READ: |
29 | rcall TWI_START ; ...jump |
30 | ; STATUSKONTROLLE |
31 | rcall TWI_LM75_1_READ ; ...jump |
32 | ; STATUSKONTROLLE |
33 | ldi r16,(1<<TWINT) | (1<<TWEA) | (1<<TWEN) ; start Transfer, |
34 | ; send ACK after communication |
35 | out TWCR,r16 |
36 | rcall CHECK_TWINT ; ...jump |
37 | in r15,TWDR ; TEMPERATURE NOW IN r15 (HIGHBYTE) |
38 | ; STATUSKONTROLLE |
39 | ldi r16, (1<<TWINT) | (0<<TWEA) | (1<<TWEN); start transfer, |
40 | ; send NACK after communication |
41 | out TWCR, r16 ; ...jump |
42 | rcall CHECK_TWINT ; ...jump |
43 | in r14,TWDR ; TEMPERATURE NOW IN r15 (LOWBYTE) |
44 | ; STATUSKONTROLLE |
45 | rcall TWI_STOP ; ...jump |
46 | ; STATUSKONTROLLE |
47 | ret ; go back |
48 | |
49 | ; CHECK TWINT bit @AT8 (transfer complete?) |
50 | CHECK_TWINT: |
51 | in r16,TWCR ; r16 = TWCR (two wire control register) |
52 | sbrs r16,TWINT ; check if bit 7 (TWINT) = 1 |
53 | rjmp CHECK_TWINT ; yes: go back, no: loop |
54 | ret |
55 | |
56 | ; LOAD LM75 address and readbit in TW data register |
57 | TWI_LM75_1_READ: |
58 | ldi r16,LM75_1_READ |
59 | out TWDR,r16 |
60 | rcall TWI_DATA |
61 | ret |
62 | |
63 | ; LOAD LM75 address and writebit in TW data register |
64 | TWI_LM75_1_WRITE: |
65 | ldi r16,LM75_1_WRITE |
66 | out TWDR,r16 |
67 | rcall TWI_DATA |
68 | ret |
69 | |
70 | ; START TWI COMMUNICATION (address must be in TWDR) |
71 | TWI_START: |
72 | ldi r16,(1<<TWINT) | (1<<TWSTA) | (1<<TWEN) |
73 | out TWCR,r16 |
74 | rcall CHECK_TWINT |
75 | ret |
76 | |
77 | ; STOP TWI COMMUNICATION |
78 | TWI_STOP: |
79 | ldi r16,(1<<TWINT) | (1<<TWSTO) | (1<<TWEN) |
80 | out TWCR,r16 ; send STOP |
81 | ret |
82 | |
83 | ; SEND DATA |
84 | TWI_DATA: |
85 | ldi r16,(1<<TWINT) | (1<<TWEN) |
86 | out TWCR,r16 |
87 | rcall CHECK_TWINT |
88 | ret |
89 | |
90 | ; initialise TWI |
91 | TWI_INIT: |
92 | ldi r16,TWI_BIT_RATE |
93 | out TWBR,r16 |
94 | ldi r16,TWI_PRESCALER |
95 | out TWSR,r16 |
96 | ;set T_hyst |
97 | rcall TWI_START |
98 | ;STATUSKONTROLLE |
99 | rcall TWI_LM75_1_WRITE |
100 | ;STATUSKONTROLLE |
101 | ldi r16,0b00000010 ; r16 = LM75 pointeraddress |
102 | out TWDR,r16 |
103 | rcall TWI_DATA ; set pointer = T_HYST |
104 | ;STATUSKONTROLLE |
105 | ldi r16,LM75_1_T_HYST |
106 | out TWDR,r16 |
107 | rcall TWI_DATA ; send MS databyte |
108 | ;STATUSKONTROLLE |
109 | out TWDR,r17 |
110 | rcall TWI_DATA ; send LS databyte |
111 | ;STATUSKONTROLLE |
112 | rcall TWI_STOP ; STOP TWI |
113 | ;read T_hyst (pointer is set) |
114 | rcall WAIT_5ms ; wait for TW BUS |
115 | rcall TWI_START ; START TWI |
116 | rcall TWI_LM75_1_READ ; ...jump |
117 | ldi r16,(1<<TWINT) | (1<<TWEA) | (1<<TWEN) ; receive data and send |
118 | ACK |
119 | out TWCR,r16 |
120 | rcall CHECK_TWINT |
121 | in r15,TWDR ; T_hyst (highbyte) now on r15 |
122 | ; STATUSKONTROLLE |
123 | ldi r16, (1<<TWINT) | (0<<TWEA) | (1<<TWEN) |
124 | out TWCR, r16 |
125 | rcall CHECK_TWINT ; T_hyst lowbyte not needed but received |
126 | ; !!! required !!! |
127 | ; STATUSKONTROLLE |
128 | rcall TWI_STOP |
129 | ; STATUSKONTROLLE |
130 | mov r16,r15 |
131 | rcall BCD_start ; start BCD |
132 | ; write T_hyst (fan stop) on LCD |
133 | ldi r16,193 |
134 | mov r22,r18 |
135 | rcall LCD_TEST |
136 | ldi r16,194 |
137 | mov r22,r19 |
138 | rcall LCD_TEST |
139 | ldi r16,195 |
140 | ldi r22,254 ; write . |
141 | rcall LCD_TEST |
142 | ldi r16,196 |
143 | ldi r22,0 |
144 | rcall LCD_TEST |
145 | ldi r22,'C'-48 |
146 | ldi r16,198 |
147 | rcall LCD_TEST |
148 | ; write T_os |
149 | rcall TWI_START |
150 | ;STATUSKONTROLLE |
151 | rcall TWI_LM75_1_WRITE |
152 | ;STATUSKONTROLLE |
153 | ldi r16,0b00000011 |
154 | out TWDR,r16 |
155 | rcall TWI_DATA ; set pointer = T_OS |
156 | ;STATUSKONTROLLE |
157 | ldi r16,LM75_1_T_OS |
158 | out TWDR,r16 |
159 | rcall TWI_DATA |
160 | ;STATUSKONTROLLE |
161 | out TWDR,r17 |
162 | rcall TWI_DATA |
163 | ;STATUSKONTROLLE |
164 | rcall TWI_STOP |
165 | rcall WAIT_5ms |
166 | ; read T_os (pointer is set) |
167 | rcall TWI_START |
168 | rcall TWI_LM75_1_READ |
169 | ldi r16,(1<<TWINT) | (1<<TWEA) | (1<<TWEN) |
170 | out TWCR,r16 |
171 | rcall CHECK_TWINT |
172 | in r15,TWDR |
173 | ; STATUSKONTROLLE |
174 | ldi r16, (1<<TWINT) | (0<<TWEA) | (1<<TWEN) |
175 | out TWCR, r16 |
176 | rcall CHECK_TWINT |
177 | |
178 | ; STATUSKONTROLLE |
179 | rcall TWI_STOP |
180 | ; STATUSKONTROLLE |
181 | mov r16,r15 |
182 | rcall BCD_start |
183 | ; write T_os (fan start) on LCD |
184 | ldi r16,173 |
185 | mov r22,r18 |
186 | rcall LCD_TEST |
187 | ldi r16,174 |
188 | mov r22,r19 |
189 | rcall LCD_TEST |
190 | ldi r16,175 |
191 | ldi r22,254 ; write . |
192 | rcall LCD_TEST |
193 | ldi r16,176 |
194 | ldi r22,0 |
195 | rcall LCD_TEST |
196 | ldi r22,'C'-48 |
197 | ldi r16,178 |
198 | rcall LCD_TEST |
199 | ret |
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.