LCD interfacing with PIC16f877A (ambiguity)

Thread Starter

irilias

Joined Jul 3, 2012
6
i just have a little problem understanding some lines in CCS C code that i have for a sphygmomanometer project & i'm not sure if i actually wired the pic16f877a (with the LCD) correctly or not ..

My reasoning was as follows:
#define lcd_e1 pin_d7 => i wired the "Enable" LCD pin to the pic pin 30 (RD7/PSP7)

#define lcd_rs1 pin_d6 => i wired the "Register Select" LCD pin to pic pin 29 (RD6/PSP6)

#define lcd_port output_b => i wired the LCD's Data pins (DB0,DB1,DB2, ... DB7) to the pic's (pin 33,pin34,pin35,...pin40) in order (which represent RB0 to RB7)

putcmd_lcd(0x38);

// sending the 0X38 to the LCD means :
( Function Set: 8bit, 2Line, 5x7 Dots ) and that's exactly the reason why i wired the whole 8 lines (and not jut 4) because i think we're using the 8 bit mode of operation .

* these are the lines that i couldn't understand :

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
do i have to wire the pins C6 & C7 ??
#define lcd_direction set_tris_b
#define lcd_command set_tris_c
and the function : lcd_port()

i did read the CCS C manual but i couldn't figure out what their actual purpose is ?

i'm new at this so please bear with me (and excuse my poor english,it's not my native language).. any help at all would be much appreciated, Thanks in advance .

Code :
Rich (BB code):
#include<16f877a.h>
#fuses hs,nowdt, noprotect, nolvp
#use delay(clock=10000000)
#include<math.h>
#include<string.h>
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#define lcd_e1 pin_d7
#define lcd_rs1 pin_d6
#define lcd_port output_b
#define lcd_direction set_tris_b
#define lcd_command set_tris_c

int mmc_init();
int mmc_response(unsigned char response);
int mmc_write_block(unsigned long block_number);

void init_lcd();//preparation de pic pour lcd
void putdata_lcd(int valued);
void erase_lcd();
void putcmd_lcd(int valuec);
void goto_lcd(int x, int y);
void put_string_lcd(char v[16]);

/* Initialises the MMC into SPI mode and sets block size, returns 0 on success */
......
/***************/

void init_lcd()
{putcmd_lcd(0x38);
delay_ms(6);
putcmd_lcd(0x38);
delay_ms(6);
putcmd_lcd(0x38);
delay_ms(6);
putcmd_lcd(0x01); //reset
delay_ms(6);
putcmd_lcd(0x06); //increment
delay_ms(6);
putcmd_lcd(0x0c);
delay_ms(6);}

void putdata_lcd(int valued)
{lcd_port(valued);
output_high(lcd_rs1); //data
output_high(lcd_e1);
delay_ms(1);
output_low(lcd_e1);
delay_ms(6);
output_low(lcd_rs1); //command
}

void erase_lcd()
{putcmd_lcd(0x01);}

void putcmd_lcd(int valuec)
{lcd_port(valuec);
output_low(lcd_rs1);
output_high(lcd_e1);
delay_ms(1);
output_low(lcd_e1);
delay_ms(6);}

void goto_lcd(int x, int y)
{ if (y==1)
{putcmd_lcd(0x80 + x);}
if (y==2)
{putcmd_lcd(0xc0 + x);}}

void put_string_lcd(char v[16])
{long i;
for(i=0;i<=strlen(v);i++)
putdata_lcd(v);}
 

BMorse

Joined Sep 26, 2009
2,675
i just have a little problem understanding some lines in CCS C code that i have for a sphygmomanometer project & i'm not sure if i actually wired the pic16f877a (with the LCD) correctly or not ..

My reasoning was as follows:
#define lcd_e1 pin_d7 => i wired the "Enable" LCD pin to the pic pin 30 (RD7/PSP7)

#define lcd_rs1 pin_d6 => i wired the "Register Select" LCD pin to pic pin 29 (RD6/PSP6)

#define lcd_port output_b => i wired the LCD's Data pins (DB0,DB1,DB2, ... DB7) to the pic's (pin 33,pin34,pin35,...pin40) in order (which represent RB0 to RB7)

