完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
5个回答
|
|
本章节为大家讲解标准SPI接线方式驱动模数转换器DAC856X。
33.1 初学者重要提示 学习本章节前,务必优先学习第31章。
这里将三种DAC结构为大家做个普及:R2R型MDAC,R2R型backDAC和Srting型DAC。 注,这些知识翻译自TI的英文技术手册。 33.2.1 R2R型MDAC 自动测试设备或仪器通常使用R2R MDAC。MDAC型制造商能够设计具有±1 LSB的高分辨率积分非线性(INL)和差分非线性(DNL)DAC。通过使用合适的外部放大器,MDAC能够实现较短的建立时间(<0.3 ms)和大于10 MHz的带宽。并且通过为MDAC的外部运算放大器提供不同电源电压和高输出电流可以增强DAC功能。 MDAC产生的电流与用户设置的数字编码,外部放大器以及RFB(在MDAC内部)将DAC的电流输出信号转换为可用的电压。 这类DAC的缺点是会有稳定性问题。 33.2.2 R2R型backDAC 通常在工业应用中使用R2R backDAC。其它一些应用还包括仪器和数字控制校准。使用这类DAC,每次新更新会将2R支路切换到参考电压高(VREF-H)或参考电压低(VREF-L)。注意R-2R梯子的布置与MDAC相比是倒置的。这就是名字backDAC的由来,这种架构很容易制造。 这类DAC的缺点是毛刺脉冲问题: 33.2.3 String型DAC String型DAC最适合便携式仪器,闭环伺服控制和过程控制。下图显示了一个3bit String DAC的模型,数字输入代码101b被解码为5/8 VREF。String DAC的输出级放大器隔离了来自输出负载的内部电阻元件。 String DAC是一种低功耗解决方案,可确保单调性在整个输入代码中具有良好的DNL(差分非线性)性能范围。毛刺能量通常低于其它DAC类型。 但是,INL(积分非线性)通常较大,具体取决于电阻式片上匹配,另一方面,控制回路中的DAC可减轻线性度影响。String DAC的噪声也相对较大,因为电阻串的阻抗很高,所以该值很高。但String DAC功耗低且非常小的故障能量。 33.3 DAC技术术语 一些常见的DAC技术术语需要大家见到了,大概了解是什么意思。 33.3.1 单位ppm℃(ppm/℃) 这个参数是专门用来定义温飘的,ppm全称是parts per million,即百万分之一。比如2ppm℃就是2 x 10^-6 ,反映到DAC8563上,定义如下: Input or 2.5-V Output 4-ppm°C Temperature Drift (Typ) 也就是说,当输出2.5V时,每变化一度,输出电压的变化是2.5V x (4 x 10^-6) = 10uV 类似的定义还有很多: ppb,ppt,ppq所代表的含义: 33.3.2 毛刺脉冲(Glitch impulse) 使用DAC进行设计时,您期望输出从一个值单调移至下一个值,但实际电路并非总是如此。在某些代码范围内,出现过冲或下冲(量化为毛刺脉冲)并不少见。主要以下面两种形式呈现: 具体原因分析在这个帖子里面进行了讲解(内容较多,就不整理到教程里面了):链接。 33.3.3 偏移误差(Offset Error) 偏移误差为标称偏移点与实际偏移点之间的差。此错误以相同的数量影响所有代码,通常可以通过修正来补偿处理。如果无法修正,则该误差称为零刻度误差。 33.3.4 增益误差(Gain Error) 增益误差定义为传输时标称增益点与实际增益点之差。 33.3.5 差分非线性误差(DNL) DNL全称Differential Nonlinearity。 差分非线性误差为实际步长宽度(对于ADC)或步长高度(对于DAC)与1 LSB的理想值之间的差值。 因此,如果阶跃宽度或高度恰好为1 LSB,则差分非线性误差为零。 如果DNL超过1 LSB,转换器可能变得非单调。这意味着增加了输入的幅度但输出的大小可能变小。 33.3.6 积分非线性误差(INL) INL全称Integral Nonlinearity 积分非线性误差是从一个传输点到相对应的理想传输曲线的最大偏差距离,不考虑偏置误差和增益误差。 这个参数对最佳传输函数或端点传输函数有一定参考意义。 33.3.7 绝对精度误差(Absolute Accuracy Error) 绝对精度误差是包括偏移,增益,积分线性等误差的总体误差。 |
|
|
|
33.4 DAC856X硬件设计
DAC的输出量可以为0到2.5V或者0到5V,通过外置运放,实现了±10V输出。 33.4.1 DAC856X模块规格 产品规格: 1、供电电压 : 2.7 - 5.5V 【3.3V供电时,输出电压也可以到正负10V】 2、通道数: 2路 (通过1片DAC8563实现) 3、输出电压范围 : -10V ~ +10V 【客户可以自己更改为 0-10V输出范围。使用烙铁切换2个焊点即可,无需更换元器件】 4、输出驱动能力:带运放驱动,最大输出电流10mA,负载电阻>1K欧姆 5、分辨率: 16位 6、功耗 : 小于20mA 7、MCU接口 :高速 SPI (50M) 支持 3.3V和5V单片机 8、DAC输出模拟带宽:350KHz 9、DAC输出响应: 10uS 到 0.003% FSR 产品特点: 1、输出和供电电压无关;模块内带正负12V升压电路 2、自适应单片机的电平(2.7 - 5V 均可以) 3、输出电压可抵达正负10V 4、上电时缺省输出0V (在软件未启动时) 5、引出正负12V电源排针,方便客户使用 重要提示: 1、DAC8562和DAC8563完全兼容,区别仅仅在于CLR引脚有效时,DAC8562数据设置为0, DAC8563数据设置为32767。注意这是DAC的内部数据,不表示输出电压。 对于-10 ~ +10V输出的模块,DAC8562输出-10V, DAC8563输出0V。 2、无论是用DAC8562还是DAC8563芯片,只要软件不启动,本模块输出电压缺省状态都是0V。 3、CLR脚悬浮时,电压在1.9V左右,容易受到干扰导致输出被清零。因此即使不用CLR控制功能,这个CLR脚也需要接固定电平(推荐接GND)。CLR是边沿触发,仅在下降沿信号出现执行清零。 产品效果: 33.4.2 DAC856X硬件接口 V6板子上DAC856X模块的插座的原理图如下(NRF24L01,AD9833,DAC8563和TM7705都是用的而这个插座): 实际对应开发的位置如下: 33.5 DAC856X关键知识点整理(重要) 驱动DAC856X需要对下面这些知识点有个认识。 33.5.1 DAC856X基础信息
33.5.2 DAC856X每个引脚的作用 DAC856X主要有下面两种封装形式:
33.5.3 DAC856X输出电压计算公式 DAC856X的计算公式如下:
33.5.4 DAC856X时序图 DAC856X的时序图如下: 这个时序里面有三个参数尤其重要(对于F4系列主要是第1个参数,H7系列这三个都要用的)。
33.5.5 DAC856X寄存器配置 DAC856X的寄存器配置看下面的图表即可,一目了然(X表示为0或者为1均可): 控制DAC856X每次要传输24bit数据,高8bit控制位 + 16bit数据位。 比如Power up DAC-A and DAC-B: DAC8562_WriteCmd((4 << 19) | (0 << 16) | (3 << 0)) 33.6 DAC856X驱动设计 DAC856X的程序驱动框架设计如下: 有了这个框图,程序设计就比较好理解了。 33.6.1 第1步:SPI总线配置 spi总线配置通过如下两个函数实现: /* ********************************************************************************************************* * 函 数 名: bsp_InitSPIBus * 功能说明: 配置SPI总线。 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ void bsp_InitSPIBus(void) { g_spi_busy = 0; bsp_InitSPIParam(SPI_BAUDRATEPRESCALER_8, SPI_PHASE_1EDGE, SPI_POLARITY_LOW); } /* ********************************************************************************************************* * 函 数 名: bsp_InitSPIParam * 功能说明: 配置SPI总线参数,时钟分频,时钟相位和时钟极性。 * 形 参: _BaudRatePrescaler SPI总线时钟分频设置,支持的参数如下: * SPI_BAUDRATEPRESCALER_2 2分频 * SPI_BAUDRATEPRESCALER_4 4分频 * SPI_BAUDRATEPRESCALER_8 8分频 * SPI_BAUDRATEPRESCALER_16 16分频 * SPI_BAUDRATEPRESCALER_32 32分频 * SPI_BAUDRATEPRESCALER_64 64分频 * SPI_BAUDRATEPRESCALER_128 128分频 * SPI_BAUDRATEPRESCALER_256 256分频 * * _CLKPhase 时钟相位,支持的参数如下: * SPI_PHASE_1EDGE SCK引脚的第1个边沿捕获传输的第1个数据 * SPI_PHASE_2EDGE SCK引脚的第2个边沿捕获传输的第1个数据 * * _CLKPolarity 时钟极性,支持的参数如下: * SPI_POLARITY_LOW SCK引脚在空闲状态处于低电平 * SPI_POLARITY_HIGH SCK引脚在空闲状态处于高电平 * * 返 回 值: 无 ********************************************************************************************************* */ void bsp_InitSPIParam(uint32_t _BaudRatePrescaler, uint32_t _CLKPhase, uint32_t _CLKPolarity) { /* 提高执行效率,只有在SPI硬件参数发生变化时,才执行HAL_Init */ if (s_BaudRatePrescaler == _BaudRatePrescaler && s_CLKPhase == _CLKPhase && s_CLKPolarity == _CLKPolarity) { return; } s_BaudRatePrescaler = _BaudRatePrescaler; s_CLKPhase = _CLKPhase; s_CLKPolarity = _CLKPolarity; /* 设置SPI参数 */ hspi.Instance = SPIx; /* 例化SPI */ hspi.Init.BaudRatePrescaler = _BaudRatePrescaler; /* 设置波特率 */ hspi.Init.Direction = SPI_DIRECTION_2LINES; /* 全双工 */ hspi.Init.CLKPhase = _CLKPhase; /* 配置时钟相位 */ hspi.Init.CLKPolarity = _CLKPolarity; /* 配置时钟极性 */ hspi.Init.DataSize = SPI_DATASIZE_8BIT; /* 设置数据宽度 */ hspi.Init.FirstBit = SPI_FIRSTBIT_MSB; /* 数据传输先传高位 */ hspi.Init.TIMode = SPI_TIMODE_DISABLE; /* 禁止TI模式 */ hspi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; /* 禁止CRC */ hspi.Init.CRCPolynomial = 7; /* 禁止CRC后,此位无效 */ hspi.Init.NSS = SPI_NSS_SOFT; /* 使用软件方式管理片选引脚 */ hspi.Init.Mode = SPI_MODE_MASTER; /* SPI工作在主控模式 */ /* 复位SPI */ if(HAL_SPI_DeInit(&hspi) != HAL_OK) { Error_Handler(__FILE__, __LINE__); } if (HAL_SPI_Init(&hspi) != HAL_OK) { Error_Handler(__FILE__, __LINE__); } } 关于这两个函数有以下两点要做个说明:
注:推荐使用查询方式。 SPI驱动的查询,中断和DMA方式主要通过函数bsp_spiTransfer实现数据传输: /* ********************************************************************************************************* * 选择DMA,中断或者查询方式 ********************************************************************************************************* */ //#define USE_SPI_DMA /* DMA方式 */ //#define USE_SPI_INT /* 中断方式 */ #define USE_SPI_POLL /* 查询方式 */ uint8_t g_spiTxBuf[SPI_BUFFER_SIZE]; uint8_t g_spiRxBuf[SPI_BUFFER_SIZE]; /* ********************************************************************************************************* * 函 数 名: bsp_spiTransfer * 功能说明: 启动数据传输 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ void bsp_spiTransfer(void) { if (g_spiLen 》 SPI_BUFFER_SIZE) { return; } /* DMA方式传输 */ #ifdef USE_SPI_DMA wTransferState = TRANSFER_WAIT; if(HAL_SPI_TransmitReceive_DMA(&hspi, (uint8_t*)g_spiTxBuf, (uint8_t *)g_spiRxBuf, g_spiLen) != HAL_OK) { Error_Handler(__FILE__, __LINE__); } while (wTransferState == TRANSFER_WAIT) { ; } #endif /* 中断方式传输 */ #ifdef USE_SPI_INT wTransferState = TRANSFER_WAIT; if(HAL_SPI_TransmitReceive_IT(&hspi, (uint8_t*)g_spiTxBuf, (uint8_t *)g_spiRxBuf, g_spiLen) != HAL_OK) { Error_Handler(__FILE__, __LINE__); } while (wTransferState == TRANSFER_WAIT) { ; } #endif /* 查询方式传输 */ #ifdef USE_SPI_POLL if(HAL_SPI_TransmitReceive(&hspi, (uint8_t*)g_spiTxBuf, (uint8_t *)g_spiRxBuf, g_spiLen, 1000000) != HAL_OK) { Error_Handler(__FILE__, __LINE__); } #endif } 通过开头宏定义可以方便的切换中断,查询和DMA方式。 |
|
|
|
33.6.3 第3步:DAC856X的时钟极性和时钟相位配置
首先回忆下STM32F4支持的4种时序配置。
有了F4支持的时序配置,再来看下DAC856X的时序图: 首先DAC856X是下降升沿做数据采集,所以STM32F4的可选的配置就是: CHOL = 0, CPHA = 1 CHOL = 1, CPHA = 0 对于这两种情况的主要区别是空闲状态下SCLK时钟选择高电平还是低电平,根据上面的时序图和DAC856X的数据手册,两种情况下都可以正常运行。经过实际测试,STM32F4使用这两个配置确实都可以正常运行。程序里面默认是选择CHOL = 0, CPHA = 1。 33.6.4 第4步:单SPI接口管理多个SPI设备的切换机制 单SPI接口管理多个SPI设备最麻烦的地方是不同设备的时钟分配,时钟极性和时钟相位并不相同。对此的解决解决办法是在片选阶段配置切换,比如DAC856X的片选: /* ********************************************************************************************************* * 函 数 名: DAC8562_SetCS * 功能说明: DAC8562 片选控制函数 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ void DAC8562_SetCS(uint8_t _Level) { if (_Level == 0) { bsp_SpiBusEnter(); /* 占用SPI总线 */ bsp_InitSPIParam(SPI_BAUDRATEPRESCALER_2, SPI_PHASE_2EDGE, SPI_POLARITY_LOW); CS_0(); } else { CS_1(); bsp_SpiBusExit(); /* 释放SPI总线 */ } } 通过这种方式就有效的解决了单SPI接口管理多设备的问题。因为给每个设备都配了一个独立的片选引脚,这样就可以为每个设备都配置这么一个片选配置。 但是频繁配置也比较繁琐,所以函数bsp_InitSPIParam里面做了特别处理。当前配置与之前配置相同的情况下无需重复配置。 33.6.5 第5步:DAC856X的数据更新 DAC856X的双通道数据更新通过下面的函数实现: /* ********************************************************************************************************* * 函 数 名: DAC8562_SetDacData * 功能说明: 设置DAC输出,并立即更新。 * 形 参: _ch, 通道, 0 , 1 * _data : 数据 * 返 回 值: 无 ********************************************************************************************************* */ void DAC8562_SetDacData(uint8_t _ch, uint16_t _dac) { if (_ch == 0) { /* Write to DAC-A input register and update DAC-A; */ DAC8562_WriteCmd((3 《《 19) | (0 《《 16) | (_dac 《《 0)); } else if (_ch == 1) { /* Write to DAC-B input register and update DAC-A; */ DAC8562_WriteCmd((3 《《 19) | (1 《《 16) | (_dac 《《 0)); } } 函数实现比较简单,每次更新发送24bit数据即可。 33.7 SPI总线板级支持包(bsp_spi_bus.c) SPI总线驱动文件bsp_spi_bus.c主要实现了如下几个API供用户调用:
函数原型: void bsp_InitSPIBus(void) 函数描述: 此函数主要用于SPI总线的初始化,在bsp.c文件调用一次即可。 33.7.2 函数bsp_InitSPIParam 函数原型: void bsp_InitSPIParam(uint32_t _BaudRatePrescaler, uint32_t _CLKPhase, uint32_t _CLKPolarity) 函数描述: 此函数用于SPI总线的配置。 函数参数:
SPI_BAUDRATEPRESCALER_4 4分频 SPI_BAUDRATEPRESCALER_8 8分频 SPI_BAUDRATEPRESCALER_16 16分频 SPI_BAUDRATEPRESCALER_32 32分频 SPI_BAUDRATEPRESCALER_64 64分频 SPI_BAUDRATEPRESCALER_128 128分频 SPI_BAUDRATEPRESCALER_256 256分频
SPI_PHASE_2EDGE SCK引脚的第2个边沿捕获传输的第1个数据
SPI_POLARITY_HIGH SCK引脚在空闲状态处于高电平 33.7.3 函数bsp_spiTransfer 函数原型: void bsp_spiTransfer(void) 函数描述: 此函数用于启动SPI数据传输,支持查询,中断和DMA方式传输。 33.8 DAC856X支持包中断方式(bsp_spi_dac8562.c) DAC856X驱动文件bsp_spi_dac8562.c主要实现了如下几个API供用户调用:
函数原型: void bsp_InitDAC8562(void) 函数描述: 主要用于DAC856X的初始化,调用前务必先调用函数bsp_InitSPIBus初始化SPI外设。 33.8.2 函数DAC8562_SetCS 函数原型: void DAC8562_SetCS(uint8_t _Level) 函数描述: 此函数用于片选DAC8562。 函数参数:
函数原型: void DAC8562_WriteCmd(uint32_t _cmd) 函数描述: 此函数用于向SPI总线发送24个bit数据。 函数参数:
函数原型: void DAC8562_SetDacData(uint8_t _ch, uint16_t _dac) 函数描述: 此函数用于设置DAC输出,并立即更新。 函数参数:
函数原型: int32_t DAC8562_DacToVoltage(uint16_t _dac) 函数描述: 此函数用于将DAC值换算为电压值,单位0.1mV。 函数参数:
函数原型: uint32_t DAC8562_VoltageToDac(int32_t _volt) 函数描述: 此函数用于将电压值转换为DAC值。 函数参数:
|
|
|
|
33.9 DAC856X驱动移植和使用
DAC856X移植步骤如下:
********************************************************************************************************* * 时钟,引脚,DMA,中断等宏定义 ********************************************************************************************************* */ #define SPIx SPI1 #define SPIx_CLK_ENABLE() __HAL_RCC_SPI1_CLK_ENABLE() #define DMAx_CLK_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE() #define SPIx_FORCE_RESET() __HAL_RCC_SPI1_FORCE_RESET() #define SPIx_RELEASE_RESET() __HAL_RCC_SPI1_RELEASE_RESET() #define SPIx_SCK_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() #define SPIx_SCK_GPIO GPIOB #define SPIx_SCK_PIN GPIO_PIN_3 #define SPIx_SCK_AF GPIO_AF5_SPI1 #define SPIx_MISO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() #define SPIx_MISO_GPIO GPIOB #define SPIx_MISO_PIN GPIO_PIN_4 #define SPIx_MISO_AF GPIO_AF5_SPI1 #define SPIx_MOSI_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() #define SPIx_MOSI_GPIO GPIOB #define SPIx_MOSI_PIN GPIO_PIN_5 #define SPIx_MOSI_AF GPIO_AF5_SPI1 #define SPIx_TX_DMA_CHANNEL DMA_CHANNEL_3 #define SPIx_TX_DMA_STREAM DMA2_Stream3 #define SPIx_RX_DMA_CHANNEL DMA_CHANNEL_3 #define SPIx_RX_DMA_STREAM DMA2_Stream0 #define SPIx_IRQn SPI1_IRQn #define SPIx_IRQHandler SPI1_IRQHandler #define SPIx_DMA_TX_IRQn DMA2_Stream3_IRQn #define SPIx_DMA_RX_IRQn DMA2_Stream0_IRQn #define SPIx_DMA_TX_IRQHandler DMA2_Stream3_IRQHandler #define SPIx_DMA_RX_IRQHandler DMA2_Stream0_IRQHandler
/* ********************************************************************************************************* * 函 数 名: DAC8562_SetCS * 功能说明: DAC8562 片选控制函数 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ void DAC8562_SetCS(uint8_t _Level) { if (_Level == 0) { bsp_SpiBusEnter(); /* 占用SPI总线 */ bsp_InitSPIParam(SPI_BAUDRATEPRESCALER_2, SPI_PHASE_2EDGE, SPI_POLARITY_LOW); CS_0(); } else { CS_1(); bsp_SpiBusExit(); /* 释放SPI总线 */ } }
/* SYNC, 也就是CS片选 */ #define CS_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE() #define CS_GPIO GPIOF #define CS_PIN GPIO_PIN_7 #define CS_1() CS_GPIO-》BSRR = CS_PIN #define CS_0() CS_GPIO-》BSRR = ((uint32_t)CS_PIN 《《 16U) /* CLR */ #define CLR_CLK_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE() #define CLR_GPIO GPIOH #define CLR_PIN GPIO_PIN_7 #define CLR_1() CLR_GPIO-》BSRR = CLR_PIN #define CLR_0() CLR_GPIO-》BSRR = ((uint32_t)CLR_PIN 《《 16U) /* LDAC */ #define LDAC_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() #define LDAC_GPIO GPIOA #define LDAC_PIN GPIO_PIN_4 #define LDAC_1() LDAC_GPIO-》BSRR = CLR_PIN #define LDAC_0() LDAC_GPIO-》BSRR = ((uint32_t)CLR_PIN 《《 16U)
/* 针对不同的应用程序,添加需要的底层驱动模块初始化函数 */ bsp_InitSPIBus(); /* 配置SPI总线 */ bsp_InitDAC8562(); /* 初始化配置DAC8562/8563 */
通过程序设计框架,让大家先对配套例程有一个全面的认识,然后再理解细节,本次实验例程的设计框架如下: 第1阶段,上电启动阶段:
配套例子: V6-014_DAC856x简易信号发生器(双通道,16bit分辨率, 正负10V输出) 实验目的:
波特率 115200,数据位 8,奇偶校验位无,停止位 1。 波形效果: 模块插入位置: 程序设计: 系统栈大小分配: 硬件外设初始化 硬件外设的初始化是在 bsp.c 文件实现: /* ********************************************************************************************************* * 函 数 名: bsp_Init * 功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次 * 形 参:无 * 返 回 值: 无 ********************************************************************************************************* */ void bsp_Init(void) { /* STM32F429 HAL 库初始化,此时系统用的还是F429自带的16MHz,HSI时钟: - 调用函数HAL_InitTick,初始化滴答时钟中断1ms。 - 设置NVIV优先级分组为4。 */ HAL_Init(); /* 配置系统时钟到168MHz - 切换使用HSE。 - 此函数会更新全局变量SystemCoreClock,并重新配置HAL_InitTick。 */ SystemClock_Config(); /* Event Recorder: - 可用于代码执行时间测量,MDK5.25及其以上版本才支持,IAR不支持。 - 默认不开启,如果要使能此选项,务必看V5开发板用户手册第8章 */ #if Enable_EventRecorder == 1 /* 初始化EventRecorder并开启 */ EventRecorderInitialize(EventRecordAll, 1U); EventRecorderStart(); #endif bsp_InitKey(); /* 按键初始化,要放在滴答定时器之前,因为按钮检测是通过滴答定时器扫描 */ bsp_InitTimer(); /* 初始化滴答定时器 */ bsp_InitUart(); /* 初始化串口 */ bsp_InitExtIO(); /* 初始化扩展IO */ bsp_InitLed(); /* 初始化LED */ BEEP_InitHard(); /* 初始化蜂鸣器 */ /* 针对不同的应用程序,添加需要的底层驱动模块初始化函数 */ bsp_InitSPIBus(); /* 配置SPI总线 */ bsp_InitDAC8562(); /* 初始化配置DAC8562/8563 */ } 主功能: 主程序实现如下操作:
/* ********************************************************************************************************* * 函 数 名: main * 功能说明: c程序入口 * 形 参: 无 * 返 回 值: 错误代码(无需处理) ********************************************************************************************************* */ int main(void) { bsp_Init(); /* 硬件初始化 */ PrintfLogo(); /* 打印例程名称和版本等信息 */ DemoSpiDac(); /* SPI DAC测试 */ } /* ********************************************************************************************************* * 函 数 名: DemoSpiDac * 功能说明: DAC8562测试 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ void DemoSpiDac(void) { uint8_t i=0; uint8_t ucKeyCode; /* 按键代码 */ sfDispMenu(); /* 打印命令提示 */ bsp_StartAutoTimer(0, 200); /* 启动1个100ms的自动重装的定时器 */ /* 生成方波数据 */ for(i =0; i《 50; i++) { ch1buf[i] = 0; } for(i =50; i《 100; i++) { ch1buf[i] = 65535; } /* 生成正弦波数据 */ MakeSinTable(ch2buf, 100, 0, 65535); /* 配置个TIM6中断,频率DAC_OUT_FREQ */ bsp_SetTIMforInt(TIM6, DAC_OUT_FREQ, 2, 0); DAC8562_SetDacData(0, 65535); /* 改变第1通道 DAC输出电压 */ while(1) { bsp_Idle(); /* 这个函数在bsp.c文件。用户可以修改这个函数实现CPU休眠和喂狗 */ /* 判断定时器超时时间 */ if (bsp_CheckTimer(0)) { /* 每隔100ms 进来一次 */ bsp_LedToggle(4); } /* 按键滤波和检测由后台systick中断服务程序实现,我们只需要调用bsp_GetKey读取键值即可。 */ ucKeyCode = bsp_GetKey(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */ if (ucKeyCode != KEY_NONE) { switch (ucKeyCode) { case KEY_DOWN_K1: /* K1键按下,双通道输出,通道1输出方波,通道2输出正弦波 */ /* 生成方波数据 */ for(i =0; i《 50; i++) { ch1buf[i] = 0; } for(i =50; i《 100; i++) { ch1buf[i] = 65535; } /* 生成正弦波数据 */ MakeSinTable(ch2buf, 100, 0, 65535); break; case KEY_DOWN_K2: /* K2键按下,双通道输出方波 */ /* 生成方波数据 */ for(i =0; i《 50; i++) { ch1buf[i] = 0; ch2buf[i] = 0; } for(i =50; i《 100; i++) { ch1buf[i] = 65535; ch2buf[i] = 65535; } break; case KEY_DOWN_K3: /* K3键按下,双通道输出正弦波 */ MakeSinTable(ch1buf, 100, 0, 65535); MakeSinTable(ch2buf, 100, 0, 65535); break; case JOY_DOWN_OK: /* 摇杆OK键按下,双通道输出直流 */ /* 通道1输出-10V */ for(i = 0; i 《 100; i++) { ch1buf[i] = 0; } /* 通道2输出 10V */ for(i = 0; i 《 100; i++) { ch2buf[i] = 65535; } /* 输出直流的话,仅设置一次输出寄存器也是可以的 */ //DAC8562_SetDacData(0, 0); //DAC8562_SetDacData(1, 65535); break; default: /* 其它的键值不处理 */ break; } } } } |
|
|
|
|
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1820 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1634 浏览 1 评论
1104 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
740 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1692 浏览 2 评论
1951浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
756浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
587浏览 3评论
605浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
570浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-31 01:51 , Processed in 0.696506 second(s), Total 59, Slave 51 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号