Forum: Mikrocontroller und Digitale Elektronik PWM und AD-Messung Assembler


von Lisa (Gast)


Lesenswert?

Hallo!!

Ich muss bei folgendem Projekt noch die AD-Werte High und Low im Duty 
der PWM als Grenzen definieren. Zumindest hat es mir mein Professor so 
erklärt. Die AD-Messung und die PWM habe ich bereits fertig. Nun meine 
Frage: Wie kann ich die Werte High und Low als obere und untere Grenze 
definieren?
Ich hoffe wirklich, dass mir schnell jemand helfen kann, da ich das 
Projekt bis spätestens nächste Woche Freitag abgeben muss.


Die Aufgabenstellung:
# Projekt µController:
Schreiben sie ein Programm, welches die Helligkeit der roten Led mittels
Poti einstellen kann.
Der AD-Wert des Poti wird ausgelesen und modifiziert am Display
ausgegeben.
z.B AD=0 --> Anzeige „-00-„  AD=255 --> Anzeige „-99-„   (Anzeige der
Helligkeit in Prozent)
Der AD-Wert des Poti wird auch zur Ansteuerung der roten Led verwendet,
die Helligkeit lässt sich
am besten mit einer einfachen PWM (Pulsweitenmodulation) realisieren.
Hinweis: Da die rote Led nicht am PWM-Pin des PICs angeschlossen ist,
kann nicht die Standard PWM
des Controllers genommen werden. Die PWM Realisierung muss daher mittels
Software (richtiges ein/ausschalten)
realisiert werden.


Mein Programm:
1
                          TITLE   "UE2.asm"    ;
2
                LIST      C=135           ;number of columns
3
                LIST      N=65            ;number of lines
4
             #include   <p16f886.inc>
5
                LIST      p=16F886
6
7
8
;#################  Configurationsbits Einstellung
9
        ;__config  _CONFIG1,0x03E4
10
        __config  _CONFIG1,0x03F4      ;ohne Power up Timer
11
        __config  _CONFIG2,0x3EFF
12
;############
13
14
;**************************************************************************************
15
;       HW Konfiguration declaration 
16
;**************************************************************************************
17
;## 7 Segmentanzeige
18
#define    A_SEG  PORTC,0
19
#define    B_SEG  PORTC,1
20
#define    C_SEG  PORTC,2
21
#define    D_SEG  PORTC,3
22
#define    E_SEG  PORTC,4
23
#define    F_SEG  PORTC,5
24
#define    G_SEG  PORTA,4
25
#define    DP_SEG  PORTB,4
26
27
#define    SEG0  PORTB,0
28
#define    SEG1  PORTB,1
29
#define    SEG2  PORTB,2
30
#define    SEG3  PORTB,3
31
32
;## Leds
33
#define    LED_GRUEN  PORTA,5
34
#define    LED_ROT    PORTA,6
35
#define    LED_GELB  PORTA,7
36
37
;## Analogpins
38
#define    POTI  PORTA,0  
39
#define    TEMP  PORTA,1    
40
#define    LDR    PORTA,2
41
42
;## Taster
43
#define    S1    PORTB,5
44
#define    S2    PORTA,3
45
46
;## RS232
47
#define    TX    PORTC,6
48
#define    RX    PORTC,7
49
;**************************************************************************************
50
51
;Makros
52
Bank0    MACRO      ;macro to select data RAM bank 0
53
      bcf  STATUS,RP0
54
      bcf  STATUS,RP1
55
      ENDM
56
57
Bank1    MACRO      ;macro to select data RAM bank 1
58
      bsf  STATUS,RP0
59
      bcf  STATUS,RP1
60
      ENDM
61
Bank2    MACRO      ;macro to select data RAM bank 2
62
      bcf  STATUS,RP0
63
      bsf  STATUS,RP1
64
      ENDM
65
66
Bank3    MACRO      ;macro to select data RAM bank 3
67
      bsf  STATUS,RP0
68
      bsf  STATUS,RP1
69
      ENDM
70
71
72
;**************************************************************************************
73
;       declaration of used variables (register)
74
;**************************************************************************************
75
           CBLOCK  20h             ;starting adress of variables 
76
        zahl_0        ;Einer
77
        zahl_1        ;zehner
78
        zahl_2        ;hunderter
79
        zahl_3        ;Tausender
80
        seg_pointer      ;Zeiger
81
82
        temp
83
        wait_tmp1
84
        wait_tmp2
85
        wait_tmp3
86
        ad_low
87
        ad_high
88
        
89
        duty
90
        flag
91
92
        save_wreg
93
        save_status
94
95
          ENDC                    ;end of byte variables
