Sari la conținut
ELFORUM - Forumul electronistilor

MAX531 cu Arduino


Vlad Mihai

Postări Recomandate

Salut, vreau sa controlez    folosind   2 butoane un DAC pe 12bit de la Maxim ce comunica pe SPI. Citind   catalogul nu prea am priceput mare lucru si nu m-am jucat   niciodata cu  acest tip de comunicatie.

Eu o sa incerc si eu maine sa   vad ce  reusesc dar o sa am nevoie de ajutor.Este cineva   dispus sa  ma ajute cu  idei/bucati de cod? Multumesc anticipat!

// include the library code:#include <SPI.h> // Set Constantsconst int dacChipSelectPin = 9;      // set pin 9 as the chip select for the DAC:const int clr = 12;// Start setup function:void setup() {    pinMode (dacChipSelectPin, OUTPUT);   // set the ChipSelectPins high initially:   digitalWrite(dacChipSelectPin, HIGH);    // initialise SPI:  SPI.begin();  } // End setup function.// Start loop function:void loop() {    setDac(200,0);  setDac(4000,1);}// End of loop function.// Function to set the DAC, Accepts the Value to be sent and the cannel of the DAC to be used.void setDac(int value, int channel) {  byte dacRegister = 0b00110000;                        // Sets default DAC registers B00110000, 1st bit choses DAC, A=0 B=1, 2nd Bit bypasses input Buffer, 3rd bit sets output gain to 1x, 4th bit controls active low shutdown. LSB are insignifigant here.  int dacSecondaryByteMask = 0b0000000011111111;        // Isolates the last 8 bits of the 12 bit value, B0000000011111111.  byte dacPrimaryByte = (value >> 8) | dacRegister;     //Value is a maximum 12 Bit value, it is shifted to the right by 8 bytes to get the first 4 MSB out of the value for entry into th Primary Byte, then ORed with the dacRegister    byte dacSecondaryByte = value & dacSecondaryByteMask; // compares the 12 bit value to isolate the 8 LSB and reduce it to a single byte.   // Sets the MSB in the primaryByte to determine the DAC to be set, DAC A=0, DAC B=1  switch (channel) {   case 0:     dacPrimaryByte &= ~(1 << 7);        break;   case 1:     dacPrimaryByte |= (1 << 7);    }  noInterrupts(); // disable interupts to prepare to send data to the DAC  digitalWrite(dacChipSelectPin,LOW); // take the Chip Select pin low to select the DAC:  SPI.transfer(dacPrimaryByte); //  send in the Primary Byte:  SPI.transfer(dacSecondaryByte);// send in the Secondary Byte  digitalWrite(dacChipSelectPin,HIGH);// take the Chip Select pin high to de-select the DAC:  interrupts(); // Enable interupts}
Editat de Vlad Mihai
Link spre comentariu
  • Răspunsuri 35
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • Vlad Mihai

    18

  • Liviu M

    14

  • Mircea

    3

  • nico_2010

    1

Top autori în acest subiect

Imagini postate

Salut, multumesc pentru raspunsuri:

Thunderer:  trebuie musai sa folosesc  Arduino, si are  librarie  SPI.

nico_2010: am citit  libraria si  incerc sa fac ceva asa ca ama nevoie de  tot ajutorul posibil

Astea  sunt configuratia  pe care am ales-o si codurile pe  care trebuie sa le trimit catre DAC .

Posted Image

 

Deci   acest  DAC vreau sa il controlez   din  LabVIEW pe serial cu ajutorul platformei Arduino, Postez  codul pe care l-am facut pana acum:

// inslude the SPI library:#include <SPI.h> const int slaveSelectPin = 10;  // set pin 10 as the slave selectconst int clearpin=9;          //set pin 9   for  clear DAC >> optionalint max_value=4095;             // max  value   for DACint min_value=0;                //min value dor DACint value;int AByte = 0;void setup() {  Serial.begin(9600);// set the slaveSelectPin as an output:  pinMode (slaveSelectPin, OUTPUT);   // initialize SPI:  SPI.begin();   }void loop() {  digitalWrite(clearpin, LOW);   AByte = Serial.read();   if ((AByte == 'W' ) && (value < max_value)) {     //incrementare DAC    increment; }       AByte = Serial.read();   if ((AByte == 'S')  && (value >min_value)) {      //decrementare DAC     decrement;   }      delay(80);}void increment(){}void decrement(){}

 

Acum ma  documentez sa vad care e treaba cu cei  16 biti.

Editat de Vlad Mihai
Link spre comentariu
  • 3 săptămâni mai târziu...

