Forum: Mikrocontroller und Digitale Elektronik Lookup Tabelle in ASM30 (dsPIC)


von Ge E. (re_n)


Lesenswert?

Guten Abend. Kennt sich einer mit besagten Thema aus und kann mir ein 
konkretes Beispiel Posten, ich finde im Netz leider nix 
aussagekräftiges, das meiste ist in C..

Folgendes es soll sich um eine Sinus Tabelle handeln, in der einen 
Spalte die Grad und in der anderen der dazugehörige Tastgrad der PWM. 
Die Grad gebe ich inkrementell vor, der PIC soll dann ohne viel zu 
rechnen den dazu Passenden PWM Wert finden und in den RAM laden.

von Max H. (hartl192)


Lesenswert?

Ich würde es so machen:
1
LUT:
2
  bra W1
3
  retlw #PwmWert0,W1
4
  retlw #PwmWert1,W1
5
  retlw #PwmWert2,W1
6
  retlw #PwmWert3,W1
7
  retlw #PwmWert4,W1
8
  retlw #PwmWert5,W1
9
  ....
10
  retlw #PwmWertN,W1

In W1 schreibst du die Stelle in der Tabelle, dann rufst du mit call LUT 
auf und dann steht der Wert in W1. Das sollte 6 Maschinenzyklen lang 
dauern.


Edit: Man könnte auch mit TBLRD was machen, damit habe ich aber noch nie 
gearbeitet.

: Bearbeitet durch User
von Maik W. (werner01)


Lesenswert?

hier die Hälfte verrate ich dir....

   .org(0xd00)
    sinetable:
.word  0x0000,0x0006,0x000D,0x0013
.word  0x0065,0x006B,0x0071,0x0077

So mach ich das und retlw gibts bei dspic nicht.

von Max H. (hartl192)


Lesenswert?

Maik Werner schrieb:
> retlw gibts bei dspic nicht.
Das sieht Microchip anders:
http://ww1.microchip.com/downloads/en/DeviceDoc/70000657H.pdf
Seite 395

Max H. schrieb:
> Das sollte 6 Maschinenzyklen lang
> dauern.
Ich sehe gearede, dass sprünge beim dsPIC länger brauchen, das mit den 6 
Zyklen stimmt also nicht.

Wie groß soll die Tabelle eigentlich werden? Wenn sie nur ganz klein 
wird könnte man sie in der RAM legen

: Bearbeitet durch User
von Ge E. (re_n)


Lesenswert?

Maik Werner schrieb:
> hier die Hälfte verrate ich dir....
>
>    .org(0xd00)
>     sinetable:
> .word  0x0000,0x0006,0x000D,0x0013
> .word  0x0065,0x006B,0x0071,0x0077
>
> So mach ich das und retlw gibts bei dspic nicht.

Danke Maik, aber so weit war ich auch schon, was ich gern wissen würde 
wie kann ich mit der Tabelle interagieren und woher weis der PIC welchen 
Wert er nehemn soll?

von Ge E. (re_n)


Lesenswert?

Bei mir sieht die Tabelle im Moment so aus:

     .section sine_tab, code, address(0xAA00)

    .word 
0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x 
1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x11 
11,0x2222
    .word 
0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x 
1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x11 
11,0x2222
    .word 
0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x 
1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x11 
11,0x2222
    .word 
0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x 
1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x11 
11,0x2222
    .word 
0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x 
1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x11 
11,0x2222
    .word 
0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x 
1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x11 
11,0x2222
    .word 
0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x 
1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x11 
11,0x2222
    .word 
0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x 
1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x11 
11,0x2222
    .word 
0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x 
1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x11 
11,0x2222
    .word 
0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x 
1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x11 
11,0x2222
    .word 
0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x 
1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x11 
11,0x2222
    .word 
0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x 
1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x11 
11,0x2222
    .word 
0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x 
1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x11 
11,0x2222
    .word 
0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x 
1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x11 
11,0x2222
    .word 
0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x 
1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x11 
11,0x2222
    .word 
0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x 
1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x11 
11,0x2222
    .word 
0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x 
1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x11 
11,0x2222
    .word 
0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x 
1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x11 
11,0x2222
    .word 
0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x 
1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x11 
11,0x2222
    .word 
0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x 
1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x11 
11,0x2222

Die Werte sind nur Platzhalter ich muss erstmal das Printip verstehen. 
Spätere Größe 200x200 bzw würde beim Silus mit Umrechnung aja auch ein 
viertel der Größe reichen. Ich brauche 100/Grad Auflösung. Also nein die 
Tabelle würde ich lieber im Speicher ablegen. RETLW geht übrigens noch 
beim dsPIC