96
97
;Bitdefinitionen
98
duty_on      EQU  .0
99
100
101
;**************************************************************************************
102
;       Program:      
103
;       *******************************************************************************
104
;       written by Gerald Hlavacek
105
;
106
;       Date: 05.10.2012      Version: 0.0      
107
;       Last modify:
108
;       *******************************************************************************
109
;       CPU running with 4 MHz oscillator
110
;**************************************************************************************
111
             ORG     0000
112
         goto    start
113
            ORG    0004
114
            goto    int_sub        ;falls benutzt einblenden
115
            ORG     0008
116
117
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
118
;Lookup Tabelle             -a-
119
;  Segmentaufteilung -gfedcba    f   b
120
;                   -g-
121
;                  e   c
122
;                   -d-
123
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
124
get_value  addwf  PCL,f
125
      retlw  b'00111111'    ;Zahl 0 
126
      retlw  b'00000110'    ;Zahl 1 
127
      retlw  b'01011011'    ;Zahl 2 
128
      retlw  b'01001111'    ;Zahl 3 
129
      retlw  b'01100110'    ;Zahl 4 
130
      retlw  b'01101101'    ;Zahl 5 
131
      retlw  b'01111101'    ;Zahl 6 
132
      retlw  b'00000111'    ;Zahl 7 
133
      retlw  b'01111111'    ;Zahl 8 
134
      retlw  b'01101111'    ;Zahl 9 
135
      retlw  b'01110111'    ;Zahl 10=A 
136
      retlw  b'01111100'    ;Zahl 11=b 
137
      retlw  b'01011000'    ;Zahl 12=c
138
      retlw  b'01011110'    ;Zahl 13=d
139
      retlw  b'01111001'    ;Zahl 14=E
140
      retlw  b'01110001'    ;Zahl 15=F
141
142
143
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
144
;Beginn des Mainprogrammes
145
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
146
147
;**************************************************************************************
148
;       MAINROUTINE:    main
149
;**************************************************************************************
150
start      call   init_pic    ;Aufruf Subroutinen
151
      call  start_tmr0_int  ;Interrupt starten
152
      call  init_adc
153
154
155
156
      bcf    flag,duty_on
157
158
    ;  bsf    LED_ROT
159
160
      movlw  b'00001000'
161
      movwf  seg_pointer
162
163
    ;Wert festlegen
164
      movlw  .0
165
      movwf  zahl_3
166
      movlw  .8
167
      movwf  zahl_2
168
      movlw  .1
169
      movwf  zahl_1
170
      movlw  .5
171
      movwf  zahl_0
172
173
    ;initialisierung tmr2+Interupt  
174
    ;#####
175
    ;call  start_tmr2_int
176
      movlw  b'00000010'
177
      movwf  T2CON
178
      bsf    INTCON,GIE
179
      bsf    INTCON,PEIE
180
      bcf    PIR1,TMR2IF    ;Flag löschen
181
      Bank1
182
      bsf    PIE1,TMR2IE
183
      Bank0
184
      bsf    T2CON,TMR2ON
185
    ;##########
186
187
start00    call  adc_8bit
188
      movf  ad_low,w        
189
      movwf  duty
190
191
      movf  duty,f
192
      btfss  STATUS,Z
193
      goto  not_null
194
      bcf    flag,duty_on
195
      bcf    LED_ROT
196
      bcf    T2CON,TMR2ON
197
      goto  start00  
198
not_null    bsf    T2CON,TMR2ON
199
      goto  start00
200
      
201
202
203
204
;**************************************************************************************
205
;       Interrupt:    int_sub
206
;**************************************************************************************
207
int_sub     movwf  save_wreg           ;Status und Working sichern
208
      movf  STATUS,w
209
      Bank0
210
      movwf  save_status
211
;-------------
212
      btfss  PIR1,TMR2IF
213
      goto  tmr0_int
214
215
      ;bcf    PIR1,TMR2IF
216
      btfss  flag,duty_on
217
      goto  einschalten
218
      bcf    flag,duty_on
219
      bcf    LED_ROT
220
      comf  duty,w
221
      Bank1
222
      movwf  PR2
223
      Bank0
224
      bcf    PIR1,TMR2IF
225
      goto  int_end2
226
einschalten bsf    flag,duty_on
227
      bsf    LED_ROT
228
      movf  duty,w
229
      Bank1
230
      movwf  PR2
231
      Bank0
232
      bcf    PIR1,TMR2IF
233
      goto  int_end2
234
;-------------
235
tmr0_int  call  reset_TMR0    ;TMR0 reseten
236
237
;--ISR Start
238
; my interrupt
239
      btfsc  seg_pointer,3
240
      goto  out_seg3
241
      btfsc  seg_pointer,2
