How to Program Parallel Slave Port (PSP) in PIC16F877A

The following code demonstrate how to use parallel slave port module. The controller offers a mechanism by which an 8-bit parallel bidirectional data transfer can be achieved between a PIC16F877A and other PSP supporting devices. The PIC16F877A's Port-D and Port-E are used in this data transfer. For this data transfer, Port-D is configured as a parallel slave port (PSP) by setting bit-4 of TRISE Register. The pins of Port-E function as control pins for data transfer. The code is written in “mikroC PRO for PIC v.6.6.3” IDE and simulation is done with Proteus 8.0 SP0. At the end of code, you can find complete project files for download.





UUT Code in mikroC

// function proto-type
void PSP_Setting(void);
void main(void)
{
// portb as input port
TRISB = 0xFF;
// portc as output port
TRISC = 0x00;
// portc init to 0x00
PORTC = 0x00;
PSP_Setting();
while(1)
{
// write request to PSP
if(TRISE.IBF == 1)
{
PORTC = PORTD;
// auto clear TRISE.IBF
}
// read request from PSP
// TRISE.IBF == 0
else
{
PORTD = PORTB;
}
}
}
void PSP_Setting(void)
{
// select porte as digital i/o
ADCON1.PCFG3 = 0;
ADCON1.PCFG2 = 0;
ADCON1.PCFG1 = 1;
ADCON1.PCFG0 = 0;
// enable PSP mode
TRISE.PSPMODE = 1;
// clear input buffer overflow error
TRISE.IBOV = 0;
// clear output buffer full bit
TRISE.OBF = 0;
// clear input buffer full bit
TRISE.IBF = 0;
}

PSP Tester Code in mikroC

sbit nRD_Dir at TRISB.B0;
sbit nWR_Dir at TRISB.B1;
sbit nCS_Dir at TRISB.B2;
sbit WR_RD_SEL_Dir at TRISB.B7;
sbit nRD at PORTB.B0;
sbit nWR at PORTB.B1;
sbit nCS at PORTB.B2;
sbit WR_RD_SEL at PORTB.B7;
//void PSP_Setting(void);
void WriteActive(void);
void ReadActive(void);
void IdleBus(void);
void main(void)
{
unsigned char count = 0x00;
unsigned char read_buf = 0x00;
// direction as output
nRD_Dir = 0;
nWR_Dir = 0;
nCS_Dir = 0;
// direction as input
WR_RD_SEL_Dir = 1;
// init to 1 because all signals are
// active low
nRD = 1;
nWR = 1;
nCS = 1;
// portc as output port
TRISC = 0x00;
// portc init to 0x00
PORTC = 0x00;
// make as output
TRISD = 0x00;
Delay_ms(1);
// pulse to init PSP
WriteActive();
while(1)
{
if(WR_RD_SEL == 1)
{
// make as output
TRISD = 0x00;
Delay_ms(1);
// data write to PSP
WriteActive();
PORTD = count++;
Delay_ms(5);
// idle bus
IdleBus();
Delay_ms(10);
}
if(WR_RD_SEL == 0)
{
// make as input
TRISD = 0xFF;
Delay_ms(1);
// data read from PSP
ReadActive();
read_buf = PORTD;
PORTC = read_buf;
Delay_ms(5);
// idle bus
IdleBus();
Delay_ms(10);
}
}
}
void PSP_Setting(void)
{
// select porte as digital i/o
ADCON1.PCFG3 = 0;
ADCON1.PCFG2 = 0;
ADCON1.PCFG1 = 1;
ADCON1.PCFG0 = 0;
// enable PSP mode
TRISE.PSPMODE = 1;
// clear input buffer overflow error
TRISE.IBOV = 0;
// clear output buffer full bit
TRISE.OBF = 0;
// clear input buffer full bit
TRISE.IBF = 0;
}
void WriteActive(void)
{
nRD = 1;
nWR = 0;
nCS = 0;
Delay_us(100);
}
void ReadActive(void)
{
nRD = 0;
nWR = 1;
nCS = 0;
Delay_us(100);
}
void IdleBus(void)
{
nRD = 1;
nWR = 1;
nCS = 1;
Delay_us(100);
}

Download Files

For download “mikroC PRO for PIC” project and “Proteus 8.0” simulation files, click here.


Comments

Popular posts from this blog

How to Program Interrupts in PIC16F877A

How to Program SPI in PIC16F877A (Slave Mode)