用Arduino控制AD5270 10位电位器

时间:2014-01-07 00:27:06

标签: macos arduino spi

我无法控制AD5270 10位数字电位器。似乎无论我写入寄存器,端子A和游标之间的电阻实际值都不会改变。我假设我遇到了“下降沿同步信号”的问题,具体来说,来自data sheet的第10页:

  

SYNC:下降沿同步信号。这是输入数据的帧同步信号。当SYNC变为低电平时,它使能移位寄存器,并在后续时钟的下降沿传输数据。所选寄存器在第16个时钟周期后的SYNC上升沿更新。如果SYNC在第16个时钟周期之前变为高电平,则SYNC的上升沿充当中断,RDAC忽略写入序列。

我一直把这个引脚看作SS引脚。到目前为止,就代码而言,这就是我所拥有的:

#include <SPI.h> 

 const int csPinCWF = 10; 

 const byte enableUpdateMSB = 0x1C; //B00011100
 const byte enableUpdateLSB = 0x02; //B00000010
 const byte command = 0x04; //B00000100

 void setup() {
  Serial.begin(9600);
  Serial.println("Ready");

  SPI.begin();
  Serial.println("SPI Begin");
  SPI.setBitOrder(MSBFIRST); //We know this from the Data Sheet
  SPI.setDataMode(SPI_MODE1); //Pg.7:Fig.3 states CPOL=0, CPHA=1 --> MODE1

  pinMode(csPinCWF,OUTPUT);
  Serial.println("Output Set");

  digitalWrite(csPinCWF, HIGH);
  Serial.println("Set pin to HIGH");
}

 void loop() {
 for(int i=0; i<1023; i++) { 
   Serial.println(i);
   enablePotWrite(csPinCWF);
   digitalPotWrite(csPinCWF, i);
   delay(5000);
  } 
}

 void digitalPotWrite(int csPin, int value) {
  Serial.println("In digitalPotWrite Now");
  digitalWrite(csPin, LOW); //select slave
  Serial.println("Set csPin to LOW");

  Serial.print("Command Byte is: ");
  Serial.println(command, BIN);

  byte shfitedValue = (value >> 8);
  Serial.print("Shifted bit value is: ");
  Serial.println(shfitedValue, BIN);

  byte byte1 = (command | shfitedValue);
  Serial.print("Byte1 is: "); 
  Serial.println(byte1, BIN);

  byte byte0 = (value & 0xFF); //0xFF = B11111111 trunicates value to 8 bits
  Serial.print("Byte0 is: ");
  Serial.println(byte0, BIN);

  //Write to the RDAC Register to move the wiper
  SPI.transfer(byte1);
  SPI.transfer(byte0);

  Serial.print("Transfered: ");
  Serial.print(byte1, BIN);
  Serial.print("    ");
  Serial.println(byte0, BIN);

  digitalWrite(csPin, HIGH); //de-select slave
  Serial.println("Set csPin back to HIGH, end of digitalPotWrite");
}

 void enablePotWrite(int csPin) { //Enable Update of the Wiper position through the digital interface
   digitalWrite(csPin, LOW); //select slave

   Serial.print("Enable byte is: ");
   Serial.print(enableUpdateMSB, BIN);
   Serial.print("    ");
   Serial.println(enableUpdateLSB, BIN);

   SPI.transfer(enableUpdateMSB); 
   SPI.transfer(enableUpdateLSB);

   digitalWrite(csPin, HIGH); //de-select slave
}

我已经过了很多次,看起来数学是正确的,它正在传输正确的字节,但我没有在终端A和雨刷之间得到任何改变。第19页:data sheet的表11显示了我应该传输的16位字的格式。任何人都可以了解我在这里可能缺少的东西吗?任何帮助将不胜感激,谢谢!

编辑:更改了我的代码以反映mpflaga的建议,但遗憾的是仍然没有骰子。

Edit2:SPI模式确实是SPI_MODE1。 PG。图7:数据表的图3表示CPOL = 0,CPHA = 1。编辑上面的代码以反映更改。再次感谢@mpflaga。

2 个答案:

答案 0 :(得分:1)

几个问题:

首先 -

根据数据表,第18页:

  

要启用RDAC寄存器的编程,写保护位(位   必须首先通过加载来编程控制寄存器的C1)   带命令7的串行数据输入寄存器

根据数据表第20页表14,显示默认C1为0,

  

0 =雨刮器位置冻结到50-TP内存中的值(默认)   ,如果之前没有编程,则为中间尺度。

通过最初发送0x1C03,参见表12的示例序列以使事物移动。我相信你可以用0x1C02代替,如果你不想启用编程而只想动态更新。


第二 -

从数据表中看,Din在时钟的下降沿采样。您需要在设置

中进行以下操作
SPI.setDataMode(SPI_MODE1);

这通常可能在MODE0(默认)下工作,数据速率较慢。

答案 1 :(得分:0)

我刚好正在使用AD5271(同样的东西,但是8位),我终于让它在Arduino Duemilanove上工作了。

这是我写的测试代码的工作副本:

#include <SPI.h>

const int SS_PIN = 10;
const int MOSI_PIN = 11;
const int MISO_PIN = 12;
const int CLK_PIN = 13;

// Writes to the control register enabling the RDAC register write access.
void initRheostat() {
    Serial.println("Writing Control Reg");
    byte upper = 0x1C;
    byte lower = 0x02;
    digitalWrite(SS_PIN, LOW);
    SPI.transfer(upper);
    SPI.transfer(lower);
    digitalWrite(SS_PIN, HIGH);
}

// Writes the value to the RDAC register.
void writeRheostat(byte val) {
    Serial.print("Writing to Rheostat... ");
    Serial.println(val);
    byte command = 0x01;
    byte upper = (command << 2) | (val >> 6);
    byte lower = val << 2;
    digitalWrite(SS_PIN, LOW);
    SPI.transfer(upper);
    SPI.transfer(lower);
    digitalWrite(SS_PIN, HIGH);
}

// Readsd the value in the RDAC register.
void readRheostat() {
    Serial.println("Reading rheostat...");
    digitalWrite(SS_PIN, LOW);
    byte upper = 0x80;
    byte response = SPI.transfer(upper);
    // Print the raw byte response.
    Serial.println(response, HEX);
    digitalWrite(SS_PIN, HIGH);
    digitalWrite(SS_PIN, LOW);
    byte lower = 0x00;
    // Print the raw byte response.
    byte secondResponse = SPI.transfer(lower);
    Serial.println(secondResponse, HEX);
    // Calculate the actual value and print it out.
    int value = ((response & 0x03) << 6) | (secondResponse >> 2);
    Serial.print("Actual Value: " );
    Serial.println(value);
    digitalWrite(SS_PIN, HIGH);
}

void setup() {
    Serial.begin(9600);
    // Initialize SPI
    pinMode(SS_PIN, OUTPUT);
    SPI.begin();
    // SPI_MODE1 (CPOL = 0, CPHA = 1) - From the datasheet
    SPI.setDataMode(SPI_MODE1);
    // MSBFIRST - From the data sheet
    SPI.setBitOrder(MSBFIRST);
    // Call to init and enable RDAC register write access.
    initRheostat();
}

void loop() {
    // Serial listener that sets the wiper to the specified value.
    while (Serial.available() > 0) {
        char inChar = Serial.read();
        writeRheostat(inChar);
        readRheostat();
    }
}

还要确保电路接线正确。您必须对10位的writeRheostat函数中的位移进行一些更改。

  • EXT_CAP应该有一个1uF电容连接到VSS
  • VDD需要使用10uF电容和0.1uF电容去耦(
  • SDO需要一个上拉电阻。

希望有所帮助。