242
      goto  out_seg2
243
      btfsc  seg_pointer,1
244
      goto  out_seg1
245
246
out_seg0  movf  zahl_0,w      ;Einerstelle
247
      call  set_zahl
248
      movlw  b'00001111'
249
      iorwf  PORTB        ;alle off
250
      bcf    SEG0        ;seg0=on
251
      goto  int_end
252
253
out_seg1  movf  zahl_1,w      ;Zehnerstelle
254
      call  set_zahl
255
      movlw  b'00001111'
256
      iorwf  PORTB        ;alle off
257
      bcf    SEG1        ;seg1=on
258
      goto  int_end
259
260
out_seg2  movf  zahl_2,w      ;Hunderterstelle
261
      call  set_zahl
262
      movlw  b'00001111'
263
      iorwf  PORTB        ;alle off
264
      bcf    SEG2        ;seg2=on
265
      goto  int_end
266
267
out_seg3  movf  zahl_3,w      ;Tausenderstelle
268
      call  set_zahl
269
      movlw  b'00001111'
270
      iorwf  PORTB        ;alle off
271
      bcf    SEG3        ;seg1=on
272
273
      
274
;--ISR Ende
275
int_end    bcf    STATUS,C
276
      rrf    seg_pointer,f
277
      movf  seg_pointer,f
278
      btfsc  STATUS,Z
279
      bsf    seg_pointer,3    ;falls 0 reseten 
280
281
int_end2  movf  save_status,w    ;STATUS und Working wieder herstellen
282
      movwf  STATUS
283
      swapf  save_wreg,f      ;swapf macht keine Änderungen am Zero Flag
284
      swapf  save_wreg,w
285
286
      retfie
287
288
289
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
290
;Beginn der Subroutines
291
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
292
           #include   "subroutinen.asm"
293
294
      end

Subroutine:
1
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2
;Beginn der Subroutines
3
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
4
5
;**************************************************************************************
6
;       SUBROUTINE:     initial PIC
7
;**************************************************************************************
8
init_pic  Bank0        ;select Bank 0
9
            clrf    PORTA       ;initialice porta, portb and portc
10
      clrf  PORTB
11
      clrf  PORTC
12
  
13
  ;register configure BANK 1
14
      Bank1        ;select Bank 1
15
16
      ;Internen Oszilator einstellen 4MHz
17
      movlw  b'01100001'
18
      movwf  OSCCON
19
20
      ;option_reg  Control-Register???
21
        movlw   b'10000110'     ;pullup disable,
22
      movwf   OPTION_REG    ;option_reg register (tm0 1:128 etc.)
23
  
24
      ;Port  Control-Register???
25
          movlw   b'00001111'     ;OUT/IN definieren
26
      movwf   TRISA
27
          movlw   b'11100000'     ;OUT/IN definieren
28
      movwf   TRISB
29
          movlw   b'10000000'     ;OUT/IN definieren
30
      movwf   TRISC
31
                
32
      ;Interrupt  Control-Register???
33
            movlw   b'00000000'     ;all Interrupts disable
34
            movwf   INTCON
35
36
  ;register configure BANK 3
37
      Bank3
38
      movlw  b'00000111'
39
      movwf  ANSEL      ;AN0,1,2 = Analog
40
      clrf  ANSELH      ;Rest digital
41
42
  ;register configure BANK 0
43
      Bank0          ;select Bank 0    
44
      clrf  ADCON0      ;AD Converter = off
45
  
46
      retlw  00h
47
;**************************************************************************************
48
49
;**************************************************************************************
50
;       SUBROUTINE:     Zahl ausgeben
51
;**************************************************************************************
52
set_zahl  andlw  b'00001111'    ;auf 0-15 limitieren
53
      call  get_value    ;Wert aus Lookup holen
54
      movwf  temp      ;Zwischenspeichern
55
      movwf  PORTC      ;Segmente setzen
56
      btfss  temp,6      ;Segment g extra setzen
57
      bcf    G_SEG
58
      btfsc  temp,6      
59
      bsf    G_SEG
60
      return
61
;**************************************************************************************
62
63
;**************************************************************************************
64
;       SUBROUTINE:     Wartezeiten
65
;    @ 4MHz
66
;    1Takt=1usec    exakte wartezeit=1028us
67
;**************************************************************************************
68
wait_1ms  clrf  wait_tmp1
69
      nop
70
      decfsz  wait_tmp1,f
71
      goto  $-2
72
      return
73
74
wait_xms  movwf  wait_tmp2
75
      call  wait_1ms
76
      decfsz  wait_tmp2,f
77
      goto  $-2
78
      return    
79
80
wait_10ms  movlw  .10
81
      call  wait_xms
