#include "STC8H.H"
#include <intrins.h>
#define uint8_t unsigned char
#define uint16_t unsigned int
#define MCP4725_ADDR 0x60 //A0接地
#define MCP4725_CMD_WRITE 0x40
#define MCP4725_CMD_EEPROM 0x60
#define I2C_DELAY() {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}
#define I2C_SCL_HIGH() I2C_SCL = 1
#define I2C_SCL_LOW() I2C_SCL = 0
#define I2C_SDA_HIGH() I2C_SDA = 1
#define I2C_SDA_LOW() I2C_SDA = 0
#define I2C_SDA_READ() I2C_SDA
sbit I2C_SCL = P1^1;
sbit I2C_SDA = P1^0;
//------------------------------------
void I2C_Init(void);
void I2C_Start(void);
void I2C_Stop(void);
bit I2C_SendByte(uint8_t dat);
uint8_t I2C_RecvByte(void);
void I2C_Ack(void);
void I2C_NAck(void);
void Delay1ms(void); //@11.0592MHz
void delay_ms(unsigned int ms);
void MCP4725_WriteDAC(uint16_t value);
void MCP4725_WriteDACAndSave(uint16_t value);
void MCP4725_SetPowerDown(uint8_t channel, uint8_t mode);
uint16_t MCP4725_VoltageToValue(float voltage, float vref);
void MCP4725_OutputVoltage(float voltage, float vref);
void MCP4725_OutputVoltageAndSave(float voltage, float vref);
//-----------------------------
void I2C_Init(void)
{
I2C_SCL = 1;
I2C_SDA = 1;
}
void I2C_Start(void)
{
I2C_SDA_HIGH();
I2C_SCL_HIGH();
I2C_DELAY();
I2C_SDA_LOW();
I2C_DELAY();
I2C_SCL_LOW();
}
void I2C_Stop(void)
{
I2C_SDA_LOW();
I2C_SCL_HIGH();
I2C_DELAY();
I2C_SDA_HIGH();
I2C_DELAY();
}
bit I2C_SendByte(uint8_t dat)
{
uint8_t i;
bit ack;
for (i = 0; i < 8; i++)
{
if (dat & 0x80)
I2C_SDA_HIGH();
else
I2C_SDA_LOW();
dat <<= 1;
I2C_DELAY();
I2C_SCL_HIGH();
I2C_DELAY();
I2C_SCL_LOW();
}
I2C_SDA_HIGH();
I2C_DELAY();
I2C_SCL_HIGH();
I2C_DELAY();
ack = I2C_SDA_READ();
I2C_SCL_LOW();
return ack;
}
uint8_t I2C_RecvByte(void)
{
uint8_t i;
uint8_t dat = 0;
I2C_SDA_HIGH();
for (i = 0; i < 8; i++)
{
dat <<= 1;
I2C_SCL_LOW();
I2C_DELAY();
I2C_SCL_HIGH();
if (I2C_SDA_READ())
dat |= 0x01;
}
I2C_SCL_LOW();
return dat;
}
void I2C_Ack(void)
{
I2C_SDA_LOW();
I2C_DELAY();
I2C_SCL_HIGH();
I2C_DELAY();
I2C_SCL_LOW();
I2C_SDA_HIGH();
}
void I2C_NAck(void)
{
I2C_SDA_HIGH();
I2C_DELAY();
I2C_SCL_HIGH();
I2C_DELAY();
I2C_SCL_LOW();
}
//-----------------------------
void Delay1ms(void) //@11.0592MHz
{
unsigned char data i, j;
i = 15;
j = 90;
do
{
while (--j);
} while (--i);
}
//-----------------------------
void delay_ms(unsigned int ms)
{
while(ms--)
{
Delay1ms();
}
}
//*******************************************
void MCP4725_WriteDAC(uint16_t value)
{
uint8_t high_byte = (value >> 4) & 0xFF;
uint8_t low_byte = (value & 0x0F) << 4;
I2C_Start();
if (!I2C_SendByte(MCP4725_ADDR << 1))
{
if (!I2C_SendByte(MCP4725_CMD_WRITE))
{
if (!I2C_SendByte(high_byte))
{
I2C_SendByte(low_byte);
}
}
}
I2C_Stop();
}
void MCP4725_WriteDACAndSave(uint16_t value)
{
uint8_t high_byte = (value >> 4) & 0xFF;
uint8_t low_byte = (value & 0x0F) << 4;
I2C_Start();
if (!I2C_SendByte(MCP4725_ADDR << 1))
{
if (!I2C_SendByte(MCP4725_CMD_EEPROM))
{
if (!I2C_SendByte(high_byte))
{
I2C_SendByte(low_byte);
}
}
}
I2C_Stop();
}
void MCP4725_SetPowerDown(uint8_t channel, uint8_t mode)
{
uint8_t high_byte = 0x80 | ((channel & 0x03) << 5) | (mode & 0x03);
uint8_t low_byte = 0x00;
I2C_Start();
if (!I2C_SendByte(MCP4725_ADDR << 1))
{
if (!I2C_SendByte(MCP4725_CMD_WRITE))
{
if (!I2C_SendByte(high_byte))
{
I2C_SendByte(low_byte);
}
}
}
I2C_Stop();
}
uint16_t MCP4725_VoltageToValue(float voltage, float vref)
{
if (voltage < 0.0f) voltage = 0.0f;
if (voltage > vref) voltage = vref;
return (uint16_t)((voltage / vref) * 4095.0f);
}
void MCP4725_OutputVoltage(float voltage, float vref)
{
uint16_t dac_value = MCP4725_VoltageToValue(voltage, vref);
MCP4725_WriteDAC(dac_value);
}
void MCP4725_OutputVoltageAndSave(float voltage, float vref)
{
uint16_t dac_value = MCP4725_VoltageToValue(voltage, vref);
MCP4725_WriteDACAndSave(dac_value);
}
//*********************************
void main(void)
{
P1M0 = 0x03;//P1.0,P1.1开漏
P1M1 = 0x03;
I2C_Init();
while(1)
{
MCP4725_OutputVoltage(1.0f, 5.0f);//1V
delay_ms(2000);
MCP4725_OutputVoltage(2.5f, 5.0f);//2.5V
delay_ms(2000);
MCP4725_OutputVoltage(5.0f, 5.0f);//5V
delay_ms(2000);
}
}
|