找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8292|回复: 1
打印 上一主题 下一主题
收起左侧

关于STM32的ADC/DAC问题汇总

[复制链接]
跳转到指定楼层
楼主
ID:171096 发表于 2017-3-17 03:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1、STM32的DAC转换是什么开始的呢?

问:STM32的DAC转换是什么开始的呢?如何利用DAC输出一个脉宽的控的单脉冲呢?
答:DAC是通过写入DAC输出寄存器开始的。另外,如果想要脉冲,使用TIM功能。


2、STM32的DAC输出电压

问:DAC的输出电压是如何调节的呢,输入的数字量和输出的电压怎么不成比例呢,输出电压不符合数据手册上提供的公式(DAC输出=VREFXDOR/4095),求高人指点,程序如下:
  1. #include"stm32f10x_lib.h"
  2. #defineDAC_DHR8R1_Address0x40007410
  3. DAC_InitTypeDefDAC_InitStructure;
  4. DMA_InitTypeDefDMA_InitStructure;
  5. ErrorStatusHSEStartUpStatus;
  6. uc8Escalator8bit[50]={0x0,0x33,0x66,0x99,0xcc,0xff};
  7. voidRCC_Configuration(void);
  8. voidGPIO_Configuration(void);
  9. voidNVIC_Configuration(void);
  10. voidDelay(vu32nCount);
  11. intmain(void)
  12. {
  13. #ifdefDEBUG
  14. debug();
  15. #endif
  16. RCC_Configuration();
  17. GPIO_Configuration();
  18. NVIC_Configuration();
  19. TIM_PrescalerConfig(TIM6,0xF,TIM_PSCReloadMode_Update);
  20. TIM_SetAutoreload(TIM6,0xFF);
  21. TIM_SelectOutputTrigger(TIM6,TIM_TRGOSource_Update);
  22. DAC_InitStructure.DAC_Trigger=DAC_Trigger_T6_TRGO;
  23. DAC_InitStructure.DAC_WaveGeneration=DAC_WaveGeneration_None;
  24. DAC_InitStructure.DAC_OutputBuffer=DAC_OutputBuffer_Disable;
  25. DAC_Init(DAC_Channel_1,&DAC_InitStructure);
  26. DMA_DeInit(DMA2_Channel3);
  27. DMA_InitStructure.DMA_PeripheralBaseAddr=DAC_DHR8R1_Address;
  28. DMA_InitStructure.DMA_MemoryBaseAddr=(u32)&Escalator8bit;
  29. DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralDST;
  30. DMA_InitStructure.DMA_BufferSize=6;
  31. DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
  32. DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;
  33. DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;
  34. DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;
  35. DMA_InitStructure.DMA_Mode=DMA_Mode_Circular;
  36. DMA_InitStructure.DMA_Priority=DMA_Priority_High;
  37. DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;
  38. DMA_Init(DMA2_Channel3,&DMA_InitStructure);
  39. DMA_Cmd(DMA2_Channel3,ENABLE);
  40. DAC_Cmd(DAC_Channel_1,ENABLE);
  41. DAC_DMACmd(DAC_Channel_1,ENABLE);
  42. TIM_Cmd(TIM6,ENABLE);
  43. while(1)
  44. {
  45. }
  46. }
  47. voidRCC_Configuration(void)
  48. {
  49. RCC_DeInit();
  50. RCC_HSEConfig(RCC_HSE_ON);
  51. HSEStartUpStatus=RCC_WaitForHSEStartUp();
  52. if(HSEStartUpStatus==SUCCESS)
  53. {
  54. FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
  55. FLASH_SetLatency(FLASH_Latency_2);
  56. RCC_HCLKConfig(RCC_SYSCLK_Div1);
  57. RCC_PCLK2Config(RCC_HCLK_Div1);
  58. RCC_PCLK1Config(RCC_HCLK_Div2);
  59. RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);
  60. RCC_PLLCmd(ENABLE);
  61. while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)
  62. {
  63. }
  64. RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
  65. while(RCC_GetSYSCLKSource()!=0x08)
  66. {
  67. }
  68. }
  69. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2,ENABLE);
  70. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOA,ENABLE);
  71. RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC,ENABLE);
  72. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);
  73. }
  74. voidGPIO_Configuration(void)
  75. {
  76. GPIO_InitTypeDefGPIO_InitStructure;
  77. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;
  78. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  79. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
  80. GPIO_Init(GPIOA,&GPIO_InitStructure);
  81. }
  82. voidNVIC_Configuration(void)
  83. {
  84. #ifdefVECT_TAB_RAM
  85. NVIC_SetVectorTable(NVIC_VectTab_RAM,0x0);
  86. #else/*VECT_TAB_FLASH*/
  87. NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0);
  88. #endif
  89. }
  90. voidDelay(vu32nCount)
  91. {
  92. for(;nCount!=0;nCount--);
  93. }
复制代码


输出电压为什么不是0~3.3V呢?



答1:(u32)&Escalator8bit;你把这个里面的数据强制转换为32位,也就是0x0,0x33,0x66,0x99转换为一个32位的数据,你这样做是不对的。你应该定义一个16位的数组,然后VREFXDOR/4095算出DOR的值,DOR的值不能超过4095.



答2:DAC_OutputBuffer-输出缓存使能再试试



1、关于STM32F103RE的DAC



问:关于STM32F103RE中有几个DAC呢?是只有一个DAC(包括两个通道)还是有两个呢?



答:有2个,这个你可以到引脚图上面看到。

2、STM32F107的DAC例程都用TIMx更新启动DMA2



问:STM32F107的DAC例程都用TIMx更新启动DMA2,没有不用TIMx启动DMA2自动把数据传送DAC的DHRxx寄存器里面?该如何设置呢?



答:不用TIM只能自己写时间判断了.可以在while()里面写一个计数器的处理或者延时的处理.



3、STM32F107可以带多个外置式ADC吗?如果可以最多可以带多少个?

问:STM32F107可以带多个外置式ADC吗?如果可以最多可以带多少个?

答:一共有16个痛多的ADC,外置式是什么类型连接的?


答:外置式ADC型号是AD7490的16通道,SPI接口。因为总共有38路模拟量的,我想用三个外置ADC。另外我想问一下是不是可以只用一个SPI接口就可以连接三个外置ADC呢?如果可以怎么做片选呢?万分感谢!



答:用其他3个IO做片选就可以



6、STM32F2ADC

问:STM32F系列单片机中ADC的每个通道的采用周期都是可配置的,我想问一下采样周期配置的越大转换出来的值越精确吗?比如STM32F2处理器的ADC采用周期可以是3、15、28、56、84、112、144、480.还有就是ADC中分为规则组和注入组,这两种模式在使用上有什么本质的不同吗?



答:ADC采用周期越大采集间隔越长,这个值越小采集越精确。规则组此模式通过设置ADC_CR1寄存器上的DISCEN位激活。它可以用来执行一个短序列的n次转换(n<=8),此转换是ADC_SQRx寄存器所选择的转换序列的一部分。数值n由ADC_CR1寄存器的DISCNUM[2:0]位给出。一个外部触发信号可以启动ADC_SQRx寄存器中描述的下一轮n次转换,直到此序列所有的转换完成为止。总的序列长度由ADC_SQR1寄存器的L[3:0]定义。举例:n=3,被转换的通道=0、1、2、3、6、7、9、10第一次触发:转换的序列为0、1、2第二次触发:转换的序列为3、6、7第三次触发:转换的序列为9、10,并产生EOC事件第四次触发:转换的序列0、1、2注入组此模式通过设置ADC_CR1寄存器的JDISCEN位激活。在一个外部触发事件后,该模式按通道顺序逐个转换ADC_JSQR寄存器中选择的序列。一个外部触发信号可以启动ADC_JSQR寄存器选择的下一个通道序列的转换,直到序列中所有的转换完成为止。总的序列长度由ADC_JSQR寄存器的JL[1:0]位定义。例子:n=1,被转换的通道=1、2、3第一次触发:通道1被转换第二次触发:通道2被转换第三次触发:通道3被转换,并且产生EOC和JEOC事件第四次触发:通道1被转换


答:非常感谢您的回答。其实我想问的是采样时间越大采样值就越精确吗?ADC采样周期可以是3、15、28、56、84、112、144、480.最小的采样时间是3个ADCCLK,最大的是480个ADCCLK,这个值是越大越好吗?



答:ADC采用周期越大采集间隔越长,这个值越小采集越精确。



7、STM32ADC操作模式有哪些?

问:STM32ADC操作模式有哪些?

答:单次转换模式:转换一次则停止连续转换模式:转换完一次后即开始下一次转换扫描模式:扫描一组模拟通道间断模式:每触发一次,转换序列中n个通道多种触发方式



8、STM32的内部温度传感器通过哪个AD采集?

答:STM32集成了片上的温度传感器,可以用来测量芯片内部的温度;STM32内部温度传感器与ADC的通道16相连,与ADC配合使用实现温度测量;测量范围–40~125℃,精度±1.5℃。



9、STM32CPU温度数值如何计算?

答:ADC转换结束以后,读取ADC_DR寄存器中的结果,通过下面的公式计算T(℃)=V25–VSENSE/Avg_Slope+25V25:温度传感器在25℃时的输出电压,典型值1.43VVSENSE:温度传感器的当前输出电压,与ADC_DR寄存器中的结果ADC_ConvertedValue之间的转换关系为:VSENSE=ADC_ConvertedValue*Vdd/Vdd_convert_value(0xFFF)Avg_Slope:温度传感器输出电压和温度的关联参数,典型值4.3mV/℃转换程序Vtemp_sensor=ADC_ConvertedValue*Vdd/Vdd_convert_value;Current_Temp=(V25-Vtemp_sensor)/Avg_Slope+25;


10、使用ADC时的注意事项是什么?

答:1、外部电路的等效输入阻抗要匹配,采样速度越快,输入阻抗越小。STM32数据手册上有对照表;2、只有在100脚和144脚的产品上才有VREF+和VREF-引出管脚。在其它产品封装中,VREF+在芯片内部与VDDA相连,VREF-在芯片内部与VSSA相连;3、电路设计时,在VREF+和VDDA上一定要有良好的滤波,使用高质量的滤波电容且一定要尽量靠近芯片的管脚。



11、关于STM32 双ADC 同步注入模式

问:我想用TIM控制双ADC同步采样6路信号,因为听说DMA方式会有错位的BUG,所以想用双ADC同步注入方式采样。但是看了手册后有以下几个疑惑
1. ADC_InitStructure.ADC_Mode = ADC_Mode_InjecSimult;
如果我设置了同步注入模式,可是触发方式选择什么呢。能否简单的说明下同步注入
模式的初始化配置流程。
2. 在数据手册上只有ADC1有注入数据寄存器,而ADC2是没有的。但是在库函数中发现有
ADC_GetInjectedConversionValue这样一个函数,用这个是否能读出ADC2注入
组的数据呢?

答1:选择自动注入就可以,注意不可能同时使用自动注入和间断模式。 2、此模式转换一个注入通道组。外部触发来自ADC1的注入组多路开关(由ADC1_CR2寄存器的JEXTSEL[2:0]选择),它同时给ADC2提供同步触发。





12、ADC 定时器触发

问:按(下面)

/* ADC 初始化 */ void ADC_Configuration(void)
{ ADC_InitTypeDef ADC_InitStructure; DMA_InitTypeDef DMA_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; /* Enable peripheral clocks ------------------------------------------------*/ /* Enable DMA1 clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* Enable GPIOA clock */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); /* TIM3 Periph clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); /* Enable ADC1 clocks */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 , ENABLE); /* Configure PA.00, PA.01, PA.02, PA.03 (ADC Channel0, Channel1, Channel2, Channel3) as analog inputs */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; GPIO_InitStr

程序初始化后,只能触发一次,转换完数据都自动复制到ADC_CvtValue中了。不能连续转换。不知啥原因?



答1:ADC_DMARequestModeConfig(ADC1,ADC_DMAMode_Circular); 就好了。如果还有问题的话你看看 ChannelNumbers; 值是多少? ADC_CvtValue; 是数组?还有你开了中断!要清除标志位!




13、STM32 DAC 库函数问题

问:在函数DAC_SetChannel1Data(u32 DAC_Align, u16 Data)中,第二个参数u16 Data是什么意思,怎么使用?
答:DATA就是你要发送的数据,也就是DAC输出的电压值





14、一个关于STM32F103VCT6 ADC的线性度的测试

问:本人同事最近做的项目,发现 STM32F103VCT6 ADC 测试出现了一个现象,线性度不好, 使用外部2.5V基准,调整10K电位器, ADC转换在 3072 3584 3840 三个点线性度很不好, 电压变化20mv,这三个点才会发生跳变,跳变不是ADC码+-1,而是加减了几十个ADCbit,我认为不是STM32内部的硬件问题,而是应用问题,不知道有人遇到过这种情况没有? 从二进制码来看,这三个数的第八位都是0

贴一张STM32 ADC性能参数图,按理说STM32的ADC不至于我测试的这么差呀,是我们使用有问题吗?

答:ADC测试的时候尽量保证电压的稳定,最好用放大器来将其分压,而电阻分压在温度、电流、电压不同的情况下会有偏差。




15、STM32的DAC转换是什么开始的呢?





问:STM32的DAC转换是什么开始的呢?如何利用DAC输出一个脉宽的控的单脉冲呢?

答:DAC是通过写入DAC输出寄存器开始的。另外,如果想要脉冲,使用TIM功能。




16、关于STM32F103RE的DAC个数问题



问:关于STM32F103RE中有几个DAC呢?是只有一个DAC(包括两个通道)还是有两个呢?

答:有2个,这个你可以到引脚图上面看到。




17、STM32F107的DAC例程都用TIMx更新启动DMA2



问:STM32F107的DAC例程都用TIMx更新启动DMA2,没有不用TIMx启动DMA2自动把数据传送DAC的DHRxx寄存器里面?该如何设置呢?



最佳答案:

不用TIM只能自己写时间判断了.可以在while()里面写一个计数器的处理或者延时的处理.




18、STM32如何与多个多通道ADC AD790进行配置



问:STM32F107VCT6如何与多个多通道ADC AD790进行SPI连接配置?谢谢各位大侠们

最佳答案:

通过AD790本身的控制,可以通过硬件来设置硬件地址。你可以详细乐队AD790的资料。




19、STM32F107可以带多个外置式ADC吗?如果可以最多可以带多少个?



问:外置式ADC型号是AD7490的 16通道,SPI接口。因为总共有38路模拟量的,我想用三个外置ADC。另外我想问一下是不是可以只用一个SPI接口就可以连接三个外置ADC呢?如果可以怎么做片选呢?万分感谢!

答:用其他3个IO做片选就可以




20、STM32F2 ADC



问:采样时间越大采样值就越精确吗?ADC采样周期可以是3、15、28、56、84、112、144、480. 最小的采样时间是3个ADCCLK,最大的是480个ADCCLK,这个值是越大越好吗?

答:ADC采用周期越大采集间隔越长,这个值越小采集越精确。 规则组 此模式通过设置ADC_CR1寄存器上的DISCEN位激活。它可以用来执行一个短序列的n次转换(n<=8),此转换是ADC_SQRx寄存器所选择的转换序列的一部分。数值n由ADC_CR1寄存器的DISCNUM[2:0]位给出。 一个外部触发信号可以启动ADC_SQRx寄存器中描述的下一轮n次转换,直到此序列所有的转换完成为止。总的序列长度由ADC_SQR1寄存器的L[3:0]定义。 举例: n=3,被转换的通道 = 0、1、2、3、6、7、9、10 第一次触发:转换的序列为 0、1、2 第二次触发:转换的序列为 3、6、7 第三次触发:转换的序列为 9、10,并产生EOC事件 第四次触发:转换的序列 0、1、2 注入组 此模式通过设置ADC_CR1寄存器的JDISCEN位激活。在一个外部触发事件后,该模式按通道顺序逐个转换ADC_JSQR寄存器中选择的序列。 一个外部触发信号可以启动ADC_JSQR寄存器选择的下一个通道序列的转换,直到序列中所有的转换完成为止。总的序列长度由ADC_JSQR寄存器的JL[1:0]位定义。 例子: n=1,被转换的通道 = 1、2、3 第一次触发:通道1被转换 第二次触发:通道2被转换 第三次触发:通道3被转换,并且产生EOC和JEOC事件 第四次触发:通道1被转换




21、STM32的双ADC操作模式有哪些?

问:STM32的双ADC操作模式有哪些?
最佳答案:
快速交替模式:在一个通道上以连续方式的快速交替模式
慢速交替模式:在一个通道上以连续方式的快速交替模式
交替触发模式:
同步模式:
快速交替模式:在一个通道上以连续方式的快速交替模式
慢速交替模式:在一个通道上以连续方式的快速交替模式
交替触发模式:

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:171475 发表于 2017-3-17 11:00 | 只看该作者
好贴,顶一个
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表