![](/media/cache/profiles/03492e99e42e7ea8480cdfb4899604f5.50x50_q85.jpg)
Chua chaotic oscillator and MCP4922 DAC
Revision 0:e5edc0373da0, committed 2011-05-07
- Comitter:
- JLS
- Date:
- Sat May 07 19:27:14 2011 +0000
- Commit message:
Changed in this revision
diff -r 000000000000 -r e5edc0373da0 MCP4922.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MCP4922.cpp Sat May 07 19:27:14 2011 +0000 @@ -0,0 +1,156 @@ +/* + * MCP4922 - DAC library. + */ + +#include "mbed.h" +#include "MCP4922.h" + +using namespace mbed; + +int dac =0; + +MCP4922::MCP4922(PinName mosi, PinName sclk, PinName cs) : _spi(mosi, NC, sclk) { + + int i; + _ndacs = 1; + _ncs_array = new DigitalOut*[ _ndacs ]; + for (i=0; i<_ndacs; i++) { + _ncs_array[i] = new DigitalOut(cs); + } + + // Initialise the DAC SPI interface. + _init(); +} + +// Destructor +MCP4922::~MCP4922() { + + // Before destroying the object, shut down all the chips. + //shdn_all(); + + // Delete all the NCS DigitalOut objects and the array pointing to + // them. + int i; + for (i=0; i<_ndacs; i++) { + delete _ncs_array[i]; + } + delete [] _ncs_array; + + // Delete the LDAC DigitalOut object if it exists. + if (_latched ) delete _nldac; +} + +// Initialise SPI interface. +void MCP4922::_init() { + + // Set up the SPI for 16-bit values (12-bit + 4 command bits) and mode 0. + _spi.format(16, 0); + + // Start with all the CS and LDAC signals high (disabled) + int i; + for (i=0; i<_ndacs; i++) { + _ncs_array[i]->write(1); + } + + if (_latched ) _nldac->write(1); + return; +} + +// Set SPI clock frequency. +void MCP4922::frequency( int freq ) { + + // Set the SPI interface clock frequency in Hz. + _spi.frequency( freq ); + return; +} + +/* + * Note: There is a lot of code in common between the following 4 functions. + * The code is kept in line to keep it efficient. Could the functions have + * been written as templates? + */ +// Write to DAC channel A with gain 1. +void MCP4922::writeA(int value) { + + // Set up the command register with the appropriate value. + // For efficiency, the caller is assumed to have checked dac. + int reg; + //int dac = 0; + reg = (value & 0x0FFF) | MCP4922_REG_A1; + + // Select the DAC chip, write to its command register and + // then unselect the DAC chip. + _ncs_array[dac]->write(0); + _spi.write(reg); + _ncs_array[dac]->write(1); + return; +} + +// Write to DAC channel B with gain 1. +void MCP4922::writeB(int value) { + + // Set up the command register with the appropriate value. + // For efficiency, the caller is assumed to have checked dac. + int reg; + reg = (value & 0x0FFF) | MCP4922_REG_B1; + + // Select the DAC chip, write to its command register and then + // unselect the DAC chip. + _ncs_array[dac]->write(0); + _spi.write(reg); + _ncs_array[dac]->write(1); + return; +} + +// Write an array of values to the DACs. +void MCP4922::write(int nchans, int values[], int gain, int latch) { + + // nchans must be at least 1 but less than or equal to ndacs x 2. + if (nchans < 1) nchans = 1; + const int maxchans = _ndacs * 2; + if (nchans > maxchans) nchans = maxchans; + + if (latch && _latched) + latch_disable(); + + int i; + + for (i=0; i<nchans;) { + dac = i/2; + writeA(values[i]); + i++; + if (i < nchans) { + writeB(values[i]); + i++; + } else break; + } + + // Automatically latch the new voltages if the latch flag is 1. + if (latch && _latched) + latch_enable(); + return; +} + +// Set latch signal to "enable". +void MCP4922::latch_enable() { + + // Latch all chips. There should be a delay of at least T_LS=40 + // nanoseconds between the last CS rising edge and the LDAC falling + // edge. The software function calls seem to be sufficient to + // introduce that delay. A delay may be inserted here if this + // software is ported to a faster processor. + if (_latched) _nldac->write(0); + // The LDAC pulse width must be at least T_LD=100 nanoseconds long. + // A delay can be inserted here if necessary, but so far this has + // not been needed (see above). + return; +} + +// Set latch signal to "disable". +void MCP4922::latch_disable() { + + // Disable latch for all chips. + if (_latched) _nldac->write(1); + return; +} +
diff -r 000000000000 -r e5edc0373da0 MCP4922.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MCP4922.h Sat May 07 19:27:14 2011 +0000 @@ -0,0 +1,80 @@ +/* + * MCP4922 - DAC library. + * + * Copyright (c) 2011 Steven Beard, UK Astronomy Technology Centre. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "mbed.h" + +#ifndef MCP4922_H +#define MCP4922_H + +/* Reference: Microchip Technology (2005), MCP4821/MCP4822 DAC Data Sheet. */ + +// MCP4922 reference voltage. +#define MCP4922_VREF 2048 // Reference voltage (mV) + +/* Define possible combinations of 16-bit command register bits */ +#define MCP4922_REG_A1 0x3000 // Channel A gain 1 +#define MCP4922_REG_B1 0xB000 // Channel B gain 1 +#define MCP4922_REG_SHDN 0x0000 // Output power down + +class MCP4922 { +public: + + MCP4922 (PinName mosi, PinName sclk, PinName cs); + + ~MCP4922(); + + /*+ + * frequency: Set the SPI bus clock frequency in Hz. + * The SPI bus frequency in Hz. Must be within the range + * supported by both the SPI interface and the DAC chips + * (~10 KHz to 20 MHz). + */ + void frequency( int freq ); + + void writeA(int value ); + + void writeB(int value ); + + void write( int nchans, int values[], int gain=2, int latch=1 ); + + void latch_enable(); + + void latch_disable(); + +private: + + MCP4922( const MCP4922& rhs ); + + void _init(); + + int _ndacs; // The number of DACS in the array + int _latched; // Is the "not LDAC" pin used (1=yes; 0=no)? + SPI _spi; // SPI bus object for communicating with DAC. + DigitalOut** _ncs_array; // Array of pointers to DigitalOut objects + // connected to "not CS" pins. + DigitalOut* _nldac; // Pointer to DigitalOut object connected + // to "not LDAC" pin (if any - NULL if none). +}; + +#endif
diff -r 000000000000 -r e5edc0373da0 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sat May 07 19:27:14 2011 +0000 @@ -0,0 +1,47 @@ +#include "mbed.h" +#include "MCP4922.h" + +MCP4922 MCP(p5, p7,p8); // MOSI, SCLK, CS + +int main() { + + MCP.frequency(1000000); + + float x = 0.5; + float y = 0.25; + float z = 0.125; + float oldx = 0; + float oldy = 0; + float oldz = 0; + + float dt = 0.005; + + float alpha = 15.6; + float beta = 28.58; + float a = -1.14286; + float b = -0.714286; + float h = 0; + + int xout = 0; + int yout = 0; + + while (1) { + + oldx = x; + oldy = y; + oldz = z; + + h = (b * x) + (0.5 * (a - b) * (abs(x+1) - abs(x-1))); + + x = oldx + dt * (alpha * (oldy - oldx - h)); + y = oldy + dt * (oldx - oldy + oldz); + z = oldz + dt * (-beta * oldy); + + xout = 2047+(850*x); + yout = 2047+6*(800*y); + + MCP.writeA(xout); + MCP.writeB(yout); + + } +} \ No newline at end of file
diff -r 000000000000 -r e5edc0373da0 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Sat May 07 19:27:14 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/63bcd7ba4912