STM32 TIM3_TRGO触发ADC TIM6触发DAC DMA

        最近正在学习STM32相关内容,了解了STM32的ADC,DAC,DMA,TIM等原理及配置后,DAC输出、ADC采集的例子。

ADC配置

ADC_GPIO配置

static void ADCx_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	ADC_GPIO_APBxClock_FUN (ADC_GPIO_CLK, ENABLE );// 打开 ADC IO端口时钟
	GPIO_InitStructure.GPIO_Pin = ADC_PIN;// 配置 ADC IO 引脚模式
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_Init(ADC_PORT, &GPIO_InitStructure);	// 初始化 ADC IO
}

ADC_TIM配置

static void ADx_TIM_Config(uint16_t arr, uint16_t psc){
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	RCC_APB1PeriphClockCmd(ADCx_TIM_CLK, ENABLE); //TIM3时钟使能
	
	//定时器TIM3初始化,简单进行定时器初始化,设置预装载值和分频系数
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
	
	TIM_SelectOutputTrigger(ADCx_TIM,TIM_TRGOSource_Update);//TIM做触发
	TIM_ITConfig(ADCx_TIM,TIM_IT_Update,ENABLE);
	TIM_Cmd(ADCx_TIM, ENABLE);  //使能TIMx	
}

ADC_TIM_NVIC配置 

static void ADCx_TIM_NVIC_Config(void){
	NVIC_InitTypeDef  NVIC_InitStructure;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
	NVIC_InitStructure.NVIC_IRQChannel = ADCx_TIM_IRQ;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
	NVIC_Init(&NVIC_InitStructure);
}

ADC配置

static void ADCx_Mode_Config(void)
{
	ADC_InitTypeDef ADC_InitStructure;		
	ADC_APBxClock_FUN ( ADC_CLK, ENABLE );// 打开ADC时钟	
	ADC_DeInit(ADCx);// ADC 模式配置	
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;// 只使用一个ADC,属于独立模式	
	ADC_InitStructure.ADC_ScanConvMode = DISABLE ; // 禁止扫描模式,多通道才要,单通道不需要	
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;// 连续转换模式	
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T3_TRGO;// 使用外部触发转换	
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;// 转换结果右对齐		
	ADC_InitStructure.ADC_NbrOfChannel = 1;	// 转换通道1个	
	ADC_Init(ADCx, &ADC_InitStructure);// 初始化ADC
	
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div8); // 配置ADC时钟为PCLK2的8分频,即9MHz	
	ADC_RegularChannelConfig(ADCx, ADC_CHANNEL, 1, 
	                         ADC_SampleTime_55Cycles5);// 配置 ADC 通道转换顺序和采样时间	
	ADC_ExternalTrigConvCmd(ADCx, ENABLE);	
	ADC_DMACmd(ADCx, ENABLE);// 使能ADC_DM请求	
	ADC_Cmd(ADCx, ENABLE);// 开启ADC,并开始转换

	
	ADC_ResetCalibration(ADCx);// 初始化ADC 校准寄存器  	
	while(ADC_GetResetCalibrationStatus(ADCx));// 等待校准寄存器初始化完成	
	ADC_StartCalibration(ADCx);// ADC开始校准
	while(ADC_GetCalibrationStatus(ADCx));// 等待校准完成
	
}

 ADC_DMA配置

static void ADCx_DMA_Config(void){
	DMA_InitTypeDef MDA_InitStruct;
	
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
	DMA_DeInit(DMA1_Channel1);
	MDA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)ADC1_BASIC_DR;    //外设地址-------相当于配置源地址
	MDA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue;              //存储器地址-----相当于配置目标地址
	MDA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;     //传输方向	设置数据传输方向,决定是从外设读取数据到内存还送从内存读取数据发送到外设,
																//也就是外设是源地还是目的地
	MDA_InitStruct.DMA_BufferSize = 1;        //传输数目
	
	MDA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;            //外设地址增量模式
	MDA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;    //外设数据宽度
	MDA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Disable;                    //存储器地址增量模式
	MDA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;            //存储器数据宽度
 
	MDA_InitStruct.DMA_Mode = DMA_Mode_Circular;        //模式选择
	MDA_InitStruct.DMA_Priority = DMA_Priority_High;    //通道优先级
	MDA_InitStruct.DMA_M2M = DMA_M2M_Disable;            //存储器到存储器模式
	
	DMA_Init(DMA1_Channel1,&MDA_InitStruct);
}

ADC初始化函数

void ADCx_Init(uint16_t arr, uint16_t psc)
{
	ADCx_GPIO_Config();
	ADCx_TIM_NVIC_Config();
	ADx_TIM_Config(arr,psc);
	ADCx_DMA_Config();
	ADCx_Mode_Config();
	DMA_Cmd(DMA1_Channel1,ENABLE);	
}

ADC配置完成后在ADC_TIM的中断函数中读取采集结果


void ADCx_TIM_IRQHandler(){
	if(TIM_GetITStatus(ADCx_TIM,TIM_IT_Update) != RESET){
		printf("%.2f\n",(float)ADC_GetConversionValue(ADCx)/4096*3.3);
	}
	TIM_ClearFlag(ADCx_TIM,TIM_IT_Update);
}

ADC配置完成后,配置DAC

static void DAC_Config(void){

  DAC_InitTypeDef  DAC_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  
  //开启DAC总线时钟
  DAC_APBxClock_FUN(DAC_CLK, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  //
  GPIO_InitStructure.GPIO_Pin = DAC_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(DAC_PORT, &GPIO_InitStructure);
	
  DAC_InitStructure.DAC_Trigger = DAC_TRIGGER_TIMx;
  DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
  DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;
  DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;
  DAC_Init(DAC_CHANNEL, &DAC_InitStructure);
  DAC_SetChannel1Data(DAC_Align_12b_R, 0);  //12位右对齐数据格式设置DAC值
  DAC_Cmd(DAC_CHANNEL, ENABLE);
}

DAC_TIM配置

static void DAC_TIMx_Config(uint16_t arr, uint16_t psc){
	TIM_TimeBaseInitTypeDef TIM_BASE_InitStructure;
	BASIC_TIM_APBxClock_FUN(BASIC_TIM_CLK,ENABLE);	
	TIM_BASE_InitStructure.TIM_Period = arr;//自动重装寄存器的值,累计TIM_Period+1后产生中断或更新事件	
	TIM_BASE_InitStructure.TIM_Prescaler = psc;//时钟预分频数
	TIM_TimeBaseInit(BASIC_TIM,&TIM_BASE_InitStructure);
	
	TIM_ClearFlag(BASIC_TIM,TIM_FLAG_Update);
	TIM_ITConfig(BASIC_TIM,TIM_IT_Update,ENABLE);
	TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update);/* 配置 TIM6 触发源 */
	
	TIM_Cmd(BASIC_TIM,ENABLE);
}

DAC_TIM_NVIC配置

static void NVIC_Configuration(void){
	NVIC_InitTypeDef  NVIC_InitStructure;
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
	
	NVIC_InitStructure.NVIC_IRQChannel = BASIC_TIM_IRQ;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
	NVIC_Init(&NVIC_InitStructure);
}

DAC初始化函数

void DAC_Mode_Init(uint16_t arr, uint16_t psc)
{
	NVIC_Configuration();
	DAC_TIMx_Config(arr,psc);
	DAC_Config();
}

DAC_TIM中断处理函数

void BASIC_TIM_IRQHandler(void){
	if(TIM_GetITStatus(BASIC_TIM,TIM_IT_Update) != RESET){
		adc_temp += 0.2;
		if(adc_temp >= 3.3)adc_temp = 0;
		DAC_SetChannel1Data(DAC_Align_12b_R,adc_temp*4096/3.3);//12位右对齐数据格式设置DAC值
		//printf("%d\n",DAC_GetDataOutputValue(DAC_Channel_1));
	}
	TIM_ClearFlag(BASIC_TIM,TIM_IT_Update);
}

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Accept_Less

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值