打印

麻烦香版进来看下

[复制链接]
1786|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
isd2560|  楼主 | 2008-12-11 16:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
万利199的板子。
疑惑1:为什么ADC寄存器复位之后,ADC校准之前,AD_DR里面冒出来0000 003B?
https://bbs.21ic.com/upfiles/img/200812/20081211161514557.jpg

疑惑2:ADC多通道的问题。老生常谈了吧,单个ADC里面开多个通道(通道0--15),非DMA传输,我只开了通道10和11,PC0和PC1都定义为模拟输入方式。我在单步调试的时候,发现AD_DR只有通道10的值,无通道11的,这个是为何?

关于DMA用在ADC多通道传输时,我先后咨询了南京万利的王工和武汉利源的李工,王工说他没有做过这种试验,因此无法作解释。李工说他做过,但是采样得来的数据不正常,很乱,数据抖动很厉害(单通道不存在此现象)。我怀疑是DMA传输的问题,特别是MemonyInc存储器自动增量模式一开就数据就出乱子。因此我尝试无DMA的多通道,下午做个简单试验,得出疑问2.

现求解!
我的工程在附件
相关链接:https://bbs.21ic.com/upfiles/img/200812/20081211163255889.rar
沙发
香水城| | 2008-12-11 16:48 | 只看该作者

ADC解惑

1)ADC寄存器复位之后,手册上说ADC_DR的复位值为0x0000,但我认为手册写错了。实际应用中,不管ADC_DR的复位值是0x0000还是一个不确定的数值,都不会影响使用效果,所以你可以不必理会它。

2)ADC的多通道传输只能使用DMA读取转换后的数值,不能用轮询的方式。

使用特权

评论回复
板凳
isd2560|  楼主 | 2008-12-11 16:51 | 只看该作者

但是多通道DMA一开就数据就乱

数据乱不正常不说,PC0管脚电压都被拉高了,不知道你们试验中是否有此现象?这几天一直在整这个,好烦哦

使用特权

评论回复
地板
香水城| | 2008-12-11 16:54 | 只看该作者

试过STM32固件库中的例子吗?

使用特权

评论回复
5
isd2560|  楼主 | 2008-12-11 17:05 | 只看该作者

没有依次试过

ADC例子一共有6个
ADC1_DMA试过,单通道的嘛,没有什么问题
我做的都是规则转换试验,因此注入方式和TIM触发的方式我还没有试过
下班了,明天早再试试看。规则多通道转换,好恼火哦,呵呵

使用特权

评论回复
6
freefish| | 2008-12-11 22:26 | 只看该作者

程序的问题,或者使用的不对

可以肯定的说,STM32的ADC没有任何问题。我用的是对两个通道连采3次取平均的方法,相当于六个通道,结果完全正确,经过付氏算法和改进模拟部分后,可以在满量程时达到万分之一的精度。
今天遇到的问题是,样机在**(无外壳)状态下,放在阳光下爆晒(F103在最顶层,晒得最重),触摸芯片会死机并被看门狗复位,在暗处则没有此问题。
实测工作电流:全速运行下32mA,与手册相符合。等壳子来了,就可以鉴定并生产了,忙了3个月,也有点结果了。

使用特权

评论回复
7
freefish| | 2008-12-11 23:04 | 只看该作者

看了下程序

 while(1)
  {
    //u32 ADC_ADD;    
    ADC_ConvertedValue = *(vu32*)(0x4001244C);
     
    u16 value =  ADC_Filter();  //准备送到LCD显示转换后的AD值

错误一:不管有没有转换完成(EOC),硬读DR寄存器的数值,有点太暴力了,没好果子吃.如果不想等待EOC,请使用DMA,如同万利的例子程序一样.
错误二:本论坛讨论过多次,多通道的规则转换,必须使用DMA!因为STM32与F2812不同,只有一个DR,而不是F2812的多个,如果不用DMA及时取走数据,将被下一次转换覆盖.
很多不喜欢用DMA的,想不明白.

使用特权

评论回复
8
isd2560|  楼主 | 2008-12-12 10:21 | 只看该作者

freefish你好

关于ADC多通道规则转换,用DMA传输的试验我做过好多次,也的确是参照手册以及万利的例子来的,但是我的数据是乱的,通道IO电压被拉高到3.3V,我的板子是万利2007年11月的板子,这个是不是跟板子版本还有干系?

您试验做成功,可否借我参考一下?我的Email:maxinwen@foxmail.com

使用特权

评论回复
9
freefish| | 2008-12-12 18:31 | 只看该作者

配置片段

以下是我项目中的片段,配置完成后,请使用软件触发,并声明一个 u16 ADC_ConvertedValueTab[6]数组。触发后等待DMA完成后就可以读数据了。
void ADC_Config(void)
{     
  ADC_DeInit(ADC1);
  ADC_DeInit(ADC2);
  ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 3; 
  ADC_Init(ADC1, &ADC_InitStructure);
  ADC_Init(ADC2, &ADC_InitStructure);
  
  ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_71Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 2, ADC_SampleTime_71Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 3, ADC_SampleTime_71Cycles5);
  ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 1, ADC_SampleTime_71Cycles5);
  ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 2, ADC_SampleTime_71Cycles5);
  ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 3, ADC_SampleTime_71Cycles5);  //55
  
  ADC_Cmd(ADC1, ENABLE);       /* Enable ADC1 */    
  ADC_DMACmd(ADC1, ENABLE);    /* Enable ADC1 DMA */
  
  ADC_ResetCalibration(ADC1);  /* Enable ADC1 reset calibaration register */  
  while(ADC_GetResetCalibrationStatus(ADC1)){} /* Check the end of ADC1 reset calibration register */  
  ADC_StartCalibration(ADC1);  /* Start ADC1 calibaration */  
  while(ADC_GetCalibrationStatus(ADC1)){}  /* Check the end of ADC1 calibration */ 
   
  ADC_Cmd(ADC2, ENABLE);       /* Enable ADC2 */  
   
  ADC_ResetCalibration(ADC2);  /* Enable ADC2 reset calibaration register */  
  while(ADC_GetResetCalibrationStatus(ADC2)){} /* Check the end of ADC2 reset calibration register */  
  ADC_StartCalibration(ADC2);  /* Start ADC2 calibaration */  
  while(ADC_GetCalibrationStatus(ADC2)){}  /* Check the end of ADC2 calibration */ 
}

void DMA_Config(void)

  DMA_DeInit(DMA1_Channel1);
  DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)ADC1_DR_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValueTab;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = 3;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel1, &DMA_InitStructure); 
  DMA_Cmd (DMA1_Channel1, ENABLE);
  DMA_ITConfig(DMA1_Channel1, DMA_IT_TC,DISABLE);/* Enable DMA channel1 */

  /* DMA1 Channel4 (triggered by USART1 Tx event) Config */
  DMA_DeInit(DMA1_Channel4);  
  DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)COMMtxd;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  DMA_InitStructure.DMA_BufferSize = 64;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//Normal;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel4, &DMA_InitStructure);
  DMA_Cmd (DMA1_Channel4, ENABLE);
  DMA_ITConfig(DMA1_Channel4, DMA_IT_TC,ENABLE);/* Enable DMA channel4 */
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

36

主题

93

帖子

0

粉丝