您的位置:首页 > 其它

STM32F103ZET6 之 ADC+TIM+DMA+USART 综合实验

2015-12-23 21:54 405 查看
1、实验目的

1)使用 TIM1 触发 ADC,ADC 采集的数据通过DMA 传至内存,然后通过串口打印出采集的数据;

2)学会 DMA 传输数据并将数据进行保存;

3)验证ADC 的采样率与实际设置的是否相符。

2、硬件资源

1)指示灯

2)ADC

3)DMA

4)TIM

5)杜邦线

3、软件设计

void  Adc_Configuration(void)
{
DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef	ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC	| RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Enable DMA1 clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

DMA_DeInit(DMA1_Channel1);		                                /* 复位DMA1寄存器到缺省状态 */
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;	                /* 选择ADC1的数据寄存器作为源 */
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_Sample.Ch1Buf;	                 /* 目标地址 */
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_HalfWord;	/* 选择外设传输单位:16bit */
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;	        /* 选择内存传输单位:16bit */
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);

/* Enable DMA1 channel1 */
DMA_Cmd(DMA1_Channel1, ENABLE);

/* 配置ADC1  */

/* ADCCLK = PCLK2/2 */
RCC_ADCCLKConfig(RCC_PCLK2_Div2);     /* ADCCLK = PCLK2/2 = 36MHz */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;		                /* 连续转换静止 */
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC3;	    /* 选择TIM1的CC3做触发 */
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	                /* 数据右对齐,高位为0 */
ADC_InitStructure.ADC_NbrOfChannel = 1;	                                /* 1个通道 */
ADC_Init(ADC1, &ADC_InitStructure);

/* ADC1 regular channels configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_1Cycles5);

/* Enable ADC1 external trigger conversion */
ADC_ExternalTrigConvCmd(ADC1, ENABLE);

/* 使能 ADC1 */
ADC_Cmd(ADC1, ENABLE);

/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);

/* 使能 ADC1 复位校准寄存器 */
ADC_ResetCalibration(ADC1);
/* 检测复位校准寄存器 */
while(ADC_GetResetCalibrationStatus(ADC1));

/* 开始 ADC1 校准 */
ADC_StartCalibration(ADC1);
/* 等待校准结束 */
while(ADC_GetCalibrationStatus(ADC1));

/* 配置采样触发定时器,使用TIM1 CC1 */
ADC_SampleRate(ADC_Sample.SampleFreq);	/* 修改采样频率 */
}

/*
* Function Name  : ADC_SampleRate
* Description    : 修改ADC的采样频率
* Input          : - freq: 采样频率 单位Hz
* Output         : None
* Return         : None
* Attention		  : None
*/
void ADC_SampleRate(uint32_t freq)
{
/* 配置定时器1第3通道CC3作为ADC1的触发源 */
uint16_t Period;
TIM_OCInitTypeDef  TIM_OCInitStructure;
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

TIM_Cmd(TIM1, DISABLE);

/* 采样频率计算公式 : period = 72000000 / freq ; 1200 == 60KHz 采样频率 */
Period = 72000000 / freq;

/* Enable TIM1 clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = Period;
TIM_TimeBaseStructure.TIM_Prescaler = 0;        /* 计数频率 = 72000 000 / 18 = 4000 000	 */
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

/* TIM1 channel1 configuration in PWM mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = TIM_TimeBaseStructure.TIM_Period / 2;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC3Init(TIM1, &TIM_OCInitStructure);

/* TIM1 counter enable */
TIM_Cmd(TIM1, ENABLE);

/* TIM1 main Output Enable */
TIM_CtrlPWMOutputs(TIM1, ENABLE);
}


采样率的确定:
由两部分组成:ADC 转换时间 + 定时器的触发需要的时间

4、验证

验证程序是自己通过 DAC 产生一个正弦波,频率为 10KHz,设置ADC的采样频率为900KHz,通过串口打印出来的数据,可以确定一个周期的点数在90个左右,符合要求。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: