Question

Stackoverflow, you've helped me before, I think I need your help again. I'm trying to bit-bang my own serial out using a GPIO on a PIC18F2550. This connects to some shift registers (3x74LS595), where the last one connects to a standard HD44780 LCD. So far I have the clocking and latching working right, and after a long fight, the data is now being spit out correct as well (turns out barrel shifting doesn't work out well and the thing will gladly spit out data out of bounds but I digress).

My problem is that to use the LCD I need to toggle the enable pin as a data clock, so to save code I simply nested another loop that runs twice and toggles the enable flag while spitting out the same byte otherwise. This should theoretically double the amount of bytes being spat out from 12 to 24. For whatever reason, when this loop is added it doesn't work. It just spits out two bytes and quits. Without it, it spits out all 12 bytes fine (though the LCD doesn't set up properly because the enable isn't there).

Here's a picture of it working, without the nested enable loop:

Linked because lack of rep

D0 is data and D1/2 underneath is clock/load respectively.

And here it is with the for loop:

Linked because lack of rep

That edge on the far left is the initial reset of the line. I know it's done after those two bytes because it beeps the little buzzer I have that indicates all the meaningful code is done.

Here's a code dump:

//First testing program for PIC18F2550

#include <p18f2550.h>
#include <stdlib.h>
#include <delays.h>

#define _XTAL_FREQ 4915200 
#pragma config PLLDIV = 1
#pragma config CPUDIV = OSC1_PLL2
#pragma config FOSC = XT_XT
#pragma config MCLRE = ON
#pragma config BOR = OFF
#pragma config WDT = OFF
#pragma config IESO = OFF
#pragma config PBADEN = OFF
#pragma config LVP = OFF

unsigned char setupstream[12] = {0b0011, 0b0011, 0b0011, 0b0010, 0b0010, 0b1000, 0b0000, 0b0001, 0b0000, 0b1111, 0b0000, 0b0110};
unsigned char teststream[6] = {0xF0, 0x00, 0xFF, 0x00, 0xFF, 0x00};
unsigned char letterstream[2] = {0b0010, 0b0001};
unsigned char c1 = 0, c2 = 0, c3 = 0, outreg = 0, outmask = 0, feedout = 0;


void main(void){

//CONFIG4L = 0b01000001;
UCONbits.USBEN=0;
UCFGbits.UTRDIS=1;
//OSCCONbits.IRCF2=1;
//OSCCONbits.IRCF1=1;
//OSCCONbits.IRCF0=1;
OSCCONbits.SCS1 = 0;
OSCCONbits.SCS0 = 0;
BAUDCONbits.TXCKP=0;
SPBRG = 0x3F;  //1200 baud
TRISA = 0x00;
TRISB = 0xFF;
TRISC = 0x00;     

LATCbits.LATC0 = 1;     //Start: beep the speaker
Delay10KTCYx(8);
LATCbits.LATC0 = 0; 
Delay10KTCYx(8);

LATA = 0;               //reset
Delay10KTCYx(8);
LATAbits.LATA2 = 1;     //load the reset
Delay10KTCYx(8);
LATAbits.LATA3 = 1;     //stop reset
LATAbits.LATA2 = 0;
Delay10KTCYx(123);

for(c1==0; c1<12; c1++){
    for(c2==0; c2<2; c2++){
        outreg = setupstream[c1] << 2;  //nibble of data needs to be in the middle
        //outreg |= 0b00000010;         //set flags  
        //outreg ^= 0b00000001; 

        outmask = 0x80;                 
        for(c3=0; c3<8; c3++){
            LATAbits.LATA0 = (outreg & outmask) ? 1:0;
            outmask >>=1;           

            Delay10KTCYx(8);
            LATAbits.LATA1 = 1;     //clock the data out
            Delay10KTCYx(8);
            LATAbits.LATA1 = 0;             
        }

        Delay10KTCYx(8);        
        LATAbits.LATA2 = 1;         //one byte fed out; load it into shift regs
        Delay10KTCYx(8);
        LATAbits.LATA2 = 0;
    }
}

LATAbits.LATA0 = 0;   //Done, clear the line and 
LATCbits.LATC0 = 1;   //Beep the speaker
Delay10KTCYx(8);
LATCbits.LATC0 = 0; 
Delay10KTCYx(8);    

while(1){  //Idle
}
}

In the above code I even disabled the toggling to see if it would spit out all the bytes. Guess not. I'm seriously considering just doing this all in assembly because with C I've been having a ton of problems with seemingly simple stuff; it feels like I have no control over what's going on in the background of this thing. I'm using Pickit 3 but I might just have to dig out the ICD2 if I want a good idea of what's actually going on.

Was it helpful?

Solution

try initialsing the for loop variables with assignment (single =) rather than comparison ( double == )

use

for(c1=0; c1<12; c1++){
    for(c2=0; c2<2; c2++){

instead of

for(c1==0; c1<12; c1++){
    for(c2==0; c2<2; c2++){
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top