putcmd_lcd(0x38);

// sending the 0X38 to the LCD means :
( Function Set: 8bit, 2Line, 5x7 Dots ) and that's exactly the reason why i wired the whole 8 lines (and not jut 4) because i think we're using the 8 bit mode of operation .

* these are the lines that i couldn't understand :

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
do i have to wire the pins C6 & C7 ??
#define lcd_direction set_tris_b
#define lcd_command set_tris_c
and the function : lcd_port()

i did read the CCS C manual but i couldn't figure out what their actual purpose is ?

i'm new at this so please bear with me (and excuse my poor english,it's not my native language).. any help at all would be much appreciated, Thanks in advance .

Code :
Rich (BB code):
#include<16f877a.h>
#fuses hs,nowdt, noprotect, nolvp
#use delay(clock=10000000)
#include<math.h>
#include<string.h>
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#define lcd_e1 pin_d7
#define lcd_rs1 pin_d6
#define lcd_port output_b
#define lcd_direction set_tris_b
#define lcd_command set_tris_c

int mmc_init();
int mmc_response(unsigned char response);
int mmc_write_block(unsigned long block_number);

void init_lcd();//preparation de pic pour lcd
void putdata_lcd(int valued);
void erase_lcd();
void putcmd_lcd(int valuec);
void goto_lcd(int x, int y);
void put_string_lcd(char v[16]);

/* Initialises the MMC into SPI mode and sets block size, returns 0 on success */
......
/***************/

void init_lcd()
{putcmd_lcd(0x38);
delay_ms(6);
putcmd_lcd(0x38);
delay_ms(6);
putcmd_lcd(0x38);
delay_ms(6);
putcmd_lcd(0x01); //reset
delay_ms(6);
putcmd_lcd(0x06); //increment
delay_ms(6);
putcmd_lcd(0x0c);
delay_ms(6);}

void putdata_lcd(int valued)
{lcd_port(valued);
output_high(lcd_rs1); //data
output_high(lcd_e1);
delay_ms(1);
output_low(lcd_e1);
delay_ms(6);
output_low(lcd_rs1); //command
}

void erase_lcd()
{putcmd_lcd(0x01);}

void putcmd_lcd(int valuec)
{lcd_port(valuec);
output_low(lcd_rs1);
output_high(lcd_e1);
delay_ms(1);
output_low(lcd_e1);
delay_ms(6);}

void goto_lcd(int x, int y)
{ if (y==1)
{putcmd_lcd(0x80 + x);}
if (y==2)
{putcmd_lcd(0xc0 + x);}}

void put_string_lcd(char v[16])
{long i;
for(i=0;i<=strlen(v);i++)
putdata_lcd(v);}



From what you described with the pin configuration, it seems you have everything wired correctly, as for C6 and C7, apparently the original code included the use of the serial port, this does not need to be connected to the LCD, this is meant to transmit serial data, which was most likely used for debugging purposes by the original author to see data on a PC app such as Hyperterminal or Putty.... if you could post all of the original code I may be able to tell you exactly what it was used for....
 

Thread Starter

irilias

Joined Jul 3, 2012
6
thank you so much for your quick reply, & what about the #define lcd_direction set_tris_b
#define lcd_command set_tris_c
and the function : lcd_port()

( i know that "set_tris_b" as a command could set the port B as a PORT OUT or IN ...)

Thank you again, i really appreciate it
 

Thread Starter

irilias

Joined Jul 3, 2012
6
here's the Original CODE
Rich (BB code):
#include<16f877a.h>
#fuses hs,nowdt, noprotect, nolvp
#use delay(clock=10000000)
#include<math.h>
#include<string.h>
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#define lcd_e1 pin_d7
#define lcd_rs1 pin_d6
#define lcd_port output_b//b=sortie
#define lcd_direction set_tris_b
#define lcd_command set_tris_c
int mmc_init();
int mmc_response(unsigned char response);
int mmc_write_block(unsigned long block_number);
void init_lcd();//preparation de pic pour lcd
void putdata_lcd(int valued);
void erase_lcd();
void putcmd_lcd(int valuec);
void goto_lcd(int x, int y);
void put_string_lcd(char v[16]);
/**/
/* Initialises the MMC into SPI mode and sets block size, returns 0 on success */

int mmc_init()
{
int i;
SETUP_SPI(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_4 | SPI_SS_DISABLED);
*0x94 |= 0x40; // set CKE = 1 - clock idle low
*0x14 &= 0xEF; // set CKP = 0 - data valid on rising edge
OUTPUT_HIGH(PIN_C2); // set SS = 1 (off)
for(i=0;i<10;i++) // initialise the MMC card into SPI mode by sending clks on
{
SPI_WRITE(0xFF);
}
OUTPUT_LOW(PIN_C2); // set SS = 0 (on) tells card to go to spi mode when it receives reset
SPI_WRITE(0x40); // send reset command
SPI_WRITE(0x00); // all the arguments are 0x00 for the reset command
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x95); // precalculated checksum as we are still in MMC mode

puts("Sent go to SPI\n\r");

if(mmc_response(0x01)==1) return 1; // if = 1 then there was a timeout waiting for 0x01 from the mmc

puts("Got response from MMC\n\r");

i = 0;
while((i < 255) && (mmc_response(0x00)==1)) // must keep sending command if response
{
SPI_WRITE(0x41); // send mmc command one to bring out of idle state
SPI_WRITE(0x00); // all the arguments are 0x00 for command one
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0xFF); // checksum is no longer required but we always send
0xFF
i++;
}

if(i >= 254) return 1; // if >= 254 then there was a timeout waiting for 0x00 from the mmc

puts("Got out of idle response from MMC\n\r");

OUTPUT_HIGH(PIN_C2); // set SS = 1 (off)
SPI_WRITE(0xFF); // extra clocks to allow mmc to finish off what it is doing
OUTPUT_LOW(PIN_C2); // set SS = 0 (on)
SPI_WRITE(0x50); // send mmc command one to bring out of idle state
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x02); // high block length bits - 512 bytes
SPI_WRITE(0x00); // low block length bits
SPI_WRITE(0xFF); // checksum is no longer required but we always send 0xFF

if((mmc_response(0x00))==1) return 1;

OUTPUT_HIGH(PIN_C2); // set SS = 1 (off)
puts("Got set block length response from MMC\n\r");
return 0;
}

/************************** MMC Write Block **************************************/
int mmc_write_block(unsigned long block_number)
{
unsigned long i;
unsigned long varh,varl;
char p,f,n;
set_adc_channel(0);
delay_us(10);
f=read_adc();
n=(f*5)/256;
p=(n*9375)/206;
varl=((block_number&0x003F)<<9);
varh=((block_number&0xFFC0)>>7);
puts("Write block\n\r"); // block size has been set in mmc_init()
OUTPUT_LOW(PIN_C2); // set SS = 0 (on)

SPI_WRITE(0x58); // send mmc write block
SPI_WRITE(varh);
SPI_WRITE(varl);
SPI_WRITE(0x00); // always zero as mulitples of 512
SPI_WRITE(0xFF); // checksum is no longer required but we always send 0xFF

if((mmc_response(0x00))==1) return 1;

puts("Got response to write block\n\r");
SPI_WRITE(0xFE); // send data token

for(i=0;i<512;i++)
{
SPI_WRITE(p); // send data
}

SPI_WRITE(0xFF); // dummy CRC
SPI_WRITE(0xFF);

if((SPI_READ(0xFF)&0x0F)!=0x05) return 1;

puts("Got data response to write block\n\r");
OUTPUT_HIGH(PIN_C2); // set SS = 1 (off)
return 0;
}

/************************** MMC get response **************************************/
/**** Repeatedly reads the MMC until we get the response we want or timeout ****/
int mmc_response(unsigned char response)
{
unsigned long count = 0xFFFF; // 16bit repeat, it may be possible to shrink this to 8 bit but there is not much point

while(SPI_READ(0xFF) != response && --count > 0);

if(count==0) return 1; // loop was exited due to timeout
else return 0; // loop was exited before timeout
}
/*******************************************************************************************/

