> > this is my first post to the list. I have a question about editing a ASM > file using Microchip's MPLAB IDE 7.3. I have been working with an ASM file > using the PIC 16F84A microchip. The code is written to sense RPM's of a Which gives me another reason to state that noone should use the 16F84A: they might continue using code like this. > micro turbine engine, and test servo units. I did not write the original > file. Currently I can only display from 0 - 99,999 RPM's. I have been told > that the chip can count the piulses for an infinite number. I want to > change Infinite... Seems unlikely, but would be nice. the program to display more than 100K. The LCD module I'm using is an 8 X 2 > using a HD44780U controller. The first line displays the 5 digits and the > 3 > letters "RPM" The second line displays a selectable number of blades from > 2 - 5 with the letters "bs" after the numbers. I'm just learning about > editing code, programming chip's and converting ASM to HEX files, but at > this point I'm stuck and can't seem to get any further. Can anyone off > some > assistance in editing this ASM file? I've included the ASM with this post > for reference and examination. Thanks for your help in advance. What would you like help with? What is the problem you are trying to solve? But to make sure that more people will answer your question, here are some hints that will help. Patrick > > LIST P=16F84A,R=HEX Use R=DEC, and add the hex qualifier to all numbers that are currently in the code to avoid confusion. ; > ; LCD TACHOMETER FOR R/C MODEL TURBINE ENGINE > ; DESMOND, P > ; > ; VERSION 3.25: 05/11/2006 UPDATE FOR KJ66 > ; VERSION 3.24: 1/19/2005 FIX BUG, REC_T CRASH AT 1500uS > ; VERSION 3.22: 09/27/2004 MENU, 8*2 LCD,(B) BLADES SECECT > ; VERSION 3.2: 09/08/2004 RA,4 CONTROLL +5V OUTPUT > ; VERSION 3.1: 09/04/2004 LEAVES SELECT > ; VERSION 3.0: 08/30/2004 ADD REC_T V1 FOR RECEIVER TESTING > ; VERSION 2.0: 08/26/2004 ADD MID & RANDOM MODES > ; VERSION 1.0: 08/25/2004 > ; > ;-------SYSTEM--------------------- > __CONFIG H'3FF1' Add the actual definitions to the CONFIG statement, so people know what you are configuring, to do this, use the official include file. ;-------DEFINE RAM------------ > TMR0 EQU 1 ;TIMER 0 Don't use EQU for variables that are also defined in the include file. Use the definitions in the include file instead. PC EQU 2 ;PROGRAM COUNTER > STATUS EQU 3 > FSR EQU 4 ;BUFFER OF INDIRECT ADDR > RA EQU 5 > RB EQU 6 > EEDATA EQU 8 ;EEPROM DATA > EEADR EQU 9 ;EEPROM ADDR > PCLATH EQU H'A' > INTCON EQU H'B' ;INTERRUPT CONTROL > OPTIONF EQU 1 ;0X81 > TRISA EQU 5 ;0X85 > TRISB EQU 6 ;0X86 > EECON1 EQU 8 ;0X88 IS EEPROM CONTROL1 > EECON2 EQU 9 ;0X89 IS EEPROM CONTROL2 > > ;-------DEFINE BIT------------- > ; > C EQU 0 Don't use EQU for bits that are defined in the include file, but use the ones from the include file. W EQU 0 ;d VALUE FOR INCF...... > F EQU 1 ;d VALUE > OFF EQU 0 ;FLAG BIT 0, > RP0 EQU 5 ;STATUS BIT 5 & 6 =REGISTER BANK SELECT > RP1 EQU 6 > INPUT EQU 7 ;RB7 AS INPUT PORT > TOIF EQU 2 ;INTCON TMR0 OVERLOW INT FLAG > TOIE EQU 5 ;INTCON TOIF ENABLE > GIE EQU 7 ;INTCON GLOBAL INT ENABLE > > ;-------USER------------------------------------- > ;-------REGISTERS------ > ; > TCNT0 EQU H'C' ;= (0.6SEC /INT* PRESCAL*CLOCK) Don't define your user variables using EQU. Don't even use CBLOCK. Switch to relocatable code, and use RES. INTR0 EQU H'D' ;AFTER INT, SAVE W VALUE > INTR1 EQU H'E' ;AFTER INT, SAVE STATUS > DD1 EQU H'F' ;DATA FOR INPUT RPM > DD2 EQU H'10' > DD3 EQU H'11' > TEMP1 EQU H'12' ; > TEMP2 EQU H'13' > TEMP3 EQU H'14' > SLOW_C EQU H'15' ;100-200 +- 1 EVERY INT_DST > INT_C EQU H'16' ;0-255 -1 EVERY INT_DST > FLAG_REG EQU H'17' > MODE_SEL EQU H'18' > PWM_C EQU H'19' > PUSH_C EQU H'1A' > RAND_HI EQU H'1B' > RAND_LO EQU H'1C' > TCNT EQU H'1D' > > ;-------BIT---------------- > F_ON EQU 0 > F_UP EQU 1 > F_TDST EQU 2 > F_REC EQU 3 > TACHO_SEL EQU 4 > ; > ;-------VARIABLES----------- > ; > TMR EQU D'181' ;(PRESCALE 64*1uS) * 75 = 4800 uS > TCNT_2 EQU D'125' ;4.8mS*125=600mS,BUT FIX SOME ODD CODE > TCNT_3 EQU D'84' ;THIS TWO * PRESCALE 1:64,TO A 0.6 SECOND DURATION > TCNT_4 EQU D'62' > TCNT_5 EQU D'50' > BDELAY EQU D'40' > TMR1 EQU D'178' ;(PRESCALE 256*78) = 19968 uS > > RLIMIT EQU D'200' ;SERVO LIMIT > LLIMIT EQU D'100' > > ;-------LCD SOUTINE------------------------- > ;-------REGISTERS--------- > ; > ADDRESS1 EQU H'41' > CHAR1 EQU H'42' > TEMP1_LCD EQU H'43' > TEMP2_LCD EQU H'44' > TEMP3_LCD EQU H'45' > TEMP4_LCD EQU H'46' > TABLE_INDEX EQU H'47' ; > ; > ;========== MAIN PROGRAM ========= > ; > ORG 0 When using relocatable code, this ORG stuff will look different. GOTO START Put "pagesel START" in front of this goto, to avoid jumping to the wrong location on other chips. ;---------------------------------------- > ; > ORG 4 ;INTERRUPT BEGIN > > INTB MOVWF INTR0 ; SAVE W > MOVF STATUS,W ; SAVE STATUS > MOVWF INTR1 > BCF STATUS,RP0 ; MAKE SURE SELECT BANK0 Use banksel instead of setting the status bits yourself. CHECK_TDST > BTFSC FLAG_REG,F_TDST ;IF SET GOTO DST MODE > GOTO INT_DST > > ;---------------------------------- > ;----- TACHOMETER INTERRUPT ----------- > > INT_TACHO > MOVLW TMR ; RESTORE TIMER0 > MOVWF TMR0 ; > DECFSZ TCNT0,F ;SKIP IF ZERO > GOTO INTEND > RELOAD MOVF TCNT,W ;RELOAD TCNT0 > MOVWF TCNT0 > ;--------------------------------------------------- > DISP_RPM > MOVLW H'0' > CALL DDRAM_ADDRESS > MOVLW B'00110000' > IORWF DD1,1 > IORWF DD2,1 > IORWF DD3,1 > MOVFW DD1 > CALL PRINT_CHAR Do not call PRINT_CHAR from the interrupt service routine. PRINT_CHAR has a 100us delay inside it (because your LCD code doesn't check for "write complete") and adding a 100us delay to your ISR is bad practice. MOVFW DD2 > CALL PRINT_CHAR > MOVFW DD3 > CALL PRINT_CHAR > MOVLW '0' > CALL PRINT_CHAR > MOVLW '0' > CALL PRINT_CHAR > MOVLW 'R' > CALL PRINT_CHAR > MOVLW 'P' > CALL PRINT_CHAR > MOVLW 'M' > CALL PRINT_CHAR > RESET_COUNT > CLRF DD1 ;DISPLAY DATA > CLRF DD2 > CLRF DD3 > > > ;------ LEAF MODE SELECT -------- > BTFSS RA,1 ;SELECT ? > BSF FLAG_REG,TACHO_SEL > MOVLW TMR ; RESTORE TIMER0 > MOVWF TMR0 ; > GOTO INTEND > > ;------ END OF TACHO INT --------- > > > > > > ;--------------------------------- > INT_DST > MOVLW TMR1 ;256*78=19968 uS > MOVWF TMR0 > MOVF PWM_C,W > MOVWF TEMP1 > ;------------------------------------- > BIN2BCD MOVWF DD3 ;1 > CLRF DD2 ;10 > CLRF DD1 ;100 > > H1 MOVLW 0X64 ; 100 > SUBWF DD3,F ; SUBTRACT 100 FROM NUMBER > BTFSC STATUS,C ; NEGATIVE RESULT? > GOTO H2 ; NO? GOTO H2 > GOTO H3 ; YES? GOTO H3 (100'S DDD3) > H2 INCF DD1,F ; INCREMENT DD1 REGISTER > GOTO H1 ; & LOOP BACK FOR ANOTHER TEST > H3 MOVLW 0X64 ; 100 > ADDWF DD3,F ; ADD 100 BACK TO NUMBER > > T1 MOVLW 0X0A ; 10 > SUBWF DD3,F ; SUBTRACT 10 FROM NUMBER > BTFSC STATUS,C ; NEGATIVE RESULT? > GOTO T2 ; NO? GOTO T2 > GOTO T3 ; YES? GOTO T3 (10'S DDD3) > T2 INCF DD2,F ; INCREMENT DD2 REGISTER > GOTO T1 ; & LOOP BACK FOR ANOTHER TEST > T3 MOVLW 0X0A ; 10 > ADDWF DD3,F ; ADD 10 BACK TO NUMBER > ;-------------------------------------------------- > MOVLW H'40' > CALL DDRAM_ADDRESS > MOVLW B'00110000' > IORWF DD1,1 > IORWF DD2,1 > IORWF DD3,1 > MOVLW ' ' > CALL PRINT_CHAR > MOVFW DD1 > CALL PRINT_CHAR > MOVFW DD2 > CALL PRINT_CHAR > MOVFW DD3 > CALL PRINT_CHAR > MOVLW '0' > CALL PRINT_CHAR > MOVLW ' ' > CALL PRINT_CHAR > MOVLW 'u' > CALL PRINT_CHAR > MOVLW 'S' > CALL PRINT_CHAR > BTFSC FLAG_REG,F_REC > GOTO INTEND > BSF RA,3 > INT_DST1 ;10 uS LOOP > NOP > NOP > NOP > NOP > NOP > NOP > NOP I would recommend macros to specify delays, possibly ones that depend on the speed of the ceramic resonator. Also, instead of two nops, you could use goto $+1, and instead of four nops, you could call a return statement somewhere in your local code. DECFSZ TEMP1,F > GOTO INT_DST1 ;END OF LOOP > BCF RA,3 > DECF INT_C,F ;INCREASE INT_COUNTER > > ;------------------------------------- > INTEND > MOVF INTR1,W ; RESTORE STATUS > MOVWF STATUS > MOVF INTR0,W ; RESTORE W > BCF INTCON,TOIF ; RESET FLAG OF INT T0 > RETFIE > ; > ; > ;------------------------------------------------- > ;============================================ > ;LCD SOUTINE > > ;============================================================== > PRINT_DATA > BSF RB,2 ;RS=1, DATA > MOVWF ADDRESS1 > BSF ADDRESS1,2 > MOVF ADDRESS1,0 > MOVWF RB > BSF RB,3 > NOP > BCF RB,3 > CALL LOOP_S ;100 uS > RETURN > > PRINT_CONT > MOVWF RB > BSF RB,3 > BCF RB,3 > CALL LOOP_S ;100 uS > RETURN > > CLEAR_DISPLAY > MOVLW B'00000000' ;0 > CALL PRINT_CONT > MOVLW B'00010000' ;1 CLEAR > CALL PRINT_CONT > MOVLW 1 > CALL LOOP_L ;10mS > RETURN > > DDRAM_ADDRESS > MOVWF ADDRESS1 > BSF ADDRESS1,7 > MOVF ADDRESS1,0 > ANDLW B'11110000' ; > CALL PRINT_CONT > SWAPF ADDRESS1,W ;SWAP HALVES F > ANDLW B'11110000' ; > CALL PRINT_CONT > RETURN > > PRINT_CHAR > MOVWF CHAR1 > ANDLW B'11110000' ; > CALL PRINT_DATA > SWAPF CHAR1,W ;SWAP HALVES F > ANDLW B'11110000' ;SENT LOW 4 BITS > CALL PRINT_DATA > RETURN > > LOOP_S ;100uS LOOP > MOVLW D'33' > MOVWF TEMP4_LCD > LOOP_S1 > DECFSZ TEMP4_LCD,1 ; > GOTO LOOP_S1 > RETURN > > LOOP_L ;10 mS LOOP > MOVWF TEMP1_LCD > LOOP_L1 > MOVLW D'10' ;10 mS > MOVWF TEMP2_LCD > LOOP_L2 > MOVLW D'249' ;(249*4)+5=1001 > MOVWF TEMP3_LCD > LOOP_L3 > NOP > DECFSZ TEMP3_LCD,1 > GOTO LOOP_L3 > DECFSZ TEMP2_LCD,1 > GOTO LOOP_L2 > DECFSZ TEMP1_LCD,1 > GOTO LOOP_L1 > RETURN > > DISP_MESSAGE > MOVWF TABLE_INDEX ;W -> INDEX, THE BEGIN OF MESSAGE > CALL MESSAGE1 > ANDLW 0FFH > SKPNZ ; IF TABLE RETURN 0 , END OF MESSAGE SECTION > RETURN > CALL PRINT_CHAR ; DOSPLAY > INCF TABLE_INDEX,0 > GOTO DISP_MESSAGE > ;==================================================== > MODE_ADDRESS > > ADDWF PC,F > RETLW 0 > RETLW 0 > RETLW D'9' > RETLW D'18' > RETLW D'27' > > MESSAGE1 > > ADDWF PC,F > RETLW 'T' > RETLW 'a' > RETLW 'c' > RETLW 'h' > RETLW 'o' > RETLW ' ' > RETLW ' ' > RETLW ' ' > RETLW 0 > RETLW 'S' ;9 > RETLW 'e' > RETLW 'r' > RETLW 'v' > RETLW 'o' > RETLW ' ' > RETLW 'T' > RETLW 'x' > RETLW 0 > RETLW 'S' ;18 > RETLW 'p' > RETLW 'e' > RETLW 'e' > RETLW 'd' > RETLW ' ' > RETLW 'T' > RETLW 'x' > RETLW 0 > RETLW 'R' ;27 > RETLW 'e' > RETLW 'c' > RETLW 'e' > RETLW 'i' > RETLW 'v' > RETLW 'e' > RETLW 'r' > RETLW 0 > > NOP ;36 > > > ;======================================= > ;---------- PROGRAM BEGIN ----------- > ;---------------------------------------- > ; > > START > BSF STATUS,RP0 ;SET 3,5 ENABLE BANK1 Again, better use banksel to select the correct bank. This file also seems to be long enough to warrant being split up into separate units. Once you use the relocatable mode, that should be relatively simple. As for increasing the number of digits, your code seem to only go from 100-25500, in steps of 100. I'm not sure, but it seems your value is kept in PWM_C. To increase the number of digits, you'll have to make PWM_C a 16-bit value, by adding another byte, and change all code accessing PWM_C to 16-bit arithmetic. After that, you will need to change BIN2BCD such that it creates DD1, DD2, DD3, DD4, and DD5 (the latter two are new) and change your print routine (which is currently in the interrupt service routine, but should really move out of there) to print DD1, DD2, DD3, DD4, DD5 and two zeroes. This will give you a range from 100-6553500 in steps of 100. Given the size of your display, you'll have to remove the "rpm" part, which can be easily found in the code. To move the print code out of the ISR is easy: just set a bit in the interrupt service routine that DD1, DD2, DD3, DD4, DD5 are filled with the correct numbers, and in your main loop check for that bit, and if set, print those numbers, then reset the bit. Good luck, given the state of the code as it is currently, this doesn't look like an easy task. Greetings, Maarten Hofman. -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist