![]() | ![]() | ![]() |
| | |||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
| | LinkBack | Thread Tools | Display Modes |
| | (permalink) |
| Hello, I recently purchased a copy of Microchip's Pickit 2 programmer, with a low pin count demo board to play around with. The board comes with a PIC16F690 chip, 4 LEDs, a pushbutton, and a pot. I'm using Microchip's MPLAB development environment. The Demo Board comes with several tutorials. The first one is called, "Hello World." It involves using Assembly language to light up a single LED, attached to one of the IO pins. The Four LEDs are connected to pins RC0-RC3. Here's the code that turns on LED RC0: #include <p16F690.inc> __config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF) org 0 Start: bsf STATUS,RP0 ; select Register Page 1 bcf TRISC,0 ; 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 I've done this, and it seems to work just fine. My question is, how would I go about turning on 2 or more LEDs? The intuitive way seems to be to use the following code: Start: bsf STATUS,RP0 ; select Register Page 1 bcf TRISC,0 ; make IO Pin C0 an output bcf TRISC,1 ; should this make pin C1 an output? bcf STATUS,RP0 ; back to Register Page 0 bsf PORTC,0 ; turn on LED C0 (DS1) bsf PORTC,1 ; shouldn't this turn on LED C1? goto $ ; wait here end I've tried this, and many other combinations, but no luck. Any thoughts? | |
| |
| | (permalink) |
| The default value of the TRISC register after a "power on reset" or "brown out reset" is b'11111111' (all inputs). You want to set both the RC0 and RC1 pins as outputs. Try to think of a '1' bit in TRISC as an Input and a '0' bit as an Output Mike <added> Almost forgot.... Welcome to the Forum... Have fun!!! Last edited by Mike, K8LH; 12th August 2008 at 03:01 AM. | |
| |
| | (permalink) |
| Hey there, Thanks for the welcome and the quick response! That makes sense. I've been operating under the impression that by adding the line, bcf TRISC,1 I would be able to set pin RC1 as an output, as well. Is that not the way to do it? Start: bsf STATUS,RP0 ; select Register Page 1 bcf TRISC,0 ; make IO Pin C0 an output bcf TRISC,1 ; Doesn't this turn pin RC1 into an output? bcf STATUS,RP0 ; back to Register Page 0 bsf PORTC,0 ; turn on LED C0 (DS1) bsf PORTC,1 ; shouldn't this turn on LED C1? goto $ ; wait here end | |
| |
| | (permalink) |
| Hi, Welcome. What happens if you do, Code: Start: bsf STATUS,RP0 ; select Register Page 1 bcf TRISC,0 ; make IO Pin C0 an output bcf TRISC,1 ; should this make pin C1 an output? bcf STATUS,RP0 ; back to Register Page 0 movlw b'00000011' movwf PORTC goto $ ; wait here end I'm also a little confused by the example code you have posted, it has both the internal clock selected and master clear turned off. This can cause problems with some chips. Is this the example supplied by Microchip? Mike. Last edited by Pommie; 12th August 2008 at 03:09 AM. Reason: wrong value | |
| |
| | (permalink) |
| Just had a look at the circuit diagram for that board and just thought I would ask, do you have JP2 on? edit, removed reply to deleted post. Mike. Last edited by Pommie; 12th August 2008 at 03:18 AM. | |
| |
| | (permalink) | |
| That fixed it! LEDs 1 and 2 are now glowing brightly! I also tried it with LEDs 0-3, (with a hex value of 0xFF) and all of them are glowing! This is just about the prettiest thing I've seen all day. Could you tell me a little bit more about this "analogue mode," and why the method I tried didn't work? I looked at the writeup for the ANSEL and ANSELH registers in the 16F690 user manual, but it's difficult to decipher: This is the first time I've done any programming ever, so please bear with me. Quote:
| ||
| |
| | (permalink) |
| Some of the pins on the 690 are configured as analogue pins at reset. Analogue pins always read as zero and so when a bsf instruction is used it reads the other bits as zero and so the second bsf will reset the first one. (bsf reads the port (or other register), modifies the value and writes it back to the port) To turn off the analogue part of the ports you would clear the ANSEL(H) registers and so you code would become, Code: Start: bsf STATUS,RP2 ;bank 2 clrf ANSEL ;turn of analogue pins clrf ANSELH ;and some more bcf STATUS,RP2 ;back to bank 0 bsf STATUS,RP0 ; select Register Page 1 bcf TRISC,0 ; make IO Pin C0 an output bcf TRISC,1 ; should this make pin C1 an output? bcf STATUS,RP0 ; back to Register Page 0 bsf PORTC,0 ; turn on LED C0 (DS1) bsf PORTC,1 ; turn on LED C1 goto $ ; wait here end Last edited by Pommie; 12th August 2008 at 04:33 AM. Reason: corrected code. | |
| |
| | (permalink) |
| I don't think that the analog mode makes any difference when the pins are being used as outputs. Analog mode only disables the input buffers. I think that the problem here could be the read-modidy-write effect on the ports. The simple rule when manipulating ports is to never modify bits on a port in subsequent instructions. so Code: bsf PORTC,0 ; turn on LED C0 (DS1) bsf PORTC,1 ; turn on LED C1 You can use Code: movlw b'00000011' iorwf PORTC Code: bsf PORTC,0 ; turn on LED C0 (DS1) nop bsf PORTC,1 ; turn on LED C1 The reason is a little technical, and you don't need to understand it if you stick to the rule of not setting bits on subsequent instructions:- On PICs, instructions that change registers, including the ports, work by reading the register value from the memory, modifying the value in the Arithmetic Logic Unit, and writing the value back into the memory. There is no way that the PIC can change individual bits in the memory, so instuctions like bsf 0x20, 0 are executed by reading register 0x20, setting bit 0 and writing the whole lot back into register 0x20. In normal registers that aren't ports that doesn't make any difference. However, with ports, if you execute bsf PORTC, 0 the value is written back to the port in the last quarter of the instruction. If the next instruction is bsf PORTC, 1, that will read the port again in the first quarter of the next instruction, only a very short time after the 1 was written. Any capacitance or load on the pin will slow the rise of the voltage on PORTC, 0 pin. If that pin is read a very short time later, the voltage will still read as 0. Even though it is rising, it will not have got to a level that reads as a 1. The second instruction (bsf PORTC, 1) will read PORTC, 0 as a 0, so that is what will be written back at the end of the second instruction. | |
| |
| | (permalink) | |
| Quote:
Mike. Last edited by Pommie; 12th August 2008 at 09:08 AM. Reason: Remove first part of quoted code to avoid confusion. | ||
| |
| | (permalink) | |
| Quote:
Code: movlw b'00000011' movwf PORTC | ||
| |
| | (permalink) |
| Hey there, Thank you all for your help! I wouldn't have gotten anywhere on this without your advice, and I really appreciate it. Now, to proceed with the rest of the lessons... =) | |
| |
| Bookmarks |
| Thread Tools | |
| Display Modes | |
| |
| | ||||
| Title | Starter | Forum | Replies | Latest |
| PICKit 2 question | speakerguy79 | Micro Controllers | 2 | 17th April 2008 05:11 PM |
| Sorry for the newbie question | gobbles | Micro Controllers | 0 | 12th October 2005 05:33 PM |
| newbie question | japl | Micro Controllers | 4 | 1st September 2003 03:49 PM |
| Newbie Question | spacechimp | Micro Controllers | 0 | 31st August 2003 10:09 PM |
| newbie - question.. | russell_writer | Robotics Chat | 1 | 29th June 2003 12:39 AM |