Last active
December 13, 2021 15:56
-
-
Save ajarmst/bacc3072cddef9edd931e87d5b75dbfc to your computer and use it in GitHub Desktop.
I2C Demo Using a DAC
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
///////////////////////////////////////////////////////////////////////////// | |
// HC12 Program: Demo 10 - SPI DAC | |
// Processor: MC9S12XDP512 | |
// Bus Speed: 20 MHz (Requires Active PLL) | |
// Author: AJ Armstrong | |
// Details: Connect and control an MCP4812 DAC via SPI. | |
// Date: 25 Oct 2021 | |
// Revision History : | |
///////////////////////////////////////////////////////////////////////////// | |
#include <hidef.h> /* common defines and macros */ | |
#include "derivative.h" /* derivative-specific definitions */ | |
// other system includes or your includes go here | |
#include <string.h> | |
#include <math.h> | |
#include <stdio.h> | |
#include "pll.h" | |
#include "swled.h" | |
#include "segs.h" | |
#include "timer.h" | |
#include "lcd.h" | |
#include "i2c.h" | |
///////////////////////////////////////////////////////////////////////////// | |
// Local Prototypes | |
///////////////////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////// | |
// LTC2633 - Dual 12-bit I2C DAC Library | |
// 7-bit device address 0x10, but 0x20 as command | |
// this device can go to 400kHz | |
///////////////////////////////////////////// | |
// this is a 12-bit, 4.096V (1mV/step), two channel DAC | |
// write time per value is ~118.5us @ 400KHz bus (measured) | |
// general form (write only): | |
// <ADDR><C3:C0,A3:A0><D11:D4[DAC Value]><D3:D0[0]> | |
// C3 C2 C1 C0 | |
// 0 0 0 0 - write to register n | |
// 0 0 0 1 - update (power up) DAC, register n | |
// 0 0 1 0 - write to input register n, update (power up) all | |
// 0 0 1 1 - write to and update (power up) DAC register n | |
// 0 1 0 0 - power down n | |
// 0 1 0 1 - power down chip | |
// 0 1 1 0 - select (power up) internal reference | |
// 0 1 1 1 - select external reference | |
// 1 1 1 1 - no op | |
// NOTE: left-aligned data | |
// A3 A2 A1 A0 | |
// 0 0 0 0 - DAC A | |
// 0 0 0 1 - DAC B | |
// 1 1 1 1 - all DACs | |
// command form (8-bit) of address is 0x20 (0x10 << 1) | |
#define LTC2633ADDR 0x20 | |
// channel decode tags for LTC write function | |
typedef enum LTC2633_CHAN_SELECT | |
{ | |
LTC2633_CHAN_A, | |
LTC2633_CHAN_B, | |
LTC2633_CHAN_BOTH | |
} LTC2633_CHAN_SELECT; | |
// write a channel | |
int LTC2633_WriteChan (unsigned int Value, LTC2633_CHAN_SELECT chan); | |
///////////////////////////////////////////////////////////////////////////// | |
// Global Variables | |
///////////////////////////////////////////////////////////////////////////// | |
volatile uint ADCVal[8] = {0}; | |
///////////////////////////////////////////////////////////////////////////// | |
// Constants | |
///////////////////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////////////////// | |
// Main Entry | |
///////////////////////////////////////////////////////////////////////////// | |
int main(void) | |
{ | |
unsigned int DACVal = 0; //12-bit DAC output (0 - 4096) | |
_DISABLE_COP(); | |
EnableInterrupts; // Ensure our board will respond to interrupt signals. | |
///////////////////////////////////////////////////////////////////////////// | |
// One-Time Initializations | |
///////////////////////////////////////////////////////////////////////////// | |
PLL_To20MHz(); // Configure the main clock to 20 MHz | |
SWL_Init(); // Standard initialization for switches and LEDs | |
SEG_Init(); // Standard initialization for 7-segment displays | |
LCD_Init_Simon(); // Standard initialization for LCD | |
// Set up Channel 5 ADC | |
///////////////////////////;////////////////////////////////////////////////// | |
// ADC Initializations | |
///////////////////////////////////////////////////////////////////////////// | |
DDR1AD0 = 0b00000000; //All channels input | |
ATD0DIEN = 0b00000000; //All channels analog | |
ATD0CTL2 = 0b11100010; //Enable intrpt, no ext trigr, on, fast, cont in wai | |
//Quick 50 mikes busy wait to allow ADC to power up | |
asm LDX #134; | |
asm DBNE X,*; | |
ATD0CTL3 = 0b00000010; //8 conversions per sequence, continue b4 freeze | |
ATD0CTL4 = 0b00100110; //div. 14 clock -> 7 mikes per sample (56 / set) | |
ATD0CTL5 = 0b10110000; //fill from bottom, sample all 8, continuous, right just | |
//Set up I2C | |
I2C_Init0(I2CMicro20MHz, I2CBus400, 0); | |
///////////////////////////////////////////////////////////////////////////// | |
// Main Program Loop | |
///////////////////////////////////////////////////////////////////////////// | |
for (;;) | |
{ | |
//Get ten-bit ADC, convert to 12 bit DAC | |
DACVal = (unsigned int)((ADCVal[5]/1024.0) * 4096); | |
(void) LTC2633_WriteChan(DACVal,LTC2633_CHAN_A); | |
SEG_16H(ADCVal[5],0); | |
SEG_16H(DACVal,1); | |
} | |
} | |
///////////////////////////////////////////////////////////////////////////// | |
// Functions | |
///////////////////////////////////////////////////////////////////////////// | |
int LTC2633_WriteChan (unsigned int Value, LTC2633_CHAN_SELECT chan) | |
{ | |
// address the device | |
if (I2C_SendAddressRW(LTC2633ADDR, I2C_WRITE, I2C_WAIT)) | |
return -1; | |
// send command (write chan, power up all) | |
if (chan == LTC2633_CHAN_A) | |
(void)I2C_WriteByte (0b00100000, I2C_NOSTOP); // P18, datasheet | |
else if (chan == LTC2633_CHAN_B) | |
(void)I2C_WriteByte (0b00100001, I2C_NOSTOP); // P18, datasheet | |
else // assume all channels | |
(void)I2C_WriteByte (0b00101111, I2C_NOSTOP); // P18, datasheet | |
// send msb data (data is 12 bits, oddly, left aligned, P18, datasheet) | |
(void)I2C_WriteByte ((unsigned char)(Value >> 4), I2C_NOSTOP); // 0x0123 becomes 0x12 | |
// send lsb data | |
(void)I2C_WriteByte ((unsigned char)(Value << 4), I2C_STOP); // 0x0123 becomes 0x30 | |
return 0; // good condition | |
} | |
///////////////////////////////////////////////////////////////////////////// | |
// Interrupt Service Routines | |
///////////////////////////////////////////////////////////////////////////// | |
/***** ATD0 Event Handler *****/ | |
interrupt VectorNumber_Vatd0 void INT_AD0 (void) | |
{ | |
ADCVal[0] = ATD0DR0; | |
ADCVal[5] = ATD0DR5; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment