完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
转dsp系列教程
本章节主要是对示波器的系统框架做一个简单的介绍,后面会推出示波器的详细设计分析。示波器的 源码注释已经很详细,对框架有个了解之后看源码即可。 45.1 ucos-iii任务分配 45.2 示波器核心任务 45.3 DAC实现方波的输出 45.4 ADC实现数据的采集 45.5 总结 45.1 uCOS-III任务分配 主要创建了如下6个用户任务: l AppTaskStart----启动任务 l AppTaskGUIUpdate---界面截图任务 l AppTaskCOM----留待以后升级使用 l AppTaskUserIF---留在以后升级使用 l AppTaskGUI------emWin任务 l AppTaskGUIRefresh---Led闪烁任务 下面主要对启动任务,界面截图任务,emWin任务,Led闪烁任务做一个介绍。 |
|
相关推荐
|
|
45.2.13 DSO_DrawBakFrame.c—绘制波形区的虚线方格
这个文件用于创建如下虚线方格(不包括波形显示): |
|
|
|
|
|
45.2.14 DSO_DrawCursorH.c—水平测量游标
这个文件用于创建如下水平测量游标: 45.2.15 DSO_DrawCursorV.c—垂直测量游标 这个文件用于创建如下垂直测量游标: |
|
|
|
|
|
45.2.16 DSO_AmplititudeWindow.c—幅值窗口
这个文件用于创建如下窗口: 45.2.17 DSO_ScaleWindow.c—时基窗口 这个文件用于创建如下窗口: |
|
|
|
|
|
45.2.18 DSO_StatusWindow.c—测量值窗口
这个文件用于创建如下窗口: 45.2.19 DSO_FirFilter_Step1KHz—Fir低通滤波 45.2.20 DSO_FirFilter_Step10KHz—Fir低通滤波 45.2.21 DSO_FirFilter_Step100KHz—Fir低通滤波 上面的三项主要用于Fir低通滤波器的实现。 |
|
|
|
|
|
45.3 DAC实现方波的输出
DAC输出方波的配置要注意初始化的顺序,顺序错误了,方波是无法输出的,还有就是不用的MDK优化等级,DAC配置时的顺序也不一样,这个应该是DAC库的一个bug。 复制代码 /* ********************************************************************************************************* * 函 数 名: bsp_InitDAC * 功能说明: DAC初始化 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ void bsp_InitDAC(void) { uint8_t i; /* 用缓存放一个周期的方波 */ for(i =0; i < 32; i++) { g_usWaveBuff[i] = 0; } for(i =0; i < 32; i++) { g_usWaveBuff[i+32] = 2048; } /* MDK优化等级为1的时候,DAC初始化顺序,不同的优化等级, 不同的输出顺序容易操作DAC无法输出波形。 这个问题要引起大家的特别注意!!。 */ DAC_Ch1_WaveConfig(); DAC_GPIOConfig(); TIM6_Config(); } |
|
|
|
|
|
45.4 ADC实现数据的采集
ADC的驱动主要注意两个问题,一个是ADC数据采集的关闭或者开启一定要保证同步,要不会出现采集数据的混乱, 还有就是由于没有使用官方的3ADC快速交替采样,官方的快速交替采用使用定时器触发采集出的数据效果不好,抖动 较大(特别是使用定时改变不同的采样频率时) 。现在采用的每个ADC都是用定时器单独的触发,并把触发数据分开,分 成三等分,每个时刻实现一个ADC的触发。 复制代码 /* ********************************************************************************************************* * 函 数 名: TIM1_Config * 功能说明: 配置定时器1,用于触发ADC1,ADC2和ADC3。 * 当外部触发信号被选为ADC规则或注入转换时,只有它的上升沿可以启动转换。 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ static void TIM1_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; /* 使能定时器1 */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); /* 先禁能再配置 */ TIM_Cmd(TIM1, DISABLE); /* ******************************************************************************** system_stm32f4xx.c 文件中 void SetSysClock(void) 函数对时钟的配置如下: HCLK = SYSCLK / 1 (AHB1Periph) PCLK2 = HCLK / 2 (APB2Periph) PCLK1 = HCLK / 4 (APB1Periph) 因为APB1 prescaler != 1, 所以 APB1上的TIMxCLK = PCLK1 x 2 = SystemCoreClock / 2; 因为APB2 prescaler != 1, 所以 APB2上的TIMxCLK = PCLK2 x 2 = SystemCoreClock; APB1 定时器有 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM7, TIM12, TIM13, TIM14 APB2 定时器有 TIM1, TIM8 ,TIM9, TIM10, TIM11 TIM1 更新周期是 = TIM1CLK / (TIM_Period + 1)/(TIM_Prescaler + 1) ******************************************************************************** */ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); //初始化定时器1的寄存器为复位值 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时间分割值 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //CR1->CMS[1:0]和DIR定时器模式 向上计数 TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /**************ADC1的触发***********************************************/ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //CCER 输出使能 TIM_OCInitStructure.TIM_Pulse = TIM_TimeBaseStructure.TIM_Period/3; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //CCER输出极性设置 TIM_OC1Init(TIM1, &TIM_OCInitStructure); /**************ADC2的触发***********************************************/ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = TIM_TimeBaseStructure.TIM_Period*2/3; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OC2Init(TIM1, &TIM_OCInitStructure); /**************ADC3的触发***********************************************/ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = TIM_TimeBaseStructure.TIM_Period-1; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OC3Init(TIM1, &TIM_OCInitStructure); //TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); //CMR2 设置预装载使能 更新事件产生时写入有效 //TIM_ARRPreloadConfig(TIM1, ENABLE); //CR1 设置ARR自动重装 更新事件产生时写入有效 TIM_Cmd(TIM1, ENABLE); /* 使能PWM输出 */ TIM_CtrlPWMOutputs(TIM1, ENABLE); } |
|
|
|
|
|
下面是DMA的开启和关闭,一定要保证按照如下的顺序进行,且这些函数不能省略一个,要不重新开启DMA数据将无法再次传输。
复制代码 /* ********************************************************************************************************* * 函 数 名: DMA_Open * 功能说明: 使能ADC1,ADC2,ADC3的DMA * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ void ADC_DMA_Open(void) { DMA_InitTypeDef DMA_InitStructure; /* DMA2 Stream1 channel1 配置用于ADC3 **************************************/ DMA_DeInit(DMA2_Stream1); DMA_InitStructure.DMA_Channel = DMA_Channel_2; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC3_DR_ADDRESS; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC3ConvertedValue; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = 1024*10; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream1, &DMA_InitStructure); DMA_Cmd(DMA2_Stream1, ENABLE); /* DMA2 Stream2 channel1 配置用于ADC2 **************************************/ DMA_DeInit(DMA2_Stream2); /* 在DMA的DMA_Mode_Normal模式,一定要使用这个函数,循环模式可以不用 */ DMA_InitStructure.DMA_Channel = DMA_Channel_1; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC2_DR_ADDRESS; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC2ConvertedValue; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = 1024*10; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream2, &DMA_InitStructure); DMA_Cmd(DMA2_Stream2, ENABLE); /* DMA2 Stream0 channel0 配置用于ADC1 **************************************/ DMA_DeInit(DMA2_Stream0); DMA_InitStructure.DMA_Channel = DMA_Channel_0; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC1ConvertedValue; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = 1024*10; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream0, &DMA_InitStructure); DMA_Cmd(DMA2_Stream0, ENABLE); ADC_RegularChannelConfig(ADC3, ADC_Channel_10, 1, ADC_SampleTime_3Cycles); /* 使能 ADC3 --------------------------------------------------------------*/ ADC_Cmd(ADC3, ENABLE); ADC_RegularChannelConfig(ADC2, ADC_Channel_10, 1, ADC_SampleTime_3Cycles); /* 使能 ADC2 --------------------------------------------------------------*/ ADC_Cmd(ADC2, ENABLE); ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_3Cycles); /* 使能 ADC1 --------------------------------------------------------------*/ ADC_Cmd(ADC1, ENABLE); /**定时器配置,一定要重新的初始化从而保证同时触发 **/ TIM1_Config(); /* 只有在普通触发模式在启动TIM8的计时功能 */ if(TriggerFlag != 0) { Time8Recorder(); } } /* ********************************************************************************************************* * 函 数 名: DMA_Close * 功能说明: 关闭ADC1,ADC2,ADC3及其DMA * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ void ADC_DMA_Close() { TIM_Cmd(TIM1, DISABLE); DMA_Cmd(DMA2_Stream1, DISABLE); DMA_Cmd(DMA2_Stream0, DISABLE); DMA_Cmd(DMA2_Stream2, DISABLE); /* 禁止 ADC1 ---------------------------------------------------------------------*/ ADC_Cmd(ADC1, DISABLE); /* 禁止 ADC2 ---------------------------------------------------------------------*/ ADC_Cmd(ADC2, DISABLE); /* 禁止 ADC3 ---------------------------------------------------------------------*/ ADC_Cmd(ADC3, DISABLE); } |
|
|
|
|
|
45.5总结
示波器的框架设计就跟大家讲解这么多,后续后推出示波器的详细设计教程。有兴趣的可以直接看源码即可,源码注释已经比较详细。 |
|
|
|
|
|
使用Keil建立完整的工程,并使用外部中断0触发数码管显示903
418 浏览 0 评论
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-使用AHT20进行环境监测之AHT20传感器介绍
1083 浏览 0 评论
846 浏览 0 评论
886 浏览 1 评论
基于瑞萨FPB-RA4E2智能床头灯项目——1编译环境搭建与点亮驱动ws2812全彩LED
882 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11834 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-1 01:49 , Processed in 0.643722 second(s), Total 78, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号