void init_lcd()

{putcmd_lcd(0x38);
delay_ms(6);
putcmd_lcd(0x38);
delay_ms(6);
putcmd_lcd(0x38);
delay_ms(6);
putcmd_lcd(0x01);//reset
delay_ms(6);
putcmd_lcd(0x06);//increment
delay_ms(6);
putcmd_lcd(0x0c);
delay_ms(6);}

void putdata_lcd(int valued)

{lcd_port(valued);
output_high(lcd_rs1);//data
output_high(lcd_e1);
delay_ms(1);
output_low(lcd_e1);
delay_ms(6);
output_low(lcd_rs1);//command
}

void erase_lcd()

{putcmd_lcd(0x01);}

void putcmd_lcd(int valuec)
{lcd_port(valuec);
output_low(lcd_rs1);
output_high(lcd_e1);
delay_ms(1);
output_low(lcd_e1);
delay_ms(6);}

void goto_lcd(int x, int y)
{ if (y==1)
{putcmd_lcd(0x80 + x);}
if (y==2)
{putcmd_lcd(0xc0 + x);}}

void put_string_lcd(char v[16])

{long i;
for(i=0;i<=strlen(v);i++)
putdata_lcd(v);}

void print()

{char v[16];
init_lcd();
goto_lcd(4,1);
sprintf(v,"Working!");
put_string_lcd(v);
goto_lcd(2,2);
sprintf(v,"Please wait!");
put_string_lcd(v);}

void delay()
{delay_ms(500);}

void main()

{long sy;
float s,f,p,n,m;
char v[16];
sy=0;
mmc_init();
lcd_direction(0x00);
lcd_command(0x00);
set_tris_d(0x00);
setup_adc_ports( all_analog );
setup_adc(ADC_CLOCK_DIV_2);

//start deflate

start:
set_adc_channel(0);
delay_us(10);

s=read_adc();

if (s>25){
output_high(pin_d3);
output_low(pin_d2);
goto start;}

output_low(pin_d3);
delay_ms(100);
print();
delay_ms(3000);

//inflate state

init_lcd();
goto_lcd(0,1);
sprintf(v,"pressure=");
put_string_lcd(v);

inflate:

set_adc_channel(0);
delay_us(10);
f=read_adc();
n=(f*5)/256;
p=(n*9375)/206;
goto_lcd(9,1);
sprintf(v,"%fummHg",p);
put_string_lcd(v);
if (f<178){
output_high(pin_d2);
goto inflate;}
output_low(pin_d2);

//deflate state

deflate:

set_adc_channel(1);
delay_us(10);
s=read_adc();
output_high(pin_d3);
delay_ms(100);
output_low(pin_d3);
delay_ms(100);

if (s>205){
sy++;}

if (sy<4){
goto deflate;}

set_adc_channel(0);
delay_us(10);
f=read_adc();
n=(f*5)/256;
p=(n*9375)/206;
mmc_write_block(1);
init_lcd();
goto_lcd(0,1);
sprintf(v,"Sys pres =");
put_string_lcd(v);
goto_lcd(0,2);
sprintf(v,"%fummHg",p);
put_string_lcd(v);
delay_ms(100);

//diastole

diastole:

output_high(pin_d3);
delay_ms(100);
output_low(pin_d3);
delay_ms(100);
set_adc_channel(1);
delay_us(10);

s=read_adc();

if (s>128)
{delay();
goto diastole;}
set_adc_channel(0);
delay_us(10);
f=read_adc();
n=(f*5)/256;
m=(n*9375)/206;
mmc_write_block(10);
init_lcd();
goto_lcd(0,1);
sprintf(v,"Diast pres =");
put_string_lcd(v);
set_adc_channel(0);
goto_lcd(0,2);
sprintf(v,"%fummHg",m);
put_string_lcd(v);

end:

set_adc_channel(0);
delay_us(10);
s=read_adc();

if (s>25)
{output_high(pin_d3);
goto end;}
output_low(pin_d3);}
 
Top