Vlad Mihai Postat Martie 10, 2015 Partajează Postat Martie 10, 2015 (editat) 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 Martie 10, 2015 de Vlad Mihai Link spre comentariu
Mircea Postat Martie 10, 2015 Partajează Postat Martie 10, 2015 (editat) Daca-ti schimbi ideea cu folosirea Arduino, uite cum il poti controla in MikroC (am ales PIC, dar merge cu orice controller): http://www.mikroe.com/download/eng/documents/compilers/mikroc/pro/pic/help/spi_library.htmEste SPI-ul hardware, exista si software. Dar sigur are si Arduino o biblioteca SPI. Editat Martie 10, 2015 de thunderer Link spre comentariu
nico_2010 Postat Martie 11, 2015 Partajează Postat Martie 11, 2015 Codul postat de tine este neadecvat controlului MAX531 (DAC-ul nu are doua canale, iar datele trebuie transmise in format de 16 biti, cate 8 biti pe rand, cu conditia "MSB first"). Citeste cu atentie explicatiile aferente librariei SPI aici: http://arduino.cc/en/Reference/SPI. Link spre comentariu
Vlad Mihai Postat Martie 11, 2015 Autor Partajează Postat Martie 11, 2015 (editat) 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 . subir fotos gratis 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 Martie 11, 2015 de Vlad Mihai Link spre comentariu
Liviu M Postat Martie 26, 2015 Partajează Postat Martie 26, 2015 (editat) 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 Martie 26, 2015 de Liviu M Link spre comentariu
Vlad Mihai Postat Martie 26, 2015 Autor Partajează Postat Martie 26, 2015 Multumesc Liviu, deci ramane sa integrez ceea ce mi-ai dat tu in codul meu si dupa sa calculez biti pentru tensiunea setata? Link spre comentariu
Liviu M Postat Martie 26, 2015 Partajează Postat Martie 26, 2015 (editat) 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 Martie 26, 2015 de Liviu M Link spre comentariu
Vlad Mihai Postat Martie 26, 2015 Autor Partajează Postat Martie 26, 2015 (editat) 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 Martie 26, 2015 de Vlad Mihai Link spre comentariu
Liviu M Postat Martie 26, 2015 Partajează Postat Martie 26, 2015 Le-ai ametit de tot. 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
Vlad Mihai Postat Martie 26, 2015 Autor Partajează Postat Martie 26, 2015 Multumesc, dar imi da eroare la compilare, daLow nu e declarat sau ceva de genul... Link spre comentariu
Liviu M Postat Martie 26, 2015 Partajează Postat Martie 26, 2015 (editat) 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. In loc de uint8_t dalaLow = 0xFF; trebuie uint8_t dataLow = 0xFF; Editat Martie 26, 2015 de Liviu M Link spre comentariu
Vlad Mihai Postat Martie 26, 2015 Autor Partajează Postat Martie 26, 2015 Am gasit intre timp, dar tot nu merge, iesirea e 89mV. asa era si inainte cand ma jucam eu... PS: sunt electronist nu programator Link spre comentariu
Liviu M Postat Martie 26, 2015 Partajează Postat Martie 26, 2015 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
Vlad Mihai Postat Martie 26, 2015 Autor Partajează Postat Martie 26, 2015 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
Liviu M Postat Martie 26, 2015 Partajează Postat Martie 26, 2015 (editat) 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 Martie 26, 2015 de Liviu M Link spre comentariu
Postări Recomandate
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 contAutentificare
Ai deja un cont? Autentifică-te aici.
Autentifică-te acum