2
\$\begingroup\$

I am working on a VGA driver for a PIC 24F microcontroller. I have set all B and C ports for OUTPUT with TRISB = 0 and TRISC = 0. After scoping I noticed that one of my pins always stays high after it is set only once, while the other pins react correctly.

More specific, PORTCbits.RC3 = 0 and PORTCbits.RC3 = 1 works perfectly fine, PORTCbits.RC4 = 1 works but stays high after the first toggle, and PORTCbits.RC4 = 0 does nothing.

The processor I am using is a PIC 24FJ64GA004, if this is relevant. All ports are configured in the same way via the tris registers and cleared beforehand.

Sorry if this question is not general enough, this is my first time asking something on this site.

\$\endgroup\$
  • \$\begingroup\$ Sounds like that specific pin on that specific PIC is defective. Have you tried swapping it out for another one of the exact same type? Is the problem reproducible there? \$\endgroup\$ – Mels Nov 20 '13 at 13:38
  • 1
    \$\begingroup\$ What happens if you write to LATCbits instead of PORTCbits? I haven't used PIC24 specifically, but this looks like a possible read-modify-write problem. \$\endgroup\$ – Tut Nov 20 '13 at 13:40
  • \$\begingroup\$ I have already tried to use the LATC bits, but that didnt help. Swapping out the pin would propably help because the other pins do seem to work (although I didnt measure all of them), but the board was presoldered with signal converters and these are the only pins available so I cant use others. \$\endgroup\$ – AEIO Nov 20 '13 at 14:08
  • 1
    \$\begingroup\$ Ok ... not the solution, but I still highly recommend you use the LAT registers when outputting. That is what they are there for. It keeps the read portion of read-modify-write internal to the chip ... more reliable. \$\endgroup\$ – Tut Nov 20 '13 at 14:26
  • \$\begingroup\$ I meant replacing the whole PIC, not the pin. Just to eliminate a hardware defect as the root cause. \$\endgroup\$ – Mels Nov 20 '13 at 15:09
1
\$\begingroup\$

I'd recommend that you check the datasheet and see if there are any errata associated with that particular micro.

From what I know (in the past), the case used to be where I would have to read/modify/write and then (in some cases) write twice to a port to ensure that it took.

Aside from that, can you isolate the port to ensure that nothing else is influencing that port pin? If you have a development board with NOTHING connected to that port, it might be worth a try to run the code there and see whether or not it is externally influenced or not.

\$\endgroup\$
1
\$\begingroup\$

PIC pins are 'multi-use' and may be (default) assigned to USART OSC I2C etc etc ect ... if it's not that, then often the reason why i/o port bits get 'stuck' is down to the loading on the pin ...

However the trick is to recognise that you don't have time during the VGA 640 pixel visible line to 'count' or 'loop' at all .. and for sure not enough time to 'bit bang' an i/o pin !!!

However add an external shift register (74HC166) and set that up to 'load' 1 byte at a time from 8 PIC i/o pins and it becomes possible to show a 80 FONT mapped (8x8) ascii characters in each of 48 lines.

You clock the shift reg at 24MHz (which is within most VGA display limits) and run the PIC with a CPU clk (OSC/2) of 15 MHz (so OSC is 30MHz) and that gets you 'exactly' 5 CPU cycles to update the byte i/o pins.

5 CPU cycles means no counting, calling, returning or any other useless time wasting. Instead we 'build' the 8x8 character font table out of 'sets' of 5 instructions that output a byte to the i/o pins and then 'jump' to the next font location that needs to output.

So each entry in the font table contains 8 sets 5 instructions that 'output a byte' and then 'find the next byte' ... specifically :-

Load litteral byte to W, Output W byte to PORT (2)

Load W word from Index++, Add W word to PCL (3)

To 'control' this sequence you load 80 Index registers with the offsets that takes the execution from one font location to the next. The last Index register contains an offset that takes you to the Line Sync code, during which time you have to load the Index registers for the next line to be output i.e. mod the contents of the 80 Index registers with 80 new offsets.

Within one line of characters, 'mod the Index registers' means re-setting the FIRST so it 'points' at the next 'font line table start' (i.e. next scan 'line down in the font) - all the other jumps are 'relative' so stay the same.

If you are displaying 8x8 character fonts you will typically have a 2 raster scanline inter-character-line 'gap' (so 480 scan lines will show 48 lines of 80 character text) and 2 lines is plenty of time to work out the 'relative offsets' for the next set of 80 of characetrs.

Note this is for single color B&W text == it can't do even B&W 'wire-frame' bit-mapped graphics without the help of external RAM (8kb is not enough space to store all the bit-map data, you need at least 640*480/8 = 38,400 bytes)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.