von Maik W. (werner01)


Lesenswert?

Hallo,

Ich lese die Tabellen aus dem ROM mit der TBLRD(L,H) Anweisung diese 
benötigt 2 Zyklen...
RAM Tabellen gehen sehr gut mit einer indirekten Adressierung.

vieleicht hilft es Dir weiter...

von Maik W. (werner01)


Lesenswert?

Also ich verstehe das so, wenn deine Tabelle eine halbe Schwingung 
enthält
so entspricht das 180° .Dies teilst Du durch die Anzahl deiner 
"Stützstellen" o. Einträge....

von Ge E. (re_n)


Lesenswert?

Wie ruft man den einen speziellen Wert aus der Tabelle ab?

von Maik W. (werner01)


Lesenswert?

Indem Du die Gradzahl kennst?

von Ge E. (re_n)


Lesenswert?

Maik Werner schrieb:
> Indem Du die Gradzahl kennst?

Die kenne ich ;) Wie speziell arbeite ich mit dem TBLRD H und L Befehl? 
Am besten währe es wenn ich den Grad Wert einfach in eine Adresse für 
die Tabelle umwandle.

Beispiel:

INT:             ; wird zB alle 1µs aufgerufen

  mov    GRAD_PRO_STEP,W0   ; fester vorberechneter Wert
  ADD    GPS  ; Vortlaufende Addierung bis zum Überlauf usw..

        ; Jetzt möchte ich den "GPS" Wert in eine Addresse umrechnen die 
mir den passenden PWM Wert nach W0 kopiert, wie genau siehen die Befehle 
aus?
        mov    -PWM WERT aus TABELLE-,W0
        mov      W0,MDC

        bclr  IFS5,#PWM1IF
  bclr  PWMCON1,#TRGSTAT
  retfie

von Ge E. (re_n)


Lesenswert?

habe mal bissl rumexperimentiert:  so geht es:

MOV   #0xAA00,W0

TBLRDH [W0],W3                 ; Read high byte to W3

TBLRDL [W0],W4                 ; Read low word to W4
mov  W4,F_DAT16

von Ge E. (re_n)


Lesenswert?

Wofür ist eigentlich der "TBLPAG" Befehl?

von Maik W. (werner01)


Lesenswert?

z.B. so:

     TBLRDL [w5],w2        -->


hiermit liest du die unteren 16b deiner 24b Romspeicherstelle aus. in W5 
steht die Adresse (indirekt) und in W2 der entsprechende 
Tabelleneintrag. Das alles dauert 2 Zyklen!
   viel Erfolg

von Ge E. (re_n)


Lesenswert?

OK danke ihr alle wart sehr hilfreich. Ich fuche jetzt mal ein bisschen 
rum :)

von Ge E. (re_n)


Lesenswert?

Wie schreibe ich hier Dezimal Zahlen? Eine Raute nimmt er leider nicht

.word 0x3333,0x4444,0x1111,0x2222

von (prx) A. K. (prx)


Lesenswert?

Re Né schrieb:
> Wofür ist eigentlich der "TBLPAG" Befehl?

Ein 8-Bit Register, das die 16 Bits aus dem Register im TBLxxx Befehl zu 
einer 24-Bit Adresse verlängert. Wären sonst ja nur 96KB ROM 
adressierbar. Bank-Switching in guter alter Microchip-Tradition.

: Bearbeitet durch User
von Ge E. (re_n)


Lesenswert?

Re Né schrieb:
> Wie schreibe ich hier Dezimal Zahlen? Eine Raute nimmt er leider nicht
>
> .word 0x3333,0x4444,0x1111,0x2222

OK habe es herausgefudnen bei Dezimalzahlen lässt man einfach das 0x weg 
also:

.word 3333,4444,1111,2222

: Bearbeitet durch User
von Ge E. (re_n)


Lesenswert?

So habe jetzt eine LTB mit 36.000 Werten generiert (Excel) und im 
Programm eingebunden. Sind gleich mal 41% vom PIC Speicher ^^  Am Montag 
setze ich das dann in die Praxis um

von Ge E. (re_n)


Angehängte Dateien:

Lesenswert?

Für die die es Interessiert hier ist der Code. Was noch nicht enthalten 
ist, ist die Steuerung per SPI. Das möchte ich gerne über DMA lösen. Im 
Anhang befindet sich die Sinus Tabelle mit 36.000 Stützen. Range (0-300) 
Das ist der PWM Wert.

