Forum: Mikrocontroller und Digitale Elektronik ATtiny414 führt Programm nicht aus?


von Daniel K. (daniel_k80)


Lesenswert?

Hallo zusammen,

ich habe einen ATtiny414, welchen ich über UPDI programmiert habe. Das 
Programm funktioniert auch, wenn ich über einen Debugger das Programm 
starte (es wird ein I/O auf High gezogen und nach 10 Sekunden fällt er 
auf Low zurück).
Wenn ich den Debugger nun abstecke und Spannung auf den Tiny gebe wird 
das Programm aber nicht ausgeführt. Der Pin bleibt die ganze Zeit auf 
Low.

Wie kommt das? Was macht der Debugger anders?

Vielen Dank für die Hilfe!
1
.def  temp1    = r16                   
2
.def  temp2    = r17                    
3
.def  temp3    = r18                    
4
.def  temp4    = r19                    
5
.def  temp5    = r20                    
6
.def  temp6    = r21
7
.def  Timeout_M  = r22                    ; Timeout für die RTC (Minuten)
8
.def  Timeout_S  = r23                    ; Timeout für die RTC (Sekunden)
9
10
.cseg                  
11
.org $0000                            ; RESET
12
  rjmp    Reset_Handler                      
13
.org CRCSCAN_NMI_vect                      ; CRCSCAN_NMI    
14
  reti
15
.org BOD_VLM_vect                        ; BOD_VLM
16
  reti
17
.org PORTA_PORT_vect                      ; PORTA_PORT
18
  reti
19
.org PORTB_PORT_vect                      ; PORTB_PORT
20
  reti
21
.org RTC_CNT_vect                        ; RTC_CNT
22
  rjmp    RTC_InterruptHandler
23
.org RTC_PIT_vect                        ; RTC_PIT
24
  reti
25
.org TCA0_OVF_vect                        ; TCA0_OVF
26
  reti
27
.org TCA0_HUNF_vect                        ; TCA0_HUNF
28
  reti
29
.org TCA0_CMP0_vect                        ; TCA0_CMP0
30
  reti
31
.org TCA0_CMP1_vect                        ; TCA0_CMP1
32
  reti
33
.org TCA0_CMP2_vect                        ; TCA0_LCMP2
34
  reti
35
.org TCB0_INT_vect                        ; TCB0_INT
36
  reti
37
.org TCD0_OVF_vect                        ; TCD0_OVF
38
  reti
39
.org TCD0_TRIG_vect                        ; TCD0_TRIG
40
  reti
41
.org AC0_AC_vect                        ; AC0_AC
42
  reti
43
.org ADC0_RESRDY_vect                      ; ADC0_RESRDY
44
  reti
45
.org ADC0_WCOMP_vect                      ; ADC0_WCOMP
46
  reti
47
.org TWI0_TWIS_vect                        ; TWI0_TWIS
48
  reti
49
.org TWI0_TWIM_vect                        ; TWI0_TWIM
50
  reti
51
.org SPI0_INT_vect                        ; SPI0_INT
52
  reti
53
.org USART0_RXC_vect                      ; USART0_RXC
54
  reti
55
.org USART0_DRE_vect                      ; USART0_DRE
56
  reti
57
.org USART0_TXC_vect                      ; USART0_TXC
58
  reti
59
.org NVMCTRL_EE_vect                      ; NVMCTRL_EE
60
  reti
61
62
Reset_Handler:
63
  ldi    temp1, low(RAMEND)
64
  out    CPU_SPL, temp1
65
  ldi    temp1, high(RAMEND)
66
  out    CPU_SPH, temp1
67
68
Main:
69
  ; B.0 als Ausgang und auf Low setzen
70
  ldi temp1, 0x01
71
  sts PORTB_DIR, temp1
72
  ldi temp1, 0x00
73
  sts PORTB_OUT, temp1
74
75
  rcall RTC_Init
76
77
  ; Globale Interrupts aktivieren
78
  lds temp1, CPU_SREG
79
  ldi temp2, (0x01 << 0x07)
80
  or temp1, temp2
81
  sts CPU_SREG, temp1
82
83
  LOOP:
84
    rjmp LOOP
