T O P I C R E V I E W |
pebe |
Posted - Jan 04 2011 : 04:32:12 AM I have written a short program in assembler for a PIC 16F676.
I have been through the code with a fine toothed comb but I cannot get it to run. I am now at the stage when I want to tear my hair out!
If I publish the code is someone willing to check it for me?
|
8 L A T E S T R E P L I E S (Newest First) |
wasssup1990 |
Posted - Jan 06 2011 : 11:32:43 AM Actually every C compiler I have used for PICs allowed me to also code in assembly in the same source file. I remember I used assembly and C together in my balancing robot I made a few years ago. That had an 8-bit PIC running at 4MIPS if I remember correctly.
The project I am working on now needs a DSP at 40MIPS because it needs to optimize power conversion efficiency and monitor currents, voltages and temperatures. I have written code for DSPs before completely in assembly and I saw that it's a huge bottle neck in design process. Modern DSPs now are being made so that they are optimized to work with the C language.
I can see why you still write all your code in assembly though. 40 years is a long time. It's kind of ingrained in you to stick with what you know perhaps?
I moved away from BASIC years ago. It's a total beginners language.
You are retired Pebe so you have plenty of time to play around. I'm a university student and I am trying to meet deadlines. I have no choice but to consider time. I hope to have this project finished by the end of the month. I already have parts coming from the distributors.
quote: If you want to do flashy things with your 40Mips machines, then good luck to you. I obtain my hobby satifaction in the challenge of trying to do what some others consider impossible. Many years ago, for a bet, I built a working 2metre walkie-talkie in a 2ounce tobbaco tin using TUBES. I won the bet.
Great! "trying to do what some others consider impossible" eh? Hmm, well I don't have the "others". I need someone who actually understands what I'm doing and appreciates the "trying to do what some others consider impossible" of my projects. I have to explain it to them thoroughly and show them examples of why my version is better than others. Well I suppose it's good practice for a job interview because I will definitely be bring my projects in and have to explain them thoroughly.
|
pebe |
Posted - Jan 06 2011 : 10:35:41 AM Nothing is faster than assembler - at least, that's what I've been told. I don't know about C but Basic definitely has limitations. I started off almost 40 years ago with 6502 and Intel 8048. These I laboriously coded in raw machine code! Those were the days of Atari and the Commodore Pet and the BBC micro . They had only just invented 'C' for Unix and the IBM PC had not yet arrived on the scene - and there wasn't an assembler in sight.
There is not much to forget with a PIC - there are only some 30+ instructions in the set. So coding in assembler really is a doddle - and you can see where you are going.
If you want to do flashy things with your 40Mips machines, then good luck to you. I obtain my hobby satifaction in the challenge of trying to do what some others consider impossible. Many years ago, for a bet, I built a working 2metre walkie-talkie in a 2ounce tobbaco tin using TUBES. I won the bet.
I love lateral thinking and time is not a consideration, so I am relishing my present task of building a metal detector with (I think) unique circuitry so that a 5year old should be able to use it without tuition. I need to know what is going on every machine cycle in the program, and I doubt if I could if I used 'C'. |
wasssup1990 |
Posted - Jan 05 2011 : 11:14:13 AM Cool. I rarely have a need to program in assembly although I can program in it after I acquaint myself with the particular version of assembly for that chip. Personally I think it's a huge waste of time. You forget things after a while and then you have to re-learn which takes time. I use C most of the time - it's a lot quicker to go from an idea to a working device. Are you still stuck in an assembly world Pebe? I think once on this forum you were wondering whether you should try C because you thought it was probably faster. I'm currently working on a project which would make it impractical to program in assembly. Besides the chip is doing 40MIPS and has a large memory. I look at the assembly code produced from my C code and there doesn't seem to be any significant overhead in simple operations like setting registers.
Glad your problem was solved. I had a feeling it would be solved quickly either by you or someone else. Glad I didn't waste my time. LOL
See ya. |
pebe |
Posted - Jan 05 2011 : 06:27:50 AM Wassup, I did say at the beginning of my posting that this was a short test program. If you had looked a little further you would have seen that it only toggles one bit – as you suggested.
I know the problem of looking over someone else’s code, so I removed my main program and only left a test program and the minimum necessary that included my faulty code.
I have now found the problem. Someone on another forum pointed out that I had not cleared the timer interrupt bit, T01F, before leaving the interrupt. I had deliberately written the interrupt in that way because in one part of my program I counted time by the number of machine cycles executed and I didn’t want timer interrupts intervening. In my real program I was clearing the bit only when entering one of the timer routines. But when faultfinding I could not see how that could possibly affect the test program that used no interrupts.
However, I was going from memory about the T01Fbit. I had wrongly assumed that when set it prevented an interrupt occurring. In fact, when I re-read the datasheet I saw it is the very flag that starts the timer interrupt. The result was that the program was stuck in the interrupt routine – unable to get out until the bit was cleared. I went through the program again and again but missed it. I would still be missing it now had it not been pointed out to me.
I will get round the problem by disabling the timer, and only enabling it when I need it for specific timed routines.
|
wasssup1990 |
Posted - Jan 04 2011 : 9:11:33 PM In the mean time you should set aside at least one output for debugging purposes. If you are not running a ICSP/Debugger this can be very handy for solving "it isn't running" problems like yours. Modify your code so that an output is turned high if the PC reaches that point in your code. That way you will know if parts of your code are working as you intended them to. I will look over your code gradually - I have my own things to do as well. It's better to have good problem solving procedures in place to fall on when problems like this occur because asking someone outside the project to help is a waste of time. They have to acquaint themselves with your code which you have already done because you wrote it.
|
pebe |
Posted - Jan 04 2011 : 11:33:19 AM OK, wassup, Here is the test program. The full program is for a metal detector that I am developing. It runs with a 20MHz crystal wired as PIC reccomendations and I know from 'scoping it that it works OK. Just to be sure the malfunction had nothing to do with the frequency, I changed the config bit _HS_OSC to _INTRC_OSC_NOCLKOUT to use the internal oscillator and took the semicolons off the next four lines after the "main" label to pick up OSCCAL. The result was the same.
The circuit is wired up on Veroboard (stripboard) using standard best practice for component placement and decoupling - the way I have done many similar ones before. All outputs go via resistors and all inputs except A0 are from opamps using the same rails as the PIC, so there is no question of overdriving them. Input A0 is from the TX coil. The coil provides a sinewave of 9Vpk via a 22K resistor and relies on the diode input protection for clamping (which my 'scope shows is working OK), so the maximum current into the pin is just 410microamps. The datasheet gives the maximum permissable current into a pin as 20mA, so it's well within limits.
Nothing is connected to PortC yet.
This is only the first half of my development. It does not need an A/D, whereas the second stage will, so I bought 4 x 16F676. The datasheet requires ANSEL to be cleared to use digital inputs. The Microchip publication 33023A.pdf also requires bits 1 and 2 of ADCON1 to be set but the '676 datasheet does not mention it. I have tried with and without ADCON1 - it makes no difference.
When the program refused to run, I took it out and substituted this simple program to toggle a bit - but it won't work on any of the four '676s I have bought. I am hoping your 'eagle eyes' can spot my mistake.
;********************************************************************** ; This file is a basic code template for assembly code generation * ; on the PIC16F676. This file contains the basic code * ; building blocks to build upon. * ; * ; Refer to the MPASM User's Guide for additional information on * ; features of the assembler (Document DS33014). * ; * ; Refer to the respective PIC data sheet for additional * ; information on the instruction set. * ; * ;********************************************************************** ; * ; Filename: MetalDetector Ph1 TEST.asm * ; Date: 1/1/11 * ; File Version: 2 * ; * ; Author: * ; Company: * ; * ; * ;********************************************************************** ; * ; Files Required: P16F676.INC * ; * ;********************************************************************** ; * ; Notes: ; This part of the metal detector handles Ground Effect cancellation, meter display, and sounder ; Uses 20MHz Xtal (HS mode) ; ; Port RA ; 0 in Tx coil ; 1 in Rx coil ; 2 in Combined signals ; 3 in Stop Resetting P B (needs external pullup) ; 4 out Xtal (osc2) ; 5 in Xtal (osc1) ; ; Port RC ; 0 out FET control ; 1 in Gyrator ; 2 out Gyrator ; 3 out Audio ; 4 out Meter A ; 5 out Meter B; ; ;**********************************************************************
list p=16f676 ; list directive to define processor #include <p16f676.inc> ; processor specific variable definitions
errorlevel -302 ; suppress message 302 from list file
__CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC
; '__CONFIG' directive is used to embed configuration word within .asm file. ; The lables following the directive are located in the respective .inc file. ; See data sheet for additional information on configuration word settings.
;***** VARIABLE DEFINITIONS w_temp EQU 0x20 ; variable used for context saving status_temp EQU 0x21 ; variable used for context saving
TXcount EQU 0X22 GYRnum EQU 0x23 ;timer count for gyrator flags EQU 0x24 ;flags hicount EQU 0x25 ;count of number of consecutive times GYR count has gone high locount EQU 0x27 ;-----ditto-----, low timeperiod EQU 0x28 ;loop counter in 18us timer loops EQU 0X29 ;general loop counter ;PortA bits Tx EQU 0 signal EQU 1 Rx EQU 2 PushB EQU 3 ;(needs external weak pullup)
;PortC bits FETup EQU 0 GYRin EQU 1 GYRout EQU 2 Audio EQU 3 MeterA EQU 4 MeterB EQU 5
tim EQU 0 ;flag bit modGYR EQU 1 ;flag to update gyrator count2 EQU 2 ;x2 extender for Tx number count count3 EQU 3 ;counter to mark end of audio pulse tim2 EQU 4 ;end of 100ms timer delay ;**********************************************************************
ORG 0x000 ; processor reset vector goto main ; go to beginning of program
ORG 0x004 ; interrupt vector location movwf w_temp ; save off current W register contents movf STATUS,w ; move status register into W register movwf status_temp ; save off contents of STATUS register ;timer interrupt routine ******************* bsf flags,tim ;set flag to show end of time ;turn off gyrator (bit2) ;turn off both meters (bits 4 & 5) bcf PORTC,MeterA bcf PORTC,MeterB ;count for audio 100ms decfsz locount goto t100 decfsz hicount goto t100 bsf flags,tim2 t100 movf status_temp,w ; retrieve copy of STATUS register movwf STATUS ; restore pre-isr STATUS register contents swapf w_temp,f swapf w_temp,w ; restore pre-isr W register contents retfie ; return from interrupt
; remaining code goes here
main ;initialise at switch on ; call 0x3FF ; retrieve factory calibration value for internal timer ; bsf STATUS,RP0 ; set file register bank to 1 ; movwf OSCCAL ; update register with factory cal value ; bcf STATUS,RP0 ; set file register bank to 0
bcf STATUS,RP0 ;select bank 0 clrf PORTA ;init clrf PORTC ;init movlw b'000111' ;turn off comparitor movwf CMCON bsf STATUS,RP0 ;select bank 1 movlw .6 movwf ADCON1 ;only digi - no A/D (ref: PIC 33023A.pdf) clrf ANSEL ;select all pins as digital ;set up PORTA all bits as inputs (except 4 = Xtal out) movlw b'101111' ;set PORTA in/out movwf TRISA movlw b'000000' ;no pullups movwf WPUA
movlw b'000010' ;set PORTC i/o (bit 1 input for GYR) movwf TRISC ;set up timer0 prescaler movlw b'00000000' ;set prescaler = 2 in timer mode movwf OPTION_REG ;set up timer interrupt movlw b'10100000' ;bits 7, 5 high movwf INTCON bcf STATUS,RP0 ; **********set file register bank to 0
clrf hicount clrf locount clrf flags ;set up initial number for gyrator pulse delay movlw .150 ;count of 106 (x 400ns) (counts up) movwf GYRnum ;MAIN PROGRAM ************************
;*******TEMPORARY TEST PROGRAM start ;temp test to toggle PortC bit 5 bsf PORTC,5 ;turn on bit 5 movlw .100 movwf loops s1 decfsz loops goto s1 bcf PORTC,5 ;turn off bit 5 movlw .100 movwf loops s2 decfsz loops goto s2 goto start ;***End of test prog ; initialize eeprom locations
ORG 0x2100 DE 0x00, 0x01, 0x02, 0x03
END ; directive 'end of program' |
fannanm |
Posted - Jan 04 2011 : 11:11:19 AM ÈÑãÌÉ ÇáãäÝÐ ÇáãÊæÇÒí Ýí ÔØÑäÌ |
wasssup1990 |
Posted - Jan 04 2011 : 09:41:44 AM Just do little tests one at a time. Start at the most critical points like... Is the internal CPU being clocked? If no then maybe you have misconfigured your OSCON bits or your external clock is not performing correctly. To perform this test, program the MCU with a simple "blink an LED" type program. This is the most easiest way to test if your MCU is capable of even starting up and has a solid clock.
If yes then it could be a whole range of things. You should just post your code if you are able to rather than delaying. Hopefully for you I might be able to help. |
|
|