Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] PIC16F1789 and ST95020 communication

tejca

Newbie
Joined
Sep 11, 2011
Messages
5
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,344
I don't know what am I doin wrong.
My code simply don't wanna work.
It is best if I show you all of my code for testing in mikroC.

Code:
//PIC16F1789 and ST95020 SPI eeprom
//RC3 is SCK to Pin 6 on ST95020
//RC4 is SDI to Pin 2 on ST95020
//RC5 is SDO to Pin 5 on ST95020
//RB4 is SS to Pin 1 on ST95020
//WP and HOLD on ST95020 are tied to +5V

#include "__T6963C.h"
sbit T6963C_ctrlcd at RE2_bit; // CD command/data signals pin8 PIC RE2
sbit T6963C_ctrlrd at RA7_bit; // RD read signal pin 6 PIC RA7
sbit T6963C_ctrlwr at RA6_bit; // WR write signal pin 5 PIC RA6
sbit T6963C_ctrlrst at RE1_bit; // RST reset signal pin 10 prej RC4
sbit T6963C_ctrlcd_Direction at TRISE2_bit; // CD command/data signal
sbit T6963C_ctrlrd_Direction at TRISA7_bit; // RD read signal
sbit T6963C_ctrlwr_Direction at TRISA6_bit; // WR write signal
sbit T6963C_ctrlrst_Direction at TRISE1_bit; // RST reset signal
// Signals not used by library, they are set in main function
sbit T6963C_ctrlce at RE0_bit; // CE signal pin 7 PIC RE0
sbit T6963C_ctrlfs at RC0_bit; // FS signal pin 19 PIC RC0
sbit T6963C_ctrlce_Direction at TRISE0_bit; // CE signal direction
sbit T6963C_ctrlfs_Direction at TRISC0_bit; // FS signal direction

sbit CS at RB4_bit;

int stevec, tlong, value, address;

void spi_eeprom_write(unsigned int address,unsigned int value)
{
CS = 0; // enable
SPI1_Write(0x02); // write command for writing data
SPI1_Write(address >> 8);
SPI1_Write(address);
SPI1_Write(value); //write value
CS = 1; // disable
}

unsigned char spi_eeprom_read(unsigned int address) //
{
CS = 0; // enable
SPI1_Write(0x03); // write instruction for read data
SPI1_Write(address >> 8);
SPI1_Write(address);
value = SPI1_Read(0); //read byte
CS = 1; // disable
return value;
}


void main() {
OSCCON = 0b11111000; //16MHz internal oscilator
CM1CON0 = 0x00; // Disable comparators
CM1CON1 = 0x00;
CM2CON0 = 0x00;
CM2CON1 = 0x00;
CM3CON0 = 0x00;
CM3CON1 = 0x00;
DAC1CON0 = 0x00;
DAC1CON1 = 0x00;

PORTA = 0b00111111;
TRISA = 0b00111111;
PORTB = 0b11000000;
TRISB = 0b11000000;

PORTC = 0b11010000;
TRISC.RC0 = 0; // output signal FS for LCD
TRISC.RC1 = 0; // output for PWM2
TRISC.RC2 = 0; // output for PWM1
TRISC.RC3 = 0; // SCL as output
TRISC.RC4 = 1; // SDI as input
TRISC.RC5 = 0; // SDO as output
TRISC.RC6 = 1; // input for key
TRISC.RC7 = 1; // input for key

TRISD = 0x00; // Port D as output
PORTE = 0b00001000;
TRISE = 0b00001000; // Port E as input

ANSELA = 0b00000000; // no analog inputs
ANSELB = 0b00000000;
ANSELC = 0b00000000;
ANSELD = 0b00000000;
ANSELE = 0x00;
APFCON1 = 0b00000000;
APFCON2 = 0b00000100; // SS on pin RB4

T6963C_ctrlce_Direction = 0;
T6963C_ctrlce = 0; // Enable T6963C
T6963C_ctrlfs_Direction = 0; // set font
T6963C_ctrlfs = 0;
delay_ms(1);
T6963C_init(240, 64, 8); // Initialize T6963C
T6963C_text(1);
T6963C_cursor(0); // cursor = off
T6963C_panelFill(0); //Clear LCD screen

value = 28; //some randome value for testing
address = 0;

SPI1_Init();

spi_eeprom_write(0x58, value); //some random address for testing
delay_ms(10);

while (1) {
stevec = spi_eeprom_read(0x58); //save to stevec

tlong = stevec / 10;
T6963C_write_char(48+tlong, 10, 0, T6963C_ROM_MODE_XOR);
tlong = stevec % 10;
T6963C_write_char(48+tlong, 11, 0, T6963C_ROM_MODE_XOR);
}
}
 
"...don't wanna[sic] work' is not a problem description that we can work with.
Is this in a simulator or a real device?
Show is the SPI code.
Show us the config settings for the PIC.
What have you tried and what was the result?
What should have happened?
Susan
 
Please provide more details about the errors you are encountering. Is the code getting compiled? Is there any error messages?
 
