ADC-DMA单通道中断模式,居然不成功,求解!

[复制链接]
4068|15
 楼主| woshiaokeman 发表于 2013-6-18 22:01 | 显示全部楼层 |阅读模式
本帖最后由 woshiaokeman 于 2013-6-19 19:24 编辑
  1. *#include "stm32f10x.h"
  2. #include "SysTick.h"
  3. #include "key.h"
  4. #include "uart.h"
  5. #include "led.h"
  6. #include "dma.h"
  7. #include "adc1_mulitchannel.h"

  8. extern u16 rebuf[20];
  9. extern u8 flag;

  10. void NVIC_Configuration(void);

  11. int main(void)
  12. {
  13. u8 count = 0;
  14. SysTick_Init();
  15. NVIC_Configuration();
  16. UART_INIT_Config();
  17. // LED_GPIO_Config();
  18. // KEY_GPIO_Config();
  19. DMA_INIT_Config();
  20. ADC_Configuration();

  21. while(1)
  22. {
  23. if (flag)
  24. {
  25. flag = 0;
  26. for (count=0 ;count<20 ;count++)
  27. {
  28. printf("%d",rebuf[count]);
  29. printf("\x00D\x00A");
  30. }
  31. }
  32. }
  33. }

  34. void NVIC_Configuration(void)
  35. {
  36. NVIC_InitTypeDef NVIC_InitStructure;
  37. /* Set the Vector Table base location at 0x08000000 */
  38. NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);

  39. /* Configure the NVIC Preemption Priority Bits */
  40. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

  41. NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
  42. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  43. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  44. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  45. NVIC_Init(&NVIC_InitStructure);
  46. }
  1. #include "adc1_mulitchannel.h"

  2. void ADC_Configuration(void)
  3. {
  4. GPIO_InitTypeDef GPIO_InitStructure;
  5. ADC_InitTypeDef ADC_InitStructure;

  6. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
  7. RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
  8. RCC_ADCCLKConfig(RCC_PCLK2_Div6);

  9. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 ;
  10. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  11. GPIO_Init(GPIOC, &GPIO_InitStructure);

  12. ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值

  13. ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
  14. ADC_InitStructure.ADC_ScanConvMode = ENABLE; //模数转换工作在单通道模式
  15. ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //模数转换工作在连续转换模式
  16. ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动
  17. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
  18. ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目
  19. ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器

  20. // ADC_TempSensorVrefintCmd(ENABLE);

  21. ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_239Cycles5 );

  22. ADC_DMACmd(ADC1, ENABLE);

  23. ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1

  24. ADC_ResetCalibration(ADC1); //使能复位校准

  25. while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束

  26. ADC_StartCalibration(ADC1); //开启AD校准

  27. while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束

  28. ADC_SoftwareStartConvCmd(ADC1, ENABLE);

  29. }

  1. #include "dma.h"
  2. #include "led.h"

  3. u16 rebuf[20];
  4. u8 flag;

  5. void DMA_INIT_Config(void)
  6. {
  7. DMA_InitTypeDef DMA_InitStructure;

  8. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  9. /* DMA channel1 configuration */
  10. DMA_DeInit(DMA1_Channel1);
  11. DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)ADC1_DR_Address;
  12. DMA_InitStructure.DMA_MemoryBaseAddr = (u32)rebuf;
  13. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  14. DMA_InitStructure.DMA_BufferSize = 20;
  15. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  16. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  17. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  18. DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord;
  19. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  20. DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  21. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  22. DMA_Init(DMA1_Channel1, &DMA_InitStructure);

  23. DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
  24. /* Enable DMA channel1 */
  25. DMA_Cmd(DMA1_Channel1, ENABLE);
  26. }

  27. void DMA1_Channel1_IRQHandler(void)
  28. {
  29. if(DMA_GetITStatus(DMA1_IT_TC1))
  30. {
  31. ADC_Cmd(ADC1, DISABLE);
  32. DMA_Cmd(DMA1_Channel1, DISABLE);
  33. flag = !flag;
  34. DMA_ClearFlag(DMA1_FLAG_TC1);
  35. DMA_ClearITPendingBit(DMA1_IT_TC1);
  36. }
  37. }
滴答定时和串口函数都是正确的,所以大家可以不用看!
其他设置都很常规,但是结果就是不对!
PC4连接的是一个可调电阻!

