toiy
Dependencies: mbed
Revision 0:daa660f72f9f, committed 2017-11-23
- Comitter:
- jnjtnutty
- Date:
- Thu Nov 23 12:09:10 2017 +0000
- Commit message:
- toiy
Changed in this revision
diff -r 000000000000 -r daa660f72f9f MCP4922.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MCP4922.cpp Thu Nov 23 12:09:10 2017 +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 daa660f72f9f MCP4922.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MCP4922.h Thu Nov 23 12:09:10 2017 +0000 @@ -0,0 +1,81 @@ +/* + * 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 MCP4922_VREF 3300 // 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 daa660f72f9f main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Nov 23 12:09:10 2017 +0000 @@ -0,0 +1,57 @@ +#include "mbed.h" +#include "MCP4922.h" + +MCP4922 MCP(SPI_MOSI, SPI_SCK,PB_6); // MOSI, SCLK, CS +/*หลักการคิดคือ จะแบ่งเป็น 4state โดยในแต่ละ state จะเป็นการเพิ่มหรือลดของ ค่า i โดยจะวนลูปเรื่อยๆจนออกจากเงื่อนไขและเปลี่ยน state */ + +/**** Main Function ***/ +int main(void) +{ + MCP.frequency(5000000); + + uint16_t i=0; //สร้างตัวแปร(int) 16 bit ชื่อ i ให้มีค่าเท่ากับ 0 + uint8_t state=0; //สร้างตัวแปร(int) 8 bit ชื่อ state ให้มีค่าเท่ากับ 0 + while(1) { //สร้างลูปให้ทำงานเมื่อมีไฟเข้า + if(state == 0) { //ถ้า state = 0 ให้ทำด้านล่าง + if(i < 0x0FFE/2) { //ถ้า i น้อยกว่าครึ่งหนึ่งของ 4094 ให้ i เพิ่มขึ้น และแสดงค่าที่จอ scop + i++; + MCP.writeA(i); + } + else { //แต่ถ้าไม่ใช่ให้ i เท่ากับครึ่งหนึ่งของ 4094 และให้ state = 1 + i = 0x0FFE/2 + state = 1; + } + } + else if(state == 1) { //ถ้า state = 1 ให้ทำด้านล่าง + if(i > 0) { //ถ้า i มากกว่า 0 ให้ i ลดลง และแสดงที่จอ scop + i--; + MCP.writeA(i); + } + else { //แต่ถ้าไม่ใช่ให้ i เท่ากับครึ่งหนึ่งของ 4095 และให้ state = 2 + i = 0x0FFF; + state = 2; + } + } + else if(state == 2) { //ถ้า state = 2 ให้ทำด้านล่าง + if(i > (0x0FFE/2)) { //ถ้า i มากกว่า ครึ่งหนึ่งของ 4094 ให้ i ลดลง และแสดงที่จอ scop + i--; + MCP.writeA(i); + } + else { //แต่ถ้าไม่ใช่ให้ i เท่ากับครึ่งหนึ่งของ 4094 และให้ state = 3 + i= 0x0FFE/2; + state = 3; + } + } + else if(state == 3) { //ถ้า state = 3 ให้ทำด้านล่าง + if(i < 0x0FFE) { //ถ้า i น้อยกว่า 4094 ให้ i เพิ่มขึ้น และแสดงค่าที่จอ scop + i++; + MCP.writeA(i); + } + else { //แต่ถ้าไม่ใช่ให้ i เท่ากับ 0 และให้ state เท่ากับ 0 + i= 0; + state = 0; + } + } + wait_us(15); //รอ 15 ไมโครวินาที เพื่อไปต่อ + } +} \ No newline at end of file
diff -r 000000000000 -r daa660f72f9f mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Thu Nov 23 12:09:10 2017 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/mbed_official/code/mbed/builds/e7ca05fa8600 \ No newline at end of file