Serial InterfaceSixteen bits of serial data are clocked into the DAC MSBfirst with the MSB preceded by four fill (dummy) bits. Thefour dummy bits are not normally needed. The seri-al input data is held in a 16-bit serial shift register. On CS’srising edge, the 12 least significant bits are transferred tothe DAC register and update the DAC.

Cu configuiratia din primul post, mi-e imi iese o functie de transfer de genul: 
// Function to send 2 bytes to the dacvoid setDac(uint8_t highData, uint8_t lowData) {  digitalWrite(dacChipSelectPin,LOW); // take the Chip Select pin low to select the DAC:  SPI.transfer(highData); //  send in the Primary Byte:  SPI.transfer(lowData);// send in the Secondary Byte  digitalWrite(dacChipSelectPin,HIGH);// take the Chip Select pin high to de-select the DAC:  interrupts(); // Enable interupts}
Trebuie ca inainte sa chemi functia sa calculezi cei doi octeti, highData & lowData. Editat de Liviu M
Link spre comentariu

Da, asa ar trebui.M-am mai uitat acum la arduino.cc si ai mai putea:- seta ordinea bitilor (desi eu cred ca MSB first e default, eu n-am vazut circuite care sa mearga altfel):SPI.setBitOrder(MSBFIRST);- modul SPI (aici arduino.cc trimite la wikipedia). In functie de cum sta ceasul in idle (sus sau jos) si care front de ceas e activ (crescator/cazator), ies mai multe moduri ($ ?) in care comunicati SPI poate functiona.

M-am mai uitat acum si la tine ar fi:SPI.setDataMode(SPI_MODE1);

 

(CPOL = CPHA = 0)

 

 

Si ai putea sa incerci cu un SCK ceva mai lent, folosind un divider mai mare: SPI.setClockDivider(SPI_CLOCK_DIV8). Default pare sa fie SPI_CLOCK_DIV4, care da o frecventa SCK de 4MHz. Cu DIV8 ai obtine 2MHz. Poate ajuta.

Editat de Liviu M
Link spre comentariu

Idee e ca nu am lucrat cu SPI deloc...

Cam asa ar arata  codul, vreo idee daca e corect/incorect/incomplet?:

// inslude the SPI library:#include <SPI.h>const int slaveSelectPin = 10;  // set pin 10 as the slave selectconst int clrPin=9;          //set pin 9   for  clear DAC >> optionalint max_value=4095;             // max  value   for DACint min_value=0;                //min value dor DACint value;int AByte = 0;int data = 0b111111111111; //  desired DAC output -2.048Vvoid setup() {  Serial.begin(9600);// set the slaveSelectPin as an output:  pinMode (slaveSelectPin, OUTPUT);   digitalWrite (slaveSelectPin, HIGH);    pinMode (clrPin,OUTPUT);  digitalWrite (clrPin, HIGH);      // clear DAC  // initialize SPI:  SPI.begin();   SPI.setBitOrder(MSBFIRST);}void loop() {  setDac();  digitalWrite (slaveSelectPin, LOW);  SPI.transfer (data);  digitalWrite (slaveSelectPin, HIGH);   delay(80);}// Function to send 2 bytes to the dacvoid setDac(uint8_t highData, uint8_t lowData) {  digitalWrite(slaveSelectPin,LOW); // take the Chip Select pin low to select the DAC:  SPI.transfer(highData); //  send in the Primary Byte:  SPI.transfer(lowData);// send in the Secondary Byte  digitalWrite(dacChipSelectPin,HIGH);// take the Chip Select pin high to de-select the DAC:  interrupts(); // Enable interupts}
Editat de Vlad Mihai
Link spre comentariu

Le-ai ametit de tot. :rade: Daca n-am gresit la numarat bitii, mie ca sa fac iesirea 1/2 Vref imi iese programul:

// inslude the SPI library:#include <SPI.h>const int slaveSelectPin = 10;  // set pin 10 as the slave selectconst int clrPin=9;          //set pin 9   for  clear DAC >> optionalint max_value=4095;             // max  value   for DACint min_value=0;                //min value dor DACint value;int AByte = 0;int data = 0b111111111111; //  desired DAC output -2.048Vvoid setup() {  Serial.begin(9600);// set the slaveSelectPin as an output:  pinMode (slaveSelectPin, OUTPUT);   digitalWrite (slaveSelectPin, HIGH);    pinMode (clrPin,OUTPUT);  digitalWrite (clrPin, HIGH);      // clear DAC  // initialize SPI:  SPI.begin();   SPI.setBitOrder(MSBFIRST);}void loop() {   uint8_t dalaLow = 0xFF;  uint8_t dataHigh = 0x07;  setDac(dataHigh, dataLow);   delay(8000);}// Function to send 2 bytes to the dacvoid setDac(uint8_t highData, uint8_t lowData) {  digitalWrite(slaveSelectPin,LOW); // take the Chip Select pin low to select the DAC:  SPI.transfer(highData); //  send in the Primary Byte:  SPI.transfer(lowData);// send in the Secondary Byte  digitalWrite(slaveSelectPin,HIGH);// take the Chip Select pin high to de-select the DAC:}
Acum vad ca aveai si o variabila data: 
// inslude the SPI library:#include <SPI.h>const int slaveSelectPin = 10;  // set pin 10 as the slave selectconst int clrPin=9;          //set pin 9   for  clear DAC >> optionalint max_value=4095;             // max  value   for DACint min_value=0;                //min value dor DACint value;int AByte = 0;int data = 0b111111111111; //  desired DAC output -2.048Vvoid setup() {  Serial.begin(9600);// set the slaveSelectPin as an output:  pinMode (slaveSelectPin, OUTPUT);   digitalWrite (slaveSelectPin, HIGH);    pinMode (clrPin,OUTPUT);  digitalWrite (clrPin, HIGH);      // clear DAC  // initialize SPI:  SPI.begin();   SPI.setBitOrder(MSBFIRST);}void loop() {   uint8_t dalaLow = data&0xFF;  uint8_t dataHigh = (data >> 8) & 0x0F;  setDac(dataHigh, dataLow);   delay(8000);}// Function to send 2 bytes to the dacvoid setDac(uint8_t highData, uint8_t lowData) {  digitalWrite(slaveSelectPin,LOW); // take the Chip Select pin low to select the DAC:  SPI.transfer(highData); //  send in the Primary Byte:  SPI.transfer(lowData);// send in the Secondary Byte  digitalWrite(slaveSelectPin,HIGH);// take the Chip Select pin high to de-select the DAC:}
Link spre comentariu

Referitor la comunicatia spi, dupa parerea mea e mai "usoara" decat i2c.In cazul de fata, cel putin, DAC-ul se comporta practic ca un registru de deplasare de 16 biti, singura conditie fiind ca datele sa vina MSB first.Cum Arduino stie sa trasmita pachete de cate 8 biti, trebuie sa trimiti 2 pachete, MSB si LSB (in ordinea asta, ca sa respecti cerinta MSB first, altfel obtii alte tensiuni decat cele dorite).DEBUG!!Pai depaneaza, ca de-aia esti programator. Vezi ca am scris gresit dataLow. :rade:

In loc de

uint8_t dalaLow = 0xFF;

trebuie

uint8_t dataLow = 0xFF;
Editat de Liviu M
Link spre comentariu

Am     gasit  intre timp, dar tot nu merge, iesirea e 89mV. asa era si inainte cand ma jucam eu...

 

PS: sunt electronist nu programator :wretre

Link spre comentariu

Hardware sunt toate conexiunile bine facute, da?

Pentru ca in primul post ai CS pe pinul 9, in urmatoarele pe 10.

Nu pui o descriere a legaturilor?

Link spre comentariu

Deci:

 DIN duce la MOSi (DIGITAL12)

 SCLK duce la SCK (DIGITAL 13)

 SS duce la  DIGITAL 10

 Clearpin duce la   digital 9.

 

Acum am 1.92 la iesire.  Atat trebuia sa am?

Link spre comentariu

La arduino.cc, pentru arduino uno pe 12 e MISO, MOSI e pe 11.Eu as evita sa folosesc pinul 10, pentru ca e oarecum dedicat pentru cazul in care arduino e slave (ma rog, parca asa am inteles eu de prin documentatii). Incearca sa conectezi SS (CS) la un alt pin la arduino.Am inteles gresit, poti folosi pinul 10 pe post de CS (SS):

Note about Slave Select (SS) pin on AVR based boardsAll AVR based boards have an SS pin that is useful when they act as a slave controlled by an external master. Since this library supports only master mode, this pin should be set always as OUTPUT otherwise the SPI interface could be put automatically into slave mode by hardware, rendering the library inoperative.It is, however, possible to use any pin as the Slave Select (SS) for the devices. For example, the Arduino Ethernet shield uses pin 4 to control the SPI connection to the on-board SD card, and pin 10 to control the connection to the Ethernet controller.

LE Ba cred ca intelesesem bine. Cel mai bine evita pinul 10. Editat de Liviu M
Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări