eyecwan 发表于 2014-4-30 07:12:29

【分享】ISD 1760PY 录音模块的arduino代码

在arduino uno调试成功,代码源于链接下。修改了两处错误。

按照文件头定义连接arduino和1760py口。模块淘宝买的28rmb。

http://forum.arduino.cc/index.php/topic,96463.0.html

//define pins
#define DATAOUT   11   //mosi
#define DATAIN        12   //miso
#define SPICLOCK    13   //sck
#define SLAVESELECT 10   //ss

//opcodes
#define PU          0x01
#define STOP          0x02
#define RESET       0x03
#define CLR_INT   0x04
#define RD_STATUS   0x05
#define RD_PLAY_PTR 0x06
#define PD          0x07
#define RD_REC_PTR0x08
#define DEVID       0x09
#define PLAY          0x40
#define REC           0x41
#define REC_LED           0x51//record with LED on
#define ERASE       0x42
#define G_ERASE   0x43
#define RD_APC        0x44
#define WR_APC1   0x45
#define WR_APC2   0x65
#define WR_NVCFG    0x46
#define LD_NVCFG    0x47
#define FWD           0x48
#define CHK_MEM   0x49
#define EXTCLK        0x4A
#define SET_PLAY    0x80
#define SET_REC   0x81
#define SET_REC_LED    0x91//set record with LED on
#define SET_ERASE   0x82

#define WAIT_TIME 10//waiting time (ms) after SS=LOW at least 500ns
#define WAIT_TIME2 100

int start_adress = 0x010;//test address to record
int end_adress = 0x024;//20unit

void setup() {
pinMode(DATAOUT, OUTPUT);
pinMode(DATAIN, INPUT);
pinMode(SPICLOCK, OUTPUT);
pinMode(SLAVESELECT, OUTPUT);

initialize();
}

void initialize()
{
   byte clr;
   
digitalWrite(SLAVESELECT, HIGH); //disable device
digitalWrite(SPICLOCK, HIGH); //SCLK
digitalWrite(DATAOUT, LOW); //MOSI

SPCR = B01111111; //data lsb, clock high when idle, samples on falling
clr = SPSR;
clr = SPDR;
delay(10);

//start serial
Serial.begin(9600);
Serial.println("Sketch is starting up");

pu();
clear_int();
}

void loop()
{
    char c;
    boolean f;
    boolean rec_fg = false;
    boolean play_fg = false;
   
   if(Serial.available())
    {
       c = Serial.read();
      switch(c)
      {
         case '0':
         initialize();
         break;
         case '1':
         set_erase(start_adress, end_adress);
         break;
         case '2':
         set_rec(start_adress, end_adress);
         rec_fg = true;
         break;
         case '3':
         set_play(start_adress, end_adress);
         play_fg = true;
         break;
         case 'l':
         clear_int();
         break;
         case 'y':
         play();
         play_fg = true;
         break;
         case 'r':
         rec();
         rec_fg = true;
         break;
         case 'f':
         fwd();
         break;
         case 'z':
         eraseAll();
         break;
         case 'e':
         erase();
         break;
         case 'p':
         stop();
         break;
         case 's':
         reset();
         break;
         case 'a':
         write_apc(true, false, 7);//mic in & no moniter on recording
         break;
         case 'b':
         write_apc(false, false, 7);//analog in & no moniter on recording
         break;
         case 'c':
         Serial.println(read_apc(), BIN);//read apc
         break;
         case 'd':
         Serial.println(read_status(), BIN);//read status
      }
    }
      
    if(play_fg == true)
    {
      ready_play_wait();
      play_fg = false;
    }
    if(rec_fg == true)
    {
      ready_rec_check();
      rec_fg = false;
    }
}

void pu()//power up
{
digitalWrite(SLAVESELECT, LOW);
delay(WAIT_TIME);
spi_transfer(PU); // power up
spi_transfer(0x00); // data byte
digitalWrite(SLAVESELECT, HIGH);
delay(WAIT_TIME2);

Serial.println("power up end");
}

void clear_int()// clear interupt
{
   digitalWrite(SLAVESELECT, LOW);
   delay(WAIT_TIME);
   spi_transfer(CLR_INT); // clear interupt and eom bit
   spi_transfer(0x00); // data byte
   digitalWrite(SLAVESELECT, HIGH);
   delay(WAIT_TIME2);
   Serial.println("clear int end");
}

