Forum: Mikrocontroller und Digitale Elektronik CAN Empfänger (ATMega16M1) asm einrichten, damit CAN nachrichtenbestätigt werden?


von Thomas (kosmos)


Lesenswert?

Hallo, kann mir jemand bei der Konfiguration eines ATMega16M1 helfen, er 
soll vorerst nur Nachrichten empfangen damit der Sender nicht immerzu 
das gleiche Telegramm sendet, weil ich so nicht weiter simulieren kann. 
Ich hänge man den Code hier einfach rein.
1
.include "m16M1def.inc"
2
.def  temp      =R16
3
.def  temp2      =R17
4
.def  daten      =R18
5
.def  status      =R19    
6
.def  aufgabe      =R20
7
.def  status_1    =R21
8
.def  status_2    =R22
9
.def  status_3    =R23
10
.def  EEPROM_Adresse  =R24
11
.def  Zaehler1    =R25
12
13
.DSEG  ;Reserve jeweils 1 Byte / Variabl eim SRAM
14
temp3:          .byte  1
15
temp4:          .byte  1
16
Status_alt:        .byte  1
17
Status_neu:        .byte  1
18
Identifier1H:      .byte  1
19
Identifier1L:      .byte  1
20
Identifier2H:      .byte  1
21
Identifier2L:      .byte  1
22
Identifier3H:      .byte  1
23
Identifier3L:      .byte  1
24
Identifier4H:      .byte  1
25
Identifier4L:      .byte  1
26
27
.CSEG
28
.ORG  0x0000
29
jmp RESET         ; Reset Handler
30
reti;  jmp ANA_COMP_0  ; Analog Comparator 0 Handler
31
nop
32
reti;  jmp ANA_COMP_1  ; Analog Comparator 1 Handler
33
nop
34
reti;  jmp ANA_COMP_2  ; Analog Comparator 2 Handler
35
nop
36
reti;  jmp ANA_COMP_3  ; Analog Comparator 3 Handler
37
nop
38
reti;  jmp PSC_FAULT  ; PSC Fault Handler
39
nop
40
reti;  jmp PSC_EC    ; PSC End of Cycle Handler
41
nop
42
reti;  jmp EXT_INT0  ; IRQ0 Handler
43
nop
44
reti;  jmp EXT_INT1  ; IRQ1 Handler
45
nop
46
reti;  jmp EXT_INT2  ; IRQ2 Handler
47
nop
48
reti;  jmp EXT_INT3  ; IRQ3 Handler
49
nop
50
reti;  jmp TIM1_CAPT  ; Timer1 Capture Handler
51
nop
52
reti;  jmp TIM1_COMPA  ; Timer1 Compare A Handler
53
nop
54
reti;  jmp TIM1_COMPB  ; Timer1 Compare B Handler
55
nop
56
reti;  jmp TIM1_OVF  ; Timer1 Overflow Handler
57
nop
58
reti;  jmp TIM0_COMPA  ; Timer0 Compare A Handler
59
nop
60
reti;  jmp TIM0_COMPB  ; Timer0 Compare B Handler
61
nop
62
reti;  jmp TIM0_OVF  ; Timer0 Overflow Handler
63
nop
64
reti;  jmp CAN_INT    ; CAN MOB,Burst,General Errors Handler
65
nop
66
reti;  jmp CAN_TOVF  ; CAN Timer Overflow Handler
67
nop
68
reti;  jmp LIN_TC    ; LIN Transfer Complete Handler
69
nop
70
reti;  jmp LIN_ERR    ; LIN Error Handler
71
nop
72
reti;  jmp PCINT0    ; Pin Change Int Request 0 Handler
73
nop
74
reti;  jmp PCINT1    ; Pin Change Int Request 1 Handler
75
nop
76
reti;  jmp PCINT2    ; Pin Change Int Request 2 Handler
77
nop
78
reti;  jmp PCINT3    ; Pin Change Int Request 3 Handler
79
nop
80
reti;  jmp SPI_STC    ; SPI Transfer Complete Handler
81
nop
82
reti;  jmp ADC      ; ADC Conversion Complete Handler
83
nop
84
reti;  jmp WDT      ; Watchdog Timer Handler
85
nop
86
reti;  jmp EE_RDY    ; EEPROM Ready Handler
87
nop
88
reti;  jmp SPM_RDY    ; Store Program Memory Ready Handler
89
90
RESET:
91
Stack_init:        ; Stackpointer initialisieren
92
ldi r16, high(RAMEND)
93
out SPH,r16
94
ldi r16, low(RAMEND)
95
out SPL,r16
96
sei            ; Interrupts aktivieren
97
98
Port_init:
99
ldi temp, 0b00000000  ;PortB ist Eingang
100
out ddrb, temp
101
ldi temp, 0b00000001  ;PullUps an Port B aktivieren
102
out Portb, temp
103
104
ldi temp, 0b01000100  ;Pin2 Ausgang für TX MCP2551 und Pin6 Ausgang für RS MCP2551
105
out ddrc, temp      
106
ldi temp, 0b10111011
107
out portc, temp
108
109
ldi temp, 0b10000000  ;Pin7 Ausgang für LED
110
out ddrd, temp
111
112
CAN_init:
113
ldi temp, (0<<ABRQ)|(0<<OVRQ)|(0<<TTC)|(0<<SYNTTC)|(0<<LISTEN)|(0<<TEST)|(0<<ENASTB)|(1<<SWRES)
114
sts CANGCON, temp    ; CAN General Control Register,   software reset
115
116
Ready_enable:
117
;lds temp, CANGSTA
118
;sbrs  temp, ENFG    ;CAN enable
119
;rjmp  Ready_enable  ;springt raus, wenn fertig
120
121
;ldi temp, 0b10000000  ;Pin7 Ausgang für LED
122
;out portd, temp
123
124
ldi temp, (0<<BRP5)|(0<<BRP4)|(1<<BRP3)|(0<<BRP2)|(0<<BRP1) |(1<<BRP0)
125
sts CANBT1, temp    ; set baud rate to 16 kbps bei Stystem Clock 8 Mhz
126
ldi temp, (1<<PRS2)|(1<<PRS1)|(1<<PRS0)
127
sts CANBT2, temp
128
ldi temp, (1<<PHS22)|(1<<PHS21)|(1<<PHS20)|(1<<PHS12)|(1<<PHS11)|(1<<PHS10)|(1<<SMP)
129
sts CANBT3,temp
130
131
ldi temp, (0<<MOBNB3)|(0<<MOBNB2)|(0<<MOBNB1)|(0<<MOBNB0)|(0<<AINC)|(0<<INDX2)|(0<<INDX1)|(0<<INDX0)
132
sts CANPAGE, temp    ; select MOb0
133
134
ldi temp, 0
135
sts CANSTMOB, temp    ; CAN Statusregister löschen
136
137
ldi temp, (1<<ENIT)|(0<<ENBOFF)|(1<<ENRX)|(0<<ENTX)|(0<<ENERR)|(0<<ENBX)|(0<<ENERG)|(0<<ENOVRT)
138
sts CANGIE, temp    ; enable Interrupts
139
140
ldi temp, (1<<CANIT)|(0<<BOFFIT)|(0<<OVRTIM)|(0<<BXOK)|(0<<SERG)|(0<<CERG)|(0<<FERG)|(0<<AERG)
141
sts CANGIT, temp
142
143
ldi temp, (0<<ENMOB5)|(0<<ENMOB4)|(0<<ENMOB3)|(0<<ENMOB2)|(0<<ENMOB1)|(1<<ENMOB0)
144
sts CANEN2, temp    ; enable MOB
145
146
ldi temp, 0b00000000
147
sts CANEN1, temp    ; reserved
148
149
ldi temp, (0<<IEMOB5)|(0<<IEMOB4)|(0<<IEMOB3)|(0<<IEMOB2)|(0<<IEMOB1)|(1<<IEMOB0)
150
sts CANIE2, temp
151
152
ldi temp, 0b00000000
153
sts CANIE1, temp    ; reserved
154
155
ldi temp, (0<<SIT5)|(0<<SIT4)|(0<<SIT3)|(0<<SIT2)|(0<<SIT1)|(0<<SIT0)
156
sts CANSIT2, temp    ; enable CAN Status Interrupt
157
158
ldi temp,(0<<TPRSC7)|(0<<TPRSC6)|(0<<TPRSC5)|(0<<TPRSC4)|(0<<TPRSC3)|(0<<TPRSC2)|(0<<TPRSC1)|(0<<TPRSC0)
159
sts CANTCON,temp    ; CAN timer Prescaler
160
161
ldi temp,(0<<HPMOB3)|(0<<HPMOB2)|(0<<HPMOB1)|(0<<HPMOB0)|(0<<CGP3)|(0<<CGP2)|(0<<CGP1)|(0<<CGP0)
162
sts CANHPMOB,temp    ; CAN Highest Priority MOb Register
163
164
init_CAN_Identifier_Maske:  ;Filter deaktivieren, alle Nachrichten werden verarbeitet
165
ldi temp, 0
166
sts CANIDM1, temp
167
sts CANIDM2, temp
168
sts CANIDM3, temp      ;nur nötig bei 29bit ID
169
sts CANIDM4, temp
170
171
ldi temp,(1<<CONMOB1)|(0<<CONMOB0)|(0<<RPLV)|(0<<IDE)|(0<<DLC3)|(0<<DLC2)|(0<<DLC1)|(1<<DLC0)
172
sts CANCDMOB, temp    ; RX Mode enable, CAN 11bit identifier, 8bit data lenght
173
174
ldi temp, (0<<ABRQ)|(0<<OVRQ)|(0<<TTC)|(0<<SYNTTC)|(0<<LISTEN)|(0<<TEST)|(1<<ENASTB)|(1<<SWRES)
175
sts CANGCON, temp    ; CAN General Control Register,   software reset
176
177
loop: rjmp loop