82
      return
83
84
wait_x_10ms  movwf  wait_tmp3
85
      movf  wait_tmp3,f    
86
      btfsc  STATUS,Z
87
      return          ;falls Nulle return      
88
      movwf  wait_tmp3    ;wait_tmp3=w
89
      call  wait_10ms    ;Aufruf der 1ms Wartezeit
90
      decfsz  wait_tmp3,f    ;wait_tmp3=wait_tmp3-1 falls 0 Sprung
91
      goto  $-2
92
      return  
93
94
95
96
97
;**************************************************************************************
98
;       SUBROUTINE:     ADC-Messungen  
99
;**************************************************************************************
100
init_adc  ;AD0,1,2 als Input und Anlog (bereits in Init_pic passiert)
101
102
      ;ADCON Register konfigurieren
103
      Bank1 
104
      movlw  b'00000000'    ;Left justified, Vss,Vdd=Referenz
105
      movwf  ADCON1
106
      Bank0
107
      movlw  b'01000001'    ;FOSC/8, AN0 default, AD=on
108
      movwf  ADCON0      
109
      return
110
111
;-------------
112
adc_8bit  Bank1
113
      bcf    ADCON1,ADFM    ;left justified
114
      Bank0
115
      bsf    ADCON0,GO_DONE  ;Messung starten
116
      btfsc  ADCON0,GO_DONE  ;Messung fertig?
117
      goto  $-1      
118
      movf  ADRESH,w
119
      movwf  ad_low      ;Wert ins Low eintragen
120
      clrf  ad_high      ;High löschen
121
         return
122
;-------------
123
adc_10bit  Bank1
124
      bsf    ADCON0,ADFM    ;right justified
125
      Bank0
126
      bsf    ADCON0,GO_DONE  ;Messung starten
127
      btfsc  ADCON0,GO_DONE  ;Messung fertig?
128
      goto  $-1      
129
      movf  ADRESH,w
130
      movwf  ad_high      ;Wert ins High eintragen
131
      Bank1
132
      movf  ADRESL,w
133
      Bank0
134
      movwf  ad_low      ;Wert ins Low eintragen      
135
         return
136
137
;**************************************************************************************
138
;       SUBROUTINE:     Timerinterrupt starten
139
;    prescaler 1:128
140
;    @ 4MHz  --> 1us : 128(Prescaler)
141
;    1Takt=256usec
142
;    alle 10ms soll ein Interrupt ausgelöst werden
143
;    10ms/256us-->39 Zählpulse --> Aufwärtszähler 256-39=217
144
;**************************************************************************************
145
reset_TMR0  movlw   .217
146
      movwf  TMR0
147
      bcf    INTCON,T0IF    ;Timer0 IF löschen
148
      return
149
150
start_tmr0_int  
151
      bcf    INTCON,T0IE    ;Interrupt disable
152
      call  reset_TMR0
153
      bsf    INTCON,T0IE    ;Interrupt enable
154
      bsf    INTCON,GIE
155
      return

Vielen Dank im Voraus :)

von Karl H. (kbuchegg)


Lesenswert?

Lisa schrieb:

> Ich muss bei folgendem Projekt noch die AD-Werte High und Low im Duty
> der PWM als Grenzen definieren.

?
Ich sehe jetzt nichts in der geposteten Aufgabenstellung, die etwas mit 
High und Low zu tun hätte.

Statt dessen sehe ich aber den Punkt
> Der AD-Wert des Poti wird ausgelesen und modifiziert am Display
> ausgegeben.
> z.B AD=0 --> Anzeige „-00-„  AD=255 --> Anzeige „-99-„   (Anzeige der
> Helligkeit in Prozent)

Und wie hier schon steht, ist das nichts anderes als eine 
Prozentrechnung.

Wenn du monatlich 255 SMS verschicken kannst und 43 schon verschickt 
hast, wieviele Prozent deines monatlichen Vorrats hast du dann schon 
aufgebraucht?

von Lisa (Gast)


Lesenswert?

Also habe ich folgenden Punkt der Aufgabenstellung eigentlich schon 
realisiert:

Der AD-Wert des Poti wird auch zur Ansteuerung der roten Led verwendet,
die Helligkeit lässt sich
am besten mit einer einfachen PWM (Pulsweitenmodulation) realisieren.


Ich weiß nur nicht genau, was der Professor dann damit gemeint hat, dass 
ich die Low- und High-Werte als Grenzen für die PWM verwenden soll.

Und die LED flackert immer wieder ein bisschen, er meinte, dass es sich 
um ein Timeing-Problem handelt, wo könnte da mein Fehler im obigen 
Programm liegen?

LG Lisa

von Karl H. (kbuchegg)


Lesenswert?

Korrigier mich, wenn ich falsch liege.

Aber irgendwie kann ich in deinem Code überhaupt keine Wertausgabe der 
gemessenen ADC Werte entdecken. Weder den direkt gemessenen Wert noch 
entsprechend in Prozent umgerechnet.

Eiegentlich hätte ich im Umfeld von
1
start00    call  adc_8bit
2
      movf  ad_low,w        
3
      movwf  duty
irgendeinen CALL erwartet, der den 'duty' (oder w) als Zahl auf der 
7-Segment zur Anzeige bringt. Der Teil fehlt mir komplett, inklusive 
entsprechendem Code, der eine Zahl im Bereich 0 bis 255 in die 
Hunderter, Einer und Zehner zerlegt und in zahl_0 bis zahl_3 ablegt.

: Bearbeitet durch User
von Lisa (Gast)


Lesenswert?

Das ist richtig, die Ausgabe der Werte fehlt mir auch noch, aber ich 
weiß nicht genau, wie ich diese realsieren könnte.

LG Lisa

von Karl H. (kbuchegg)


Lesenswert?

Lisa schrieb:
> Das ist richtig, die Ausgabe der Werte fehlt mir auch noch, aber ich
> weiß nicht genau, wie ich diese realsieren könnte.

Dann hätte ich vorgschlagen, du kümmerst dich erst mal darum.

So wie das aussieht, reicht es, wenn du eine Zahl im Bereich 0 bis 255 
in Hunderter, Zehner und Einer zerlegst und die jeweiligen Ziffern in 
zahl_0 bis zahl_3 ablegst. Den Rest macht dann schon die vorhandene 
7-Segment Ausgaberoutine.

Ist dein duty zb 187, dann muss 7 nach zahl_0, 8 nach zahl_1, 1 nach 
zahl_2 und 0 nach zahl_3. Den Rest machen dann schon die vorhandenen 
7-Segment Routinen.

Du bist drann.

: Bearbeitet durch User
von Lisa (Gast)


Lesenswert?

Und wie realisiere ich dann die Prozentausgabe?? Ich muss die Zahlen von 
0-255 ja in Prozent ausgeben, also wären 255 meine 100%, aber wie sage 
ich das dem Programm? Und Zahlen festlegen kann ich, aber wie gebe ich 
dann die Werte aus, die aus dem Verstellen des Poti resultieren?

von Karl H. (kbuchegg)


Lesenswert?

Lisa schrieb:
> Und wie realisiere ich dann die Prozentausgabe?? Ich muss die Zahlen von
> 0-255 ja in Prozent ausgeben, also wären 255 meine 100%, aber wie sage
> ich das dem Programm?

Wie wärs mit .... Multiplizieren und Dividieren?

> Wenn du monatlich 255 SMS verschicken kannst und 43 schon verschickt
> hast, wieviele Prozent deines monatlichen Vorrats hast du dann schon
> aufgebraucht?

Wie rechnest du höchstpersönlich mit Papier und Bleistift das aus?


> Und Zahlen festlegen kann ich, aber wie gebe ich dann die Werte
> aus, die aus dem Verstellen des Poti resultieren?

Wieviele Hunderter gibt es denn in 187? Warum? Wie hast du das 
ausgerechent?
Wieiele Zehner? Wie hast du das ausgerechnet? Und wieviele Einer?

: Bearbeitet durch User
von genazt (Gast)


Lesenswert?

Hallo,

Zu den  High-, und Low-Werten als Grenzen für die PWM fielen mir spontan 
2 Deutungsmöglichkeiten ein, über deren Wahrscheinlichkeit und Sinn mal 
nebensächlich sein.

1. Mit "low" und "high" war das low-, und das high-Byte des AD-Wertes 
gemeint. Zusammen ergeben das low-, und high-Byte ja deinen aktuellen 
AD-Wert, der dann als grenzwert in einer timerroutine die led schalten 
könnte.

2. Wenn du das Poti auf "null" drehst, muss der AD-Wert nicht exakt 0 
sein, genau so muss das auf anschlag gedrehte Poti bei der AD-Wandlung 
nicht den maximalwert des AD-Wandlers ausgeben. Möglichkeit 2 wäre also, 
dass dein Prof will, dass du die AD-Werte bei völlig zu- und 
aufgedrehtem Poti als Grenzen benutzt, und nicht die möglichen minimal 
und maximal Werte des AD-Wandlers..

Freundliche Grüße!

von Lisa (Gast)


Lesenswert?

Karl Heinz schrieb:
> Und Zahlen festlegen kann ich, aber wie gebe ich dann die Werte
>> aus, die aus dem Verstellen des Poti resultieren?

