[mw_shl_code=c,true]*********************************************************************************************************[/mw_shl_code]
[mw_shl_code=c,true]* 函 数 名: InitDSO
* 功能说明: 对示波器通道1进行初始化配置。主要完成GPIO的配置、ADC的配置、DMA配置、TIM配置。
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void InitDSO(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
/* 初始化时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_ADC2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div2); //ADCCLK = PCLK2/2 = 36MHz
/*初始化 PC0 PC1的ADC输入引脚*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/*初始化DMA*/
DMA_DeInit(DMA1_Channel1); /* 复位DMA1寄存器到缺省状态 */
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; /* 选择ADC1的数据寄存器作为源 */ ////////////////////ADC1_DR_Address
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&g_DSO.buffer; /* 目标地址 */ ////////////////////g_DSO.buffer
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; /* 设置DMA传输方向,外设(ADC)作为源 */
DMA_InitStructure.DMA_BufferSize = SAMPLE_COUNT; /* 设置缓冲区大小 */
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; /* 外设地址不自增 */
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /* 存储器地址需要自增 */
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; /* 选择外设传输单位:32bit */
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; /* 选择内存传输单位:32bit */
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; /* 无需循环模式 */
DMA_InitStructure.DMA_Priority = DMA_Priority_High; /* 选择DMA优先级 */
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; /* DMA传输类型,不是内存到内存 */
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel1, ENABLE);
ADC_DeInit(ADC1);
ADC_DeInit(ADC2);
/* ADC1 配置 ------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_FastInterl;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC3;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_1Cycles5);
ADC_ExternalTrigConvCmd(ADC1, ENABLE);
/* ADC2 配置 ------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_FastInterl;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC2, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC2, ADC_Channel_10, 1, ADC_SampleTime_1Cycles5);
ADC_ExternalTrigConvCmd(ADC2, ENABLE);
/* 使能 ADC1 */
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
/* 使能 ADC2 */
ADC_Cmd(ADC2, ENABLE);
ADC_ResetCalibration(ADC2);
while(ADC_GetResetCalibrationStatus(ADC2));
ADC_StartCalibration(ADC2);
while(ADC_GetCalibrationStatus(ADC2));
/*初始化定时器1 作为ADC的触发源*/
TIM_Cmd(TIM1, DISABLE);
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); //初始化定时器1的寄存器为复位值
TIM_TimeBaseStructure.TIM_Period = 72000000 / g_DSO.SampleFreq; //ARR自动重装载寄存器周期的值(定时时间)到设置频率后产生个更新或者中断(也是说定时时间到)
TIM_TimeBaseStructure.TIM_Prescaler = 0; //PSC时钟预分频数 例如:时钟频率=TIM1CLK/(时钟预分频+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);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //CCMR2在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为有效电平,否则为无效电平
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //CCER 输出使能
TIM_OCInitStructure.TIM_Pulse = TIM_TimeBaseStructure.TIM_Period / 2;//CCR3同计数器TIMx_CNT的比较,并在OC3端口上产生输出信号
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //CCER输出极性设置 高电平有效
TIM_OC3Init(TIM1, &TIM_OCInitStructure);
//TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); //CMR2 设置预装载使能 更新事件产生时写入有效
//TIM_ARRPreloadConfig(TIM1, ENABLE); //CR1 设置ARR自动重装 更新事件产生时写入有效
TIM_Cmd(TIM1, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE); //使能PWM 输出
}[/mw_shl_code]
[mw_shl_code=c,true]*******************************************************************************************
* 函数名: SetSampRate
* 输 入: freq : 采样频率 单位Hz
* 输 出:
* 功 能:修改采样频率 配置定时器1 通道CC2, CC2作为ADC1的触发源
说 明:TIMxCLK = 72 MHz, 如果Prescaler =N(不分频) 那么TIMx counter clock = 72 MHz/(N+1)
计算公式:
PWM输出频率 = TIMx counter clock /(ARR + 1)
在TIM8和TIM1需要设置TIM_RepetitionCounter(TIM1_RCR)=0,每次向上溢出都产生更新事件
当外部触发信号被选为ADC规则或注入转换时,只有它的上升沿可以启动转换
*********************************************************************************************/
void SetSampRate(uint32_t freq)
{
TIM1->ARR=72000000 / freq; //设定计数器自动重装值
}[/mw_shl_code]
[mw_shl_code=c,true]/*******************************************************************************
* 函数名: StartADC
* 输 入: 无
* 输 出: 无
* 功 能:开启ADC采样 这里全部直接寄存器操作 加快速度
*******************************************************************************/
void StartADC(void)
{
DMA1_Channel1->CPAR=ADC1_DR_Address; //DMA1 外设地址
DMA1_Channel1->CMAR=(uint32_t)&g_DSO.buffer; //DMA1,存储器地址
DMA1_Channel1->CNDTR=SAMPLE_COUNT; //DMA1,传输数据量
DMA1_Channel1->CCR=0X00000000; //复位
DMA1_Channel1->CCR|=0<<4; //从外设来读
DMA1_Channel1->CCR|=0<<5; //普通模式
DMA1_Channel1->CCR|=0<<6; //外设地址非增量模式
DMA1_Channel1->CCR|=1<<7; //存储器增量模式
DMA1_Channel1->CCR|=2<<8; //外设数据宽度为32位
DMA1_Channel1->CCR|=2<<10; //存储器数据宽度32位
DMA1_Channel1->CCR|=2<<12; //高优先级
DMA1_Channel1->CCR|=0<<14; //非存储器到存储器模式
DMA1_Channel1->CCR|=1; //开启DMA传输
//TIM1->CR1|=1; //开启定时器1
}[/mw_shl_code]
[mw_shl_code=c,true]/*******************************************************************************
* 函数名: StopADC
* 输 入: 无
* 输 出: 无
* 功 能:暂停ADC采样
********************************************************************************/
void StopADC(void)
{
DMA1_Channel1->CCR&=0xffffffe; //关闭DMA传输
//TIM1->CR1&=0xffffffe; //关闭定时器1
}[/mw_shl_code]
|