DAC7512—软件模拟SPI实现与DAC7512通信

今天使用DAC751实现输出0-5V电压,效果良好精度很高。

DAC7512时序图。需要注意的是要给出5V参考电压,实现DAC5V正常输出。根据时序图,在开启写入数据之前,片选信号拉高再拉低,然后时钟线和数据线同步写入16个数据,之后片选信号线拉高,完成16位数据写入。
在这里插入图片描述

软件代码

引脚配置

初始化引脚配置为3个推挽输出即可。

#define SOFT_CLK_1  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_SET)
#define SOFT_CLK_0  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET)

#define SOFT_Data_1 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET)
#define SOFT_Data_0 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET)

#define SOFT_CS_1   HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET)
#define SOFT_CS_0   HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET)

1us延时函数实现

static u32 fac_us=0;
void delay_us(u32 nus)
{
    
    		
	u32 ticks;
	u32 told,tnow,tcnt=0;
	u32 reload=SysTick->LOAD;				//LOAD的值	    	 
	ticks=nus*fac_us; 						//需要的节拍数 
	delay_osschedlock();					//阻止OS调度,防止打断us延时
	told=SysTick->VAL;        				//刚进入时的计数器值
	while(1)
	{
    
    
		tnow=SysTick->VAL;	
		if(tnow!=told)
		{
    
    	    
			if(tnow<told)tcnt+=told-tnow;	//这里注意一下SYSTICK是一个递减的计数器就可以了.
			else tcnt+=reload-tnow+told;	    
			told=tnow;
			if(tcnt>=ticks)break;			//时间超过/等于要延迟的时间,则退出.
		}  
	};
	delay_osschedunlock();					//恢复OS调度											    
}  

软件模式SPI实现过程


void dac7512_SendData(uint16_t data)
{
    
    

#ifdef SOFT_SPI     /* 软件SPI */

    int i;

    SOFT_CS_1;
    SOFT_CLK_1;
    SOFT_Data_1;
    delay_us(1);
    SOFT_CS_0;
		delay_us(1);
    for (i = 0; i < 16; ++i) {
    
    
        if (0x8000&data) {
    
      //判断写入0还是写入1
            SOFT_Data_1;    //写入1
        }
        else {
    
    
            SOFT_Data_0;    //写入0
        }
        delay_us(1);
        SOFT_CLK_0;
        data = data << 1;
        delay_us(1);
        SOFT_CLK_1;

    }
    SOFT_CS_1;
    SOFT_CLK_1;
    SOFT_Data_1;


#endif


#ifdef HARD_SPI     /* 硬件SPI */
       SOFT_CS_0;

       while(__HAL_SPI_GET_FLAG(&hspi1,SPI_FLAG_TXE) == RESET)
           HAL_SPI_Transmit(hspi1, data, 1, 1000);

       SOFT_CS_1;
#endif
}

1us延时函数实现

主函数实现

输出一个锯齿波。

int main(void)
{
    
     
	HAL_Init();                    	//初始化HAL库    
	Stm32_Clock_Init(336,8,2,7);  	//设置时钟,168Mhz
	delay_init(168);               	//初始化延时函数
	LED_Init();						//初始化LED	
	int i;
	while(1)
	{
    
    

				for(i = 0;i <4095;i++)
				dac7512_SendData(i);
				for(i = 4095;i >0;i--)
				dac7512_SendData(i);
	}
}

实验现象

锯齿波输出,示波器查看波形。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_46152793/article/details/124136894
今日推荐