|
|
View previous topic :: View next topic |
Author |
Message |
ressas
Joined: 15 Nov 2019 Posts: 135
|
|
Posted: Sat Nov 30, 2019 3:27 am |
|
|
That's right, and you said it pretty well. but the code doesn't work
let me try a little more
Thank you |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19430
|
|
Posted: Sat Nov 30, 2019 5:54 am |
|
|
OK. Try doing the second read as well, but just throw away what it returns.
As I mentioned, there is this odd reference in the data sheet suggesting
that you must do both reads or there will be issues. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9196 Location: Greensville,Ontario
|
|
Posted: Sat Nov 30, 2019 10:07 am |
|
|
This is a great example of why it'd be nice to have the module on my bench and a LOT of time to diagnose what is going on. Having a 1/2 written 'datasheet' for any peripheral is bad, but for a COMPLICATED device like this is a horror story.
Hopefully just a few more hours and the OP will get the correct numbers....
Sad thing is it's less trouble than programming a 5KW Chinese diesel heater using their LCD interface.....I still can't find a well worded English version of how to program it.......though someone's hacked it ...
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19430
|
|
Posted: Sat Nov 30, 2019 12:20 pm |
|
|
You do realise that CH0_RCOUNT should be set to a different value for
the 12bit chip?. What is this being set to?. Wants 0x400 for the 12bit
chip. |
|
|
ressas
Joined: 15 Nov 2019 Posts: 135
|
FDC2214 to FDC2112 |
Posted: Mon Dec 02, 2019 12:19 am |
|
|
Hello to everyone.
This is the final version of the code. But it still doesn't work.
FDC2112.h
Code: |
///////////////////fdc221 datasheet page 22///////////////////////
// Address is 0x2A = 0x54 (default) or 0x2B = 0x55 (if ADDR is high)
#define FDC2214_I2C_ADDR_0 0x54
#define FDC2214_I2C_ADDR_1 0x55
//bitmasks
#define FDC2214_CH0_UNREADCONV 0x0008 //denotes unread CH0 reading in STATUS register
#define FDC2214_CH1_UNREADCONV 0x0004 //denotes unread CH1 reading in STATUS register
#define FDC2214_CH2_UNREADCONV 0x0002 //denotes unread CH2 reading in STATUS register
#define FDC2214_CH3_UNREADCONV 0x0001 //denotes unread CH3 reading in STATUS register
//registers
#define FDC2214_DEVICE_ID 0x7F
#define FDC2214_MUX_CONFIG 0x1B
#define FDC2214_CONFIG 0x1A
#define FDC2214_RCOUNT_CH0 0x08 //0x400
#define FDC2214_RCOUNT_CH1 0x09
#define FDC2214_RCOUNT_CH2 0x0A
#define FDC2214_RCOUNT_CH3 0x0B
#define FDC2214_OFFSET_CH0 0x0C
#define FDC2214_OFFSET_CH1 0x0D
#define FDC2214_OFFSET_CH2 0x0E
#define FDC2214_OFFSET_CH3 0x0F
#define FDC2214_SETTLECOUNT_CH0 0x10
#define FDC2214_SETTLECOUNT_CH1 0x11
#define FDC2214_SETTLECOUNT_CH2 0x12
#define FDC2214_SETTLECOUNT_CH3 0x13
#define FDC2214_CLOCK_DIVIDERS_CH0 0x14
#define FDC2214_CLOCK_DIVIDERS_CH1 0x15
#define FDC2214_CLOCK_DIVIDERS_CH2 0x16
#define FDC2214_CLOCK_DIVIDERS_CH3 0x17
#define FDC2214_STATUS 0x18
#define FDC2214_DATA_CH0_MSB 0x00
#define FDC2214_DATA_CH0_LSB 0x01
#define FDC2214_DATA_CH1_MSB 0x02
#define FDC2214_DATA_CH1_LSB 0x03
#define FDC2214_DATA_CH2_MSB 0x04
#define FDC2214_DATA_CH2_LSB 0x05
#define FDC2214_DATA_CH3_MSB 0x06
#define FDC2214_DATA_CH3_LSB 0x07
#define FDC2214_DRIVE_CH0 0x1E
#define FDC2214_DRIVE_CH1 0x1F
#define FDC2214_DRIVE_CH2 0x20
#define FDC2214_DRIVE_CH3 0x21
// mask for 28bit data to filter out flag bits
#define FDC2214_DATA_CHx_MASK_DATA_2 0b00000000000000000000111111111111
#define FDC2214_DATA_CHx_MASK_DATA 0x0FFF
#define FDC2214_DATA_CHx_MASK_ERRAW 0x1000
#define FDC2214_DATA_CHx_MASK_ERRWD 0x2000
//------------------------------------------------
///////////////////////////////////////////////////////////////////
#define CHAN_COUNT 2 // channel number,
void write16FDC(unsigned int16 address, unsigned int16 data);
unsigned int16 read16FDC(char address);
int1 FDC2214_begin(char chanMask,char autoscanSeq, char deglitchValue, int1 intOsc);
void loadSettings(char chanMask, char autoscanSeq, char deglitchValue, int1 intOsc);
unsigned int32 getReading28(char channel);
|
FDC2112.c
Code: |
#include "Pic16f1824_fdc2214.h"
char dev_adds = FDC2214_I2C_ADDR_0; //dev_adds = 0x54
// fdc2214 datasheet steps on page 22 followed
void write16FDC(unsigned int16 address, unsigned int16 data) {
i2c_start();
i2c_write(dev_adds); //first, sending integrated address
i2c_write(address & 0xff); //secondly, sending register address
// (?) Masked with 0xff, to ensure that 8 bits are sent
i2c_write(data >>8); //i2c communicates with 8 bits. But data = 16 bits.
//so we're shifting
i2c_write(data);
//other 8 bits
i2c_stop();
}
// fdc2214 datasheet steps on page 22 followed
unsigned int16 read16FDC(char address) {
unsigned int16 data;
i2c_start();
i2c_write(dev_adds);
i2c_write(address);
i2c_start();
i2c_write(dev_adds + 1); // Set R/W bit = 1 to read bytes
char datahigh=i2c_read(); //two pieces made from 8 bits to 16 bits
char datalow=i2c_read(0);
data=make16(datahigh,datalow);
i2c_stop();
return data;
}
int1 FDC2214_begin(char chanMask,char autoscanSeq, char deglitchValue, int1 intOsc) {
printf("FDC2214_begin");
int devId = read16FDC(FDC2214_DEVICE_ID);
//Checking the lighting of the device on the i2c line (sda, scl).
//If the values 0x3054 and 0x3055 are displayed; connected to the correct device
if (devId != 0x3054) {
if (devId != 0x3055) {
//two valid device ids for FDC2214 0x3054 and 0x3055
return false;
}
}
loadSettings(chanMask, autoscanSeq, deglitchValue, intOsc);
return true;
}
void loadSettings(char chanMask, char autoscanSeq, char deglitchValue, int1 intOsc) {
//Adjusting configuration settings
// When the FDC powers up, it enters into Sleep Mode and will wait for configuration.
//Once the device is configured, exit Sleep Mode by setting CONFIG.
printf("loadSettings");
if (intOsc) {
write16FDC(FDC2214_CONFIG, 0x1C81); //set config 0x1C81
printf("0x1C81");
} else {
write16FDC(FDC2214_CONFIG, 0x1E81); //set config 0x1E81
printf("0x1E81");
}
//FDC2214 HAVE 2 CHANNEL
//We make configuration settings for each channel.
//If channel 1 selected, init it..
if (chanMask & 0x01) {
//settle count maximized, slow application
write16FDC(FDC2214_SETTLECOUNT_CH0, 0x6400); // 0x6400
//rcount maximized for highest accuracy
write16FDC(FDC2214_RCOUNT_CH0, 0xFFFF); //0xFFFF
//no offset
write16FDC(FDC2214_OFFSET_CH0, 0x0000);
// Set clock dividers
write16FDC(FDC2214_CLOCK_DIVIDERS_CH0, 0x2001); //0x2001
//set drive register
write16FDC(FDC2214_DRIVE_CH0, 0xF800); //0xF800
}
// Init chan2, if selected by channel init mask
if (chanMask & 0x02) {
write16FDC(FDC2214_SETTLECOUNT_CH1, 0x6400);
write16FDC(FDC2214_RCOUNT_CH1, 0xFFFF);
write16FDC(FDC2214_OFFSET_CH1, 0x0000);
write16FDC(FDC2214_CLOCK_DIVIDERS_CH1, 0x2001);
write16FDC(FDC2214_DRIVE_CH1, 0xF800);
}
/////////////////////////////////////////////////////////////////////////////
unsigned int16 muxVal = 0x0208 | ( (unsigned int16)autoscanSeq << 13) | deglitchValue;
//(?) I have no idea what's going on here.
write16FDC(FDC2214_MUX_CONFIG, muxVal); //set mux config for channels
}
unsigned int32 getReading28(char channel) {
// Serial.println("getReading28");
int timeout = 100;
unsigned int32 reading = 0;
int status = read16FDC(FDC2214_STATUS);
char addressMSB;
char addressLSB;
char bitUnreadConv;
// Set to channel selection, we match registers with variables.
switch (channel) {
case 0:
addressMSB = FDC2214_DATA_CH0_MSB;
// addressLSB = FDC2214_DATA_CH0_LSB;
bitUnreadConv = FDC2214_CH0_UNREADCONV;
break;
case 1:
addressMSB = FDC2214_DATA_CH1_MSB;
bitUnreadConv = FDC2214_CH1_UNREADCONV;
break;
default: return 0;
}
//(?)
while (timeout && !(status & bitUnreadConv)) {
status = read16FDC(FDC2214_STATUS);
timeout--;
}
if (timeout == 100) {
reading = ((unsigned int32) read16FDC(addressMSB) & FDC2214_DATA_CHx_MASK_DATA)/*<<16*/;
//reading |= read16FDC(addressLSB);
while (timeout && !(status & bitUnreadConv)) {
status = read16FDC(FDC2214_STATUS);
timeout--;
}
}
if (timeout) {
reading = ((unsigned int32) read16FDC(addressMSB) & FDC2214_DATA_CHx_MASK_DATA)/*<<16*/;
//reading |= read16FDC(addressLSB);
return reading;
} else {
// Could not get data, chip readynes flag timeout
return 0;
}
}
|
Example Code:
Code: |
#include <16f1824.h>
//#device ADC=10
#INCLUDE <stdlib.h> //Required to send make16()
#fuses XT,NOWDT,NOBROWNOUT,NOPUT,NOWRT,NODEBUG, NOMCLR//, NOPROTECT, NOWDT, NOLVP,INTRC_IO,
#use delay(clock=4000000) //When you do 8, 16 or 32 you do not get a result
#use rs232(baud=9600,parity=N,xmit=PIN_C4,rcv=PIN_C5,bits=8)
#use i2c(Master,sda=PIN_c1,scl=PIN_c0,slow=400000,FORCE_HW)
#include "Pic16f1824_fdc2214.c"
void main() {
output_high(pin_c2);
setup_oscillator(OSC_4MHZ|OSC_INTRC|OSC_PLL_ON);
delay_ms(10000); // this not necessary
int1 capOk = FDC2214_begin(0xF, 0x0006, 0x5, true); //again config
//setup all four channels, autoscan with 4 channels, deglitch at 10MHz, external oscillator
if (capOk) //we check whether it is connected
printf("open");
else
printf("close");
while(true) {
unsigned int32 capa[CHAN_COUNT]; // variable to store data from FDC
for (int i = 0; i < CHAN_COUNT; i++) { // for each channel
// ### read 28bit data
// getReading28(reading);
capa[i] = getReading28(i); //
// ### Transmit data to serial in simple format readable by SerialPlot application.
printf("%lu ",capa[i]);
if(i==1) // printing the data we read to the bottom line
{
printf("\n");
}
if (i < CHAN_COUNT - 1) printf(",");
else printf("");
}
delay_ms(100);
}}
|
#define FDC2214_RCOUNT_CH0 0x08 when
I read the following information from serial communications;
Quote: |
-> FDC2214_beginloadSettings0x1C81open0 ,0
-> 0 ,0
-> 0 ,0
-> 0 ,0
-> 0 ,0
-> 0 ,0
-> 0 ,0
-> 0 ,0
-> 0 ,0
-> 0 ,0
|
#define FDC2214_RCOUNT_CH0 0x400 when
I read the following information from serial communications;
Quote: |
-> FDC2214_beginloadSettings0x1C81open4095 ,4095
-> 4095 ,4095
-> 4095 ,4095
-> 4095 ,4095
-> 4095 ,4095
-> 4095 ,4095
-> 4095 ,4095
-> 4095 ,4095
-> 4095 ,4095
|
I'm waiting for your answer |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19430
|
|
Posted: Mon Dec 02, 2019 2:36 am |
|
|
Whoa.
You must not change the define for RCOUNT.
You need to change the value written to this register. Changing the
define means the value will be going to the wrong register. No wonder it
won't work.
The locations are the two places where you write to the RCOUNT registers:
write16FDC(FDC2214_RCOUNT_CH0, 0xFFFF); //0xFFFF
//no offset
The value here should be 0x400 for the 12bit chip, instead of 0xFFFF for the
28bit chip, and the same for CH1. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Dec 02, 2019 2:53 am |
|
|
Also, I found two compiler warnings that are important in FDC2112.c:
Quote: |
>>> Warning 203 "C:\...\FDC2112.c" Line 40(1,1): Condition always TRUE
>>> Warning 203 "C:\...\FDC2112.c" Line 41(1,1): Condition always TRUE
>>> Warning 202 "C:\FDC2112.c" Line 100(8,18): Variable never used: addressLSB
|
In the code below, you have declared devId as an 'int'. In the PCM
compiler, an 'int' is an unsigned 8-bit integer. You can't successfully
compare it to a 16-bit constant. Change the declaration of 'devId' to an int16.
Quote: |
int1 FDC2214_begin(char chanMask,char autoscanSeq, char deglitchValue, int1 intOsc) {
printf("FDC2214_begin");
int devId = read16FDC(FDC2214_DEVICE_ID);
//Checking the lighting of the device on the i2c line (sda, scl).
//If the values 0x3054 and 0x3055 are displayed; connected to the correct device
if (devId != 0x3054) {
if (devId != 0x3055) {
//two valid device ids for FDC2214 0x3054 and 0x3055
return false;
} |
Example:
Code: | int16 devID = read16FDC(FDC2214_DEVICE_ID); |
|
|
|
ressas
Joined: 15 Nov 2019 Posts: 135
|
|
Posted: Mon Dec 02, 2019 4:18 am |
|
|
I did both of you, but the result hasn't changed. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19430
|
|
Posted: Mon Dec 02, 2019 4:26 am |
|
|
You are sure you have put the FDC2214_RCOUNT_CH0 define back to the
correct value?. |
|
|
ressas
Joined: 15 Nov 2019 Posts: 135
|
|
Posted: Mon Dec 02, 2019 4:40 am |
|
|
Quote: |
if (chanMask & 0x01) {
//settle count maximized, slow application
write16FDC(FDC2214_SETTLECOUNT_CH0, 0x6400); // 0x6400
//rcount maximized for highest accuracy
write16FDC(FDC2214_RCOUNT_CH0, 0x0400); //0xFFFF //0x400 //0x4000
//I try the all of them
//no offset
write16FDC(FDC2214_OFFSET_CH0, 0x0000);
// Set clock dividers
write16FDC(FDC2214_CLOCK_DIVIDERS_CH0, 0x2001); //0x2001
//set drive register
write16FDC(FDC2214_DRIVE_CH0, 0xF800); //0xF800
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19430
|
|
Posted: Mon Dec 02, 2019 6:10 am |
|
|
The point is have you set the #define back to it's correct value. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Dec 02, 2019 6:16 am |
|
|
He wants you to put it like this, and leave it that way:
Code: | #define FDC2214_RCOUNT_CH0 0x08 |
|
|
|
ressas
Joined: 15 Nov 2019 Posts: 135
|
|
Posted: Mon Dec 02, 2019 7:08 am |
|
|
YES I did it that way. I do exactly what you say. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19430
|
|
Posted: Mon Dec 02, 2019 7:26 am |
|
|
OK. If is is reading 4095, then this is what the chip gives for 'over range':
0xfff = over range
You probably need to look at changing your selected Fref depending on how
your sense circuit is laid out. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9196 Location: Greensville,Ontario
|
|
Posted: Mon Dec 02, 2019 7:26 am |
|
|
Your last program( 4-5 posts above) doesn't appear to have 'setup' or 'loaded' any registers with 'configuration' data.
While you do include the 'driver', that only contains functions to access the device. Main() has to config or init a LOT of registers before you try to read data from it.
Please post your current program so that we can see exactly what you're doing. As pointed out ....rcount... has to be loaded with 0x400 as well.
Jay |
|
|
|
|
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
|