Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

GP2 as output on PIC10F200

Status
Not open for further replies.

Diver300

Well-Known Member
Most Helpful Member
I'm having trouble getting GP2 to become an output on an PIC10F200.

GP0 and GP1 work fine as outputs, but GP2 appears to still be an output. Here is my code:-

Code:
    nop
    nop
    nop
    nop

    clrf    5    ;osccal

    movlw    0b11110001
    movwf    7    ;cmcon


    movlw    0x00
    tris    6    

loop

    bsf        6, 2
    nop
    bsf        6, 1
    nop       
    bsf        6, 0

    decfsz    0x10, f
    goto    $-1

    bcf        6, 2
    nop
    bcf        6, 1
    nop       
    bcf        6, 0

    decfsz    0x10, f
    goto    $-1

    goto    loop

I haven't found the include file so that I can use friendly names for the registers, but register 6 is the IO.

I realise that there is no comparator on a PIC10F200, so writing to CMCON (register 7) shouldn't be needed, and I haven't found it makes any difference as GP2 isn't an output whether I write to that or not.

This code is putting out square waves on GP0 and GP1, but GP2 is still floating.

Any ideas what I'm doing wrong?
 
If you haven't found the include file, then you're working in the dark - get your error sorted out before anything else - don't try and program without the supplied include file.

Get the include file sorted, and read the datasheet.
 
Does this help?
200.png


Mike.
 
Some things wrong with your program:

1. Missing ORG 0 command at the top of the program. This is bad practice.
2. Referencing registers by number instead of name. Also bad practice. And confusing.
3. No configuration word at the top of the program.
4. Because of #3 the GP3 pin will default to MCLR. And without a pullup it will probably keep resetting the chip.
5. Because of #3 the watchdog timer will be enabled and keep resetting the chip.
6. Because of #3 T0CS defaults to 1. As pointed out above.
7. The use of "goto $-1". Use "goto label".
8. Lack of a shadow register for the output port. See the Read-Modify-Write problem. Much better to write to a shadow register and then copy that register to the output
 
On my windows 10 machine, I found file p10f200.inc in C:\Program Files (x86)\Microchip\MPASM Suite
If you don't have it let me know and I can post it.

I also find that starting with the Microchip template file helps.
File 10F200TEMP.ASM should be in C:\Program Files (x86)\Microchip\MPASM Suite\Template\Code
 
the datasheet said:
Some instructions operate internally as read followed
by write operations. The BCF and BSF instructions, for
example, read the entire port into the CPU, execute the
bit operation and rewrite the result. Caution must be
used when these instructions are applied to a port
where one or more pins are used as input/outputs. For
example, a BSF operation on bit 2 of GPIO will cause
all eight bits of GPIO to be read into the CPU, bit 2 to
be set and the GPIO value to be written to the output
latches. If another bit of GPIO is used as a bidirectional
I/O pin (say bit 0), and it is defined as an input at this
time, the input signal present on the pin itself would be
read into the CPU and rewritten to the data latch of this
particular pin, overwriting the previous content. As long
as the pin stays in the Input mode, no problem occurs.
However, if bit 0 is switched into Output mode later on,
the content of the data latch may now be unknown

Even though the lack of include file the program should work however!! I found this.. Weird or what.

Basically its better to write the whole port in one...
 
Diver300
Attached is the .inc file from MPLAB9.82. File date = 03/10/13. Just change the extension and it should work.
Ian Rogers
That quote seems to describe the read-modify-write (RMW) problem inherent in PIC's. Later PIC's avoid it by having LATx registers (latch). Adage: "read a port, write a latch." The usual workaround is to use a shadow register and byte instructions, like movwf in this instance. However, RMW becomes a problem only when driving capacitive loads that may change state slowly, and many programmers/compilers (including C, I believe) still use bit instructions. The problem as reported is not with the other pins doing funny stuff, but GP2 not doing as expected, I think Pommie is on the right track. Something is not set right.
 

Attachments

  • PIC10F200.txt
    4.9 KB · Views: 298
That quote seems to describe the read-modify-write (RMW) problem inherent in PIC's. Later PIC's avoid it by having LATx registers (latch). Adage: "read a port, write a latch." The usual workaround is to use a shadow register and byte instructions, like movwf in this instance. However, RMW becomes a problem only when driving capacitive loads that may change state slowly, and many programmers/compilers (including C, I believe) still use bit instructions. The problem as reported is not with the other pins doing funny stuff, but GP2 not doing as expected, I think Pommie is on the right track. Something is not set right.
Yup I know.. But that was specifically about a BSF BCF instruction AND specifically about GP2..

BTW Howdy John.. Nice to see you back! I've missed you here!!
 
