你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

9通道ADC DMA传输错位问题

[复制链接]
hacker 提问时间:2017-12-11 11:24 /
开发环境IAR8.10.1,芯片103VCT6
现象:ADC配置文件已设置只读,原本正常的数据顺序,重新编译后出现错位问题,不管他,过一会编译又正常。
基本功能读数没任何问题,但是就是通道顺序错位
天天这样,受不了了。
各位有遇到么?麻烦高手指点
C文件:
  1. #define ADC1_DR_Address    ((u32)0x40012400+0x4c)


  2. static uint16_t ADC_ConvertedValue[9];

  3. /**
  4. * [ADC1_GPIO_Config description]
  5. */
  6. static void ADC1_GPIO_Config(void)
  7. {
  8.         GPIO_InitTypeDef GPIO_InitStructure;
  9.                
  10.         /* Enable ADC1 and GPIOC clock */
  11.         // RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
  12.         // RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);
  13.         // RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);

  14.         RCC_APB2PeriphClockCmd(GPIO_RCCx(JOYSTICK1_X_PIN), ENABLE);
  15.         
  16.         GPIO_InitStructure.GPIO_Pin = ADC_PINS;                        
  17.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  18.         GPIO_Init(GPIO_PORTx(JOYSTICK1_X_PIN), &GPIO_InitStructure);                                

  19.         RCC_APB2PeriphClockCmd(GPIO_RCCx(RS_STICK_PIN), ENABLE);
  20.         GPIO_InitStructure.GPIO_Pin = GPIO_PINx(RS_STICK_PIN) |  GPIO_PINx(RD_STICK_PIN);                        
  21.         GPIO_Init(GPIO_PORTx(RS_STICK_PIN), &GPIO_InitStructure);        

  22.         RCC_APB2PeriphClockCmd(GPIO_RCCx(PWR_ADC_PIN), ENABLE);
  23.         GPIO_InitStructure.GPIO_Pin = GPIO_PINx(PWR_ADC_PIN);                        
  24.         GPIO_Init(GPIO_PORTx(PWR_ADC_PIN), &GPIO_InitStructure);                                
  25. }


  26. void adc_dma_init()
  27. {
  28.         DMA_InitTypeDef DMA_InitStructure;
  29.         RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

  30.         /* DMA channel1 configuration */
  31.         DMA_DeInit(DMA1_Channel1);
  32.         DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;         //ADC地址
  33.         DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue;//内存地址~在这里进行赋值
  34.         DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  35.         DMA_InitStructure.DMA_BufferSize = 9;
  36.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址固定
  37.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址固定
  38.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;        //半字
  39.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  40.         DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                //循环传输
  41.         DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  42.         DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  43.         DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  44.         
  45.         /* Enable DMA channel1 */
  46.         DMA_Cmd(DMA1_Channel1, ENABLE);        
  47. }

  48. /* 函数名:ADC1_Mode_Config
  49. * 描述  :配置ADC1的工作模式为MDA模式
  50. * 输入  : 无
  51. * 输出  :无
  52. * 调用  :内部调用
  53. */
  54. static void ADC1_Mode_Config(void)
  55. {
  56.         ADC_InitTypeDef ADC_InitStructure;
  57.         
  58.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
  59.         /* ADC1 configuration */
  60.         
  61.         ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;        //独立ADC模式
  62.         ADC_InitStructure.ADC_ScanConvMode = ENABLE ;          //禁止扫描模式,扫描模式用于多通道采集
  63.         ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;        //开启连续转换模式,即不停地进行ADC转换
  64.         ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;        //不使用外部触发转换
  65.         ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;         //采集数据右对齐
  66.         ADC_InitStructure.ADC_NbrOfChannel = 9;                 //要转换的通道数目1
  67.         ADC_Init(ADC1, &ADC_InitStructure);        

  68.         /*配置ADC时钟,为PCLK2的8分频,即9Hz*/
  69.         RCC_ADCCLKConfig(RCC_PCLK2_Div8);
  70.         /*配置ADC1的通道11为55.        5个采样周期,序列为1 */
  71.         ADC_RegularChannelConfig(ADC1, ADC_Channel_0,  1, ADC_SampleTime_239Cycles5);//PWR_ADC_PIN ADC_SampleTime_239Cycles5
  72.         ADC_RegularChannelConfig(ADC1, ADC_Channel_8,  2, ADC_SampleTime_239Cycles5);//RD_STICK_PIN ADC_SampleTime_55Cycles5
  73.         ADC_RegularChannelConfig(ADC1, ADC_Channel_9,  3, ADC_SampleTime_239Cycles5);//RS_STICK_PIN
  74.         ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 4, ADC_SampleTime_239Cycles5);//JOYSTICK2_X_PIN
  75.         ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 5, ADC_SampleTime_239Cycles5);//JOYSTICK2_Y_PIN
  76.         ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 6, ADC_SampleTime_239Cycles5);//JOYSTICK1_Y_PIN
  77.         ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 7, ADC_SampleTime_239Cycles5);//JOYSTICK1_X_PIN
  78.         ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 8, ADC_SampleTime_239Cycles5);//LD_STICK_PIN
  79.         ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 9, ADC_SampleTime_239Cycles5);//LS_STICK_PIN

  80.         /* Enable ADC1 DMA */
  81.         ADC_DMACmd(ADC1, ENABLE);
  82.         
  83.         /* Enable ADC1 */
  84.         ADC_Cmd(ADC1, ENABLE);
  85.         
  86.         /*复位校准寄存器 */   
  87.         ADC_ResetCalibration(ADC1);
  88.         /*等待校准寄存器复位完成 */
  89.         while(ADC_GetResetCalibrationStatus(ADC1));
  90.         
  91.         /* ADC校准 */
  92.         ADC_StartCalibration(ADC1);
  93.         /* 等待校准完成*/
  94.         while(ADC_GetCalibrationStatus(ADC1));
  95.         
  96.         /* 由于没有采用外部触发,所以使用软件触发ADC转换 */
  97.         ADC_SoftwareStartConvCmd(ADC1, ENABLE);
  98. }

  99. /*
  100. * 函数名:ADC1_Init
  101. * 描述  :无
  102. * 输入  :无
  103. * 输出  :无
  104. * 调用  :外部调用
  105. */
  106. void ADC1_Init(void)
  107. {
  108.         ADC1_GPIO_Config();
  109.         adc_dma_init();
  110.         ADC1_Mode_Config();
  111. }

  112. u16 adc_single_channel_get(u8 channel)
  113. {
  114.         return ADC_ConvertedValue[channel];
  115. }

  116. void adc_all_channel_get(u16 data[])
  117. {
  118.         data[0] = ADC_ConvertedValue[1];
  119.         data[1] = ADC_ConvertedValue[2];
  120.         data[2] = ADC_ConvertedValue[3];
  121.         data[3] = ADC_ConvertedValue[4];
  122.         data[4] = ADC_ConvertedValue[5];
  123.         data[5] = ADC_ConvertedValue[6];
  124.         data[6] = ADC_ConvertedValue[7];
  125.         data[7] = ADC_ConvertedValue[8];
  126. }