Wie ich das am Papier aufspalte ist mir natürlich klar, aber ich weiß 
trotzdem immer noch nicht, wie ich das dann quasi für Zufallszahlen im 
Programm realisieren kann.

von Lisa (Gast)


Lesenswert?

Könnte das irgendwie im Zusammenhang mit dem von auch vom Prof genannten 
Timingproblem und dem dadurch ausgelösten flackern der LED stehen?

LG

von Karl H. (kbuchegg)


Lesenswert?

Lisa schrieb:
> Könnte das irgendwie im Zusammenhang mit dem von auch vom Prof genannten
> Timingproblem und dem dadurch ausgelösten flackern der LED stehen?

gant klares Nein.

Wie man etwas rechnet (bzw. noch nicht rechnet) hat noch nichts damit zu 
tun, dass du mit dem Timing nicht hinkommst.

von Karl H. (kbuchegg)


Lesenswert?

Lisa schrieb:
> Karl Heinz schrieb:
>> Und Zahlen festlegen kann ich, aber wie gebe ich dann die Werte
>>> aus, die aus dem Verstellen des Poti resultieren?
>
> Wie ich das am Papier aufspalte ist mir natürlich klar, aber ich weiß
> trotzdem immer noch nicht, wie ich das dann quasi für Zufallszahlen im
> Programm realisieren kann.

Dann musst du dich mal schlau machen, wie man mit dem PIC multipliziert 
und dividiert.

Da du die ganze Zeit von Professor sprichst, gehe ich davon aus, dass du 
auf einer Uni oder FH bist. Und im Regelfall kriegt man da in einer 
Vorlesung Unterlagen.

: Bearbeitet durch User
von Lisa (Gast)


Lesenswert?

Karl Heinz schrieb:
> Wieviele Hunderter gibt es denn in 187? Warum? Wie hast du das
> ausgerechent?
> Wieiele Zehner? Wie hast du das ausgerechnet? Und wieviele Einer?

1
;Wert festlegen
2
      movlw  .0
3
      movwf  zahl_3
4
      movlw  .8
5
      movwf  zahl_2
6
      movlw  .1
7
      movwf  zahl_1
8
      movlw  .5
9
      movwf  zahl_0

Da habe ich schon mal eine Zahl aufgespalten, damals war das die Ausgabe 
für meine Matrikelnummer. Die Werte sind fixe Zahlen, die sich nicht 
verändern, aber wenn ich das Poti verdrehe bekomme ich Zufallswerte. Wie 
kann ich dann die Zufallswerte ausgeben bzw. zerlegen und in Prozent 
ausgeben?

von Karl H. (kbuchegg)


Lesenswert?

Lisa schrieb:
> Karl Heinz schrieb:
>> Wieviele Hunderter gibt es denn in 187? Warum? Wie hast du das
>> ausgerechent?
>> Wieiele Zehner? Wie hast du das ausgerechnet? Und wieviele Einer?
>
>
>
1
;Wert festlegen
2
>       movlw  .0
3
>       movwf  zahl_3
4
>       movlw  .8
5
>       movwf  zahl_2
6
>       movlw  .1
7
>       movwf  zahl_1
8
>       movlw  .5
9
>       movwf  zahl_0
10
>
>
> Da habe ich schon mal eine Zahl aufgespalten,

Nein hast du nicht.
Du hast Zahlenkonstante hingeschrieben. Das hat nichts damit zu tun, 
dass dein Computer rechnen muss.

> verändern, aber wenn ich das Poti verdrehe bekomme ich Zufallswerte. Wie
> kann ich dann die Zufallswerte ausgeben bzw. zerlegen und in Prozent
> ausgeben?

Ja und?
Glaubst du im Ernst, ein Computer könne nicht rechnen?

Die Zahl, die du vom ADC kriegst sei x.
Wieviele Hunderter stecken in x? Wie rechnest du das aus?

Wenn du 255 SMS pro Monat zur Verfügung hast und x SMS davon schon 
aufgebraucht hast, wieviele Prozent sind das? Wie errechnet sich diese 
Prozenzahl, wenn x gegeben und einen beliebigen Zahlenwert (im Bereich 0 
bis 255) hat?

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Und noch was: Die Lösung "Gelöst durch Hinsehen" gilt nicht. Natürlich 
ist mir klar, dass du durch Hinsehen erkennst, dass in 187 genau 1 
Hunderter, 8 Zehner und 7 Einer stecken. Aber darum gehts nicht. Es geht 
darum ein allgemeines Schema zu haben, eine Rechenvorschrift, wie man 
die Zahl der Hunderter, Zehner und Einer in x (beliebig aber fix und 
innerhalb der Grenzen) ermittelt.
1
sei x eine Zahl, beliebig aber fix und im Bereich 0 bis 255
2
3
x / 100  -> Anzahl der Hunderter
4
sei tmp gleich x - (Anzahl der Hunderter * 100)
5
tmp / 10 -> Anzahl der Zehner
6
sei tmp gleich tmp - (Anzahl der Zehner * 10)
7
tmp -> Anzahl der Einer