Hello and sorry for late replay.
There are no errors in compiling.
This is a real device and it's only purpouse is to store a single number.
I did it with I2C protocol and I can store multiple variables in different locations on that chip without any problems.
And it looks like mikroC is handling configuration for I2C in they're librarys and I did'nt have to do and kind of special configuraton to use I2C.
By the look in mikroC compiler help library using SPI should be relatively easy. Obviously I don't understand a lot of stuff what
is goin on here. That is why I am here.
First I think it would be good if we check my connections from PIC to EEPROM first.
//PIC16F1789 and ST95020 SPI eeprom
//RC3 is SCK to Pin 6 SCK on ST95020
//RC4 is SDI to Pin 2 SDO on ST95020
//RC5 is SDO to Pin 5 SDI on ST95020
//RB4 is SS to Pin 1 CS on ST95020
//WP and HOLD on ST95020 are tied to +5V

Tejca
 
So how do you know that it is not working?
Have you tried using the debugger?
You really do need to give us the information that will help us actually help you.
Susan
 
Hello!

I will try to show you a bit more specifically what is missing in your code.

- It's completely fuzzy, everything is mixed, you don't explain what is what.
Example: do you expect everybody to know what T6963 is?
NB: I have checked, and it's a LCD dot matrix. Why do I have to check the components
you are using?

- In order to be clear, every part should be in its own file. For example you may
consider to have a pair of T6963.c / .h (or LCD.c / .h) files. An additional bonus is that if you
reuse the same LCD in another project, then you copy the files, and it will work
at once.

- If you want to check a single character, then your main() code should be
extremely short. 1. Initialization of the LCD, 2. Initialization of the memory;
3. Read some value to the memory at some location, 4. Read the same location
5. Write an error message if necessary.
This means 5 lines + some variable declarations.

Note that:
1. If you break your code into functions, you will have to focus on a single function
at a time, therefore a very limited scope, which helps understanding what happens.
That's what functions are for.

2. You should never hard-code anything. Example: PORTE = 0b00001000 should be
#define SOME_VALUE 0b00001000
PORTE = SOME_VALUE.
Same for OSCCON, you should define somewhere #define OSC_16MHz 0b11111000
and write OSCCON = OSC_16MHz; in which case you don't even have to comment that line.
This way, if you have to use some values at many places, they will all have the same
value. If you write it each time, you may write for instance 0x00010000 instead of
0x00001000 in which case you may pull all your hair because you don't notice it's
different.
That's what #defines are for.

Now a few questions:
- Does your LCD work properly?
- If you look at the SPI signal with a scope, does it seem to comply to what it should be?
- Is the SPI frequency adapted to the memory?

etc...

Dora.
 
Ok I will disect my code just to show you what is goin on and what each part is doin.
LCD is working because if I put some number in stevec variable the it is shown on LCD.

This code is for setting the connections for LCD which is driven by T6963c driver and is
supported by mikroC compiler.
Code:
#include   "__T6963C.h"
char T6963C_dataPort at PORTD;                   // DATA port pin 11-18

sbit T6963C_ctrlcd  at RE2_bit;                  // CD command/data signals pin8 PIC RE2
sbit T6963C_ctrlrd  at RA7_bit;                  // RD read signal pin 6  PIC RA7
sbit T6963C_ctrlwr  at RA6_bit;                  // WR write signal pin 5  PIC RA6
sbit T6963C_ctrlrst at RE1_bit;                  // RST reset signal pin 10  prej RC4
sbit T6963C_ctrlcd_Direction  at TRISE2_bit;     // CD command/data signal
sbit T6963C_ctrlrd_Direction  at TRISA7_bit;     // RD read signal
sbit T6963C_ctrlwr_Direction  at TRISA6_bit;     // WR write signal
sbit T6963C_ctrlrst_Direction at TRISE1_bit;     // RST reset signal

// Signals not used by library, they are set in main function
sbit T6963C_ctrlce at RE0_bit;                   // CE signal  pin 7 PIC RE0
sbit T6963C_ctrlfs at RC0_bit;                   // FS signal  pin 19  PIC RC0
sbit T6963C_ctrlce_Direction  at TRISE0_bit;     // CE signal direction
sbit T6963C_ctrlfs_Direction  at TRISC0_bit;     // FS signal direction

Thees two lines are for setting SS or chip select pin and some variables that I will use.
Code:
sbit CS at RB4_bit;

int  stevec, tlong, value, address;

Firs function for writing value variable to eeprom.
Code:
void spi_eeprom_write(unsigned int address,unsigned int value)
{
       CS = 0;             // enable
       SPI1_Write(0x02);        // write command for writing data
       SPI1_Write(address >> 8);
       SPI1_Write(address);
       SPI1_Write(value);  //write value
       CS = 1;             // disable
}

Function for reading from eeprom.
Code:
unsigned char spi_eeprom_read(unsigned int address)   //
{
     CS = 0;             // enable
     SPI1_Write(0x03);    // write instruction for read data
     SPI1_Write(address >> 8);
     SPI1_Write(address);
     value = SPI1_Read(0);    //read byte
     CS = 1;             // disable
     return value;
}

