第二个是电脑圈圈,他对USB的理解令我钦佩。我能搞出驱动,他提供的源码包非常重要,有些代码也是直接在他的基础上
修改的。
2整体方案
先说下一次完整的采集,比如外面进来的波形是正弦波,波形电压有正负,STM32单片机的AD只能采集0~3.6V的电压,所以
要对信号进行处理。也就是需要一个模拟前端电路,把电压抬上去。接着就是采集了,STM32的AD可以用外设进行触发,这
里用定时器进行触发。每过一个单位时间AD开启一次,采集一个点,这样采集的频率只要调整这个单位时间也就是定时器就
可以控制了。采集了一桢数据,比如200个点。DMA中断被触发,开启USB,把数据发送到上位机,然后显示出来。
整个过程大体就是这样了,还有一个很重要的环节补充下。熟悉示波器的人都知道示波器有个触发概念。像刚才这样显示的
话,比如前一帧数据是波峰开始显示,后一帧是波谷开始。这样显示出来的波形就是乱的,于是为了解决这个问题,就需要做
触发,也就是保证每次采集的起始电位相同。我们的采用的是用外中断的形式,外面波形数据先不采集,先让它通过一个比较
器,比如比较器的基准电压是1V,也就是每次都和1V比较,低于1V输出低电平,高于1V输出高电平。当数据电压大于1V的
时候,比较器输出高电平,高电平接到单片机外中断口,这样外中断就被触发。然后开始采集,这样就能保证每帧数据的起始
点都相同。
这个方案是大体方案,后来做了下修改。就是让AD一直在采集。外中断触发了后开启的是DMA,AD一直开着,只是控制
DMA什么时候去取。从哪里开始取,取多少个点。下位机部分不再详说,贴下主要的程序,大侠们随便看看,多多指教。
定时器设置代码如下:
voidTIM2_Configuration(void)
{
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
TIM_OCInitTypeDefTIM_OCInitStructure;
TIM_DeInit(TIM2);//TIM2初始化
TIM_TimeBaseStructure.TIM_Period=18;//设置了下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler=0;//设置了用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision=0;//设置了时钟分割
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//选择了计数器模式向上计数
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);//根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx
//TIM_PrescalerConfig(TIM2,1,TIM_PSCReloadMode_Update);//设置TIMx重载次数预分频值在更新事件装入
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_Toggle;
TIM_OCInitStructure.TIM_Channel=TIM_Channel_2;
TIM_OCInitStructure.TIM_Pulse=9;
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;//TIM输出比较极性低
TIM_OCInit(TIM2,&TIM_OCInitStructure);
TIM_ARRPreloadConfig(TIM2,ENABLE);//使能或者失能TIMx在ARR上的自动装载寄存器
TIM_Cmd(TIM2,ENABLE);//使能TIMx外设
}
AD以及DMA设置代码:
voidADC_Configuration(void)
{
DMA_DeInit(DMA_Channel1);//复位DMA_Channel1
DMA_InitStructure.DMA_PeripheralBaseAddr=ADC1_DR_Address;//外围设备地址
DMA_InitStructure.DMA_MemoryBaseAddr=(u32)&ADC_Data[0];//memory地址
DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;//外围设备做为源