The key question is: Does it work? --- James Newton (PICList Admin #3) mailto:jamesnewton@piclist.com 1-619-652-0593 PIC/PICList FAQ: http://www.piclist.com or .org -----Original Message----- From: pic microcontroller discussion list [mailto:PICLIST@MITVMA.MIT.EDU]On Behalf Of Jeffrey Frey Sent: Tuesday, August 15, 2000 14:00 To: PICLIST@MITVMA.MIT.EDU Subject: [PICLIST] [PIC] First Time Code Review Hello everyone, I just got into PIC programming a couple of weeks ago and I wanted to post my first program to get some constructive criticism. The following code continually reads in a 0-5V analog signal on AN0, converts the result to BCD and outputs each digit to 4543s (BCD to 7-segment) and then to an LCD display. There is also a Timer interrupt that I use to produce a square wave output on RA2 to each of the 4543s. I'm curious to know if I'm on the right track and if I'm missing something that will haunt me later. I'm also curious about how I handled using the both the Timer interrupt and analog interrupt. Is this kosher? The BCD code was grabbed from some example code that I found. I'm clocking this with a 32767kHz crystal because this is going to be a battery operated device in which battery life is very important. Thanks, Jeff Frey #include "P16C71.INC" ; Include header file LIST P=16C71, R=HEX ; Use the PIC16C71 and hexidecimal system __config _LP_OSC & _WDT_OFF & _PWRTE_ON ;--------------------------------------------------------------------------- -- ; CPU Equates (memory map) bin equ 0x0C hundreds equ 0x0D tens_and_ones equ 0x0E tens equ 0x0F ones equ 0x10 temp equ 0x11 ;--------------------------------------------------------------------------- -- ORG 0x00 ; This tells the assembler where GOTO Start ; to put the first instruction. ORG 0x04 ; This tells the assembler where goto Iserv ; jump for the interrupt service routine Start clrwdt ; Clear WDT and prescaler bsf STATUS, RP0 ; Select Bank 1 movlw 0x1B ; Select Output for PORTA bit 2, all others Input movwf TRISA clrf TRISB ; Select Output on all PORTB bits movlw 0x02 ; Configure A/D inputs PORTA (0 and 1) movwf ADCON1 ; movlw 0xD8 ; Select TMR0 Config (Source & movwf OPTION_REG ; prescale-1:1) bcf STATUS, RP0 ; Select Bank 0 movlw 0xC1 ; RC Clock, A/D is on, Channel 0 is selected movwf ADCON0 bcf INTCON, T0IF ; Clear TMR0 Interrupt Flag bsf INTCON, T0IE ; Enable TMR0 Overflow Interrupt clrf PORTB ; Make sure PORTB is all off Main bsf INTCON, GIE ; Enable all interrupts Circle goto Circle ; Wait for Interrupts Iserv clrw btfsc INTCON, 2 ; Check to see if Timer Interrupt call TimerInt ; has occurred and call TimerInt movwf temp btfss temp, 0 ; Check to see if Timer Interrupt call AioInt ; If not call Analog Interrupt retfie TimerInt movlw 0xBA ; Reset Timer for Interrupt movwf TMR0 bcf INTCON, 2 ; Clear TMR0 Interrupt Flag btfsc PORTA, 2 ; Toggles PORTA bit 2 on and off goto togoff ; every other timer interrupt togon bsf PORTA, 2 ; cycle at approx. 50 Hz to LCD Backplane bsf INTCON, ADIE ; Enable A/D Converter Interrupt bsf ADCON0,GO ; Start A/D conversion goto togend togoff bcf PORTA, 2 togend retlw 0x01 ; Return to Iserv and set status as complete AioInt bcf INTCON, ADIE ; Enable A/D Converter Interrupt movf ADRES,W ; Write A/D result to movwf bin ; bin CLRF hundreds SWAPF bin,w ; Add the upper and lower nibbles ADDWF bin,w ; to get the one's digit ANDLW 0x0f SKPNDC ; Go through a binary to bcd ADDLW 0x16 ; conversion for just the one's SKPNDC ; digit ADDLW 0x06 ADDLW 0x06 SKPDC ADDLW -0x06 BTFSC bin,4 ; Bit 4 is a special case ADDLW 0x16 - 1 + 0x6 SKPDC ADDLW -0x06 ; Now adjust the ten's digit BTFSC bin,5 ; 2^5 = 32, so add 3 to the ten's ADDLW 0x30 ; digit if bit 5 is set BTFSC bin,6 ; 2^6 = 64, so add 6 ADDLW 0x60 ; if bit 6 is set BTFSC bin,7 ; 2^7 = 128, so add 2 (the ten's ADDLW 0x20 ; digit) if bit 7 is set ADDLW 0x60 ; Convert the ten's digit to BCD RLF hundreds,F ; If there's a carry, then the input BTFSS hundreds,0 ; was greater than 99. ADDLW -0x60 MOVWF tens_and_ones BTFSC bin,7 ; If msb is set then the hundred's INCF hundreds,F ; digit is a '2' movf hundreds,w ; Load w with tens_and_ones andlw 0x0F ; AND with '00001111' to extract hundreds BCD movwf hundreds swapf tens_and_ones,w ; Swap the contents of tens and ones and andlw 0x0F ; AND with '00001111' to extract tens BCD movwf tens movf tens_and_ones,w ; Load w with tens_and_ones andlw 0x0F ; AND with '00001111' to extract ones BCD movwf ones bsf hundreds, 4 ; Hundreds Enable pin to 4543 movf hundreds, w ; Move copy of hundreds to w movwf PORTB ; and output to PORTB nop bcf PORTB, 4 nop bsf tens, 5 ; Tens Enable pin to 4543 movf tens, w ; Move copy of tens to w movwf PORTB ; and output to PORTB nop bcf PORTB, 5 nop bsf ones, 6 ; Ones Enable pin to 4543 movf ones, w ; Move copy of ones to w movwf PORTB ; and output to PORTB nop bcf PORTB, 6 return ; return from interrupt end -- http://www.piclist.com hint: The list server can filter out subtopics (like ads or off topics) for you. See http://www.piclist.com/#topics -- http://www.piclist.com hint: The list server can filter out subtopics (like ads or off topics) for you. See http://www.piclist.com/#topics