复制代码
头文件:
  1. typedef enum
  2. {
  3.         PWR_ADC_NUM                        = 0,
  4.         RD_STICK_NUM                = 1,
  5.         RS_STICK_NUM                = 2,
  6.         JOYSTICK2_X_NUM                = 3,
  7.         JOYSTICK2_Y_NUM                = 4,
  8.         JOYSTICK1_Y_NUM                = 5,
  9.         JOYSTICK1_X_NUM                = 6,
  10.         LD_STICK_NUM                = 7,
  11.         LS_STICK_NUM                = 8
  12. }AD_SEQUENCE_NEUM;

  13. void ADC1_Init(void);
  14. u16 adc_single_channel_get(u8 channel);
  15. void adc_all_channel_get(u16 data[]);
复制代码




收藏 1 评论6 发布时间:2017-12-11 11:24

举报

6个回答
回答时间:2017-12-11 11:43:32
实际电路中data[0] 对应的是ADC_ConvertedValue[1]吗?初始化顺序是什么?先初始化DMA,再初始化ADC。
hacker 回答时间:2017-12-11 11:54:57
安 发表于 2017-12-11 11:43
实际电路中data[0] 对应的是ADC_ConvertedValue[1]吗?初始化顺序是什么?先初始化DMA,再初始化ADC。 ...

这里只是调用函数,因为第一个数据是电压,这个函数只负责采集电位器数据,没关系
我主要是在线观测ADC_ConvertedValue数组数据,ADC_ConvertedValue[0]应该是PWR_ADC的数据,但有时候跑到了ADC_ConvertedValue[1]
回答时间:2017-12-11 13:49:48
我看和你的用法差不多,我是先初始化DMA,再初始化ADC。
hacker 回答时间:2017-12-11 14:04:34
安 发表于 2017-12-11 13:49
我看和你的用法差不多,我是先初始化DMA,再初始化ADC。

虽然还是不是很清楚原理,不过按你说的,问题解决了,我后续再试试看还会不会

非常感谢
回答时间:2017-12-11 14:19:23
我看你的代码如果先初始化ADC,可能会导致第一次已经采集完了,DMA才开始工作。
hacker 回答时间:2017-12-11 15:45:52
哦,你的意思是,DMA工作的时候可能是直接采集的第二通道的结果哈,这个说得过去

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版