während man sich hier noch um die Multiplikation / Division drücken 
könnte, führt bei der Prozentrechnung kein Weg daran vorbei (ausser 
einer Tabellenlösung)

Ganz abgesehen davon, dass du auf längere Sicht sowieso nicht drum rum 
kommst, etwas Arithmetik mit dem µC zu betreiben.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:

> sei tmp gleich x - (Anzahl der Hunderter * 100)

Das ist im übrigen nichts anderes als der Rest, der sich bei der 
vorhergehenden (ganzzahligen) Division durch 100 ergeben hat. Je nachdem 
magst du eine Divisionsroutine zur Verfügung haben, bei der sich dieser 
Rest bereits fertig ergibt und du ihn nicht getrennt ausrechnen musst.

von Volker S. (vloki)


Lesenswert?

-> Beitrag "Hilfe bei Programmierung in Mplab"
Lisa Zwiletitsch schrieb im Beitrag #3913758 am 06.12.2014:
> Hallo!
> Ich bin neu hier und brauche dringend Hilfe. Ich muss für mein Studium
> ziemlich bald ein Projekt abgeben, habe jedoch keine Ahnung, wie ich
> überhaupt beginne.

War wohl doch nicht so dringend ;-)

von robin (Gast)


Lesenswert?

Ich denke deinem Prof geht es in erster Linie um das effiziente 
umrechnen der zahlen.
Divisionen durch 10 sind auf einem µC umständlich und sollten vermieden 
werden.

Ich würde die Aufgabenstellung nochmal genau lesen. Es wird nicht 0-100 
verlangt, sondern nur bis 99... Und die zahlen 0x00-ff zu 00-99 zu 
wandeln ist nicht schwer. Mehr verrate ich aber nicht, das musst du dir 
selbst erarbeiten.

von Lisa (Gast)


Lesenswert?

Volker SchK schrieb:
> -> Beitrag "Hilfe bei Programmierung in Mplab"
> Lisa Zwiletitsch schrieb im Beitrag #3913758 am 06.12.2014:
>> Hallo!
>> Ich bin neu hier und brauche dringend Hilfe. Ich muss für mein Studium
>> ziemlich bald ein Projekt abgeben, habe jedoch keine Ahnung, wie ich
>> überhaupt beginne.
>
> War wohl doch nicht so dringend ;-)

Der überaus nette Professor hat mir mehr Zeit gegeben ;) dafür bin ich 
auch schon ein Stückchen weitergekommen und habe nun zusätzliche 
Probleme ;)

von Karl H. (kbuchegg)


Lesenswert?

robin schrieb:
> Ich denke deinem Prof geht es in erster Linie um das effiziente
> umrechnen der zahlen.

Ich denke, hier geht es konkret darum, überhaupt erst mal irgendwie 
umzurechnen. Effizient kommt später.

Lieber eine Lösung, die etwas langsamer ist als gar keine Lösung.

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:

> Ich denke, hier geht es konkret darum, überhaupt erst mal irgendwie
> umzurechnen.

D.h. wenn der überaus nette Professor nicht überhaupt die 
Aufgabenstellung soweit vereinfacht hat, dass der Teil 'Anzeige in 
Prozentform' überhaupt gefallen ist und durch etwas Einfacheres ersetzt 
wurde.

Stichwort 'auf Maximum und Minimum beschränken'.
Ich denke nämlich genau so ist es zu ...
> Ich muss bei folgendem Projekt noch die AD-Werte High und Low
> im Duty der PWM als Grenzen definieren. Zumindest hat es mir
> mein Professor so erklärt.
... gekommen.

Also Lisa: Ich denke es wird Zeit, Farbe zu bekennen.
Und ganz ehrlich, wenn du nicht mal dieses hinkriegst, dann solltest du 
dir ernsthaft überlegen, das Studium zu wechseln. Und das sage ich 
nicht, weil ich bösartig bin.

: Bearbeitet durch User
von Volker S. (vloki)


Lesenswert?

Karl Heinz schrieb:
> Also Lisa: Ich denke es wird Zeit, Farbe zu bekennen.
> Und ganz ehrlich, wenn du nicht mal dieses hinkriegst, dann solltest du
> dir ernsthaft überlegen, das Studium zu wechseln. Und das sage ich
> nicht, weil ich bösartig bin.

