What instructions can I use to set a VIA output pin low and then high with the shortest possible time between the low and high transitions, please? I will study the Datasheet but thought I might ask here as well.
I'd like to determine the RC time constant (tau) I'll need on a little 2-pin LCD backpack to be able to drive an HD44780 type LCD from a 1-MHz 6502 through a VIA chip. Backpack diagram and example Arduino program below to show how I use the backpack on PIC and Arduino systems.
TIA. Happy Holidays. Mike
Attachment:
LCD Backpack.png [ 171.09 KiB | Viewed 1733 times ]
Attachment:
rc timing.png [ 17.81 KiB | Viewed 1782 times ]
Code:
/******************************************************************
* Mike McLaren's 2-pin 8-bit 74HC595/74HC164 LCD Backpack Demo *
* *
* 16-Sep-18 Arduino 1.8.6 / Arduino Nano *
******************************************************************/
#define line1 (0x80+0x00) // set DDRAM command + line 1 address
#define line2 (0x80+0x40) // set DDRAM command + line 2 address
#define line3 (0x80+0x14) // set DDRAM command + line 3 address
#define line4 (0x80+0x54) // set DDRAM command + line 4 address
char Scramble [] = "AAAAAAAAA";
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~(1<<bit)) // clear bit
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= 1<<bit) // set bit
/******************************************************************
* *
******************************************************************/
#define clk PORTC2 // 'clk' on PC2 (A2) pin
#define lat PORTC3 // 'lat' on PC3 (A3) pin
class LCD : public Print
{ public: //
void init(); //
void cmd(uint8_t); //
size_t write(uint8_t); //
private: //
bool rs = 0; // lcd 'rs' flag
};
void LCD::init ()
{ DDRC = 1<<clk|1<<lat; // make 'clk' and 'lat' outputs
cbi(PORTC,lat); // lat = 0
sbi(PORTC,clk); // clk = 1
_delay_ms(100); // LCD power-on delay
cmd(0x38); // 8-bit, 2-lines, 5x7 font
cmd(0x0C); // display on, cursor & blink off
cmd(0x06); // cursor inc, shift off
cmd(0x01); // clear display
_delay_ms(2); // required delay
} //
size_t LCD::write (uint8_t work)
{ uint8_t bitctr = 8; //
uint8_t SaveSREG = SREG; //
do // start of bit clock cycle
{ if(!(work & 128)) // if b7 is a '0' bit
cbi(PORTC,clk); // start clock cycle for a '0'
_delay_us(9); // charge or drain cap to 3t
cli(); // interrupts off
cbi(PORTC,clk); // start clock cycle for a '1'
sbi(PORTC,clk); // clock out the '0' or '1'
SREG = SaveSREG; // restore SREG & irq enable bit
work <<= 1; // prep for next bit
} while(--bitctr); // until all 8 bits clocked out
if(!rs) cbi(PORTC,clk); // make clk pin = rs flag
sbi(PORTC,lat); // latch 595 & pulse LCD 'E' pin
cbi(PORTC,lat); // "
sbi(PORTC,clk); // always leave clk pin high
return 1; //
} //
void LCD::cmd (uint8_t c)
{ rs = 0; write(c); rs = 1; //
} //
/******************************************************************
* main *
******************************************************************/
LCD lcd; // create instance 'lcd' of LCD class
int main() //
{
lcd.init(); // 8-bit mode, cursor inc & off
/* *
* send a couple 'flash string helper' strings *
* */
lcd.print(F("K8LH Backpack")); // (44) 1st instance
lcd.print(F(" v2")); // (16) 2nd instance
lcd.cmd(line2+2); // line 2, tab 2 (6 bytes)
lcd.print(Scramble); // (40 bytes) 1st instance
lcd.cmd(line2+1); // line 2, tab 1 (6 bytes)
lcd.print(Scramble); // (8 bytes) 2nd instance
while(1) // loop forever
{ //
} //
} //