Thanks to Pommie, I've realised that I had missed that TOCS / TOCKI has to be disabled, and now that I have set the option register, GP2 is working.

The configuration bits had been set in MPLAP, and I had a pull-up resistor on the MCLR pin, as the code was running.

I also found the .inc file, so I've now made the code a bit more readable.

Code:
    include p10f200.inc

    __config    0x0FFB        ; Watchdog off, code protection off, MCLR enabled

delay_reg equ 0x10

    org 0

    nop
    nop

    nop
    nop

    clrf    OSCCAL

    movlw    0x00
    tris    6   

    movlw    0xDF
    option

loop

    bsf        GPIO, 2
    nop
    bsf        GPIO, 1
    nop       
    bsf        GPIO, 0

    decfsz    delay_reg, f
    goto    $-1

    bcf        GPIO, 2
    nop
    bcf        GPIO, 1
    nop       
    bcf        GPIO, 0

    decfsz    delay_reg, f
    goto    $-1

    goto    loop

    end

This was only a quick test to see if the hardware worked, so I don't think that any of the code will be used.

While I agree with most of what upand_at_them said, I find it easier to use "goto $-1" for jumps that just go back one line. For longer jumps a label is better. On the 24F and 32F processors, there is the "repeat #n" command that repeats the following line n time, and there no need of a label for that.

Also using a shadow register is a good way to avoid the read-modify-write problem, but one register is 1/16th of the available RAM on an 10F200, and I think it's just as effective to make sure that bitwise port operations are separated by at least one line of code.
 
I find it easier to use "goto $-1" for jumps that just go back one line.
That works fine until you switch to an 18 (or higher) series chip.

RMW problems only appear (IMHO) when the port pin is overloaded or has a capacitive load (overloaded too?) - an LED without a series resistor seems to be the main culprit. Also caused by leaving the port as analogue.

My personal hate is using a hex value for the config value. How is anyone to know what that means?

Mike.
Edit, BTW, how does repeat #n fix anything?
 
That works fine until you switch to an 18 (or higher) series chip.

RMW problems only appear (IMHO) when the port pin is overloaded or has a capacitive load (overloaded too?) - an LED without a series resistor seems to be the main culprit. Also caused by leaving the port as analogue.

My personal hate is using a hex value for the config value. How is anyone to know what that means?

Mike.
Edit, BTW, how does repeat #n fix anything?

An 18 series chip has code that is quite different and and code for 10F - 16F pics can't be used directly, so I don't think that there is much point in worrying about 18 series processors when writing for the lower series of processors.

RMW has been a problem for me when running a processor at MHz speeds, but not when it's running at 30 kHz.

With the normal 8 bit processors, a instruction is executed every 4 clock cycles, and the reading of the register is at the beginning of the four clock cycles, with the writing at the end. If there are two subsequent port operations, the writing from the first operation is on one clock cycle before the reading part of the second operation, giving little time for the pin voltage to stabilise.

I wouldn't have thought that the RMW problem would be an issue with an analogue input, because it doesn't matter what is written to the port when it's an input.

I do have clearer ways of doing the config for more complicated processors, but this one only has three config bits. I set the values that I want in MPLAB, which gives me the hex value that I need in the code. I don't often change the config bits.

I only mentioned the repeat #N instruction to illustrate labels aren't really needed for vey short jumps.
 
I wouldn't have thought that the RMW problem would be an issue with an analogue input, because it doesn't matter what is written to the port when it's an input.
If the port is left as analogue then any analogue pin will always read zero even if set to output. This appears like a RMW type error even though it isn't.

Using goto $±n is a habit that people get used to. This is habit forming and produce unreadable code and a change of processors does not get people out of the habit and they'll still use goto $-1 to skip back an instruction with disastrous consequences. I always use a label - and a meaningful one - outputLoop instead of loop etc. - more typing but less likely a bug and much more readable code.

On the use of hex in config statements, I know what config WDT_OFF (syntax?) does but without knowing the processor (intimately ), I've no idea what the individual bit do. This is much preferred when asking for help on a forum as people are far more likely to spot an error is they can understand the code.

Mike.
 
On the use of hex in config statements, I know what config WDT_OFF (syntax?) does but without knowing the processor (intimately ), I've no idea what the individual bit do. This is much preferred when asking for help on a forum as people are far more likely to spot an error is they can understand the code.

Mike.
I had realised that most people won't know the processor very well. That was why I had added the comment which stated the config settings. The 10F200 only has three.
 
BTW, If you don't have a *.INC file, you can just declare them at the start of the PGM by consulting the Register file Data memory map.
.
e.g.
STATUS equ 0x02
GPIO equ 0x03

etc, etc.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top