STM32f103c8t6通过模拟IC2驱动8路DAC模块ad5593r

本文详细介绍了AD5593R模块的I/O配置,展示了如何通过I2C连接硬件电路,以及如何使用MCP4725库进行DAC输出和模拟/数字输入配置的软件设计。提供了完整的初始化和数据传输函数示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章目录

AD5593R模块介绍

AD5593R有8个输入/输出(I/O)引脚,可独立配置为数模转换器(DAC)输出、模数转换器(ADC)输入、数字输出或数字输入。当一个I/O引脚被配置为一个模拟输出时,它是由一个12位的DAC驱动的。DAC的输出范围为0V到VREF或0V到2×VREF。当I/O引脚被配置为模拟输入时,它通过模拟多路复用器连接到12位ADC。ADC的输入范围为0V到VREF或0V到2×VREF。输入/输出引脚也可以配置为通用的数字输入或输出(GPIO)引脚。可以通过I2C写或读取操作分别访问GPIO写数据寄存器和GPIO读取寄存器配置寄存器来设置或读回GPIO引脚的状态。

硬件电路连接

VCC,RES,ADD,VRE都接5V;

GND接GND;

SCL接PB6;

SDA接PB7;

其中RES引脚。将此引脚置高,以便于正常操作。当该引脚降低时,AD5593R将被重置为其默认配置,ADD为地址输入引脚。设置7位从属地址的LSB,IO0-7为8个输出通道。

软件设计

I2C写入的第一个字节一般是固定的,第一位为器件代码,根据手册内容第一位写入为(0X22),位[D7:D4]是选择要执行的操作的模式位。位[D3:D0]中包含的数据取决于所需的操作。要配置为DAC输出,

第二位写入应该为(0x05)即00000101。

第三位第四位为DAC通道配置,这边直接写入(0x00)、(0xFF),将所有通道都配置为DAC输出。

配置好了就需要进行DAC电压写入,这部分我参考了MCP4725的设计代码:(0x10)为通道0,(0x11)为通道1,以此内推,(0x17)为通道7。

void MCP4725_WriteData_Voltage(uint16_t Vout)   //电压单位mV
{
		uint8_t temp;
		uint16_t Dn;
		Dn = (4095 * Vout) / VREF_5V; //这里的VREF_5V宏定义为5000
		temp = (0x0F00 & Dn) >> 8;  //12位数据。0000XXXX XXXXXXXX 
		IIC_Start();
		IIC_Send_Byte(0X22);      //器件寻址,器件代吗:1100; 地址位A2,A1,A0为 0 , 0 , 1;-> 1100 0010
    //这个地址0XC0或0XC1,根据自己购买的模块决定
    IIC_Wait_Ack();	

		IIC_Send_Byte(0X10);
		IIC_Wait_Ack();
	
    IIC_Send_Byte(temp); 	  //将高8位送到DAC寄存器
    IIC_Wait_Ack();	 
    IIC_Send_Byte(Dn);        //将低8位送到DAC寄存器
		IIC_Wait_Ack();	
    IIC_Stop();//产生一个停止条件  	
		Delay_ms(10);	
}

代码

MCP4725.h代码:

#ifndef __MCP4725_H
#define __MCP4725_H
#include "myIIC.h" 
 
 
#define VREF_5V      3200   //这个数值根据自己给模块的供电电压而定
 
void MCP4725_Init(void);
void MCP4725_WriteData_Digital(uint16_t data);
void MCP4725_WriteData_Voltage(uint16_t Vout);
 
 
#endif
 

MCP4725.c代码:(其中0x03部分为配置2×VREF电压

#include "stm32f10x.h"                  // Device header
 
#include "MCP4725.h" 
#include "delay.h"
 
 
//初始化IIC接口
void MCP4725_Init(void)
{
	IIC_Init();
	
	IIC_Start();
	IIC_Send_Byte(0X22);
	IIC_Wait_Ack();
	IIC_Send_Byte(0X05);
	IIC_Wait_Ack();
	IIC_Send_Byte(0X00);
	IIC_Wait_Ack();
	IIC_Send_Byte(0XFF);
	IIC_Wait_Ack();
	IIC_Stop();//产生一个停止条件  	
	Delay_ms(10);
	
	IIC_Start();
	IIC_Send_Byte(0X22);
	IIC_Wait_Ack();
	IIC_Send_Byte(0X03);
	IIC_Wait_Ack();
	IIC_Send_Byte(0X00);
	IIC_Wait_Ack();
	IIC_Send_Byte(0X00);//0X10为2*VREF,不超过供电电压
	IIC_Wait_Ack();
	IIC_Stop();//产生一个停止条件  	
	Delay_ms(10);	
		
}
 
//使用快速模式写命令写DAC寄存器
void MCP4725_WriteData_Voltage(uint16_t Vout)   //电压单位mV
{
		uint8_t temp;
		uint16_t Dn;
		Dn = (4095 * Vout) / VREF_5V; //这里的VREF_5V宏定义为5000
		temp = (0x0F00 & Dn) >> 8;  //12位数据。0000XXXX XXXXXXXX 
		IIC_Start();
		IIC_Send_Byte(0X22);      //器件寻址,器件代吗:1100; 地址位A2,A1,A0为 0 , 0 , 1;-> 1100 0010
    //这个地址0XC0或0XC1,根据自己购买的模块决定
    IIC_Wait_Ack();	

		IIC_Send_Byte(0X10);
		IIC_Wait_Ack();
	
    IIC_Send_Byte(temp); 	  //将高8位送到DAC寄存器
    IIC_Wait_Ack();	 
    IIC_Send_Byte(Dn);        //将低8位送到DAC寄存器
		IIC_Wait_Ack();	
    IIC_Stop();//产生一个停止条件  	
		Delay_ms(10);	
}
 
void MCP4725_WriteData_Digital(uint16_t data)   //12位数字量
{
    uint8_t data_H=0,data_L=0;
		data_H = (0x0F00 & data) >> 8;
		data_L = 0X00FF & data ;
		IIC_Start();
		IIC_Send_Byte(0X22);      //器件寻址,器件代吗:1100; 地址位A2,A1,A0为 0 , 0 , 0;-> 1100 0010
		IIC_Wait_Ack();	
		
		IIC_Send_Byte(0X10);
		IIC_Wait_Ack();

    IIC_Send_Byte(data_H); 	
    IIC_Wait_Ack();	 
    IIC_Send_Byte(data_L);
		IIC_Wait_Ack();	
    IIC_Stop();//产生一个停止条件  	
		Delay_ms(10);	
}

IIC.c代码:

#include "stm32f10x.h"                  // Device header
#include "myIIC.h"
#include "delay.h"
 
/*引脚配置*/
#define MCP4725_W_SCL(x)		GPIO_WriteBit(GPIOB, GPIO_Pin_6, (BitAction)(x))
#define MCP4725_W_SDA(x)		GPIO_WriteBit(GPIOB, GPIO_Pin_7, (BitAction)(x))
#define MCP4725_W_SDAIN			GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_7)
 
 
//初始化IIC
void IIC_Init(void)
{					     
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB, ENABLE );	//使能GPIOB时钟
	   
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;         //PB6 ->SCL;  PB7->SDA
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7); 	//PB6,PB7 输出高,因为IIC空闲状态都是高电平
}
 
//SDA设置为输入
void SDA_IN (void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB, ENABLE );	
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}
 