void reset()// reset
{
digitalWrite(SLAVESELECT, LOW);
delay(WAIT_TIME);
spi_transfer(RESET); // resett
spi_transfer(0x00); // data byte
digitalWrite(SLAVESELECT, HIGH);
delay(WAIT_TIME2);

Serial.println("reset end");
}

void play()
{
digitalWrite(SLAVESELECT, LOW);
delay(WAIT_TIME);
spi_transfer(PLAY); // play
spi_transfer(0x00); // data byte
digitalWrite(SLAVESELECT, HIGH);
delay(WAIT_TIME2);

Serial.println("play start");
}

void stop()
{
digitalWrite(SLAVESELECT, LOW);
delay(WAIT_TIME);
spi_transfer(STOP); // stop
spi_transfer(0x00); // data byte
digitalWrite(SLAVESELECT, HIGH);
delay(WAIT_TIME2);

Serial.println("stop end");
}

void rec()
{
   uint8_t data = {0xFF,0xFF};
   
digitalWrite(SLAVESELECT, LOW);
delay(WAIT_TIME);
//spi_transfer(REC);// record
data = spi_transfer(REC_LED);// record with LED on
data = spi_transfer(0x00); // data byte
digitalWrite(SLAVESELECT, HIGH);

delay(WAIT_TIME2);
}

void set_erase(int starta, int enda)
{
digitalWrite(SLAVESELECT, LOW);
delay(WAIT_TIME);
spi_transfer(SET_ERASE); // clear interupt and eom bit
spi_transfer(0); // data byte

spi_transfer(starta & 255); // data byte start
spi_transfer(starta >> 8); // data byte last 3 bits
spi_transfer(enda & 255); // data byte stop
spi_transfer(enda >> 8); // data byte last 3 bits
spi_transfer(0); // data byte blank
digitalWrite(SLAVESELECT, HIGH);
delay(WAIT_TIME2);

Serial.println("set erase end");
}

void set_play(int starta, int enda)
{
digitalWrite(SLAVESELECT, LOW);
delay(WAIT_TIME);
spi_transfer(SET_PLAY); // clear interupt and eom bit
spi_transfer(0); // data byte

spi_transfer(starta & 255); // data byte start
spi_transfer(starta >> 8); // data byte last 3 bits
spi_transfer(enda & 255); // data byte stop
spi_transfer(enda >> 8); // data byte last 3 bits
spi_transfer(0); // data byte blank
digitalWrite(SLAVESELECT, HIGH);
delay(WAIT_TIME2);

Serial.println("set play end");
}

void set_rec(int starta, int enda)
{
digitalWrite(SLAVESELECT, LOW);
delay(WAIT_TIME);
//spi_transfer(SET_REC); // clear interupt and eom bit
spi_transfer(SET_REC_LED);//set record with LED on
spi_transfer(0); // data byte

spi_transfer(starta & 255); // data byte start
spi_transfer(starta >> 8); // data byte last 3 bits
spi_transfer(enda & 255); // data byte stop
spi_transfer(enda >> 8); // data byte last 3 bits
spi_transfer(0); // data byte blank
digitalWrite(SLAVESELECT, HIGH);
delay(WAIT_TIME2);

Serial.println("set rec end");
}

void erase()
{
digitalWrite(SLAVESELECT, LOW);
delay(WAIT_TIME);
spi_transfer(ERASE);// erase
spi_transfer(0x00); // data byte
digitalWrite(SLAVESELECT, HIGH);
delay(WAIT_TIME2);

Serial.println("erase end");
}

void eraseAll()
{
digitalWrite(SLAVESELECT, LOW);
delay(WAIT_TIME);
spi_transfer(G_ERASE);// g_erase
spi_transfer(0x00); // data byte
digitalWrite(SLAVESELECT, HIGH);
delay(WAIT_TIME2);

Serial.println("erase all end");
}

void fwd()
{
digitalWrite(SLAVESELECT, LOW);
delay(WAIT_TIME);
spi_transfer(FWD); // forward
spi_transfer(0x00); // data byte
digitalWrite(SLAVESELECT, HIGH);
delay(WAIT_TIME2);

Serial.println("forward end");
}

