HC32模拟i2c驱动MCP4725程序 亲测可用

//初始化IIC
/**
 * @brief       初始化IIC
 * @param       无
 * @retval      无
 */
 void iic_init_ch0_ch1(void)
 {
//		stc_gpio_init_t stcGpioInit;
//	  /* PC11 set to GPIO-Output */
//    (void)GPIO_StructInit(&stcGpioInit);
//    stcGpioInit.u16PinDir = PIN_DIR_OUT;
//    stcGpioInit.u16PinAttr = PIN_ATTR_DIGITAL;
//		stcGpioInit.u16PullUp = PIN_PU_ON;
//    (void)GPIO_Init(IIC_SDA_CH0_CH1_PORT, IIC_SDA_CH0_CH1_PIN, &stcGpioInit);

//    /* PC12 set to GPIO-Output */
//    (void)GPIO_StructInit(&stcGpioInit);
//    stcGpioInit.u16PinDir = PIN_DIR_OUT;
//    stcGpioInit.u16PinAttr = PIN_ATTR_DIGITAL;
//    (void)GPIO_Init(IIC_SCL_CH0_CH1_PORT, IIC_SCL_CH0_CH1_PIN, &stcGpioInit);
	 
		iic_stop_ch0_ch1();
 }
 
 /**
 * @brief       IIC延时函数,用于控制IIC读写速度
 * @param       无
 * @retval      无
 */
static void iic_delay_ch0_ch1(void)
{
	DDL_DelayUS(2);
}

 /**
 * @brief       产生IIC起始信号
 * @param       无
 * @retval      无
 */
void iic_start_ch0_ch1(void)
{
    IIC_SDA_ch0_ch1(1);
    IIC_SCL_ch0_ch1(1);
    iic_delay_ch0_ch1();
    IIC_SDA_ch0_ch1(0);     /* START信号: 当SCL为高时, SDA从高变成低, 表示起始信号 */
    iic_delay_ch0_ch1();
    IIC_SCL_ch0_ch1(0);     /* 钳住I2C总线,准备发送或接收数据 */
    iic_delay_ch0_ch1();
}

 /**
 * @brief       产生IIC停止信号
 * @param       无
 * @retval      无
 */
void iic_stop_ch0_ch1(void)
{
    IIC_SDA_ch0_ch1(0);     /* STOP信号: 当SCL为高时, SDA从低变成高, 表示停止信号 */
    iic_delay_ch0_ch1();
    IIC_SCL_ch0_ch1(1);
    iic_delay_ch0_ch1();
    IIC_SDA_ch0_ch1(1);     /* 发送I2C总线结束信号 */
    iic_delay_ch0_ch1();
}

/**
 * @brief       等待应答信号到来
 * @param       无
 * @retval      1,接收应答失败
 *              0,接收应答成功
 */
uint8_t iic_wait_ack_ch0_ch1(void)
{
    uint8_t waittime = 0;
    uint8_t rack = 0;

    IIC_SDA_ch0_ch1(1);     /* 主机释放SDA线(此时外部器件可以拉低SDA线) */
    iic_delay_ch0_ch1();
    IIC_SCL_ch0_ch1(1);     /* SCL=1, 此时从机可以返回ACK */
    iic_delay_ch0_ch1();

    while (IIC_READ_SDA_ch0_ch1)    /* 等待应答 */
    {
        waittime++;

        if (waittime > 250)
        {
            iic_stop_ch0_ch1();
            rack = 1;
            break;
        }
    }

    IIC_SCL_ch0_ch1(0);     /* SCL=0, 结束ACK检查 */
    iic_delay_ch0_ch1();
    return rack;
}

/**
 * @brief       产生ACK应答
 * @param       无
 * @retval      无
 */
void iic_ack_ch0_ch1(void)
{
    IIC_SDA_ch0_ch1(0);     /* SCL 0 -> 1 时 SDA = 0,表示应答 */
    iic_delay_ch0_ch1();
    IIC_SCL_ch0_ch1(1);     /* 产生一个时钟 */
    iic_delay_ch0_ch1();
    IIC_SCL_ch0_ch1(0);
    iic_delay_ch0_ch1();
    IIC_SDA_ch0_ch1(1);     /* 主机释放SDA线 */
    iic_delay_ch0_ch1();
}

/**
 * @brief       不产生ACK应答
 * @param       无
 * @retval      无
 */
