Categories
Uncategorized

A/D conversion

I’ve gotten the A/D converter on the Microchip PIC P12F675 to work. The pulse width modulation technique is allowing me to simulate different intensities of light. What you do is send extremely fast pulses of light on and off. Your eye “averages” these out to appear as a middle intensity brightness.

Here is a movie:







Here is the source code:

  1  ;Software License Agreement                                         
  2  ;                                                                    
  3  ;The software supplied herewith by Microchip Technology             
  4  ;Incorporated (the "Company") is intended and supplied to you, the  
  5  ;Company~Rs customer, for use solely and exclusively on Microchip    
  6  ;products. The software is owned by the Company and/or its supplier,
  7  ;and is protected under applicable copyright laws. All rights are   
  8  ;reserved. Any use in violation of the foregoing restrictions may   
  9  ;subject the user to criminal sanctions under applicable laws, as   
 10  ;well as to civil liability for the breach of the terms and         
 11  ;conditions of this license.                                        
 12  ;                                                                    
 13  ;THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES,  
 14  ;WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED  
 15  ;TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A       
 16  ;PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,  
 17  ;IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR         
 18  ;CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.       
 19  ;****************************************************************************
 20  ;Filename:      atod.asm
 21  ;Author:        Ruan Lourens
 22  ;Date:          1.03.03 
 23  ;Version:       1.0 (A/D Version)
 24  ;Description:   This is an ASSEMBLY written program designed to show the user  
 25  ;               a timer driven analog-to-digital conversion.It is based on the 
 26  ;               interrupt driven conversionLED State Machine used in 
 27  ;               tutorial #3.     
 28  ;****************************************************************************
 29  ;Revision History
 30  ;****************************************************************************
 31
 32
 33      list      p=12F675              ; list directive to define processor
 34      #include <p12f675.inc>          ; processor specific variable definitions
 35      ;#include "atod.h"
 36      errorlevel  -302               ; suppress message 302 from list file
 37
 38      __CONFIG   _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT
 39
 40  ; '__CONFIG' directive is used to embed configuration word within .asm file.
 41  ; The lables following the directive are located in the respective .inc file.
 42  ; See data sheet for additional information on configuration word settings.
 43
 44  ;****************************************************************************
 45  ;Defines
 46  ;****************************************************************************
 47  #define BANK1       bsf     STATUS,RP0  ; Bank1
 48  #define BANK0       bcf     STATUS,RP0  ; Bank0
 49  #define LED1TRIS    b'11001111'
 50  #define LED2TRIS    b'11001111'
 51  #define LED3TRIS    b'11101011'
 52  #define LED4TRIS    b'11101011'
 53  #define LED5TRIS    b'11011011'
 54  #define LED6TRIS    b'11011011'
 55  #define LED7TRIS    b'11111001'
 56  #define LED8TRIS    b'11111001'
 57  #define LED1ON      b'00010000'
 58  #define LED2ON      b'00100000'
 59  #define LED3ON      b'00010000'
 60  #define LED4ON      b'00000100'
 61  #define LED5ON      b'00100000'
 62  #define LED6ON      b'00000100'
 63  #define LED7ON      b'00000100'
 64  #define LED8ON      b'00000010'
 65  #define NUMBEROFBITS    .8
 66  #define ANSelect    b'00010001'     ;Used to configure AD
 67  #define ADControl   b'00000001'     ;Used to configure AD
 68
 69  LEDREGISTER EQU 0x31
 70
 71  mcount        EQU     22h
 72  ncount        EQU     23h
 73  new_tris        EQU     24h
 74  new_gpio        EQU     25h
 75  brightness_num  EQU  26h
 76  brightness_den  EQU 27h
 77  brightness_dat  EQU 28h
 78  IS_ON_BIT       EQU 0
 79  brightness_count EQU 29h
 80  temp EQU 30h
 81  ALL_OFF_TRIS EQU b'11111111'
 82
 83  ;****************************************************************************
 84  ;General Purpose Registers (GPR's) 
 85  ;****************************************************************************
 86      ; UDATA_SHR
 87  WTEMP       res 1           ; register used in Interrupt Routine
 88  STATUSTEMP  res 1           ; register used in Interrupt Routine
 89  PCLATHTEMP  res 1           ; register used in Interrupt Routine
 90  FSRTEMP     res 1           ; register used in Interrupt Routine
 91  FLAGS       res 1           ; register used to set flags
 92
 93  ;****************************************************************************
 94  ;Reset Vector
 95  ;****************************************************************************
 96      ORG     0x000             ; processor reset vector
 97      nop                       ; Inserted For ICD2 Use
 98      goto    Init              ; go to beginning of program
 99
100  ;****************************************************************************
101  ;Interrupt Vector - Interrupts only active during animation sequence
102  ;                 - Interrupt Sources:  1.  TIMER0 Overflow
103  ;
104  ;FLAGS register - bit0:  1 = A/D will be serviced, 0 = Display will be serviced
105  ;
106  ;****************************************************************************
107      ORG     0x004             ; interrupt vector location
108  Isr
109      movwf   WTEMP           ;Save off current W register contents
110      movf    STATUS,w
111      clrf    STATUS          ;Force to page0
112      movwf   STATUSTEMP
113      ;movf   PCLATH,w
114      ;movwf  PCLATHTEMP      ;Save PCLATH
115      ;movf   FSR,w
116      ;movwf  FSRTEMP         ;Save FSR
117
118
119  ;****************************************************************************
120  ;Interrupt Source Checks
121  ;****************************************************************************
122  Timer0InterruptCheck
123      BANK1                   ; BANK1   
124      movf    INTCON,w
125      andlw   0x20
126      btfsc   STATUS,Z        ;Is T0IE Set?
127      goto    Next1           ;No
128      movf    INTCON,w        ;Yes
129      andlw   0x04
130      btfss   STATUS,Z        ;Is TOIF Set?
131      goto    Timer0Interrupt ;Yes
132
133  Next1
134  GPIFInterruptCheck
135      movf    INTCON,w
136      andlw   0x08
137      btfsc   STATUS,Z        ;Is GPIE Set?
138      goto    Next2           ;No
139      movf    INTCON,w        ;Yes
140      andlw   0x01
141      btfss   STATUS,Z        ;Is GPIF Set?
142      goto    GPIFInterrupt   ;Yes
143
144  Next2
145  GP2_INT_ExternalInterruptCheck
146      movf    INTCON,w
147      andlw   0x10
148      btfsc   STATUS,Z        ;Is INTE Set?
149      goto    Next3           ;No
150      movf    INTCON,w        ;Yes
151      andlw   0x02
152      btfss   STATUS,Z        ;Is INTF Set?
153      goto    GP2_INTExternalInterrupt;Yes
154
155  Next3
156  PeripheralInterruptCheck
157      movf    INTCON,w
158      andlw   0x40
159      btfsc   STATUS,Z        ;Is PEIE Set?
160      goto    EndIsr          ;No
161
162  Next4
163  EEIFInterruptCheck
164      movf    PIE1,w
165      andlw   0x80
166      btfsc   STATUS,Z        ;Is EEIE Set?
167      goto    Next5           ;No
168      BANK0                   ;Yes
169      movf    PIR1,w
170      BANK1
171      andlw   0x80
172      btfss   STATUS,Z        ;Is EEIF Set?
173      goto    EEPROMInterrupt;Yes
174
175  Next5
176  ADIFInterruptCheck
177      movf    PIE1,w
178      andlw   0x40
179      btfsc   STATUS,Z        ;Is ADIE Set?
180      goto    Next6           ;No
181      BANK0
182      movf    PIR1,w
183      BANK1
184      andlw   0x40
185      btfss   STATUS,Z        ;Is ADIF Set?
186      goto    A_DConverterInterrupt;Yes   
187
188  Next6
189  CMIFInterruptCheck
190      movf    PIE1,w
191      andlw   0x08
192      btfsc   STATUS,Z        ;Is CMIE Set?
193      goto    Next7           ;No
194      BANK0                   ;Yes
195      movf    PIR1,w
196      BANK1
197      andlw   0x08
198      btfss   STATUS,Z        ;Is CMIF Set?
199      goto    ComparatorInterrupt;Yes
200
201  Next7
202  TMR1IFInterruptCheck
203      movf    PIE1,w
204      andlw   0x01
205      btfsc   STATUS,Z        ;Is TMR1IE Set?
206      goto    EndIsr          ;No
207      BANK0                   ;Yes
208      movf    PIR1,w
209      BANK1
210      andlw   0x01
211      btfss   STATUS,Z        ;Is TMR1IF Set?
212      goto    Timer1Interrupt ;Yes
213      goto    EndIsr          ;No
214
215  Timer0Interrupt             ;Interrupt every 1024 uS
216      BANK0               ;BANK0
217      btfsc   FLAGS,0         ;Check if A/D functions will be serviced or the display routine                 
218      call    AD_Functions        ;Yes, service A/D
219      BANK0               ;BANK0
220      btfss   FLAGS,0         ;Check if Display functions will be serviced
221      call    Display         ;Yes, goto Display
222      BANK0               ;BANK0
223      movlw   b'00000001'
224      xorwf   FLAGS,F         ;Toggle FLAGS,1
225      BANK1               ;BANK1
226      bcf     INTCON,T0IF ;Clear TMR0 Interrupt Flag  
227      goto    EndIsr
228
229  Display
230      decfsz brightness_count,f
231      goto activate_leds
232      goto toggle_on_off
233  toggle_on_off:
234      movlw   b'11111111'
235      xorwf   brightness_dat,f
236      btfsc   brightness_dat,IS_ON_BIT
237      goto store_off_time
238      goto store_on_time
239  store_on_time:
240      movfw   brightness_num
241      movwf   brightness_count
242      goto activate_leds
243  store_off_time:
244      movfw   brightness_den
245      movwf   brightness_count
246  activate_leds:
247      btfsc   brightness_dat,IS_ON_BIT
248      goto show_black
249      goto show_lights
250  show_black:
251          movlw   b'11111111'
252          bsf     STATUS,RP0  ;Bank 1
253          movwf   TRISIO      ;and set GP<5:4,1:0>
254          bcf     STATUS,RP0  ;Bank 0
255          movlw   b'00000000'
256          movwf   GPIO
257      goto end_of_intr
258  show_lights:
259          movfw   new_tris;
260          bsf     STATUS,RP0  ;Bank 1
261      ;movlw b'11001111'
262          movwf   TRISIO      ;and set GP<5:4,1:0>
263          bcf     STATUS,RP0  ;Bank 0
264          movfw   new_gpio
265      ;movlw  b'00010000'
266          movwf   GPIO
267  end_of_intr:
268      return
269
270
271
272
273  GPIFInterrupt
274      goto    EndIsr
275
276  GP2_INTExternalInterrupt
277      goto    EndIsr
278
279  EEPROMInterrupt
280      goto    EndIsr
281
282  A_DConverterInterrupt
283      goto    EndIsr
284
285  ComparatorInterrupt
286      goto    EndIsr
287
288  Timer1Interrupt
289
290  EndIsr
291      clrf    STATUS            ;Select Bank0
292      ;movf   FSRTEMP,w
293      ;movwf  FSR               ;Restore FSR
294      ;movf   PCLATHTEMP,w
295      ;movwf  PCLATH            ;Restore PCLATH
296      movf    STATUSTEMP,w
297      movwf   STATUS            ;Restore STATUS
298      swapf   WTEMP,f
299      swapf   WTEMP,w           ;Restore W without corrupting STATUS bits
300      retfie                    ;Return from interrupt    
301
302
303  ;****************************************************************************
304  ;AD_Functions
305  ;****************************************************************************
306  AD_Functions
307      BANK0               ;BANK0
308      movf    ADRESH,W        ;Move the most significant byte of A/D Result to W
309      movwf   LEDREGISTER     ;The A/D result is moved to LEDREGISTER and will be displayed
310      bsf ADCON0,GO       ;Start A/D
311      return
312
313  ;****************************************************************************
314  ;Initialization
315  ;****************************************************************************
316  Init
317      ;call    0x3FF      ; retrieve factory calibration value
318                          ; comment instruction if using simulator, ICD2, or ICE2000
319      BANK1
320      movwf   OSCCAL      ; update register with factory cal value 
321      ;call   InitLED     ;Initialize LED Routine Variables
322      movlw   b'00000001'
323      movwf   TRISIO          ;Tri-State All Inputs
324      BANK0               ;BANK 0
325      clrf    GPIO            ;Clear Port
326      movlw   b'00100000'
327      movwf   GPIO
328
329      BANK1               ;BANK 1
330      clrf    VRCON           ;Vref Off
331      BANK0               ;BANK 0
332      clrf    TMR0
333      movlw   0x07
334      movwf   CMCON           ;Comparator Off
335
336      BANK1                   ;BANK 1 
337      movlw   b'10000001'
338      movwf   OPTION_REG      ;TIMER0 Prescaler = 4 and pull-ups disabled
339      bsf     INTCON,T0IE     ;Interrupt on TIMER0 Overflow Enabled
340      bcf     INTCON,T0IF     ;Clear TIMER0 Overflow Interrupt Flag
341      bsf     INTCON,GIE      ;Turn on Global Interrupts
342      movlw   ANSelect
343      movwf   ANSEL           ;Configure AN0 & prescale to A/D    
344
345      BANK0                   ;BANK 0
346      movlw   ADControl
347      movwf   ADCON0          ;Select AN0, Left justified & enables A/D
348      NOP
349      NOP
350      NOP
351      NOP                     ; Give 4 uS delay before starting A/D
352      bsf ADCON0,GO           ; Start A/D
353
354  ;****************************************************************************
355  ;MAIN - Main Routine
356  ;****************************************************************************
357  Main
358          movlw   0x02
359          movwf   brightness_num
360          movlw   0x1F
361          movwf   brightness_den
362          movlw   0xFF
363          movwf   brightness_count
364  go
365          ; D0
366          movlw   b'11001111'
367          movwf   new_tris
368          movlw   b'00010000'
369          movwf   new_gpio
370          call    delay
371          ; D0
372          movlw   b'11001111'
373          movwf   new_tris        ;and set GP<5:4,1:0>
374          movlw   b'00100000'
375          movwf   new_gpio
376          call    delay
377          ; D0
378          movlw   b'11101011'
379          movwf   new_tris        ;and set GP<5:4,1:0>
380          movlw   b'00010000'
381          movwf   new_gpio
382          call    delay
383          ; D0
384          movlw   b'11101011'
385          movwf   new_tris        ;and set GP<5:4,1:0>
386          movlw   b'00000100'
387          movwf   new_gpio
388          call    delay
389          ; D7
390          movlw   b'11111001'
391          movwf   new_tris        ;and set GP<5:4,1:0>
392          movlw   b'00000010'
393          movwf   new_gpio
394          call    delay
395          ; D6
396          movlw   b'11111001'
397          movwf   new_tris        ;and set GP<5:4,1:0>
398          movlw   b'00000100'
399          movwf   new_gpio
400          call    delay
401          ; D5
402          movlw   b'11011011'
403          movwf   new_tris        ;and set GP<5:4,1:0>
404          movlw   b'00000100'
405          movwf   new_gpio
406          call    delay
407          ; D0
408          movlw   b'11011011'
409          movwf   new_tris        ;and set GP<5:4,1:0>
410          movlw   b'00100000'
411          movwf   new_gpio
412          call    delay
413         goto go
414
415
416  ;delay loop
417  delay   movlw   0x01
418          movwf   temp
419          movwf   brightness_num
420  loadm2   movlw   0x2f
421          movwf   mcount
422  loadn2  movfw   LEDREGISTER
423          addlw   1
424          movwf   ncount
425  repeat2
426          decfsz  ncount,f
427          goto    repeat2
428          decfsz  mcount,f
429          goto    loadn2
430          incf    brightness_num,f
431          movlw   0x13
432          movwf   brightness_den
433          movfw   brightness_num
434          subwf   brightness_den,f
435          incf    brightness_den,f
436          movlw   0x13
437          xorwf   brightness_num,w
438          movwf   temp
439          incf    temp,f
440          decfsz  temp,f
441          goto    loadm2
442          goto delay2
443  delay2   movlw   0x13
444          movwf   brightness_num
445  loadm   movlw   0x2f
446          movwf   mcount
447          movlw   0x13
448          movwf   brightness_den
449          movfw   brightness_num,f
450          subwf   brightness_den,f
451          incf    brightness_den,f
452  loadn   movfw   LEDREGISTER
453          addlw   1
454          movwf   ncount
455  repeat
456          decfsz  ncount,f
457          goto    repeat
458          decfsz  mcount,f
459          goto    loadn
460          decfsz  brightness_num,f
461          goto    loadm
462          return
463
464
465  ; initialize eeprom locations
466
467          ORG 0x2100
468          DE  0x00, 0x01, 0x02, 0x03
469
470
471          END                       ; directive 'end of program'
472

One reply on “A/D conversion”

nobody is going to comment on this thing because you have to scroll through 300+ lines of code. sheesh. he claims that he is posting this for the good of computer geeks everywhere…

Comments are closed.