void ready_play_wait()
{
byte byte1;
byte byte2;
byte byte3;

while(byte3 << 7 != 128)
{
    digitalWrite(SLAVESELECT, LOW);
    delay(WAIT_TIME);
    byte1 = spi_transfer(RD_STATUS); // clear interupt and eom bit
    byte2 = spi_transfer(0x00); // data byte
    byte3 = spi_transfer(0x00); // data byte
    digitalWrite(SLAVESELECT, HIGH);
    delay(WAIT_TIME2);
}

delay(100);

Serial.println("play end");
}

void ready_rec_check()
{
byte byte1;
byte byte2;
byte byte3;

while(byte3 << 7 == 128)
{
    digitalWrite(SLAVESELECT, LOW);
    delay(WAIT_TIME);
    byte1 = spi_transfer(RD_STATUS); // clear interupt and eom bit
    byte2 = spi_transfer(0x00); // data byte
    byte3 = spi_transfer(0x00); // data byte
    digitalWrite(SLAVESELECT, HIGH);
    delay(WAIT_TIME2);
}

delay(100);

Serial.println("rec start");
}

char spi_transfer(volatile char data)
{
SPDR = data;         // Start the transmission
while (!(SPSR & (1 << SPIF)))   // Wait for the end of the transmission
{
};
return SPDR;         // return the received byte
}

//flag : false=analog in/true=mic in
//flag2 : false=no monitor on recording / true=monitor on recording
//vol : volume max=7 min=0
void write_apc(boolean flag, boolean flag2, int vol)
{
    uint16_t d;
      d = 0x00;
    }
    if(flag == true)
      d = 0x01;
    if(flag2 == true)
      d = 0x01;
      
    int vv = 7 - vol;
      
    d = vv & 0x01;
    d = vv & 0x02;
    d = vv & 0x04;
   
    uint16_t apc =(d | d << 1 | d << 2 | d << 3 | d << 4 | d << 5 | d << 6 | d << 7 | d << 8 | d << 9 | d << 10 | d << 11);
      
    digitalWrite(SLAVESELECT, LOW);
    delay(WAIT_TIME);
    spi_transfer(WR_APC2); // write apc register 2
    spi_transfer(apc & 0xFF); // data byte start
    spi_transfer(apc >> ; // data byte last 3 bits

    digitalWrite(SLAVESELECT, HIGH);
   
    delay(WAIT_TIME2);
   
    Serial.println("write apc end");
}

uint16_t read_apc()
{
uint16_t apc;
uint8_t data = {0xFF,0xFF,0xFF,0xFF};

digitalWrite(SLAVESELECT, LOW);
delay(WAIT_TIME);
data = spi_transfer(RD_APC); // read apc register
data = spi_transfer(0);
data = spi_transfer(0);
data = spi_transfer(0);
digitalWrite(SLAVESELECT, HIGH);

delay(WAIT_TIME2);

apc = word(data, data);

Serial.println("read apc end");

return apc;
}

uint16_t read_status(void)
{
uint16_t sr1;
uint8_t data = {0xFF,0xFF,0xFF};

digitalWrite(SLAVESELECT, LOW);
delay(WAIT_TIME);
data = spi_transfer(RD_STATUS); // read status register
data = spi_transfer(0);
data = spi_transfer(0);
digitalWrite(SLAVESELECT, HIGH);

delay(WAIT_TIME2);

sr1 = word(data, 0xFF);
return sr1;
}

弘毅 发表于 2014-4-30 08:51:36

不错。。代码好长~

eyecwan 发表于 2014-4-30 08:55:33

这个是刚看到的一个官网的data sheet和使用指南,结合代码应该很容易理解

http://www.atvoc.com/rjxz/isd1700.pdf

Du_゜小草先生 发表于 2014-5-7 17:59:34

楼主,372行是不是有错?d=0x00是啥?

Du_゜小草先生 发表于 2014-5-7 18:06:13

弘毅 发表于 2014-4-30 08:51 static/image/common/back.gif
不错。。代码好长~

代码很长,错误很多391行移位,373行误入一个括号。。。
页: [1]
查看完整版本: 【分享】ISD 1760PY 录音模块的arduino代码