Forum: Mikrocontroller und Digitale Elektronik Atmega8515 auf Atmega16L


von Mr. D (Gast)


Lesenswert?

Ich habe folgendes Problem:
Einen Assemblercode in avr gcc für den Atmega8515 für einen Atmega16L 
verwenden.
1
//
2
// local functions
3
//
4
;    r24    r22
5
; void startSCI(u08 mode, u08 address)
6
startSCI:
7
    cbi  MP3_PORT,MP3_PIN    ; activate VS1001 Chip Select
8
    rcall  spi_tx_rx      ; send the mode (READ or WRITE)
9
    mov  r24,r22        ; get address
10
    rjmp  spi_tx_rx      ; send address
11
12
; void endSCI(void)
13
endSCI:
14
     sbi   MP3_PORT, MP3_PIN    ; set CS hi
15
    clr  r25        ; do a 10us
16
    rcall  delay10us      ; delay
17
    ret
18
19
spi_tx_rx:
20
    out   SPDR, r24      ; send over SPI
21
vspi1:    sbis   SPSR,SPIF      ; while flag is clear
22
     rjmp   vspi1        ; wait for SPI
23
     in   r24, SPDR      ; and get input data
24
    ret          ; done
25
26
27
//
28
// global functions
29
//
30
31
;      r24
32
;void vs1001_send_data(u08 data)
33
  .global vs1001_send_data
34
vs1001_send_data:  
35
    cli
36
     sbi  BSYNC_PORT,BSYNC_PIN    ; start BSYNC
37
    out   SPDR, r24      ; send over SPI
38
    nop
39
    nop
40
    nop
41
     cbi  BSYNC_PORT,BSYNC_PIN    ; stop BSYNC
42
vssd1:    sbis   SPSR,SPIF      ; while flag is clear
43
     rjmp   vssd1        ; wait for SPI
44
    sei
45
     ret
46
 
47
48
;    r24    
49
;u16 vs1001_read(u08 address)
50
  .global vs1001_read
51
vs1001_read:
52
    mov  r22,r24        ; address in r22
53
    ldi  r24,VS1001_READ
54
    rcall   startSCI      ; start SCI communication
55
      clr  r24
56
     rcall  spi_tx_rx      ; get a byte
57
    mov  r23,r24
58
      clr  r24
59
     rcall  spi_tx_rx      ; get a byte
60
    mov  r22,r24
61
      rcall  endSCI
62
      mov  r24,r22        ; get back word
63
      mov  r25,r23        ; get back word
64
      ret
65
66
;       r24    r23/r22
67
;void vs1001_write(u08 address, u16 data)
68
  .global vs1001_write
69
70
vs1001_write:
71
    mov  r18,r22        ; save register
72
    mov  r22,r24        ; address in r22
73
    ldi  r24,VS1001_WRITE
74
    rcall   startSCI      ; start SCI communication
75
      mov  r24,r23        ; get hi byte
76
     rcall  spi_tx_rx      ; send it
77
      mov  r24,r18        ; get lo byte
78
     rcall  spi_tx_rx      ; send it
79
      rjmp  endSCI
80
81
  
82
; send a 32 byte block of data to the VS1001   
83
; using the SPI port.               
84
;      r25/r24
85
;void vs1001_send_32(char *pData);
86
87
  .global vs1001_send_32
88
89
vs1001_send_32:
90
    mov   r31,r25        ; transfer input pointer to Z
91
    mov   r30,r24
92
      ldi  r25,32        ; init loop counter
93
vs32_2:    ld   r24,Z+        ; get a byte and inc pointer
94
    rcall  vs1001_send_data
95
     dec  r25        ; dec loop counter
96
     brne  vs32_2        ; loop if not zero
97
     ret
98
99
100
;      r25/r24
101
; void vs1001_nulls(u16 nNulls)
102
  .global vs1001_nulls
103
  
104
vs1001_nulls:
105
    mov  r30,r24  
106
    mov  r31,r25  
107
vs1001_nulls_2:    
108
    clr  r24    
109
    rcall  vs1001_send_data
110
    sbiw  r30,1