: Bearbeitet durch User
von Rudolph (Gast)


Lesenswert?

Bäh, warum tust Du Dir das in Assembler an?

Hier, das sollte laufen:
1
#include <avr/io.h>
2
3
int main(void)
4
{
5
  uint8_t i,j;
6
7
  DDRB = 0x00;  // alle Pins auf Eingang
8
  PORTB = 0xff; // Pullups an
9
10
  DDRC = (1<<PORTC2);  // PORTC2 auf Ausgang
11
  PORTC = 0xff; // Pullups an
12
13
  DDRD = 0x00; // alle Pins auf Eingang
14
  PORTD = 0xff; // Pullup-Widerstände an
15
16
  DDRE = 0x00;  // alle Pins auf Eingang
17
  PORTE = 0xff; // Pullups an
18
  
19
20
  CANGCON = (1<<SWRES); // off and reset
21
22
  //reset all MObs
23
  for (i=0; i<6; i++)
24
  {
25
    CANPAGE = (i<<4); // select MOb
26
    CANCDMOB = 0x00;    // disable MOb
27
    CANSTMOB = 0x00;    // clear status
28
    CANIDT1 = 0x00;    // clear ID
29
    CANIDT2 = 0x00;
30
    CANIDT3 = 0x00;
31
    CANIDT4 = 0x00;
32
    CANIDM1 = 0x00;    // clear mask
33
    CANIDM2 = 0x00;
34
    CANIDM3 = 0x00;
35
    CANIDM4 = 0x00;
36
    for (j=0; j<8; j++)
37
    {
38
      CANMSG = 0x00; // clear data
39
    }
40
  }
41
42
  // setup für 500 kBit/s mit 16 MHz Quarz
43
  CANBT1 = (1<<BRP0);
44
  CANBT2 = (1<<PRS2) | (1<<PRS1);
45
  CANBT3 = (1<<PHS21) | (1<<PHS20) | (1<<PHS11) | (1<<PHS10) | (1<<SMP);
46
47
  CANGCON = (1<<ENASTB); // enable CAN
48
49
  CANGIE = 0x00;
50
  CANIE1 = 0x00;
51
  CANIE2 = 0x00;
52
  CANSIT1 = 0x00;
53
  CANSIT2 = 0x00;
54
  
55
  while(1);
56
}

