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

【安富莱——DSP教程】第45章 示波器设计—系统框架

[复制链接]
baiyongbin2009 发布时间:2015-5-5 11:45
阅读主题, 点击返回1楼
收藏 评论12 发布时间:2015-5-5 11:45
12个回答
baiyongbin2009 回答时间:2015-5-6 11:32:42
45.3 DAC实现方波的输出
    DAC输出方波的配置要注意初始化的顺序,顺序错误了,方波是无法输出的,还有就是不用的MDK优化等级,DAC配置时的顺序也不一样,这个应该是DAC库的一个bug。
  1. /*
  2. *********************************************************************************************************
  3. *        函 数 名: bsp_InitDAC
  4. *        功能说明: DAC初始化
  5. *        形    参: 无
  6. *        返 回 值: 无
  7. *********************************************************************************************************
  8. */
  9. void bsp_InitDAC(void)
  10. {   
  11.     uint8_t i;

  12. /* 用缓存放一个周期的方波 */
  13. for(i =0; i < 32; i++)
  14. {
  15. g_usWaveBuff[i] = 0;
  16. }
  17. for(i =0; i < 32; i++)
  18. {
  19. g_usWaveBuff[i+32] = 2048;
  20. }
  21. /* MDK优化等级为1的时候,DAC初始化顺序,不同的优化等级,
  22.    不同的输出顺序容易操作DAC无法输出波形。
  23.    这个问题要引起大家的特别注意!!。
  24. */
  25. DAC_Ch1_WaveConfig();
  26. DAC_GPIOConfig();
  27.     TIM6_Config();
  28. }
复制代码

baiyongbin2009 回答时间:2015-5-6 11:35:12
45.4  ADC实现数据的采集
    ADC的驱动主要注意两个问题,一个是ADC数据采集的关闭或者开启一定要保证同步,要不会出现采集数据的混乱,还有就是由于没有使用官方的3ADC快速交替采样,官方的快速交替采用使用定时器触发采集出的数据效果不好,抖动较大(特别是使用定时改变不同的采样频率时) 。现在采用的每个ADC都是用定时器单独的触发,并把触发数据分开,分成三等分,每个时刻实现一个ADC的触发。
  1. /*
  2. *********************************************************************************************************
  3. *        函 数 名: TIM1_Config
  4. *        功能说明: 配置定时器1,用于触发ADC1,ADC2和ADC3。
  5. *             当外部触发信号被选为ADC规则或注入转换时,只有它的上升沿可以启动转换。
  6. *        形    参: 无
  7. *        返 回 值: 无
  8. *********************************************************************************************************
  9. */
  10. static void TIM1_Config(void)
  11. {
  12.     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  13.     TIM_OCInitTypeDef  TIM_OCInitStructure;
  14.    
  15. /* 使能定时器1 */
  16.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
  17.    
  18. /* 先禁能再配置 */
  19.     TIM_Cmd(TIM1, DISABLE);
  20.     /*
  21.      ********************************************************************************
  22.     system_stm32f4xx.c 文件中 void SetSysClock(void) 函数对时钟的配置如下:

  23.     HCLK = SYSCLK / 1     (AHB1Periph)
  24.     PCLK2 = HCLK / 2      (APB2Periph)
  25.     PCLK1 = HCLK / 4      (APB1Periph)

  26.     因为APB1 prescaler != 1, 所以 APB1上的TIMxCLK = PCLK1 x 2 = SystemCoreClock / 2;
  27.     因为APB2 prescaler != 1, 所以 APB2上的TIMxCLK = PCLK2 x 2 = SystemCoreClock;

  28.     APB1 定时器有 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM7, TIM12, TIM13, TIM14
  29.     APB2 定时器有 TIM1, TIM8 ,TIM9, TIM10, TIM11
  30.          
  31.     TIM1 更新周期是 = TIM1CLK / (TIM_Period + 1)/(TIM_Prescaler + 1)
  32.     ********************************************************************************
  33.     */
  34.     TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);            //初始化定时器1的寄存器为复位值
  35.     TIM_TimeBaseStructure.TIM_Period =  168000000/g_SampleFreqTable[TimeBaseId][0] - 1;    TIM_TimeBaseStructure.TIM_Prescaler = g_SampleFreqTable[TimeBaseId][1]-1;    TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;                        //CR1->CKD时间分割值
  36.     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;     //CR1->CMS[1:0]和DIR定时器模式 向上计数
  37.     TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

  38.     /**************ADC1的触发***********************************************/
  39.     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;                TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;      //CCER 输出使能         
  40.     TIM_OCInitStructure.TIM_Pulse = TIM_TimeBaseStructure.TIM_Period/3;    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;               //CCER输出极性设置
  41.     TIM_OC1Init(TIM1, &TIM_OCInitStructure);
  42. /**************ADC2的触发***********************************************/
  43. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;           
  44.     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;     
  45.     TIM_OCInitStructure.TIM_Pulse = TIM_TimeBaseStructure.TIM_Period*2/3;
  46.     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;              
  47.     TIM_OC2Init(TIM1, &TIM_OCInitStructure);
  48. /**************ADC3的触发***********************************************/
  49. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;           
  50.     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;     
  51.     TIM_OCInitStructure.TIM_Pulse = TIM_TimeBaseStructure.TIM_Period-1;
  52.     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;              
  53.     TIM_OC3Init(TIM1, &TIM_OCInitStructure);
  54.     //TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);         //CMR2 设置预装载使能  更新事件产生时写入有效
  55.     //TIM_ARRPreloadConfig(TIM1, ENABLE);                              //CR1  设置ARR自动重装 更新事件产生时写入有效
  56.     TIM_Cmd(TIM1, ENABLE);
  57.     /* 使能PWM输出 */
  58.     TIM_CtrlPWMOutputs(TIM1, ENABLE);  
  59. }
复制代码
下面是DMA的开启和关闭,一定要保证按照如下的顺序进行,且这些函数不能省略一个,要不重新开启DMA数据将无法再次传输。
  1. /*
  2. *********************************************************************************************************
  3. *        函 数 名: DMA_Open
  4. *        功能说明: 使能ADC1,ADC2,ADC3的DMA
  5. *        形    参: 无
  6. *        返 回 值: 无
  7. *********************************************************************************************************
  8. */
  9. void ADC_DMA_Open(void)
  10. {
  11.     DMA_InitTypeDef       DMA_InitStructure;

  12. /* DMA2 Stream1 channel1 配置用于ADC3 **************************************/
  13.     DMA_DeInit(DMA2_Stream1);
  14. DMA_InitStructure.DMA_Channel = DMA_Channel_2;  
  15. DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC3_DR_ADDRESS;
  16. DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC3ConvertedValue;
  17. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  18. DMA_InitStructure.DMA_BufferSize = 1024*10;
  19. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  20. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  21. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  22. DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord;
  23. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  24. DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  25. DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  26. DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
  27. DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  28. DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  29. DMA_Init(DMA2_Stream1, &DMA_InitStructure);
  30.     DMA_Cmd(DMA2_Stream1, ENABLE);
  31. /* DMA2 Stream2 channel1 配置用于ADC2 **************************************/
  32.     DMA_DeInit(DMA2_Stream2);  /* 在DMA的DMA_Mode_Normal模式,一定要使用这个函数,循环模式可以不用 */
  33. DMA_InitStructure.DMA_Channel = DMA_Channel_1;  
  34. DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC2_DR_ADDRESS;
  35. DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC2ConvertedValue;
  36. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  37. DMA_InitStructure.DMA_BufferSize = 1024*10;
  38. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  39. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  40. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  41. DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord;
  42. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  43. DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  44. DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  45. DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
  46. DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  47. DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  48. DMA_Init(DMA2_Stream2, &DMA_InitStructure);
  49.     DMA_Cmd(DMA2_Stream2, ENABLE);
  50. /* DMA2 Stream0 channel0 配置用于ADC1 **************************************/
  51.     DMA_DeInit(DMA2_Stream0);
  52. DMA_InitStructure.DMA_Channel = DMA_Channel_0;  
  53. DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS;
  54. DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC1ConvertedValue;
  55. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  56. DMA_InitStructure.DMA_BufferSize = 1024*10;
  57. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  58. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  59. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  60. DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord;
  61. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  62. DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  63. DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  64. DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
  65. DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  66. DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  67. DMA_Init(DMA2_Stream0, &DMA_InitStructure);
  68.     DMA_Cmd(DMA2_Stream0, ENABLE);

  69. ADC_RegularChannelConfig(ADC3, ADC_Channel_10, 1, ADC_SampleTime_3Cycles);

  70. /* 使能 ADC3 --------------------------------------------------------------*/
  71. ADC_Cmd(ADC3, ENABLE);
  72. ADC_RegularChannelConfig(ADC2, ADC_Channel_10, 1, ADC_SampleTime_3Cycles);

  73. /* 使能 ADC2 --------------------------------------------------------------*/
  74. ADC_Cmd(ADC2, ENABLE);
  75. ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_3Cycles);

  76. /* 使能 ADC1 --------------------------------------------------------------*/
  77. ADC_Cmd(ADC1, ENABLE);

  78. /**定时器配置,一定要重新的初始化从而保证同时触发 **/
  79. TIM1_Config();

  80. /* 只有在普通触发模式在启动TIM8的计时功能 */
  81. if(TriggerFlag != 0)
  82. {
  83. Time8Recorder();
  84. }
  85. }

  86. /*
  87. *********************************************************************************************************
  88. *        函 数 名: DMA_Close
  89. *        功能说明: 关闭ADC1,ADC2,ADC3及其DMA
  90. *        形    参: 无
  91. *        返 回 值: 无
  92. *********************************************************************************************************
  93. */
  94. void ADC_DMA_Close()
  95. {
  96. TIM_Cmd(TIM1, DISABLE);
  97. DMA_Cmd(DMA2_Stream1, DISABLE);
  98. DMA_Cmd(DMA2_Stream0, DISABLE);
  99. DMA_Cmd(DMA2_Stream2, DISABLE);
  100. /* 禁止 ADC1 ---------------------------------------------------------------------*/
  101. ADC_Cmd(ADC1, DISABLE);

  102. /* 禁止 ADC2 ---------------------------------------------------------------------*/
  103. ADC_Cmd(ADC2, DISABLE);
  104. /* 禁止 ADC3 ---------------------------------------------------------------------*/
  105. ADC_Cmd(ADC3, DISABLE);
  106. }
复制代码

baiyongbin2009 回答时间:2015-5-6 11:35:32
45.5总结
示波器的框架设计就跟大家讲解这么多,后续后推出示波器的详细设计教程。有兴趣的可以直接看源码即可,源码注释已经比较详细。
12

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

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