串口输出到电脑是随机数,不是随着可调电阻改变而改变的数值!可调电阻调到最小竟然输出65536,调到最大输出0!
 楼主| woshiaokeman 发表于 2013-6-19 08:53 | 显示全部楼层
没有那个朋友帮看看么?
一般我不会贴代码出来的,只是这个简单的程序足足修改了两天都改不出来,所以才贴代码上来!
sun1238898 发表于 2013-6-19 11:53 | 显示全部楼层
你贴代码,别人怎么帮你看,最好说现象,才好进行解决呀,
 楼主| woshiaokeman 发表于 2013-6-19 19:24 | 显示全部楼层
sun1238898 发表于 2013-6-19 11:53
你贴代码,别人怎么帮你看,最好说现象,才好进行解决呀,

串口输出到电脑是随机数,不是随着可调电阻改变而改变的数值!可调电阻调到最小竟然输出65536,调到最大输出0!
zeluo 发表于 2013-6-20 07:41 | 显示全部楼层
不是很了解   这一块   帮你顶一个   再看看别人的意见吧  
sun1238898 发表于 2013-6-20 10:46 | 显示全部楼层
按你的意思,那的确是程序应该出的问题。你最好外部给出一个准确电压,然后再测试,还有参考一下别人的代码,进行更改,祝你好运。
 楼主| woshiaokeman 发表于 2013-6-20 18:58 | 显示全部楼层
sun1238898 发表于 2013-6-20 10:46
按你的意思,那的确是程序应该出的问题。你最好外部给出一个准确电压,然后再测试,还有参考一下别人的代码 ...

我有两个程序,另外一个是直接查询法,不用DMA,可以正常运行,但是现在这个使用DMA就是不能正常运行,和别人校对过很多次了,但是就是不能正常运行!
 楼主| woshiaokeman 发表于 2013-6-20 22:53 | 显示全部楼层
有没有那个朋友花点时间给我答疑 - -!
自己看了两天,等了两天都没人帮帮么……
sun1238898 发表于 2013-6-21 09:23 | 显示全部楼层
DMA,那你要确定一下你DMA的数据宽度,以及传输多个个数据,如果你采样的数据与DMA传输数据宽度不一样,也会报错的。
 楼主| woshiaokeman 发表于 2013-6-21 10:28 | 显示全部楼层
sun1238898 发表于 2013-6-21 09:23
DMA,那你要确定一下你DMA的数据宽度,以及传输多个个数据,如果你采样的数据与DMA传输数据宽度不一样,也 ...
  1. u16 rebuf[20];

  2. DMA_InitStructure.DMA_BufferSize = 20;

  3. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  4. DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord;


从这里看这个代码存放没有问题啊!
这些我都检查过了。
sun1238898 发表于 2013-6-21 11:35 | 显示全部楼层
你是多通道采样。还是单通道采样的。
 楼主| woshiaokeman 发表于 2013-6-21 16:10 | 显示全部楼层
sun1238898 发表于 2013-6-21 11:35
你是多通道采样。还是单通道采样的。
  1. ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式

  2. ADC_InitStructure.ADC_ScanConvMode = ENABLE; //模数转换工作在单通道模式

  3. ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //模数转换工作在连续转换模式

  4. ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动

  5. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐

  6. ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目

  7. ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器



官方例程里面也是这样配置 ADC单通道连续转换模式 DMA连续中断模式
 楼主| woshiaokeman 发表于 2013-6-22 11:10 来自手机 | 显示全部楼层
苦逼了,怎么看怎么测都实现不了。。。难道以后不能用这个功能了么。。。
zeluo 发表于 2013-6-22 18:32 | 显示全部楼层
不是很了解   楼主  帮你顶一个   看看别人的意见吧
596142041 发表于 2013-6-23 14:46 | 显示全部楼层
DMA_InitStructure.DMA_BufferSize = 20;
单通道为1,你试试,你有几个通道就设为几,
 楼主| woshiaokeman 发表于 2013-6-23 17:02 | 显示全部楼层
596142041 发表于 2013-6-23 14:46
DMA_InitStructure.DMA_BufferSize = 20;
单通道为1,你试试,你有几个通道就设为几,

这个是存放的长度吧!如果改为1的话和直接用ADC中断应该没什么区别吧!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

58

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部