Configuration of the PIC16F1789 and its output and inputs.
Code:
  OSCCON = 0b11111000;      //16MHz internal oscilator
  CM1CON0 = 0x00;               // Disable comparators
  CM1CON1 = 0x00;
  CM2CON0 = 0x00;
  CM2CON1 = 0x00;
  CM3CON0 = 0x00;
  CM3CON1 = 0x00;
  DAC1CON0 = 0x00;
  DAC1CON1 = 0x00;

 PORTA = 0b00111111;
 TRISA = 0b00111111;
 PORTB = 0b11000000;
 TRISB = 0b11000000;

 PORTC = 0b11010000;
 TRISC.RC0 = 0;   // output signal FS for LCD
 TRISC.RC1 = 0;   // output for PWM2
 TRISC.RC2 = 0;   // output for PWM1
 TRISC.RC3 = 0;   // SCL as output
 TRISC.RC4 = 1;  // SDI as input
 TRISC.RC5 = 0;  // SDO as output
 TRISC.RC6 = 1;  // input for key
 TRISC.RC7 = 1;  // input for key

 TRISD = 0x00;             // Port D as output
 PORTE = 0b00001000;
 TRISE = 0b00001000;       // Port E as input

 ANSELA = 0b00000000;    // no analog inputs
 ANSELB = 0b00000000;
 ANSELC = 0b00000000;
 ANSELD = 0b00000000;
 ANSELE = 0x00;
 APFCON1 = 0b00000000;
 APFCON2 = 0b00000100;  // SS on pin RB4

Another configuration for LCD.
Code:
  T6963C_ctrlce_Direction = 0;
  T6963C_ctrlce = 0;            // Enable T6963C
  T6963C_ctrlfs_Direction = 0;  // set font
  T6963C_ctrlfs = 0;
  delay_ms(1);
  T6963C_init(240, 64, 8);         // Initialize T6963C
  T6963C_text(1);
  T6963C_cursor(0);         // cursor = off
  T6963C_panelFill(0);      //Clear LCD screen

Adding a number to value variable, initialization and calling write funcion.
Code:
 value = 28;    //some randome value for testing
 address = 0;

 SPI1_Init();    //Initializing SPI

spi_eeprom_write(0x58, value);   //some random address for testing
delay_ms(10);

While loop, writing some text to LCD just to see if it works, calling read function and showing it on
LCD in row 0 and column 10 and 11.

Code:
 while (1) {

  T6963C_write_text("save to eeprom", 1, 6, T6963C_ROM_MODE_XOR);  //this is added just to see if LCD is working
 stevec = spi_eeprom_read(0x58);  //save to stevec

 tlong = stevec / 10;
 T6963C_write_char(48+tlong, 10, 0, T6963C_ROM_MODE_XOR);
 tlong  = stevec % 10;
 T6963C_write_char(48+tlong, 11, 0, T6963C_ROM_MODE_XOR);
           }
 
OK so you know the LCD is working.
Have you read the ST95020 data sheet, and in particular the 'Byte Write Operation' section on page 9? It says that you need to send the "WREN" instruction to set the Write Enable latch. This is complete instruction in its own right and so requires that the \CS\ signal be lowered at the start and raised afterwards.
Only THEN can you do the "WRITE" operation.
The timing diagrams on page 7 show this clearly.
As an added check that the WREN instruction has worked, you can try reading the status register first, issue the WREN command and then read the status register again to make sure that the 'WEL' bit is set. The read of the status register will NOT reset the 'WEL' bit but if it is not set then any subsequent WRITE will be useless.
Also, if the WRITE command does work, then you can immediately poll the status register to check that the 'WIP' bit is set and then wait for it to be cleared so you know the write has completed.
Reading and understanding datasheets is an essential skill that everyone must acquire to be successful at using any component.
Susan
 
Hello guys. Sorry it took me so long to write back.
Susan you where wright about understanding datasheets.
I have finaly made it and it works now.
The biggest problem that I had was with hardware.
JLCPCB made a mistake - I was missing 1,5mm of a track and I totaly overlooked it.
Its a good thing that I have a osciloscope. Jupiiiii hehehehe
I will post the complete code when I have tested it enough just to be shure.
Anyway thank you all who have tryed to help me and If we ever meet I would buy you a beer..
Cheers
 
Last edited:
Hello guys. Sorry it took me so long to write back.
I have finaly made it and it works now.
This is all I need to write and read to eeprom.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void Write_SPI(int Address, char stevec) {
Chip_Select = 0;
SPI1_Write(WREN);
Chip_Select = 1;
delay_ms(1);
Chip_Select = 0;
SPI1_Write(write);
SPI1_Write(Address);
SPI1_Write(stevec);
Chip_Select = 1;
}
 
char Read_SPI(int Address) {
Chip_Select = 0;
SPI1_Write(read);
SPI1_Write(Address);
stevec = SPI1_Read(0);
Chip_Select = 1;
return stevec;
}


Anyway thank you all who have tryed to help me and If we ever meet I would buy you a beer.
Cheers

[ADDED CODE TAGS]
 
Last edited by a moderator:

LaTeX Commands Quick-Menu:

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top