|
|
View previous topic :: View next topic |
Author |
Message |
jvargasrpr
Joined: 11 Nov 2011 Posts: 3 Location: Puerto Rico
|
PIC18F452 and CS5463 SPI help |
Posted: Fri Nov 11, 2011 4:44 pm |
|
|
Hey guys -
I'm currently working on the communication between the CS5463 chip (http://www.cirrus.com/en/products/cs5463.html). I have messaged the guys over Cirrus, but got no answer.
I'm having problems with the SPI communication. Right now, I connected the PIC18F452 to the CS5463, and trying to read the voltage from the CS5463 to test the connection, but am not getting anything. I have a LCD screen where I refresh data every 5 seconds. After putting LEDs on the SDO and SDI pins, I noticed that every 10~13 seconds the LED turns on and turns off.
I am using a 10 MHz crystal oscillator on the PIC18F452. I read somewhere that I could use a crystal oscillator of up to 20 MHz on the CS5463, as long as I changed a K value on the CS5463. However, I may just buy a 4 MHz crystal oscillator and try to do the communication with that since I'm not getting anything back on 10 MHz after trying to send commands to change that K value.
The source file I am using is from an older post found on this forum, to which I added the definition of registers and a few functions:
Code: | //CS5463 driver
#use delay(clock=10000000)
#define CS PIN_E2 //SCK
#define RESET PIN_C1 //'(SS)
#define SDO PIN_C5
#define SDA PIN_C4
#define INT PIN_C2 //TRIG
#define CS5463_CONFIG_REG 0
#define CS5463_DCOFFSET_REG 1
#define CS5463_CURRENTGAIN_REG 2
#define CS5463_VOLTAGEDCOFFSET_REG 3
#define CS5463_VOLTAGEGAIN_REG 4
#define CS5463_CYCLECOUNT_REG 5
#define CS5463_PULSERATEE_REG 6
#define CS5463_INSTCURRENT_REG 7
#define CS5463_INSTVOLTAGE_REG 8
#define CS5463_INSTPOWER_REG 9
#define CS5463_ACTIVEPOWER_REG 10
#define CS5463_RMSCURRENT_REG 11
#define CS5463_RMSVOLTAGE_REG 12
#define CS5463_EPSILON_REG 13
#define CS5463_POWEROFFSET_REG 14
#define CS5463_STATUS_REG 15
#define CS5463_IACOFF_REG 16
#define CS5463_VACOFF_REG 17
#define CS5463_MODE_REG 18
#define CS5463_TEMPERATURE_REG 19
#define CS5463_REACTIVEPOWERAVG_REG 20
#define CS5463_INSTREACTIVEPOWER_REG 21
#define CS5463_PEAKCURRENT_REG 22
#define CS5463_PEAKVOLTAGE_REG 23
#define CS5463_REACTIVEPOWERTRIANGLE_REG 24
#define CS5463_POWERFACTOR_REG 25
#define CS5463_MASK_REG 26
#define CS5463_APPARENTPOWER_REG 27
#define CS5463_CTRL_REG 28
#define CS5463_HARMONICACTIVEPOWER_REG 29
#define CS5463_FUNDACTIVEPOWER_REG 30
#define CS5463_FUNDREACTIVEPOWER_REG 31
// SPI modes
#define SPI_MODE_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1 (SPI_L_TO_H)
#define SPI_MODE_2 (SPI_H_TO_L)
#define SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_L_TO_H)
//--------------------------------
void CS5463_write_command(int8 command){
output_low(CS);
spi_write(command);
output_high(CS);
}
//---------------------------------
void CS5463_write_reg(int8 reg, int8 msb, int8 mid, int8 lsb){
output_low(CS);
spi_write((reg << 1) | 0x40); // OR with Write bit
spi_write(msb);
spi_write(mid);
spi_write(lsb);
output_high(CS);
}
//---------------------------------
int32 CS5463_read_reg(int8 reg){
int8 msb, mid, lsb;
int32 retval;
output_low(CS);
spi_write(reg << 1);
msb = spi_read(0xFF);
mid = spi_read(0xFF);
lsb = spi_read(0xFF);
output_high(CS);
retval = make32(0, msb, mid, lsb);
return(retval);
}
void CS5463_reset(){
output_low(CS);
spi_write(0xFF);
spi_write(0xFF);
spi_write(0xFF);
spi_write(0xFE);
CS5463_write_command(0xE8);
output_high(CS);
}
int getInstantaneousCurrent(){
return make8(CS5463_read_reg(CS5463_INSTCURRENT_REG),2);
}
int getInstantaneousVoltage(){
return make8(CS5463_read_reg(CS5463_INSTVOLTAGE_REG),2);
}
int getInstantaneousPower(){
return make8(CS5463_read_reg(CS5463_INSTPOWER_REG),2);
}
int getActivePower(){
return make8(CS5463_read_reg(CS5463_ACTIVEPOWER_REG),2);
}
int getRmsCurrent(){
return make8(CS5463_read_reg(CS5463_RMSCURRENT_REG),2);
}
int getRmsVoltage(){
return make8(CS5463_read_reg(CS5463_RMSVOLTAGE_REG),2);
}
int getAverageReactivePower(){
return make8(CS5463_read_reg(CS5463_REACTIVEPOWERAVG_REG),2);
}
int getInstantaneousActivePower(){
return make8(CS5463_read_reg(CS5463_INSTREACTIVEPOWER_REG),2);
}
int getPeakCurrent(){
return make8(CS5463_read_reg(CS5463_PEAKCURRENT_REG),2);
}
int getPeakVoltage(){
return make8(CS5463_read_reg(CS5463_PEAKVOLTAGE_REG),2);
}
int getPowerFactor(){
return make8(CS5463_read_reg(CS5463_POWERFACTOR_REG),2);
}
int getApparentPower(){
return make8(CS5463_read_reg(CS5463_APPARENTPOWER_REG),2);
}
|
My main source code:
Code: | #if defined(__PCH__)
//#device PIC18F242
#include <18F452.h>
#include <delay.h>
#include <Flex_LCD420.c>
#include <CS5463.c>
#fuses HS,NOWDT
#use delay(clock=10000000)
//#use rs232(baud=19200, xmit=31766, rcv=31767)
#endif
void main()
{
int instCurrent = 0;
int instVoltage = 1;
int instPower = 0;
int activePower = 0;
int rmsCurrent = 0;
int rmsVoltage = 0;
int avgReactivePower = 0;
int instActivePower = 0;
int peakCurrent = 0;
int peakVoltage = 0;
int powerFactor = 0;
int apparentPower = 0;
//setup_adc_ports(NO_ANALOGS);
//setup_adc(ADC_OFF);
setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_4);
//setup_wdt(WDT_OFF);
//setup_timer_0(RTCC_INTERNAL);
//setup_timer_1(T1_DISABLED);
//setup_timer_2(T2_DISABLED,0,1);
//Initialization of CS5463
output_high(CS);
output_high(RESET);
delay_ms(100); // CS5463 osc start-up time is 60 ms type
CS5463_write_command(0xE8); //continuous conversions
//LCD initialization
lcd_init();
delay_ms(500);
while(true){
instVoltage = getInstantaneousVoltage();
printf(lcd_putc,"\fVoltage = %d", instVoltage);
delay_ms(2000);
output_high(PIN_A0);
delay_ms(2000);
output_low(PIN_A0);
delay_ms(2000);
}
}
|
I seriously need help with this since this project is due in two weeks. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Nov 11, 2011 5:15 pm |
|
|
Quote: |
//CS5463 driver
#use delay(clock=10000000)
|
This line should not be in the driver file. It belongs only in the main file,
just below the #fuses.
Quote: |
#use delay(clock=10000000)
setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_4);
|
A 10 MHz crystal with a clock divisor of 4 gives an SCLK of 2.5 MHz.
But on page 11 of the CS5453 data sheet,
http://www.cirrus.com/en/pubs/proDatasheet/CS5463_F3.pdf
it says that SCLK can be a maximum of 2.0 MHz. You need to
use the next higher clock divisor:
Quote: |
//#use rs232(baud=19200, xmit=31766, rcv=31767) |
This is very bad. Always use CCS pin names. The numbers can
change if you use a different PIC. If you use CCS pin names and
#include the .h file for the PIC, then it all automatically works.
That's the beauty of CCS.
Quote: |
//#device PIC18F242
#include <18F452.h>
#include <delay.h>
#include <Flex_LCD420.c>
#include <CS5463.c>
|
What's this delay.h ? This looks like it's for C18 or Hi-Tech or something.
It doesn't belong in a CCS program.
Post a list of the connections for the SPI pins (SCLK, SDO, SDI, CS)
between your PIC and the CS5463. Don't post the signal names.
Trace out the wires or PCB tracks with an ohmmeter (or visually) and
post which pin number on the PIC is connected to which pin number on
the CS5463. I want to make sure that you have the SPI pins connected
correctly. |
|
|
jvargasrpr
Joined: 11 Nov 2011 Posts: 3 Location: Puerto Rico
|
|
Posted: Sat Nov 19, 2011 12:54 pm |
|
|
Using the PICKIT3 I already tried to use the code CCS gives, but it will never work. Setting those fuses and not using the main.h header file created automatically fixed the problem.
For the rs232 line, I do concur with you that it's better to use the pin names; I just commented it out because I was going to need to use rs232 with my x-bee's (which I already got working), so I initially left it like that because I was using the initial declarations from the codes a friend generally writes, which worked when I programmed the PIC. I put the #include of the other files just after the #delay so that fixed the problem.
For the delay.h, I noticed that it isn't doing anything, so I just excluded the file. The code now looks like this:
Code: |
#if defined(__PCH__)
//#device PIC18F242
#include <18F452.h>
#fuses HS,NOWDT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, bits=8, parity=N, stream = XBEE)
#include <Flex_LCD420.c>
#include <CS5463.c>
#endif
void main()
{
int instCurrent = 0;
int instVoltage = 1;
int instPower = 0;
int activePower = 0;
int rmsCurrent = 0;
int rmsVoltage = 0;
int avgReactivePower = 0;
int instActivePower = 0;
int peakCurrent = 0;
int peakVoltage = 0;
int powerFactor = 0;
int apparentPower = 0;
//SPI Setup
//setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_4);
setup_spi(SPI_MASTER | SPI_MODE_0 );
//Initialization of CS5463
//output_high(CS);
//output_high(RESET);
//delay_ms(100); // CS5463 osc start-up time is 60 ms type
//CS5463_write_command(0xE8); //continuous conversions
//LCD initialization
lcd_init();
delay_ms(500);
//To display on the LCD, use printf(lcd_putc, "Message here");
//To transfer on the X-Bee, use fprintf(XBEE, "Message here");
while(true){
//instVoltage = getInstantaneousVoltage();
//printf(lcd_putc,"\fVoltage = %d", instVoltage);
delay_ms(500);
output_high(PIN_A0);
delay_ms(1000);
output_low(PIN_A0);
delay_ms(1000);
}
} |
I just received the 4 MHz crystals, so I'll be using 4 MHz on the PIC18F452 and the CS5463. I noticed that the crystal for the CS5463 can be up to 20 MHz, and in those cases where the frequency is high, I should need to set the K value such that the frequency is divided and is in the range of 2.5 MHz - 5 MHz (Page 11). So I guess with the 4 MHz crystal I don't need to do any value setup, and I can just erase the division for the SPI and try it like that.
As for the connections:
PIC18F452 TO CS5463
PIN E2 (CS) -> CS
PIN C1 (RESET) -> RESET
PIN C2 (SDO) -> SDA
PIN C4 (SDA) -> SDO
PIN C2 (INT) -> INT
I checked them and they seem to be OK. I'm gonna test this and will provide feedback in a few minutes.
EDIT: Forgot to add that the PIN C3 (18/SCK/SCL) is connected to the SCLK pin on the CS5463. Still not getting anything on the PIC. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Nov 20, 2011 8:07 pm |
|
|
Quote: |
Forgot to add that the PIN C3 (18/SCK/SCL) is connected to the SCLK pin
on the CS5463. Still not getting anything on the PIC.
|
Right, but your current program doesn't do anything except blink an LED
on pin A0. It doesn't talk to the CS5463. That part is commented out.
Quote: |
So I guess with the 4 MHz crystal I don't need to do any value setup, and
I can just erase the division for the SPI and try it like that.
|
Removing the SPI_CLK_DIV_4 from setup_spi() doesn't "erase" the
division. It just removes the documentation of the selected divisor
value from the program. In fact, the minimum divisor is 4, per the
18F452 data sheet:
Quote: |
REGISTER 15-2: SSPCON1: MSSP CONTROL REGISTER1 (SPI MODE)
bit 3-0 SSPM3:SSPM0: Synchronous Serial Port Mode Select bits
0010 = SPI Master mode, clock = FOSC/64
0001 = SPI Master mode, clock = FOSC/16
0000 = SPI Master mode, clock = FOSC/4
|
So with a 4 MHz crystal, you will have a 1 MHz SCLK for the SPI. |
|
|
jvargasrpr
Joined: 11 Nov 2011 Posts: 3 Location: Puerto Rico
|
|
Posted: Sun Nov 20, 2011 9:30 pm |
|
|
I copied the code before deleting the comment slashes... so I guess I'll use again the 10 MHz crystals, setting the SPI divisor on the 18F452 to 4 and the K value on the CS5463 to 4 as well.... I'll try that out sometime this week and let you know. |
|
|
|
|
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
|