Heisst das, du bist zwar bösartig aber das ist nicht der Grund für deine 
Aussage ? ;-)

@Lisa
Ich fürchte er könnte recht haben. Dein Programm ist überaus schlecht 
kommentiert. Es ist viel zu mühsam heraus zu finden was das gnze soll.
Beschreib doch mal in Worten, was das macht ...

Baut ihr echt noch Programme zusammen indem ihr Assembler Dateien mit 
#include einbindet ?
goto $-x sollte man auch nicht unbedingt verwenden. Ein Label ist 
sicherer.

: Bearbeitet durch User
von Lisa (Gast)


Lesenswert?

Karl Heinz schrieb:
> Also Lisa: Ich denke es wird Zeit, Farbe zu bekennen.
> Und ganz ehrlich, wenn du nicht mal dieses hinkriegst, dann solltest du
> dir ernsthaft überlegen, das Studium zu wechseln. Und das sage ich
> nicht, weil ich bösartig bin.

Solche "Ratschläge" benötige ich nun wirklich NICHT!! Ich bin im 5. 
Semester meines Studiums und bereits im Berufspraktikum, das ich OHNE 
Hilfe von irgendjemandem bekommen habe!! Jeder hat ein Fach, das ihm 
überhaupt nicht liegt!!

Volker SchK schrieb:
> Baut ihr echt noch Programme zusammen indem ihr Assembler Dateien mit
> #include einbindet ?
> goto $-x sollte man auch nicht unbedingt verwenden. Ein Label ist
> sicherer.

Ja, ich habe nur die Interrupt-Routinen, die AD-Messung und das Main 
geschrieben, den Rest bekommen wir vorgegeben!

Volker SchK schrieb:
> Ich fürchte er könnte recht haben. Dein Programm ist überaus schlecht
> kommentiert. Es ist viel zu mühsam heraus zu finden was das gnze soll.
> Beschreib doch mal in Worten, was das macht ...

Nur weil ich nicht die komplett kommentierte Version reinkopiert habe 
soll ich also mein Studium wechseln?! Alles klar!!

Trotzdem danke für die teilweise nette Hilfe!

LG

von Karl H. (kbuchegg)


Lesenswert?

Lisa schrieb:
> Karl Heinz schrieb:
>> Also Lisa: Ich denke es wird Zeit, Farbe zu bekennen.
>> Und ganz ehrlich, wenn du nicht mal dieses hinkriegst, dann solltest du
>> dir ernsthaft überlegen, das Studium zu wechseln. Und das sage ich
>> nicht, weil ich bösartig bin.
>
> Solche "Ratschläge" benötige ich nun wirklich NICHT!! Ich bin im 5.
> Semester meines Studiums und bereits im Berufspraktikum, das ich OHNE
> Hilfe von irgendjemandem bekommen habe!! Jeder hat ein Fach, das ihm
> überhaupt nicht liegt!!

Wenn du bei der bereits vereinfachten Aufgabenstellung nicht auf die 
Idee kommst, dass dein Prof gemeint hat
1
start00    call  adc_8bit
2
      movf  ad_low,w
3
4
5
     wenn w kleiner als ein Minimumwert
6
     dann setze w auf diesen Minimumwert
7
8
     wenn w grosser als ein Maximumwert
9
     dann setze w auf diesen Maximumwert     
10
        
11
      movwf  duty
12
...

dann ist 'liegt mir nicht' eine höfliche Umschreibung.
(Ob man diese Werte Modifikation am w macht oder gleich direkt am ad_low 
ist Geschmackssache und hängt auch noch von anderen Nebenbedingungen ab. 
Aber genau das ist das Prinzip, um das es geht und das du wahrscheinlich 
hättest rausfinden sollen.)

: Bearbeitet durch User
von Helge A. (besupreme)


Lesenswert?

Anfang und Ende von Potis sind ja immer bissel doof. Manchmal kommt man 
nit ganz an die Endwerte.

Der ADC von deinem Pic hat 10 bit, entsprechend 0..1023.

Min und Max sollen auch bei einem etwas schlechteren Poti erkannt 
werden.

Aufgrund dessen wäre auf meiner Werkbank die Struktur so:

ADC-Wandeln 10 bit
Min-Merker rücksetzen
Max-Merker rücksetzen
Wert-12<0?
 Wert2=0
 Min-Merker setzen
sonst
 Wert2=Wert/10
 Wert2>99?
  Wert2=99
  Max-Merker setzen
**Wandlung und Fehlerbehandlung fertig**

Dann braucht es noch eine Funktion binär->Einzelziffern. Die läßt sich 
bestimmt irgendwo im Netz finden. Suche nach "pic binary-to-BCD".

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.