//SDA设置为输出
void SDA_OUT(void)
{ 
		GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB, ENABLE );	
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}
//产生IIC起始信号
void IIC_Start(void)
{
	SDA_OUT();     //sda线设置为输出
	MCP4725_W_SDA(1);	  	  
	MCP4725_W_SCL(1);
	Delay_us(10);
 	MCP4725_W_SDA(0);     //START:when CLK is high,DATA change form high to low 
	Delay_us(10);
	MCP4725_W_SCL(0);     //钳住I2C总线,准备发送或接收数据 
}	  
//产生IIC停止信号
void IIC_Stop(void)
{
	SDA_OUT();//sda线输出
	MCP4725_W_SCL(0);
	MCP4725_W_SDA(0);    //STOP:when CLK is high DATA change form low to high
 	Delay_us(10);
	MCP4725_W_SCL(1);
	MCP4725_W_SDA(1);    //发送I2C总线结束信号
	Delay_us(10);							   	
}
//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
uint8_t IIC_Wait_Ack(void)
{
	uint8_t ucErrTime=0;
	SDA_IN();      //SDA设置为输入  
	MCP4725_W_SDA(1);
	Delay_us(2);	   
	MCP4725_W_SCL(1);
	Delay_us(2);	 
	while(MCP4725_W_SDAIN)
	{
		ucErrTime++;
		if(ucErrTime>250)
		{
			IIC_Stop();
			return 1;
		}
	}
	MCP4725_W_SCL(0);//时钟输出0 	   
	return 0;  
} 
//产生ACK应答
void IIC_Ack(void)
{
	MCP4725_W_SCL(0);
	SDA_OUT();
	MCP4725_W_SDA(0);
	Delay_us(5);
	MCP4725_W_SCL(1);
	Delay_us(5);
	MCP4725_W_SCL(0);
}
//不产生ACK应答		    
void IIC_NAck(void)
{
	MCP4725_W_SCL(0);
	SDA_OUT();
	MCP4725_W_SDA(1);
	Delay_us(5);
	MCP4725_W_SCL(1);
	Delay_us(5);
	MCP4725_W_SCL(0);
}					 				     
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答			  
void IIC_Send_Byte(uint8_t txd)
{                        
  uint8_t t;   
	SDA_OUT(); 	    
	MCP4725_W_SCL(0);//拉低时钟开始数据传输
    for(t=0;t<8;t++)    //开始准备信号线
    {              
		if((txd&0x80)>>7)
			MCP4725_W_SDA(1);
		else
			MCP4725_W_SDA(0);
		txd<<=1; 	  
		Delay_us(5);   //对TEA5767这三个延时都是必须的
		MCP4725_W_SCL(1);
		Delay_us(5); 
		MCP4725_W_SCL(0);
		Delay_us(5);
    }	 
} 	    
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
uint8_t IIC_Read_Byte(unsigned char ack)
{
	unsigned char i,receive=0;
	SDA_IN();//SDA设置为输入
    for(i=0;i<8;i++ )
	{
      MCP4725_W_SCL(0);
        Delay_us(5);
			MCP4725_W_SCL(1);
        receive<<=1;
      if(MCP4725_W_SDAIN)
				{receive++;  }
			Delay_us(4); 
  }					 
    if (!ack)
        IIC_NAck();//发送nACK
    else
        IIC_Ack(); //发送ACK   
    return receive;
}

main.c代码:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "Serial.h"

#include "MCP4725.h" 
#include "myIIC.h"

uint8_t RxData;

int main(void)
{

	LED_Init();
	
	MCP4725_Init();
	
	Serial_Init();
	GPIO_InitTypeDef  GPIO_Initstructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
	GPIO_Initstructure.GPIO_Pin = GPIO_Pin_13;
	GPIO_Initstructure.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_Initstructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOC,&GPIO_Initstructure);
	
	GPIO_SetBits(GPIOC,GPIO_Pin_13);
	
	 while (1)
  {
		//Serial_SendByte('B');
		//GPIO_ResetBits(GPIOC, GPIO_Pin_13);
		//Delay_ms(1000);	
		//GPIO_SetBits(GPIOC, GPIO_Pin_13);	
		//Delay_ms(1000);		
		
		MCP4725_WriteData_Voltage(2200);
	 }
}

小结

实测过,代码绝对可用,初学者,还请多多关照!需要工程代码可联系博主。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值