|
|
View previous topic :: View next topic |
Author |
Message |
NEW_GUY
Joined: 31 Aug 2012 Posts: 10 Location: India
|
MCP23S17 interfacing with SPI with controller PIC18F8722 |
Posted: Fri Aug 31, 2012 4:42 am |
|
|
Hi guys,
I am wondering if anyone could help me in my problem,
- There is a driver provided by the CCS compiler for MCP23S17. I am not sure how to use it for communication on SPI.
- Also there are several API for initialization and operations on SPI, will they be suitable for the same controller ?
- Currently interfacing the 16x2 LCD module to it (as I am using PIC18f8722 development board).
I can not even initialize the LCD.
Your help is greatly appreciated.
Thank you. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9236 Location: Greensville,Ontario
|
|
Posted: Fri Aug 31, 2012 5:13 am |
|
|
First do not try to get the MCP working yet...your priority is to get the LCD 'up and running'.
Post the manufacturer / make/model info of the developement board or a link to it.
Did the board come with any test software like 'Hello World' or 'blinking LED'. Does the mfr have a forum/help/FAQ site?
Is the LCD part of the board or did you add it ?
When you say it doesn't work what are the symptoms? Single row of black boxes ,wrong data on screen, totally 'dead'?
Generally speaking it's a good idea to first get an LED to blink at 1Hz to confirm the board/PIC work..then connect/test an LCD ( use the flex_driver)..then add/test other peripherals..
This way you know the hardware works in a known manner and can always go back to a working configuration.
The more information you give us the better (and faster) we can try to help you.
hth
jay |
|
|
sseidman
Joined: 14 Mar 2005 Posts: 159
|
|
Posted: Fri Aug 31, 2012 9:21 am |
|
|
temtronic wrote: | First do not try to get the MCP working yet...your priority is to get the LCD 'up and running'.
Post the manufacturer / make/model info of the developement board or a link to it.
Did the board come with any test software like 'Hello World' or 'blinking LED'. Does the mfr have a forum/help/FAQ site?
Is the LCD part of the board or did you add it ?
When you say it doesn't work what are the symptoms? Single row of black boxes ,wrong data on screen, totally 'dead'?
Generally speaking it's a good idea to first get an LED to blink at 1Hz to confirm the board/PIC work..then connect/test an LCD ( use the flex_driver)..then add/test other peripherals..
This way you know the hardware works in a known manner and can always go back to a working configuration.
The more information you give us the better (and faster) we can try to help you.
hth
jay |
Great advice! The only thing I would change is to offer the option of using a serial port instead of the LCD -- less resources, no external drivers, you don't have to make your output fit on two lines, the output doesn't disappear when the next output comes along, and you always have a terminal available as you're programming (well, if you have a box w/ a serial port or a serial to usb converter). You might need to have a serial port driver, if your converter doesn't support straight TTL, but once you have this built, you're done and ready for anything. |
|
|
NEW_GUY
Joined: 31 Aug 2012 Posts: 10 Location: India
|
|
Posted: Mon Sep 03, 2012 2:31 am |
|
|
temtronic wrote: | First do not try to get the MCP working yet...your priority is to get the LCD 'up and running'.
Post the manufacturer / make/model info of the development board or a link to it.
Did the board come with any test software like 'Hello World' or 'blinking LED'. Does the mfr have a forum/help/FAQ site?
Is the LCD part of the board or did you add it ?
When you say it doesn't work what are the symptoms? Single row of black boxes, wrong data on screen, totally 'dead'?
Generally speaking it's a good idea to first get an LED to blink at 1Hz to confirm the board/PIC work..then connect/test an LCD ( use the flex_driver)..then add/test other peripherals..
This way you know the hardware works in a known manner and can always go back to a working configuration.
The more information you give us the better (and faster) we can try to help you.
hth
jay |
Hey temtronic , Thanks.
I really appreciate your efforts and basic explanations. Thank you for that again.
What is happening actually the development board is from Microchip { PIC18F8722 PICDEM (TM) board. }
It previously had a test code in it, which runs texts WELCOME on LCD. But as i have used it for several months for other firmware development, i didnt need LCD. So that's why i am not aware where i could find that source code.
Actually on the board, LCD is connected only thru the MCP23S17 which is on SPI bus obviously, so i cant even test it by sending my data to it as i am not able to initialize my MCP23S17.
I just needs guidelines/methods/procedures which will follow the correct sequence for execution in case of MCP23S17 initialization.
Regards |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9236 Location: Greensville,Ontario
|
|
Posted: Mon Sep 03, 2012 6:08 am |
|
|
ah..now the light comes on ! The LCD is not attached to the PIC but rather to the SPI I/O expander chip.....( I downloaded the manual...)
I would suggest you download the MCP23S17 datasheet and see what the command/sequence/data is required to 'talk' to the device. Most LCD units share a common command/data set so once you figure out if it's in 4 bit or 8 bit mode, you can reverse engineer the code the PIC uses to send through the MCP23S17 to the LCD module.
It's not that hard as you have all the pieces of the puzzle including schematics !
I don't have that uChip dev board, perhaps others do and have already done the 'exercise' for you. Perhaps searching this forum will find a similar thread ?
hth
jay |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 03, 2012 5:20 pm |
|
|
Here's a thread where someone wrote an LCD driver for the C18 compiler
for that board:
http://www.microchip.com/forums/m423849.aspx
But if you're a newbie to the C language or to CCS, you're probably not
going to be able to convert that code to CCS. |
|
|
NEW_GUY
Joined: 31 Aug 2012 Posts: 10 Location: India
|
|
Posted: Mon Sep 03, 2012 10:23 pm |
|
|
PCM programmer wrote: | Here's a thread where someone wrote an LCD driver for the C18 compiler
for that board:
http://www.microchip.com/forums/m423849.aspx
But if you're a newbie to the C language or to CCS, you're probably not
going to be able to convert that code to CCS. |
Thank you. |
|
|
NEW_GUY
Joined: 31 Aug 2012 Posts: 10 Location: India
|
|
Posted: Tue Sep 04, 2012 12:57 am |
|
|
temtronic wrote: | ah..now the light comes on ! The LCD is not attached to the PIC but rather to the SPI I/O expander chip.....( I downloaded the manual...)
I would suggest you download the MCP23S17 datasheet and see what the command/sequence/data is required to 'talk' to the device. Most LCD units share a common command/data set so once you figure out if it's in 4 bit or 8 bit mode, you can reverse engineer the code the PIC uses to send through the MCP23S17 to the LCD module.
It's not that hard as you have all the pieces of the puzzle including schematics !
I don't have that uChip dev board, perhaps others do and have already done the 'exercise' for you. Perhaps searching this forum will find a similar thread ?
hth
jay |
Hey temtronic,
I just come across the main problem,
- according to my knowledge SPI is working fine,
- MCP23S17 is getting init
- but the main problem is LCD,
This LCD is not the normal HITACHI LCD, its from lumex (LCM-SO1602 DTR/M), i never worked on this, so if my code is correct then it must be problem with command sequence while initializing the LCD.
If you can help me finding the command summary for this LCD that wil be great help. FYI, I have searched most possible places on the internet where I could find the info, but I couldn't...
Thank you and regards. |
|
|
NEW_GUY
Joined: 31 Aug 2012 Posts: 10 Location: India
|
|
Posted: Wed Sep 05, 2012 11:24 pm |
|
|
I got my code working...
somehow with help of this forum...
There was the mistake in LCD commands, as it is not usual LCD from hitachi.
I am going to post my code here for the reference very soon.
Thank you. |
|
|
Bill24
Joined: 30 Jun 2012 Posts: 45
|
|
Posted: Thu Nov 01, 2012 10:41 am |
|
|
NEW_GUY wrote: | I got my code working...
somehow with help of this forum...
There was the mistake in LCD commands, as it is not usual LCD from hitachi.
I am going to post my code here for the reference very soon.
Thank you. |
I'd be grateful to see your solution. |
|
|
Bill24
Joined: 30 Jun 2012 Posts: 45
|
|
Posted: Tue Nov 06, 2012 2:40 am |
|
|
NEW_GUY wrote: | PCM programmer wrote: | Here's a thread where someone wrote an LCD driver for the C18 compiler
for that board:
http://www.microchip.com/forums/m423849.aspx
But if you're a newbie to the C language or to CCS, you're probably not
going to be able to convert that code to CCS. |
Thank you. |
Here is a conversion of the code running on a PIC18 Explorer board.
Code: | #include <18F66K80.h>
#device ICD=TRUE
#device adc=16
#device ICD=TRUE
#device adc=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES VREGSLEEP_SW //Ultra low-power regulator is enabled
#FUSES INTRC_LP //LF-INTOSC in Low-Power mode during Sleep
#FUSES SOSC_DIG //Digital mode, I/O port functionality of RC0 and RC1
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES PUT //Power Up Timer
#FUSES BORM_LOW //Low-power BOR
#FUSES WDT_NOSLEEP //Watch Dog Timer, disabled during SLEEP
#FUSES DEBUG //Debug mode for use with ICD
#use delay(int=8000000,RESTART_WDT)
#USE FAST_IO(a)
#USE FAST_IO(c)
#USE FAST_IO(c)
#USE FAST_IO(f)
// SPI registers
#word LCD_SSPBUF = 0x0FC9 // SPI1BUF
#word LCD_SPICON1 = 0x0FC6 // SPI1CON1
#word LCD_SPISTAT = 0x0FC7 // SPI1STAT
#word LCD_SPI_IF = 0x0F9E // PIR1
#define SSP1IF_BIT 0x03
#define LED PIN_D0
// ----------- PICDEM HPC Explorer 18 LCD defines
#define LCD_CS (PIN_A2) //LCD chip select
#define LCD_RST (PIN_F6) //LCD Reset
#define LCD_CLK (PIN_C3)
#define LCD_SI (PIN_C5)
// ---------------------------------------------------
// Forward declarations
// PICDEM HPC Explorer 18 LCD controlled via MCP923S17
void LCDBusy(void);
void WritePortA(char b);
void WritePortB(char b);
void d_write(char b);
void i_write(char b);
void LCDLine_1(void);
void LCDLine_2(void);
void LCDClear(void);
void InitWrite(char b);
void InitPortA_SPI(char b);
void InitPortB_SPI(char b);
void InitSPI(void);
void LCDInit(void);
unsigned char LCDText[16*2+1];
void main(void)
{
int tmpcnt = 0;
// Set PIN_A2 (chip sel) to output.
set_tris_a(0x0FB);
// Set Pin_C3 (clk ) and pin_C5 (si) to output.
set_tris_c(0x0D7);
// Set PIN_D0 to output.
set_tris_d(0x0FE);
// Set Pin_F6 (reset ) to output.
set_tris_f(0x0BF);
// Initialize the LCD display
LCDInit();
//Test - blinking LED program
while(true)
{
output_low(LED);
// output_low(LCD_CS); // PIN_A2
// output_low(LCD_RST); // PIN_F6
// output_low(LCD_CLK); // PIN_C3
// output_low(LCD_SI); // PIN_C5
delay_ms(500);
output_high(LED);
// output_high(LCD_CS); // PIN_A2
// output_high(LCD_RST); // PIN_F6
// output_high(LCD_CLK); // PIN_C3
// output_high(LCD_SI); // PIN_C5
delay_ms(500);
// Write the cammand to start on line 1
LCDLine_1();
// Write the data one char at a time.
d_write('H');
d_write('e');
d_write('l');
d_write('l');
d_write('0');
// Write the cammand to start on line 2
LCDLine_2();
// Write the data to line 2 one char at a time
// You can put this in a loop and read from a table
d_write('P');
d_write('I');
d_write('C');
d_write('1');
d_write('8');
delay_ms(500);
tmpcnt++;
switch(tmpcnt)
{
case 10:
d_write(' ');
d_write('1');
d_write('0');
break;
case 20:
d_write(' ');
d_write('2');
d_write('0');
break;
case 30:
d_write(' ');
d_write('3');
d_write('0');
break;
case 40:
d_write(' ');
d_write('4');
d_write('0');
break;
}
}
}
//*****************************************************************
// LCD busy delay
//*****************************************************************
void LCDBusy(void)
{
delay_us(100);
}
//*****************************************************************
// Write to MCP923S17 Port A
//*****************************************************************
void WritePortA(char b)
{
output_low(LCD_CS);
LCD_SSPBUF = 0x40;
while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
bit_clear(LCD_SPI_IF,SSP1IF_BIT);
LCD_SSPBUF = 0x12;
while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
bit_clear(LCD_SPI_IF,SSP1IF_BIT);
LCD_SSPBUF = b;
while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
bit_clear(LCD_SPI_IF,SSP1IF_BIT);
output_high(LCD_CS);
}
//*****************************************************************
// Write to MCP923S17 Port B
//*****************************************************************
void WritePortB(char b)
{
output_low(LCD_CS);
LCD_SSPBUF = 0x40;
while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
bit_clear(LCD_SPI_IF,SSP1IF_BIT);
LCD_SSPBUF = 0x13;
while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
bit_clear(LCD_SPI_IF,SSP1IF_BIT);
LCD_SSPBUF = b;
while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
bit_clear(LCD_SPI_IF,SSP1IF_BIT);
output_high(LCD_CS);
}
//*****************************************************************
// Write the data to the display
//*****************************************************************
void d_write(char b)
{
WritePortA(0x80);
LCDBusy();
WritePortB(b);
delay_us(10);
WritePortA(0xC0);
delay_us(10);
WritePortA(0x00);
//TXREG = b; //carriage return
//while(!LCD_TXSTA_TRMT); //wait for data TX
//LCD_TXSTA_TRMT = 0;
}
//*****************************************************************
// Send a instruction to the display
//*****************************************************************
void i_write(char b)
{
WritePortA(0x00);
LCDBusy();
WritePortB(b);
delay_us(10);
WritePortA(0x40);
delay_us(10);
WritePortA(0x00);
}
//*****************************************************************
// Write to line 1 of the display
//*****************************************************************
void LCDLine_1(void)
{
i_write(0x80);
}
//*****************************************************************
// Write to line 1 of the display
//*****************************************************************
void LCDLine_2(void)
{
i_write(0xC0);
}
//*****************************************************************
// To clear the display
//*****************************************************************
void LCDClear(void)
{
i_write(0x01);
}
//******************************************************************
// Function to write to the PORT
//******************************************************************
void InitWrite(char b)
{
WritePortA(0);
WritePortB(b);
delay_us(10);
WritePortA(0x40);
delay_us(20);
WritePortA(0);
}
//*****************************************************************
// Initialize MCP923S17 Port A
//*****************************************************************
void InitPortA_SPI(char b)
{
output_low(LCD_CS);
LCD_SSPBUF = 0x40;
while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
bit_clear(LCD_SPI_IF,SSP1IF_BIT);
LCD_SSPBUF = 0x00;
while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
bit_clear(LCD_SPI_IF,SSP1IF_BIT);
LCD_SSPBUF = b;
while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
bit_clear(LCD_SPI_IF,SSP1IF_BIT);
output_high(LCD_CS);
}
//*****************************************************************
// Initialize MCP923S17 Port B
//*****************************************************************
void InitPortB_SPI(char b)
{
output_low(LCD_CS);
LCD_SSPBUF = 0x40;
while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
bit_clear(LCD_SPI_IF,SSP1IF_BIT);
LCD_SSPBUF = 0x01;
while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
bit_clear(LCD_SPI_IF,SSP1IF_BIT);
LCD_SSPBUF = b;
while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
bit_clear(LCD_SPI_IF,SSP1IF_BIT);
output_high(LCD_CS);
}
//*****************************************************************
// Initialize MCP923S17 SPI
//*****************************************************************
void InitSPI(void)
{
// Set SSPM1 bit and SSPEN bit
LCD_SPICON1 = 0x22;
// Set CKE bit
LCD_SPISTAT = 0x40;
// Set Master Synchronous Serial Port Interrupt Flag bit bit in PIR1 to 0
bit_clear(LCD_SPI_IF,SSP1IF_BIT);
}
//******************************************************************
// LCD Initialization function
//******************************************************************
void LCDInit(void)
{
output_high(LCD_CS);
delay_us(50);
output_low(LCD_RST);
delay_us(50);
output_high(LCD_RST);
InitSPI();
InitPortA_SPI(0);
InitPortB_SPI(0);
WritePortA(0);
delay_us(50);
InitWrite(0x3C); //0011NFxx
delay_us(50);
InitWrite(0x0C); //Display Off
delay_us(50);
InitWrite(0x01); //Display Clear
delay_us(50);
InitWrite(0x06); //Entry mode
} |
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Nov 06, 2012 3:55 am |
|
|
Thanks for posting the driver.
Could you also post it in the Code Library forum? There it will be easier for people to find.
BTW: do you know why there are functions i_write and initWrite ? Apart from a different delay these are identical. |
|
|
Bill24
Joined: 30 Jun 2012 Posts: 45
|
|
Posted: Wed Nov 07, 2012 6:32 am |
|
|
ckielstra wrote: | Thanks for posting the driver.
Could you also post it in the Code Library forum? There it will be easier for people to find.
BTW: do you know why there are functions i_write and initWrite ? Apart from a different delay these are identical. |
The code is a quick and dirty port of the Microchip version which itself was ported from assembler. If I get time I will clean it up and post it in the Library. |
|
|
bboone
Joined: 04 Jun 2014 Posts: 3 Location: United States
|
|
Posted: Wed Jun 04, 2014 12:12 pm |
|
|
I know this is a couple years old but has anyone got this to work using #use spi and spi_xfer? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jun 04, 2014 12:33 pm |
|
|
See this post in the Code Library:
http://www.ccsinfo.com/forum/viewtopic.php?t=51264
To initialize PortA in the code from this thread, he sends 0x40, 0, 0:
Quote: |
void LCDInit(void)
{
.
.
InitPortA_SPI(0);
.
}
void InitPortA_SPI(char b)
{
output_low(LCD_CS);
LCD_SSPBUF = 0x40;
while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
bit_clear(LCD_SPI_IF,SSP1IF_BIT);
LCD_SSPBUF = 0x00;
while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
bit_clear(LCD_SPI_IF,SSP1IF_BIT);
LCD_SSPBUF = b; // 0x00
while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
bit_clear(LCD_SPI_IF,SSP1IF_BIT);
output_high(LCD_CS);
} |
The Code Library routines do the same thing, but they use spi_xfer():
Quote: |
#define IO_DEVICE_ADDRESS_WRITE 0x40
#define IODIRA 0x00
void setup_MCP23S17()
{
MCP23S17_write(IOCON, 0x18);
MCP23S17_write(IODIRA, 0x00);
MCP23S17_write(IODIRB, 0xFF);
MCP23S17_write(GPPUA, 0x00);
MCP23S17_write(GPPUB, 0xFF);
MCP23S17_write(IPOLA, 0xFF);
MCP23S17_write(IPOLB, 0x00);
}
void MCP23S17_write(unsigned char address, unsigned char value)
{
output_low(CS);
spi_xfer(IO_DEVICE_ADDRESS_WRITE); // 0x40
spi_xfer(address); // 0x00
spi_xfer(value); // 0x00
output_high(CS);
} |
You should be able to take the Code Library code as an example
and use it to modify the routines in this thread to use spi_xfer(). |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|