111
    brne  vs1001_nulls_2
112
    ret
113
114
;      r24  r22    
115
;void vs1001_setvolume(u08 left, u08 right)
116
  .global vs1001_setvolume
117
vs1001_setvolume:
118
    mov  r23,r24  
119
    ldi  r24,11        ; volume register
120
    rjmp  vs1001_write
121
122
123
.comm vs1001_xtalcomp,2        ; compensation value for the VS1001 xtal
124
125
;      r24
126
;void vs1001_reset(bool bLoud)
127
  
128
  .global  vs1001_reset
129
  
130
vs1001_reset:
131
    push   r24
132
    ldi  r25,8
133
    clr  r24
134
    rcall  vs1001_nulls
135
    
136
    ldi  r24,VS1001_MODE
137
    clr  r23
138
    ldi  r22,4  
139
    rcall  vs1001_write
140
    rcall  delay10us      ; delay
141
w_dreq:
142
    sbis  DREQ_PORT-2,DREQ_PIN    ;  wait for DREQ
143
    rjmp  w_dreq
144
    clr  r25
145
    ldi  r24,32;
146
    rcall  vs1001_nulls
147
148
    ; set CLOCKF to compensate for a non 24,576 MHz x-tal
149
    ldi  r24,VS1001_CLOCKF
150
    lds  r23,vs1001_xtalcomp+1    
151
    lds  r22,vs1001_xtalcomp    
152
    rcall  vs1001_write
153
    
154
    ; set sound enchance bit
155
    
156
    pop  r24
157
    clr  r22        ; clear r22
158
    ror  r24        ; rotate bit into carry
159
    ror  r22        ; rotate carry to high bit of r22
160
    clr  r23
161
    ldi  r24,VS1001_MODE
162
    rjmp  vs1001_write
163
164
165
;           r25/r24
166
; void vs1001_setcomp(u16 comp)
167
.global vs1001_setcomp
168
vs1001_setcomp:
169
    sts  vs1001_xtalcomp,r24
170
    sts  vs1001_xtalcomp+1,r25
171
    ret

die Fehlermeldung :../vs1001.s:93: Error: number must be less than 32
an Stellen die mit den Portzugriffen und dem SPI zutun haben.

Wie soll ich diese Stellen umschreiben damit das alles wieder 
funktioniert?

Danke

von spess53 (Gast)


Lesenswert?

Hi

>Wie soll ich diese Stellen umschreiben damit das alles wieder
>funktioniert?

Kennzeichne mal die Stellen, an denen Fehler auftreten. Eigentlich 
dürfte es keine Probleme geben, das die IO-Adressen für SPI identisch 
sind.

MfG Spess

von Mr. D (Gast)


Lesenswert?

Es sind folgende Stellen:

bei denen die Fehlermeldung auftritt:
1
cbi  MP3_PORT,MP3_PIN    ; activate VS1001 Chip Select
1
sbi   MP3_PORT, MP3_PIN    ; set CS hi
1
sbis   SPSR,SPIF      ; while flag is clear
1
sbi  BSYNC_PORT,BSYNC_PIN    ; start BSYNC
1
cbi  BSYNC_PORT,BSYNC_PIN
1
cbi  BSYNC_PORT,BSYNC_PIN    ; stop BSYNC
1
sbis  DREQ_PORT-2,DREQ_PIN

wo mit sbi,cbi,sbis gearbeitet wird

Ich habe gelesen dass das mit der avr version zusammenhängt.

von spess53 (Gast)


Lesenswert?

Hi

>Ich habe gelesen dass das mit der avr version zusammenhängt.

Nein, nur mit dem AVR-Typ.

Die Meldung

Fehlermeldung :../vs1001.s:93: Error: number must be less than 32

Deutet darauf hin, das 'MP3_PORT'... falsch definiert sind.

MfG Spess

von Mr. D (Gast)


Lesenswert?

ich sehe das es mit dem sbi, cbi und sbis zusammenhängt

von Mr. D (Gast)


Lesenswert?

teils verstehe ich nicht warum das nicht fuktioniert da es ein fertiges 
funktionierendes Programm war