85
86
; --------------------------------------------------------------------------------------------------------------
87
; RTC Initialisierung
88
;  - Verwende den internen 32 kHz ULP Oszillator mit einem Prescaler von 32
89
;  - Prescaler 1024
90
;  - Overflow Register laden
91
;  - Overflow Interrupt aktivieren
92
;  - RTC aktivieren
93
; --------------------------------------------------------------------------------------------------------------
94
RTC_Init:
95
  ; Prescaler setzen
96
  ldi temp1, (RTC_PRESCALER1_bm | RTC_PRESCALER3_bm)
97
  sts RTC_CTRLA, temp1
98
  rcall RTC_WaitBusy
99
100
  ; Interne 1 kHz Taktquelle einstellen 
101
  ldi  temp1, RTC_CLKSEL_INT1K_gc
102
  sts RTC_CLKSEL, temp1
103
104
  ; Interruptflags löschen
105
  ldi temp1, 0x00
106
  sts RTC_INTFLAGS, temp1
107
108
  ; Overflow interrupt aktivieren
109
  ldi temp1, RTC_OVF_bm
110
  sts RTC_INTCTRL, temp1
111
112
  ; Aktiviere die RTC
113
  ldi Timeout_M, 0
114
  ldi Timeout_S, 10
115
  rcall RTC_SetAlarm
116
  rcall RTC_Enable
117
118
  ; Setze B.0 auf High
119
  ldi temp1, 0x01
120
  sts PORTB_OUTTGL, temp1
121
122
  ret
123
124
; --------------------------------------------------------------------------------------------------------------
125
; RTC aktivieren
126
; --------------------------------------------------------------------------------------------------------------
127
RTC_Enable:
128
  lds temp1, RTC_CTRLA
129
  ldi temp2, RTC_RTCEN_bm
130
  or temp1, temp2
131
  sts RTC_CTRLA, temp1
132
133
  ; Auf Sync warten
134
  rcall RTC_WaitBusy
135
  ret
136
137
; --------------------------------------------------------------------------------------------------------------
138
; Auf RTC Sync warten
139
; --------------------------------------------------------------------------------------------------------------
140
RTC_WaitBusy:
141
  BusyLoop:
142
  lds temp1, RTC_STATUS
143
  cpi temp1, 0
144
  brne BusyLoop
145
  ret
146
147
; --------------------------------------------------------------------------------------------------------------
148
; RTC Alarm aktivieren
149
;  - Verwendet R22 für den Timeout in Minuten
150
;  - Verwendet R23 für den Timeout in Sekunden
151
; --------------------------------------------------------------------------------------------------------------
152
RTC_SetAlarm:
153
  ; Berechnen der Sekunden für den Timeout
154
  ldi temp1, 60
155
  mul Timeout_M, temp1
156
  movw r24, r0
157
  add r24, Timeout_S
158
  ldi temp1, 0
159
  adc r25, temp1
160
  subi r24, 1
161
162
  ; Kopiere das unterste Byte des Overflow-Wertes in das TEMP-Register und 
163
  ; starte den Schreibvorgang durch das Schreiben des obersten Bytes 
164
  ; des Overflow-Wertes
165
  sts RTC_TEMP, r24
166
  sts RTC_PERH, r25
167
  rcall RTC_WaitBusy
168
  ret
169
170
; --------------------------------------------------------------------------------------------------------------
171
; RTC Interrupt handler
172
; - Verwendet r16 für die Interruptbehandlung
173
; --------------------------------------------------------------------------------------------------------------
174
RTC_InterruptHandler:
175
  ; Setze B.0 auf Low
176
  ldi temp1, 0x01
177
  sts PORTB_OUTCLR, temp1
178
179
  ; Interruptflags kopieren
180
  lds temp1, RTC_INTFLAGS
181
  andi temp1, RTC_CMP_bm
182
  
183
  ; Interruptflags löschen
184
  ldi temp2, 0x03
185
  sts RTC_INTFLAGS, temp2
186
187
  ;cpi temp1, 0x01
188
  ;breq Overflow
189
  ;rjmp Overflow_End
190
  ;Overflow:
191
  ;  ; Lösche das Overflow-Flag
192
  ;  lds temp1, RTC_INTFLAGS
