I got my PICKit 2 Starter Kit today and I have been trying things out with some success. I have started reading the manuals, online forums, etc. and I'm kind of getting confused.
The sample code that comes with the programmer to blink an LED is:
Code:
#include <p16F690.inc>
__config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)
cblock 0x20
Delay1 ; Define two file registers for the
Delay2 ; delay loop
endc
org 0
Start:
bsf STATUS,RP0 ; select Register Page 1
bcf TRISC,0 ; make IO Pin B.0 an output
bcf STATUS,RP0 ; back to Register Page 0
MainLoop:
bsf PORTC,0 ; turn on LED C0
OndelayLoop:
decfsz Delay1,f ; Waste time.
goto OndelayLoop ; The Inner loop takes 3 instructions per loop * 256 loopss = 768 instructions
decfsz Delay2,f ; The outer loop takes and additional 3 instructions per lap * 256 loops
goto OndelayLoop ; (768+3) * 256 = 197376 instructions / 1M instructions per second = 0.197 sec.
; call it a two-tenths of a second.
bcf PORTC,0 ; Turn off LED C0
OffDelayLoop:
decfsz Delay1,f ; same delay as above
goto OffDelayLoop
decfsz Delay2,f
goto OffDelayLoop
goto MainLoop ; Do it again...
end
Everything works great with that, and I am starting to understand the basics of what is going on...but what confuses me is why when I try to use code off the internet it gives me compiling errors?
hmm, I suppose that isn't a great way to describe the problem. What I mean is, how can I work with this code to do things like make it blink faster, slower, random?
Is there something I can do to add a fade? Or can I have it blink to a "beat"?
How do I get it to control the other LED's?
Sorry if that's a loaded question, but any help would be great. I'm in the process of reading tutorials, but because the chips they're using aren't what I am using, the whole thing falls apart when I try to compile things because if I can't move on with the tutorials, then I'm hooped.
Hi,
Please use code for code instead of quote, to make it more readable
Can you tell us what's the error message you get?
This is how I learn too. Copy the working program, edit and see the changes.
More examples for assembly language can be found here.
The nice thing about compiling errors is that they tell you what line the error is on, and why it's an error. Just find the line, decrypt the error, and stare at the datasheet for a few minutes to figure out what you did wrong.
I went to the site of the link above, and I went to the tutorial to blink an LED.
Code:
;Tutorial 1.1 - Nigel Goodwin 2002
LIST p=16F628 ;tell assembler what chip we are using
include "P16F628.inc" ;include the defaults for the chip
__config 0x3D18 ;sets the configuration settings
;(oscillator type etc.)
org 0x0000 ;org sets the origin, 0x0000 for the 16F628,
;this is where the program starts running
movlw 0x07
movwf CMCON ;turn comparators off (make it like a 16F84)
bsf STATUS, RP0 ;select bank 1
movlw b'00000000' ;set PortB all outputs
movwf TRISB
movwf TRISA ;set PortA all outputs
bcf STATUS, RP0 ;select bank 0
Loop
movlw 0xff
movwf PORTA ;set all bits on
movwf PORTB
nop ;the nop's make up the time taken by the goto
nop ;giving a square wave output
movlw 0x00
movwf PORTA
movwf PORTB ;set all bits off
goto Loop ;go back and do it again
end
Thinking that it had to have my MCU's config and include...and I got this...
---------------------------------------------------------------------
Release build of project `C:\PK2 Lessons\LPC Demo Board\02 Blink\Blink.mcp' started.
Tue Jun 17 21:57:58 2008
----------------------------------------------------------------------
Make: The target "C:\PK2 Lessons\LPC Demo Board\02 Blink\Blink.o" is out of date.
Executing: "C:\Program Files\Microchip\MPASM Suite\MPASMWIN.exe" /q /p16F690 "Blink.asm" /l"Blink.lst" /e"Blink.err"
Warning[205] C:\PK2 LESSONS\LPC DEMO BOARD\02 BLINK\BLINK.ASM 35 : Found directive in column 1. (org)
Error[113] C:\PK2 LESSONS\LPC DEMO BOARD\02 BLINK\BLINK.ASM 38 : Symbol not previously defined (CMCON)
Message[302] C:\PK2 LESSONS\LPC DEMO BOARD\02 BLINK\BLINK.ASM 42 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\PK2 LESSONS\LPC DEMO BOARD\02 BLINK\BLINK.ASM 43 : Register in operand not in bank 0. Ensure that bank bits are correct.
Halting build on first failure as requested.
----------------------------------------------------------------------
Release build of project `C:\PK2 Lessons\LPC Demo Board\02 Blink\Blink.mcp' failed.
Tue Jun 17 21:57:59 2008
----------------------------------------------------------------------
BUILD FAILED
Analog comparator module with:
- Two analog comparators
- Programmable on-chip voltage reference
(VREF) module
- Programmable input multiplexing from device
inputs and internal voltage reference
- Comparator outputs are externally accessible
I meant to ask if YOUR chip (16F690?) has a comparator, but I'm stupid when it comes to reading, hahah. Anyways, taking a peek in the 16F690's include/header shows that CMCON isn't defined, so that's where your error comes from. You should be able to just get rid of that CMCON part of the sample code since it doesn't apply to the 690.
I meant to ask if YOUR chip (16F690?) has a comparator, but I'm stupid when it comes to reading, hahah. Anyways, taking a peek in the 16F690's include/header shows that CMCON isn't defined, so that's where your error comes from. You should be able to just get rid of that CMCON part of the sample code since it doesn't apply to the 690.
Yup, you're right. The compiler worked (meaning it didn't give me any errors), but it didn't do anything. This is why I find things confusing because the first code I posted worked perfectly, but the second code, meant to blink an LED just the same is almost twice as long...and doesn't work.
I suspect it has something to do with the PORTS / TRIS
EDIT:
Ya, I changed the TRISB to TRISC as I'm pretty sure that's where my LED's are hooked up on this Starter Kit board thing. But it doesn't blink....I'll mess with it for a minute.
Anyways, if you have a multimeter with a frequency measurement setting, you might want to check the frequency on the lines you're blinking, just in case you're blinking them way too fast (Speaking from experience, you can't quite see it if your LED's are blinking at 7kHz)
Bah...ok this isn't making sense. I'm like 5 steps ahead.
I need to be able to break down the code I have, and slowly build on it so I can see why it's doing what it's doing.
My ultimate goal with this is to get the 4 LED's on this thing to randomly fade from bright to dim. If I can work towards that goal I'll be pretty happy to go from there. So far I understand completely (well mostly) why the first code posted works.
The next step would be to figure out how to randomize the blinking perhaps.
Fading is something you would need the PWM module for (I assume the 690 has PWM) or a resistor ladder for basic Digital-to-Analog conversion.
And random is something that (at least low-end) PIC's don't do. Random and pseudo-random number generation aren't features of the 16F-series instruction set.
Hmm, I was going to order a few 18F chips tomorrow so I hope that would work.
Specifically the 18LF1320 I think.
That's odd that you can't do a random thing with the 16F chips....hmmm..oh well.
Just so you know...in the end what I want to do is:
- Control a TX and RX IR LED's that send out and check for unique ID's
- Light up 4 - 5 LED's/bulbs when the receiver detects the ID from two other TX's
- Randomize the Dimming/lighting of the LED's when lit
I'm kinda stuck with this chip till then, so I was just trying to get some of the basics down. I was reading up on PWM a bit, but I couldn't find a simple code that would work with this chip, and that seems to be my main problem. It seems none of the tutorials I find are for this chip, so they all fail due to something.
You could do simple **broken link removed** too. Might even be easier than hardware PWM, especially if you want more than four LEDs fading (the 690 has four hardware PWM pins).
And random is something that (at least low-end) PIC's don't do. Random and pseudo-random number generation aren't features of the 16F-series instruction set.
Most (all?) C compilers have a random function in the libraries somewhere. I use BoostC and it does. Trivial to get pseudo-random numbers if you feed it a good pseudo-random seed.
A decent random number generator can be written in asm too.
You can just grab my MSN if you want and we could figure out some code
I suppose you could write a reasonable "random" number generator by taking certain bits from ever-changing registers (like from the high TMR1 register, the TMR0, pointer, so forth)
random16:
rlf RandHi, W
xorwf RandHi, W ; xor (D15, D14) now in W reg, D7
movwf temp
swapf RandHi, W
rlf RandLo, f
rlf RandHi, f
swapf RandLo, f ; D3 now in RandLo, D0
xorwf RandLo, W ; xor (D12, D3) now in W reg, D0
swapf RandLo, f
rlf temp, f
rlf temp, f
xorwf temp, W
movwf temp
rrf RandLo, f
rrf temp, f
rlf RandLo, f
return
Just so you know...in the end what I want to do is:
- Control a TX and RX IR LED's that send out and check for unique ID's
- Light up 4 - 5 LED's/bulbs when the receiver detects the ID from two other TX's
- Randomize the Dimming/lighting of the LED's when lit
I'm kinda stuck with this chip till then
You should be able to do this with the 16F chip. MicroChip supplies a free C compiler for the 18F series PICs which might be a language you are more familiar with. Learning assembler is a good thing though.
And random is something that (at least low-end) PIC's don't do. Random and pseudo-random number generation aren't features of the 16F-series instruction set.
They aren't a feature of any CPU (as far as I know), you simply write the routines to do it, it's a common requirement, and routines for it are all over the net.
They aren't a feature of any CPU (as far as I know), you simply write the routines to do it, it's a common requirement, and routines for it are all over the net.
I went to the site of the link above, and I went to the tutorial to blink an LED.
Code:
;Tutorial 1.1 - Nigel Goodwin 2002
LIST p=16F628 ;tell assembler what chip we are using
include "P16F628.inc" ;include the defaults for the chip
__config 0x3D18 ;sets the configuration settings
;(oscillator type etc.)
org 0x0000 ;org sets the origin, 0x0000 for the 16F628,
;this is where the program starts running
movlw 0x07
movwf CMCON ;turn comparators off (make it like a 16F84)
bsf STATUS, RP0 ;select bank 1
movlw b'00000000' ;set PortB all outputs
movwf TRISB
movwf TRISA ;set PortA all outputs
bcf STATUS, RP0 ;select bank 0
Loop
movlw 0xff
movwf PORTA ;set all bits on
movwf PORTB
nop ;the nop's make up the time taken by the goto
nop ;giving a square wave output
movlw 0x00
movwf PORTA
movwf PORTB ;set all bits off
goto Loop ;go back and do it again
end
The reason you don't see the LED blink in the above program is the fact it's blinking so fast you can't see it blink...we're talking microseconds, here. That is why delay code is added.... to slow down the process to allow the human eye to catch up. The delay is based upon the number of cycles used in a loop. Most instructions, except goto and call, use one cycle. If your oscillator is 4MHz, divided by 4, = 1 MHz, so each instruction last 1 microsecond.
Turn a led on, 1 microsecond.
Turn a led off, 1 microsecond.
That can't be seen. So you have to put about 200,000 microseconds in between the two instructions in order to have a resonable blink. A delay sequence, with its repeating loops of cycles, accomplishes this.
You are right. It is confusing at first. I started learning assembly programming about a week ago, so I know what your frustrations are. LOL.
I think I'm starting to get the hang of it...sort of...
I'm just trying to do something simple here, just cause...
How do I turn on two LED's at a time?
Code:
Start:
bsf STATUS,RP0 ; select Register Page 1
clrf TRISC ; make IO Pin C0 an output
bcf STATUS,RP0 ; back to Register Page 0
bsf PORTC,0 ; turn on LED C0 (DS1)
goto $ ; wait here
end
From what I understand it's making the TRISC all outputs, then turning on the LED on PORTC, 0 (which I am assuming is RA0).
How do I tell it to also light up the LED next to it? (PORTC, 1)