void iic_nack_ch0_ch1(void)
{
    IIC_SDA_ch0_ch1(1);     /* SCL 0 -> 1  时 SDA = 1,表示不应答 */
    iic_delay_ch0_ch1();
    IIC_SCL_ch0_ch1(1);     /* 产生一个时钟 */
    iic_delay_ch0_ch1();
    IIC_SCL_ch0_ch1(0);
    iic_delay_ch0_ch1();
}

/**
 * @brief       IIC发送一个字节
 * @param       data: 要发送的数据
 * @retval      无
 */
void iic_send_byte_ch0_ch1(uint8_t data)
{
    uint8_t t;
    
    for (t = 0; t < 8; t++)
    {
        IIC_SDA_ch0_ch1((data & 0x80) >> 7);    /* 高位先发送 */
        iic_delay_ch0_ch1();
        IIC_SCL_ch0_ch1(1);
        iic_delay_ch0_ch1();
        IIC_SCL_ch0_ch1(0);
        data <<= 1;     /* 左移1位,用于下一次发送 */
    }
    IIC_SDA_ch0_ch1(1);         /* 发送完成, 主机释放SDA线 */
}

/**
 * @brief       IIC读取一个字节
 * @param       ack:  ack=1时,发送ack; ack=0时,发送nack
 * @retval      接收到的数据
 */
uint8_t iic_read_byte_ch0(uint8_t ack)
{
    uint8_t i, receive = 0;

    for (i = 0; i < 8; i++ )    /* 接收1个字节数据 */
    {
        receive <<= 1;  /* 高位先输出,所以先收到的数据位要左移 */
        IIC_SCL_ch0_ch1(1);
        iic_delay_ch0_ch1();

        if (IIC_READ_SDA_ch0_ch1)
        {
            receive++;
        }
        
        IIC_SCL_ch0_ch1(0);
        iic_delay_ch0_ch1();
    }

    if (!ack)
    {
        iic_nack_ch0_ch1();     /* 发送nACK */
    }
    else
    {
        iic_ack_ch0_ch1();      /* 发送ACK */
    }

    return receive;
}

//初始化IIC接口
void MCP4725_Init_CH0_CH1(void)
{
	iic_init_ch0_ch1();
	MCP4725_WriteData_Voltage_CH0(DAC_SET_OYT_VOLTAGE_CH0);
	MCP4725_WriteData_Voltage_CH1(DAC_SET_OYT_VOLTAGE_CH1);
}

//使用快速模式写命令写DAC寄存器-CH0
void MCP4725_WriteData_Voltage_CH0(u16 Vout)   //电压单位mV
{
  u8 temp;
	u16 Dn;
	Dn = ( 4096 * Vout) / DAC_VREF_CH0; //这里的VREF_5V宏定义为5000
	temp = (0x0F00 & Dn) >> 8;  //12位数据。0000XXXX XXXXXXXX 
	iic_start_ch0_ch1();
	iic_send_byte_ch0_ch1(DAC_ADDRESS_CH0);      //器件寻址,器件代吗:1100; 地址位A2,A1,A0为 0 , 0 , 1;-> 1100 0010
	iic_wait_ack_ch0_ch1();	 
	iic_send_byte_ch0_ch1(temp); 	  //将高8位送到DAC寄存器
	iic_wait_ack_ch0_ch1();	 
	iic_send_byte_ch0_ch1(Dn);        //将低8位送到DAC寄存器
	iic_wait_ack_ch0_ch1();	
	iic_stop_ch0_ch1();//产生一个停止条件  	
	DDL_DelayMS(10);
}
 
void MCP4725_WriteData_Digital_CH0(u16 data)   //12位数字量
{
	u8 data_H=0,data_L=0;
	data_H = ( 0x0F00 & data) >> 8;
	data_L = 0X00FF & data ;
	iic_start_ch0_ch1();
	iic_send_byte_ch0_ch1(DAC_ADDRESS_CH0);      //器件寻址,器件代吗:1100; 地址位A2,A1,A0为 0 , 0 , 0;-> 1100 0010
	iic_wait_ack_ch0_ch1();	 
	iic_send_byte_ch0_ch1(data_H); 	
	iic_wait_ack_ch0_ch1();	 
	iic_send_byte_ch0_ch1(data_L);
	iic_wait_ack_ch0_ch1();	
	iic_stop_ch0_ch1();//产生一个停止条件  	
	DDL_DelayMS(10);	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值