Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
8 years, 8 months ago.
Trouble communication SPI
Hello, i want i send voltage to a component, which is regulated thanks to the AD5668. I wrote this code, but when i mesure the voltage, it kepps the same. Here is the code i wrote, maybe you could help me finding what's wrong :) Thanjks, Yann
#include "mbed.h"
#include "limits.h"
Serial pc(USBTX, USBRX);
SPI spi(PA_7, PA_6, PA_5); // mosi, miso, sclk
DigitalOut cs(PA_4);
int main() {
int rep =0;
int bit32[32];
int ch;
int choix;
// Chip must be deselected
// Setup the spi for 8 bit data, high steady state clock,
// second edge capture, with a 1MHz clock rate
spi.format(16,1);
spi.frequency(1000000);
//-----------------------Conversion de l'entier en 16 bits----------------------
long int decimalNumber,remainder,quotient;
int i=1,j,temp;
char hexadecimalNumber[100];
pc.printf("Ecrire dans le registre ADC(1)\n\n");
pc.printf("Mettre a jour le registre ADC(2)\n\n");
pc.printf("Ecrire et mettre a jour le registre ADC(3)\n\n");
pc.printf("Mise sous tension ou hors tension(4)\n\n");
pc.printf("Reinitialiser la mise sous tension (5)\n\n");
scanf("%d",&ch);
switch(ch) {
case 01:
pc.printf("Quel pourcentage de voltage (0-65535) ?\n");
scanf("%ld",&decimalNumber);
quotient = decimalNumber;
while(quotient!=0){
temp = quotient % 16;
//To convert integer into character
if( temp < 10)
temp =temp + 48;
else
temp = temp + 55;
hexadecimalNumber[i++]= temp;
quotient = quotient / 16;
}
pc.printf("Equivalent hexadecimal value of decimal number %d: ",decimalNumber);
for(j = i -1 ;j> 0;j--)
{ pc.printf("%c",hexadecimalNumber[j]); }
//------------------------------------------------------------------------------
// Select the device by seting chip select low
cs = 0;
rep = spi.write(0x00FFFFF0);
wait(0.5);
cs=1;
pc.printf("\n rep: %d \n",rep);
break;
case 02:
cs=0;
rep = spi.write(0x01F00000);
wait(0.5);
cs=1;
pc.printf("\n rep2: %d \n",rep);
pc.printf("Modification effectuee \n");
break;
case 03: pc.printf("Quel pourcentage de voltage (0-65535) ?\n");
scanf("%ld",&decimalNumber);
quotient = decimalNumber;
while(quotient!=0){
temp = quotient % 16;
//To convert integer into character
if( temp < 10)
temp =temp + 48;
else
temp = temp + 55;
hexadecimalNumber[i++]= temp;
quotient = quotient / 16;
}
pc.printf("Equivalent hexadecimal value of decimal number %d: ",decimalNumber);
for(j = i -1 ;j> 0;j--)
{ pc.printf("%c",hexadecimalNumber[j]); }
// Select the device by seting chip select low
cs = 0;
spi.write(0x0);
rep = spi.write(0x02FFFFF0);
wait(0.5);
cs=1;
pc.printf("\n rep: %d \n",rep);
break;
case 04: pc.printf("Souhaitez vous une mise en tension(1) ou hors tension (2) ?\n");
scanf("%d",&choix);
if (choix == 1) {
pc.printf("bien recu m\n");
}
else if (choix == 2) {
pc.printf("bien recu h\n");
} else {
pc.printf("Commande non reconnue\n");
}
break;
default: break;
}
}

Here is the method to write to the AD. Do we agree that 0x02FFFFF0 should set the maximum voltage value et apply it directly ?
2 Answers
8 years, 8 months ago.
You need to break your write up into two 16-bit transactions, or four 8-bit transactions in order to shift all 32 bits required. Make sure you shift the most significant byte or word first. (EDIT: I see you are trying something like this. Make sure you set the format back to 8 bits though if you are doing 4 transactions)
Thank you for your answer as you said, i tried it and it seems to work, but nos as correctly as it should ! How do you make sure you shift the most significant byte or word first ? And do i have to set the format at 16 or 32 ?
posted by 09 Mar 2017I would keep the format as 8 bit
spi.format(8,1);
and then shift the value out byte by byte such as
.... unsigned int val = 0xAABBCCDD; //whatever your 32-bit value to be written is .... spi.write((uint8_t)val>>24); spi.write((uint8_t)val>>16) spi.write((uint8_t)val>>8); spi.write((uint8_t)val); ...
I have not looked at your algorithm in detail but make sure you follow all of the required initialization in the datasheet.
Bill
posted by 10 Mar 2017So i just tried your method, and it doesn't seem to work, the voltage is still the same ? Is it possible to do it like below ?
spi.write((uint16_t)val>>16);
spi.write((uint16_t)val);
So i choose format (16,1) Plus, do i have to send bits in order to make the AD understand i want to "talk" to him before sending bit stream ? I am a bit confused
posted by 10 Mar 20178 years, 8 months ago.
The code above is very hard to read and understand. Please use the <<code>> and <</code>> tags to post your code.
Looks like you are setting up SPI in 16 bit mode
spi.format(16,1);
However, you send values as 32 bit. The SPI write will truncate that to the least significant 16 bits.
//Select the device by seting chip select low cs = 0; rep = spi.write(0x00FFFFF0); wait(0.5); cs=1;
I just tried to mesure the voltage again and by changing the lines, i succeeded in getting a 7.12V voltage (started at 1). But i sent the maximum 16 bit value (FFFF) and it doesn't get me the maximum voltage, why ?
// Select the device by seting chip select low cs = 0; spi.write(0x02); spi.write(0xFF); spi.write(0xA5); spi.write(0xF0); //wait(0.5); cs=1; pc.printf("\n rep: %d \n",rep)