von Rudolph (Gast)


Angehängte Dateien:

Lesenswert?

Hier noch die .hex dazu.

von wendelsberg (Gast)


Lesenswert?

Rudolph schrieb:
> Bäh, warum tust Du Dir das in Assembler an?

Naja, bei diesem Problem ist der Unterschied so riesig nicht.

wendelsberg

von Thomas (kosmos)


Lesenswert?

danke für die .hex spiele ich heute Abend mal drauf.

Bisher habe ich alles in .asm gelöst bekommen und außerdem hat das Ding 
nur 16kB Flash ;-)

von Rudolph (Gast)


Lesenswert?

Thomas O. schrieb:
> Bisher habe ich alles in .asm gelöst bekommen

Gut für Dich. :-)
Ich tue mir das nur noch an wenn es wirklich notwendig wird.
Und das ist es quasi nie.

> und außerdem hat das Ding nur 16kB Flash ;-)

Ha, die müssen erstmal voll werden und die sind in C auch nicht 
schneller voll. :-)
Und dann gibt es ja noch 32M1 und 64M1... ;-)

von Thomas F. (igel)


Lesenswert?

Thomas O. schrieb:

vorletzte Zeile:
1
> ldi temp, 
2
> (0<<ABRQ)|(0<<OVRQ)|(0<<TTC)|(0<<SYNTTC)|(0<<LISTEN)|(0<<TEST)|(1<<ENASTB)|(1<<SWRES)
3
> sts CANGCON, temp    ; CAN General Control Register,   software reset

Hier sollte Reset eher nicht mehr gesetzt werden, das hast du ja zu 
Anfangs schon gemacht.

von Thomas (kosmos)


Lesenswert?

@Thomas Forster: Das war der Fehler ich bin davon ausgegangen das das 
SWRST Bit nur einen CAN Reset mit einem uC Reset verknüpft damit kann 
man aber immer einen CAN Reset ausführen.

@All: Der Code funktioniert wen man dieses eine Bit löscht und den 
Resetvektor für CAN_INT korrigiert, es wird CAN_INT angesprungen dort 
muss man sich dann um die Auswertung kümmern.

von Rudolph R. (rudolph)


Lesenswert?

Thomas O. schrieb:
> @All: Der Code funktioniert wen man dieses eine Bit löscht und den
> Resetvektor für CAN_INT korrigiert, es wird CAN_INT angesprungen dort
> muss man sich dann um die Auswertung kümmern.

Die Anforderung war ein ACK zu generieren, dazu braucht es weder einen 
Interrupt, noch gar irgend eine Auswertung.

von Thomas (kosmos)


Lesenswert?

Ich wollte damit nur sagen das es auf der Empfängerseite nicht viel mehr 
erfordert. Die ganze Bearbeitung in den verschiedenen Fehlerfällen mach 
ich nach und nach.

Zum Speicherplatz: Beim Sender bin ich inzwischen bei 5% und beim 
Empfänger waren es nicht mal 1%, selbst wenn ich da noch nen Bootloader 
und andere Goodies dazu bastele ist genug Platz vorhanden.

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.