1
;RA0
2
;RA1
3
;RA2
4
;RA3
5
6
;RB0
7
;RB1
8
;RB2
9
;RB3
10
;RB4
11
;RB5
12
;RB6
13
;RB7  SCK1
14
;RB8  SDO1
15
;RB9  SDI1
16
;RB10
17
;RB11
18
;RB12 PWM2H
19
;RB13 PWM2L
20
;RB14 PWM1H
21
;RB15 PWM1L
22
23
  
24
25
.title "MFG DDS"
26
.sbttl ""              ; Firmware Version
27
28
 .equ __33EP256MC202, 1         ; Define the type of MCU
29
 .include "P33EP256MC202.inc"      ; Include the definitions for the
30
                        ; selected MCU
31
32
; CONFIG
33
    ;config __FPOR, PWRT_128          ; PWRT 128ms
34
    ;config __FOSC, CSW_FSCM_OFF & FRC_LO_RANGE  ; LOW RANGE
35
    ;config __FWDT, FWDTEN_OFF & WINDIS_OFF  ; WDT OFF
36
    ;config __FOSCSEL,FRC_PLL        ; FRC PLL 
37
    ;config __FGS, CODE_PROT_OFF
38
    ;config __FICD, ICS_NONE          ; kein ICS
39
    ;config __FBS, NO_BOOT_CODE
40
41
42
.global __reset
43
__reset:                ; hier setzt der PIC nach einem Reset ein
44
45
46
47
.text                  ; hier geht der asm code weiter!
48
49
      mov     #__SP_init,w15          ; Initalize the Stack Pointer
50
     ;  mov     #0x2AFEA,W0          ; Initialize the Stack Pointer Limit Register
51
     ;  mov     W0,SPLIM            ; (__SP_init & __SPLIM_init values are calculated by linker)
52
       ;nop                        ; Add NOP to follow SPLIM initialization
53
54
55
;#########################################################################################################  
56
57
; Ports config (alle unbenutzten Pins sollten auf Out und low sein)
58
      
59
    clr    TRISA
60
    ;bset  TRISA,#0
61
    clr    TRISB
62
    ;bset  TRISA,#1
63
    CLR    LATA        ; alle Ausgänge löschen
64
    CLR    LATB
65
66
; ################################################################## 
67
  
68
    ;.global  __INT0Interrupt
69
    ;.global  __INT1Interrupt
70
    ;.global  __INT2Interrupt
71
    ;.global  __IC1Interrupt
72
    ;.global  __OC1Interrupt
73
    .global    __T1Interrupt
74
    ;.global  __IC2Interrupt
75
    .global    __T2Interrupt
76
    .global    __T3Interrupt
77
    .global    __T4Interrupt
78
    .global    __T5Interrupt
79
    .global      __PWM1Interrupt
80
    ;.global  __SPI1ErrInterrupt
81
    ;.global  __SPI1Interrupt
82
    ;.global  __CNInterrupt
83
    ;.global  __CMP1Interrupt
84
    ;.global  __CMP2Interrupt
85
    ;.global  __U1RXInterrupt
86
    ;.global  __U1TXInterrupt  
87
88
89
; Labelmacros
90
    ;  .macro HF_AN bit_operation
91
   ;  \bit_operation PTCON,#15
92
    ;  .endm
93
94
     .section sine_tab, code, address(0x200)  ; 0x200
95
96
   .include "SINE_TAB.S"          ; Include SINE TAB
97
98
99
 
100
.text                  ; hier beginnt das Assembler Programm
101
102
    .section .nbss, bss, near    ;Register festlegen
103
    .align 2
104
    FQ:        .space 2
105
    .align 2
106
    USK:      .space 2
107
    .align 2
108
    GRAD_PRO_STEP:  .space 2
109
    .align 2
110
    GPS:      .space 2
111
    .align 2
112
    GPS_L:      .space 2
113
    .align 2
114
    GPS_H:      .space 2
115
    .text              ; hier geht der asm code weiter!
116
117
118
    MOV     #0b0000000000000000,W0  ;  
119
    MOV   W0,CLKDIV
120
121
    mov    #511,W0          ; 511
122
    mov    W0,PLLFBD        ; PLL multiplier
123
124
    MOV     #0b1000000000000000,W0  ;   
125
    MOV   W0,T1CON
126
127
    mov    #100,W0          ; 
128
    mov    W0,PR1
129
130
    MOV     #0b1100000000000000,W0  ;  
131
    MOV   W0,IOCON1
