• 16-STM32 ADC外部触发


    STM32 ADC外部触发

      1 #include "adc.h"
      2 
      3 //用来保存ADC各通道转换完成后的数据
      4 vu16 ADC_ConvertedValue[4];
      5 
      6 
      7 
      8 //利用定时器TIM4的通道4的输出比较功能,给ADC1提供采样触发信号,这里触发周期为:100ms
      9 //触发周期计算公式为:psc/72*period/1000000(单位为秒)
     10 
     11 void TIM_OCTigrConfig(void)
     12 {
     13     TIM_TimeBaseInitTypeDef TIM_timeBaseStucture;
     14     TIM_OCInitTypeDef TIM_ocInitStructure;
     15     
     16     u16 period     = 60000;                                            //设置周期值
     17     u16 pluse     = 30000;                                            //设置CRR值,这里的值可以随便设置,不影响ADC采样周期,但要保证在正确的范围内
     18     
     19     //使能TIM4的时钟,TIM4是挂在APB1总线上的,注意TIM4的时钟是72M的
     20     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
     21     
     22     TIM_timeBaseStucture.TIM_Prescaler = 120-1;                        //预分频,给TIMx_CNT驱动的时钟
     23     TIM_timeBaseStucture.TIM_ClockDivision = TIM_CKD_DIV1;          //分频因子,输出给定时器的ETRP数字滤波器提供时钟
     24     TIM_timeBaseStucture.TIM_CounterMode = TIM_CounterMode_Up;        //向上计数
     25     TIM_timeBaseStucture.TIM_Period = period;                        //设置周期,给ARR赋值
     26     TIM_TimeBaseInit(TIM4,&TIM_timeBaseStucture);
     27     
     28     //配置TIM4通道4的输出比较
     29     TIM_ocInitStructure.TIM_OCMode = TIM_OCMode_PWM1;                //PWM输出模式为PWM1
     30     TIM_ocInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;        //设置有效电平的极性
     31     TIM_ocInitStructure.TIM_OutputState = TIM_OutputState_Enable;    //使能通道输出
     32     TIM_ocInitStructure.TIM_Pulse = pluse;                            //设置PWM的脉冲宽度值,即CRR值
     33     TIM_OC4Init(TIM4,&TIM_ocInitStructure);
     34     
     35     TIM_ARRPreloadConfig(TIM4,ENABLE);                                //使能TIM4的寄存器ARR的预装载功能,DISABLE时将会使改变ARR值时立即生效
     36     TIM_OC4PreloadConfig(TIM4,TIM_OCPreload_Enable);                //使能TIM4通道1的CCR的预装载功能,DISABLE时将会使改变CRR值时立即生效
     37     
     38     //使能TIM4定时器
     39     TIM_Cmd(TIM4,ENABLE);
     40 }
     41 
     42 
     43  
     44 
     45 
     46 //利用TIM4通道4的输出比较触发ADC1开始采样,并且ADC各通道的数据转换完成后,触发DMA
     47 //请求,将ADC_DR中的数据存入内存数组中,DMA传输完成后,触发DMA传输完成中断
     48 
     49 //PB0--ADC_Pitch
     50 //PB1--ADC_Roll
     51 //PA1--ADC_THR
     52 //PA2--ADC_Yaw
     53 void ADC_DmaConfig(void)
     54 {
     55     GPIO_InitTypeDef GPIO_initStructure;
     56     DMA_InitTypeDef DMA_initStructure;
     57     ADC_InitTypeDef ADC_initStructure;
     58     NVIC_InitTypeDef NVIC_InitStructure;
     59     
     60     //开启DMA1时钟
     61     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
     62     
     63     //配置DMA1通道1,将ADC采样转换得到的数据传输到内存数组中(协助CPU)
     64     DMA_initStructure.DMA_BufferSize = 4;                                        //每次传输的数据的个数,传输完时触发中断
     65     DMA_initStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                            //传输方向为:外设->内存
     66     DMA_initStructure.DMA_M2M = DMA_M2M_Disable;                                //失能内存到内存的传输方式
     67     DMA_initStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue;                //数据保存到内存中数组的首地址(这里因为ADC_ConvertedValue是数组名,所以不用加&)
     68     DMA_initStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;            //以16位为单位进行数据的传输
     69     DMA_initStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                        //内存地址自增(这里地址是每次增加1,因为是以半字(16位)作为单位传输的)
     70     DMA_initStructure.DMA_Mode = DMA_Mode_Circular;                                //循环传输的方式,这里必须为循环传输方式,否则会导致DMA只能传输一次
     71     DMA_initStructure.DMA_PeripheralBaseAddr = ((u32)&ADC1->DR);                //&ADC1->DR
     72     DMA_initStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;    //以半字为单位进行数据的传输
     73     DMA_initStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;            //外设地址固定
     74     DMA_initStructure.DMA_Priority = DMA_Priority_Medium;                        //DMA通道1的优先级设置为中级,(这个优先级是当同一个DMA的不同通道同时有传输数据的要求时,优先级高的先进行传输)
     75     DMA_Init(DMA1_Channel1,&DMA_initStructure);
     76     
     77     DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE);                                //打开DMA通道1数据传输完成中断
     78     NVIC_EnableIRQ(DMA1_Channel1_IRQn);                                            //打开NVIC中对应的DMA通道1的中断通道
     79     
     80     NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
     81     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
     82     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
     83     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
     84     NVIC_Init(&NVIC_InitStructure);
     85     
     86     //开启DMA1的通道1
     87     DMA_Cmd(DMA1_Channel1,ENABLE);
     88     
     89     
     90     //使能ADC时钟
     91     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_ADC1,ENABLE);
     92     
     93     GPIO_initStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2;    //ADC1的通道1,2
     94     GPIO_initStructure.GPIO_Mode = GPIO_Mode_AIN;                    //ADC输入管脚需要为模拟输入模式
     95     GPIO_Init(GPIOA,&GPIO_initStructure);
     96     
     97     GPIO_initStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;    //ADC1的通道8,9
     98     GPIO_initStructure.GPIO_Mode = GPIO_Mode_AIN;                    //ADC输入管脚需要为模拟输入模式
     99     GPIO_Init(GPIOB,&GPIO_initStructure);
    100     
    101     //配置ADC1
    102     ADC_initStructure.ADC_ContinuousConvMode = DISABLE;                            //单次采样模式,每次由TIM4的CCR触发采样开始
    103     ADC_initStructure.ADC_DataAlign = ADC_DataAlign_Right;                        //数据对齐模式为:右对齐
    104     ADC_initStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T4_CC4;        //TIM4的通道4的CCR触发采样
    105     ADC_initStructure.ADC_Mode = ADC_Mode_Independent;                            //各通道独立
    106     ADC_initStructure.ADC_NbrOfChannel = 4;                                        //一共要采样的通道的数目
    107     ADC_initStructure.ADC_ScanConvMode = ENABLE;                                //打开扫描模式,由于这里有四个通道要采集,所以开始用扫描模式
    108     ADC_Init(ADC1,&ADC_initStructure);
    109     
    110     //开启ADC
    111     ADC_Cmd(ADC1,ENABLE);
    112     
    113     //开启ADC——DMA数据传输通道
    114     ADC_DMACmd(ADC1,ENABLE);
    115     
    116     //配置ADC采样参考时钟的预分频值
    117     RCC_ADCCLKConfig(RCC_PCLK2_Div8);                                            
    118     
    119     //配置ADC的规则通道的采样顺序和采样时间
    120     ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_71Cycles5);    
    121     ADC_RegularChannelConfig(ADC1,ADC_Channel_2,2,ADC_SampleTime_71Cycles5);
    122     ADC_RegularChannelConfig(ADC1,ADC_Channel_8,3,ADC_SampleTime_71Cycles5);
    123     ADC_RegularChannelConfig(ADC1,ADC_Channel_9,4,ADC_SampleTime_71Cycles5);
    124     
    125     ADC_ResetCalibration(ADC1);                                                    //重置ADC采样校准器,防止出现较大的误差
    126     while(ADC_GetCalibrationStatus(ADC1));                                        //等待校准成功
    127     ADC_StartCalibration(ADC1);                                                    //开启ADC采样状态
    128     while(ADC_GetCalibrationStatus(ADC1));                                        //等到开启成功
    129     
    130     //使能外部触发ADC采样
    131     ADC_ExternalTrigConvCmd(ADC1,ENABLE);
    132 }
    133 
    134 
    135 //DMA1通道1中断通道处理函数,触发此中断时,说明已经将数据从ADC转移到内存数组中,可以触发数据发送了
    136 void DMA1_Channel1_IRQHandler(void){
    137     if(DMA_GetITStatus(DMA1_IT_TC1)==SET){
    138         
    139         //printf("%d    %d    %d    %d
    ",ADC_ConvertedValue[0],ADC_ConvertedValue[1],ADC_ConvertedValue[2],ADC_ConvertedValue[3]);
    140         DMA_ClearITPendingBit(DMA1_IT_TC1);                        //清除DMA1通道1传输完成中断
    141     }
    142 }
  • 相关阅读:
    C语言I博客作业07
    C语言I 博客作业03
    我的第一次作业
    C语言I博客作业05
    js闭包在你身边却不知
    浅谈SQL Transaction在请求中断后的行锁表锁
    事件订阅分发模型
    js 继承 对象方法与原型方法
    PHP学习笔记有关php中的变量
    PHP学习笔记不同编码占据不同的字节
  • 原文地址:https://www.cnblogs.com/darren-pty/p/14094370.html
Copyright © 2020-2023  润新知