MCP23S17 weird problem

Discussion about projects that used PIC Microcontroller, Hardware Interface, Programming Algorithm and etc......

MCP23S17 weird problem

Postby shahrul » Tue Apr 09, 2013 9:17 am

I was interface LCD and keypad throught I/O Expander MCP23S17.
The code was successful read keypad and display LCD, but the problem is when I off and on it's cannot display.
Below schematic and code.
Untitled.jpg

CODE: SELECT_ALL_CODE
#define   SPI
#define   CS            RC0
#define   LCD            GPIOA
#define   KEYPAD         GPIOB
#define   MCP23S17_WRITE   0b01000000
#define   MCP23S17_READ   0b01000001
#define   IODIRA         0x00
#define   IODIRB         0x01
#define   IOCONA         0x0A
#define   IOCONB         0x0B
#define   GPPUA         0x0C
#define   GPPUB         0x0D
#define   GPIOA         0x12
#define   GPIOB         0x13
#define   LCD_RS          0
#define     LCD_RW         1
#define     LCD_EN          2
#define     LCD_LIGHT      3
#define   LCD_D4         4
#define   LCD_D5         5
#define   LCD_D6         6
#define   LCD_D7         7
#define     C1             0
#define     C2             1
#define     C3             2
#define     C4             3
#define     R1             4   
#define     R2             5   
#define     R3            6   
#define     R4             7

#include "LibraryHardware.h"
#include "LibraryPeripheral.h"

char lcd_data=0;

void pic_init();
void mcp23s17_init(char trisa, char trisb);
void mcp23s17_write(char address, char value);
char mcp23s17_read(char address);
void lcd_init(void);
void lcd_pulse();
void lcd_write(unsigned char c);
void lcd_goto(unsigned char pos, unsigned char row);
void lcd_string(const char *s);
void lcd_number(unsigned int no, char base, char digit);
char read_keypad(void);

main()
{char keypad;
pic_init();                  //initialize PIC
spi1_init();               //initialize SPI
mcp23s17_init(0x00,0x0F);      //initialize mcp23s17
lcd_init();                  //initialize LCD
for(;;){                  //loop forever
   keypad=read_keypad();

   lcd_goto(0,0);
   lcd_string("MCP23S17 HD44780");

   lcd_goto(0,1);
    switch(keypad){
        case 0:{lcd_string("    NO PRESS    ");break;}
        case 1:{lcd_string("  YOU PRESS 1   ");break;}
        case 2:{lcd_string("  YOU PRESS 2   ");break;}
        case 3:{lcd_string("  YOU PRESS 3   ");break;}
        case 4:{lcd_string("  YOU PRESS 4   ");break;}
        case 5:{lcd_string("  YOU PRESS 5   ");break;}
        case 6:{lcd_string("  YOU PRESS 6   ");break;}
        case 7:{lcd_string("  YOU PRESS 7   ");break;}
        case 8:{lcd_string("  YOU PRESS 8   ");break;}
        case 9:{lcd_string("  YOU PRESS 9   ");break;}
        case 10:{lcd_string("  YOU PRESS 0   ");break;}
        case 11:{lcd_string("  YOU PRESS *   ");break;}
        case 12:{lcd_string("  YOU PRESS #   ");break;}
        case 13:{lcd_string("  YOU PRESS A   ");break;}
        case 14:{lcd_string("  YOU PRESS B   ");break;}
        case 15:{lcd_string("  YOU PRESS C   ");break;}
        case 16:{lcd_string("  YOU PRESS D   ");break;}
    }
   }
}

void pic_init(){
TRISA=0b00000000;
TRISB=0b00000000;
TRISC=0b10000000;
TRISD=0b00000000;
TRISE=0b00000000;
set_digital();
PORTA=0b00000000;
PORTB=0b00000000;
PORTC=0b00000000;
PORTD=0b00000000;
PORTE=0b00000000;
CS=1;
}

void mcp23s17_init(char trisa, char trisb)
{int i;
CS=0;
spi1_write(MCP23S17_WRITE);   //Write
spi1_write(IOCONA);
spi1_write(0b00110000);   
spi1_write(0b00110000);   
CS=1;
__delay_us(1);
CS=0;
spi1_write(MCP23S17_WRITE);   //Write
spi1_write(GPPUA);
spi1_write(0b00000000);   
spi1_write(0b00000000);   
CS=1;
__delay_us(1);
CS=0;
spi1_write(MCP23S17_WRITE);   //Write
spi1_write(IODIRA);
spi1_write(trisa);      
spi1_write(trisb);      
CS=1;
__delay_us(1);
CS=0;
spi1_write(MCP23S17_WRITE);   //Write
spi1_write(0x02);
for(i=0;i<=7;i++) spi1_write(0b00000000);   //Address 0x02-0x09   
CS=1;
__delay_us(1);
CS=0;
spi1_write(MCP23S17_WRITE);   //Write
spi1_write(0x0E);
for(i=0;i<=3;i++) spi1_write(0b00000000);   //Address 0x0E-0x11   
CS=1;
__delay_us(1);
CS=0;
spi1_write(MCP23S17_WRITE);   //Write
spi1_write(GPIOA);      
spi1_write(0b00000000);   
spi1_write(0b00000000);
CS=1;
__delay_us(1);
}

void mcp23s17_write(char address, char value)
{
CS=0;
spi1_write(MCP23S17_WRITE);         //Write
spi1_write(address);      
spi1_write(value);   
CS=1;
__delay_us(1);
}

char mcp23s17_read(char address)
{char data;
CS=0;
spi1_write(MCP23S17_READ);   //Read
spi1_write(address);
data=spi1_read();
CS=1;
__delay_us(1);
return data;
}

void lcd_init(void)
{
delay_ms(15);            //delay for LCD Power Up
lcd_data=lcd_data|(1<<LCD_LIGHT);
lcd_write(0x28);          //function set
lcd_write(0x0C);          //display on/off control
lcd_write(0x06);          //entry mode set
lcd_write(0x01);         //clear screen
delay_ms(2);
}

void lcd_pulse()
{
lcd_data=lcd_data|(1<<LCD_EN);
mcp23s17_write(LCD,lcd_data);
lcd_data=lcd_data&~(1<<LCD_EN);
mcp23s17_write(LCD,lcd_data);
}

void lcd_write(unsigned char c)
{
if (((c>>4)&1)==1) lcd_data=lcd_data|(1<<LCD_D4);
else lcd_data=lcd_data&~(1<<LCD_D4);
if (((c>>5)&1)==1) lcd_data=lcd_data|(1<<LCD_D5);
else lcd_data=lcd_data&~(1<<LCD_D5);
if (((c>>6)&1)==1) lcd_data=lcd_data|(1<<LCD_D6);
else lcd_data=lcd_data&~(1<<LCD_D6);
if (((c>>7)&1)==1) lcd_data=lcd_data|(1<<LCD_D7);
else lcd_data=lcd_data&~(1<<LCD_D7);
mcp23s17_write(LCD,lcd_data);
lcd_pulse();

if (((c>>0)&1)==1) lcd_data=lcd_data|(1<<LCD_D4);
else lcd_data=lcd_data&~(1<<LCD_D4);
if (((c>>1)&1)==1) lcd_data=lcd_data|(1<<LCD_D5);
else lcd_data=lcd_data&~(1<<LCD_D5);
if (((c>>2)&1)==1) lcd_data=lcd_data|(1<<LCD_D6);
else lcd_data=lcd_data&~(1<<LCD_D6);
if (((c>>3)&1)==1) lcd_data=lcd_data|(1<<LCD_D7);
else lcd_data=lcd_data&~(1<<LCD_D7);
mcp23s17_write(LCD,lcd_data);
lcd_pulse();
delay_us(10);
}

void lcd_goto(unsigned char pos, unsigned char row)
{
lcd_data=lcd_data&~(1<<LCD_RS);
mcp23s17_write(LCD,lcd_data);

switch(row){
case 0:{lcd_write(0x80+pos);break;}
case 1:{lcd_write(0xC0+pos);break;}
case 2:{lcd_write(0x94+pos);break;}
case 3:{lcd_write(0xD4+pos);break;}}

lcd_data=lcd_data|(1<<LCD_RS);
mcp23s17_write(LCD,lcd_data);
}

void lcd_string(const char *s)
{
lcd_data=lcd_data|(1<<LCD_RS);
mcp23s17_write(LCD,lcd_data);            
while(*s) lcd_write(*s++);
}

void lcd_number(unsigned int no, char base, char digit)
{char i,j,di[10];
for(i=0;i<=9;i++) di[i]=0;
i=0;
do{
   di[i]=no%base;
   no=no/base;
   i=i+1;}
while(no!=0);
for(j=digit;j>0;j--){
   if(di[j-1]<=9) lcd_write(di[j-1]+'0');
   else lcd_write(di[j-1]-10+'A');}
}

char read_keypad(void)
{char data,i=0;
mcp23s17_write(KEYPAD,0b11101111);
data=mcp23s17_read(KEYPAD);
if(((data>>C1)&1)==0) i=i+1;
if(((data>>C2)&1)==0) i=i+2;
if(((data>>C3)&1)==0) i=i+3;
if(((data>>C4)&1)==0) i=i+13;

mcp23s17_write(KEYPAD,0b11011111);
data=mcp23s17_read(KEYPAD);
if(((data>>C1)&1)==0) i=i+4;
if(((data>>C2)&1)==0) i=i+5;
if(((data>>C3)&1)==0) i=i+6;
if(((data>>C4)&1)==0) i=i+14;

mcp23s17_write(KEYPAD,0b10111111);
data=mcp23s17_read(KEYPAD);
if(((data>>C1)&1)==0) i=i+7;
if(((data>>C2)&1)==0) i=i+8;
if(((data>>C3)&1)==0) i=i+9;
if(((data>>C4)&1)==0) i=i+15;

mcp23s17_write(KEYPAD,0b01111111);
data=mcp23s17_read(KEYPAD);
if(((data>>C1)&1)==0) i=i+11;
if(((data>>C2)&1)==0) i=i+10;
if(((data>>C3)&1)==0) i=i+12;
if(((data>>C4)&1)==0) i=i+16;
return i;
}
User avatar
shahrul
Professional
 
Posts: 812
Joined: Sat May 16, 2009 9:54 pm
Location: Selangor

Return to PIC Microcontroller

Who is online

Users browsing this forum: No registered users and 8 guests

cron