132
133
    MOV     #0b1100000000000010,W0  ; SWAP Low High
134
    MOV   W0,IOCON2
135
136
    bset  PWMCON2,#8        ; MDC
137
    bset  PWMCON1,#8        ; MDC
138
    bset  PWMCON1,#TRGIEN      ; TRGIEN
139
140
    MOV     #0b1000000000000000,W0  ;
141
    MOV   W0,PTCON
142
143
    mov    #300,W0          ; 300=800kHz
144
    mov    W0,PTPER        ; Frequenz
145
146
    mov    #150,W0
147
    mov    W0,MDC          ; Pulse Breite
148
149
    mov    #5,W0
150
    mov    W0,DTR1          ; Dead Time Links
151
152
    mov    #5,W0
153
    mov    W0,ALTDTR1        ; Dead Time Links
154
155
    mov    #5,W0
156
    mov    W0,DTR2          ; Dead Time Rechts
157
158
    mov    #5,W0
159
    mov    W0,ALTDTR2        ; Dead Time Rechts
160
161
162
; ############ FQ nach Grad pro Step wandeln (auf anderem PIC berechnen und GRAD_PRO_STEP per SPI schicken.)################
163
    mov    #1001,W0          ; Hz/100
164
    mov    W0,FQ
165
166
    mov    #0x98,W1        ; 0b10111110101    #10.000.000
167
    mov    #0x9680,W0        ; 0b1110000100000000
168
169
    mov    FQ,W2          ; FQ -> W2
170
    repeat   #18-1
171
    div.ud  W0,W2          ; 100.000.000 / FQ -> W0
172
    mov    W0,USK
173
174
    mov    #100,W0
175
    MUL    USK            ; 100 x USK = W3:W2
176
177
    mov    W3,W1          ; W3:W2 nach W1:W0
178
    mov    W2,W0
179
    mov    #625,W2          ; 625ns (Sampelrate) -> W2
180
    repeat   #18-1
181
    div.ud  W0,W2          ; X / 100 -> W0
182
    mov    W0,USK          ; ns der Periode
183
184
    mov    #0x36,W1        ; 3.600.000 nach W1:W0
185
    mov    #0xEE80,W0
186
    mov    USK,W2          ; USK -> W2
187
    repeat   #18-1
188
    div.ud  W0,W2          ; 3.600.000 / USK -> W0
189
    mov    W0,GRAD_PRO_STEP    ; (Grad x 1000)
190
; #######################################################################
191
192
; RAM
193
    clr    GPS
194
195
; Interrupt
196
    bset  IEC0,#T1IE      ; Interrupt Enable
197
    bset   IPC0,#T1IP2      ; Interrupt Priority 4
198
  ;  bset  IEC5,#PWM1IE      ; Interrupt Enable
199
  ;  bset   IPC23,#PWM1IP2      ; Interrupt Priority 4
200
    ; SPI per DMA!!!
201
  
202
203
MAIN:
204
205
    goto  MAIN
206
207
208
209
210
;__PWM1Interrupt:        ; 32 cycles max.
211
212
__T1Interrupt:
213
214
    mov    GRAD_PRO_STEP,WREG
215
    ADD    GPS
216
217
    mov    #36000,W0
218
    mov    #36000,W1
219
    mov    GPS,W2
220
    CPSGT  W1,W2      ; skip if N > GPS
221
    SUB    GPS        ; if N < GPS
222
223
    mov    #2,W0
224
    MUL    GPS        ; GPS x 2 = W3:W2
225
226
    mov    W3,GPS_H
227
    mov    W2,GPS_L
228
229
    mov    #512,W0
230
    ADD    GPS_L
231
232
    mov    GPS_H,W0
233
    mov    W0,TBLPAG
234
    
235
    MOV   GPS_L,W0 
236
                
237
  ;  TBLRDH [W0],W3                 ; Read high byte to W3 (Kann gelöscht werden wenn keine Fehler auftreten)
238
    TBLRDL [W0],W4                 ; Read low word to W4
239
    mov    W4,MDC  
240
    
241
    bclr  IFS0,#T1IF
242
  ;  bclr  IFS5,#PWM1IF
243
  ;  bclr  PWMCON1,#TRGSTAT
244
    retfie
245
246
247
switch:
248
249
    btss  LATB,#6
250
    goto  setB6
251
252
    btsc  LATB,#6
253
    goto  clrB6
254
255
setB6:
256
    bset  LATB,#6
257
    return
258
259
clrB6:
260
    bclr  LATB,#6
261
    return
262
263
264
    .end                ; Programm Ende

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.