zoukankan      html  css  js  c++  java
  • STM32F103ZET6 之 ADC+TIM+DMA+USART 综合实验

    1、实验目的

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

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

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


    2、硬件资源

    1)指示灯

    2)ADC

    3)DMA

    4)TIM

    5)杜邦线


    3、软件设计

    1. void  Adc_Configuration(void)  
    2. {     
    3.   DMA_InitTypeDef DMA_InitStructure;  
    4.   ADC_InitTypeDef   ADC_InitStructure;    
    5.   GPIO_InitTypeDef GPIO_InitStructure;   
    6.   
    7.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC   | RCC_APB2Periph_AFIO, ENABLE);      
    8.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;  
    9.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;  
    10.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
    11.   GPIO_Init(GPIOC, &GPIO_InitStructure);  
    12.       
    1.   /* Enable DMA1 clock */  
    2.   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  
    3.       
    4.   DMA_DeInit(DMA1_Channel1);                                        /* 复位DMA1寄存器到缺省状态 */  
    5.   DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;                   /* 选择ADC1的数据寄存器作为源 */  
    6.   DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_Sample.Ch1Buf;                   /* 目标地址 */  
    7.   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                            /* 设置DMA传输方向,外设(ADC)作为源 */  
    8.   DMA_InitStructure.DMA_BufferSize = SAMPLE_COUNT;                              /* 设置缓冲区大小 */  
    9.   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;              /* 外设地址不自增 */  
    10.   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                       /* 存储器地址需要自增 */  
    11.   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;   /* 选择外设传输单位:16bit */  
    12.   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;           /* 选择内存传输单位:16bit */  
    13.   DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                                 /* 无需循环模式   */  
    14.   DMA_InitStructure.DMA_Priority = DMA_Priority_High;                           /* 选择DMA优先级 */  
    15.   DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                                  /* DMA传输类型,不是内存到内存 */  
    16.   DMA_Init(DMA1_Channel1, &DMA_InitStructure);  
    17.   
    18.   /* Enable DMA1 channel1 */  
    19.   DMA_Cmd(DMA1_Channel1, ENABLE);  
    20.       
    21.       
    22.  /* 配置ADC1  */  
    23.       
    24.   /* ADCCLK = PCLK2/2 */  
    25.   RCC_ADCCLKConfig(RCC_PCLK2_Div2);     /* ADCCLK = PCLK2/2 = 36MHz */  
    26.   
    27.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);  
    28.   
    29.   ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;  
    30.   ADC_InitStructure.ADC_ScanConvMode = DISABLE;  
    31.   ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;                       /* 连续转换静止 */  
    32.   ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC3;     /* 选择TIM1的CC3做触发 */  
    33.   ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                    /* 数据右对齐,高位为0 */  
    34.   ADC_InitStructure.ADC_NbrOfChannel = 1;                                   /* 1个通道 */  
    35.   ADC_Init(ADC1, &ADC_InitStructure);  
    36.   
    37.   /* ADC1 regular channels configuration */  
    38.   ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_1Cycles5);  
    39.   
    40.   /* Enable ADC1 external trigger conversion */  
    41.   ADC_ExternalTrigConvCmd(ADC1, ENABLE);  
    42.   
    43.   /* 使能 ADC1 */  
    44.   ADC_Cmd(ADC1, ENABLE);  
    45.   
    46.   /* Enable ADC1 DMA */  
    47.   ADC_DMACmd(ADC1, ENABLE);  
    48.   
    49.   /* 使能 ADC1 复位校准寄存器 */  
    50.   ADC_ResetCalibration(ADC1);  
    51.   /* 检测复位校准寄存器 */  
    52.   while(ADC_GetResetCalibrationStatus(ADC1));  
    53.   
    54.   /* 开始 ADC1 校准 */  
    55.   ADC_StartCalibration(ADC1);  
    56.   /* 等待校准结束 */  
    57.   while(ADC_GetCalibrationStatus(ADC1));  
    58.       
    59.           
    60.   /* 配置采样触发定时器,使用TIM1 CC1 */  
    61.   ADC_SampleRate(ADC_Sample.SampleFreq);    /* 修改采样频率 */  
    62. }                   
    63.   
    64. /* 
    65.  * Function Name  : ADC_SampleRate 
    66.  * Description    : 修改ADC的采样频率 
    67.  * Input          : - freq: 采样频率 单位Hz 
    68.  * Output         : None 
    69.  * Return         : None 
    70.  * Attention          : None 
    71.  */  
    72. void ADC_SampleRate(uint32_t freq)  
    73. {  
    74.   /* 配置定时器1第3通道CC3作为ADC1的触发源 */     
    75.   uint16_t Period;    
    76.   TIM_OCInitTypeDef  TIM_OCInitStructure;  
    77.   TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;  
    78.   
    79.   TIM_Cmd(TIM1, DISABLE);  
    80.   
    81.     /* 采样频率计算公式 : period = 72000000 / freq ; 1200 == 60KHz 采样频率 */  
    82.   Period = 72000000 / freq;       
    83.   
    84.   /* Enable TIM1 clock */  
    85.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);  
    86.   
    87.   TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);   
    88.   TIM_TimeBaseStructure.TIM_Period = Period;            
    89.   TIM_TimeBaseStructure.TIM_Prescaler = 0;        /* 计数频率 = 72000 000 / 18 = 4000 000    */  
    90.   TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;      
    91.   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;    
    92.   TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);  
    93.   
    94.   /* TIM1 channel1 configuration in PWM mode */  
    95.   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;   
    96.   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;                  
    97.   TIM_OCInitStructure.TIM_Pulse = TIM_TimeBaseStructure.TIM_Period / 2;   
    98.   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;           
    99.   TIM_OC3Init(TIM1, &TIM_OCInitStructure);  
    100.   
    101.   /* TIM1 counter enable */  
    102.   TIM_Cmd(TIM1, ENABLE);  
    103.   
    104.   /* TIM1 main Output Enable */  
    105.   TIM_CtrlPWMOutputs(TIM1, ENABLE);    
    106. }  


    采样率的确定:

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


    4、验证

    验证程序是自己通过 DAC 产生一个正弦波,频率为 10KHz,设置ADC的采样频率为900KHz,通过串口打印出来的数据,可以确定一个周期的点数在90个左右,符合要求。

  • 相关阅读:
    Web前端学习笔记之离线安装npm
    Java学习笔记之linux配置java环境变量(三种环境变量)
    Docker学习笔记之docker volume 容器卷的那些事(二)
    Docker学习笔记之docker volume 容器卷的那些事(一)
    Docker学习笔记之docker-save vs docker-export vs docker-commit
    Linux学习笔记之Linux运行脚本时 $' ' 错误
    K8S学习笔记之Flannel解读
    map_server地图服务器
    ros navigation stack 各个包的作用
    struct 与 class 的区别
  • 原文地址:https://www.cnblogs.com/zym0805/p/7149358.html
Copyright © 2011-2022 走看看