von Krapao (Gast)


Lesenswert?

> teils verstehe ich nicht warum das nicht fuktioniert da es ein fertiges
> funktionierendes Programm war

Naja. Der Code oben ist ein Teil eines Programms. Es fehlen z.B. die 
Definitionen der Makros xxx_PORT und xxx_PIN. Wie Spess schon 
geschrieben hat, sind die zu kontrollieren.

Möglicherweise steht in einer Includedatei was drin ala "Wenn als µC-Typ 
Atmega8515 definiert ist, dann bedeutet xxx_PORT DIES und wenn nicht 
dann DAS." Bei einem Wechsel auf den Atmega16L ohne Anpassung einer 
solchen bedingten Makrodefinition klappt's nicht mehr.

von Mr. D (Gast)


Lesenswert?

Ich kompiliere die ganze Assembler Datei.
1
#include <avr/io.h>
2
//
3
// VS1001 I/O pins
4
//
5
6
#define MP3_PORT  PORTB
7
#define BSYNC_PORT  PORTB    
8
#define DREQ_PORT  PORTB
9
10
#define MP3_PIN    PB4        // MP3 control bit 
11
        
12
#define DREQ_PIN  PB2        // DREQ signal
13
#define BSYNC_PIN   PB3             // BSYNC signal
14
15
16
//
17
// VS1001 commands
18
//
19
#define VS1001_READ  0x03
20
#define VS1001_WRITE  0x02
21
22
//
23
// VS1001 registers
24
//
25
#define VS1001_MODE      0x00
26
#define VS1001_STATUS  0x01
27
#define VS1001_INTFCTLH  0x02
28
#define VS1001_CLOCKF  0x03
29
#define VS1001_PLAYTIME  0x04
30
#define VS1001_AUDATA  0x05
31
#define VS1001_VOLUME  0x0B
32
33
34
  .section  .text
35
36
//
37
// local functions

Das ist der Programmteil den ich vorher noch nicht hier gepostet habe.

von holger (Gast)


Lesenswert?

Versuchs mal so:

#define _ASSEMBLER_ 1
#define __SFR_OFFSET 0

#include <avr/io.h>

von holger (Gast)


Lesenswert?

Ach shit die Foren Formatierung hat zugeschlagen;)
1
#define __ASSEMBLER__ 1
2
#define __SFR_OFFSET 0
3
4
#include <avr/io.h>

von Mr. D (Gast)


Lesenswert?

@holger

Vielen Vielen Dank
Jetzt kommen die Fehler nicht mehr.
was bedeuten genau diese Anweisungen?

Jetzt ist dort noch ein Fehler mit
1
rcall  delay10us

befindet sich dieser Befehl in einer weitern header Datei?

Danke

von Hannes L. (hannes)


Lesenswert?

Mr. D schrieb:
> Jetzt ist dort noch ein Fehler mit
> rcall  delay10us
>
>
> befindet sich dieser Befehl in einer weitern header Datei?

Nein, der Befehl "RCALL" befindet sich im Befehlssatz des Assemblers.

Die von RCALL aufgerufene Routine mit dem Label "delay10us" liegt da, 
wo sie der Autor des Programms hingelegt hat. Da wirst Du wohl mal in 
allen zum Projekt gehörenden Dateien suchen müssen.

Viele professionelle Programmierer meinen, dass modularer Aufbau des 
Programms mit Auslagerung der Teile in separate Dateien (nach C-Manier) 
den Quellcode übersichtlicher macht. Aber ab einer gewissen 
Zerstückelung bekommt ein Außenstehender ein "Sucht-Problem", man sucht 
und sucht und sucht... - Und wenn man es gefunden hat, dann hat man 
vergessen, wonach man gesucht hat...

Ja, auch ich arbeite gelegentlich mit Include-Dateien, aber man kann es 
auch übertreiben.

...

von Mr. D (Gast)


Lesenswert?

@Hannes Lux

Vielen Dank

Tatsächlich hat sich diese Routine in einer extra .c Datei befunden, wo 
wirklich genau nur diese eine Funktion steht.

Danke

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.