193
  ;  ldi temp2, 0x03
194
  ;  and temp1, temp2
195
  ;  sts RTC_INTFLAGS, temp1
196
197
  ;  ldi r16, 7
198
  ;Overflow_End:
199
  reti

: Bearbeitet durch User
von Karl M. (Gast)


Lesenswert?

Hallo,

da bleibt nur die Reset Beschaltung des Attiny übrig.
Lege doch bitte man diesen Pin über einen Widerstand 1k-10k Ohm auf Vcc.

von Karl M. (Gast)


Lesenswert?

Hallo,

ich habe da noch einen kleinen Tipp:
In RTC_Enable, kann man auch direkt
1
RTC_Enable:
2
lds temp1, RTC_CTRLA
3
ori temp1,RTC_RTCEN_bm
4
; gleichwertig, pseudonym:
5
;SBR temp1,RTC_RTCEN_bm
6
sts RTC_CTRLA, temp1
7
:
schreiben.

Daniel K. schrieb:
> RTC_Enable:
>   lds temp1, RTC_CTRLA
>   ldi temp2, RTC_RTCEN_bm
>   or temp1, temp2
>   sts RTC_CTRLA, temp1
>
>   ; Auf Sync warten
>   rcall RTC_WaitBusy
>   ret

von Karl M. (Gast)


Lesenswert?

Auch hierfür gibt es einen Einfachen Befehl:
1
sei

siehe http://ww1.microchip.com/downloads/en/DeviceDoc/40001912A.pdf
8.7.3 Status Register

Und komplett:
37. Instruction Set Summary

Für alle 8 Bits im Status Register gibt es 1 Takt lange Befehle:
Carry:  SEC / CLC
Negative Flag: SEN / CLN
Zero Flag: SEZ / CLZ
Global Interrupt: SEI / CLI
Signed Test: SES / CLS
Two’s Complement Overflow: SEV / CLV
T in SREG: SET / CLT
Half Carry Flag: SEH / CLH

Daniel K. schrieb:
> ; Globale Interrupts aktivieren
>   lds temp1, CPU_SREG
>   ldi temp2, (0x01 << 0x07)
>   or temp1, temp2
>   sts CPU_SREG, temp1

von Daniel K. (daniel_k80)


Lesenswert?

Hallo Karl,

danke für die Anmerkungen :)
Kenne das sei() Makro bisher nur aus C. Wusste nicht, dass es auch in 
Assembler verfügbar ist.

Der Pull-Up hat leider nichts gebracht. Der Tiny macht immer noch nichts 
:(

von Daniel K. (daniel_k80)


Lesenswert?

Ok, der Fehler scheint wohl nicht am Mikrocontroller zu liegen, sondern 
vielmehr macht die RTC ohne Debugger nicht das was sie soll (nämlich 10 
Sekunden warten).
Statt 10 Sekunden sind es 10 ms. Da scheint noch was nicht richtig 
gesetzt zu werden...

Edit:
Problem gelöst. Ohne Debugger wurde der Prescaler nicht richtig gesetzt.
Ich habe das Problem nun gelöst, indem ich vor dem Setzen noch auf einen 
Sync warte, dann den Wert setze und dann noch einmal synchronisiere.
Nun funktioniert es.
1
RTC_Init:
2
  rcall RTC_WaitBusy
3
  ldi temp1, (RTC_PRESCALER1_bm | RTC_PRESCALER3_bm)
4
  sts RTC_CTRLA, temp1
5
  rcall RTC_WaitBusy

: Bearbeitet durch User
von Karl M. (Gast)


Lesenswert?

Daniel K. schrieb:
> Hallo Karl,
>
> danke für die Anmerkungen :)
> Kenne das sei() Makro bisher nur aus C. Wusste nicht, dass es auch in
> Assembler verfügbar ist.

Ist aber im Assembler kein Macro.

Kennst Du schon die vielen Info(-seiten) zum Atmel AVR 
Assemblerbefehlssatz?

1) https://www.microchip.com/webdoc/avrassembler/index.html
2) http://ww1.microchip.com/downloads/en/devicedoc/40001917a.pdf

Mehr?

google: "https://www.microchip.com/ avr assembler"

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.