为了熟悉定时器定时器和ADC

用STM32F407DIS做了一个简单的工程:

通过高级定时器TIM1溢出更新时间作为触发输出信号(TRGO),触发TIM8开始计数;

同时TIM1的通道1、2、3以及分别的互补通道输出6路PWM波用于控制三相电机;

TIM1的通道4用于触发ADC1的注入通道;

TIM8的通道1用于触发三个ADC的的规则通道;

TIM8的通道2用于触发ADC2的注入通道;

最后采样结果通过DMA传输到数组内保存起来;

为此,绘制了程序框图:

由框图来看工程更加清晰,更便于理解;

接下来配置工程,实现该任务:

首先配置定时器:

1     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
2 TIM_OCInitTypeDef TIM_OCInitStructure;3 TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
4 GPIO_InitTypeDef GPIO_InitStructure;

开启时钟以及基础设置

 1     // TIM1 clock enable
2 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
3 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOE, ENABLE);
4
5 // Time Base configuration
6 TIM_TimeBaseStructure.TIM_Prescaler = 0; //时钟频率除数的预分频值
7 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
8 TIM_TimeBaseStructure.TIM_Period = 4200; //ARR
9 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //时钟分割
10 TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
11 TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

通道设置

 1     // Channel 1, 2 and 3 Configuration in PWM mode
2 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
3 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
4 TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
5 TIM_OCInitStructure.TIM_Pulse = TIM1->ARR / 2; //待装入捕获比较寄存器的值 5000
6 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出比较极性 高
7 TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; //互补输出极性 高
8 TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; //空闲状态期间输出比较引脚状态
9 TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;
10
11 TIM_OC1Init(TIM1, &TIM_OCInitStructure);
12 TIM_OC2Init(TIM1, &TIM_OCInitStructure);
13 TIM_OC3Init(TIM1, &TIM_OCInitStructure);
14 TIM_OC4Init(TIM1, &TIM_OCInitStructure);
15
16 TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
17 TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
18 TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
19 TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);

死区设置

1     TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
2 TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
3 TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
4 TIM_BDTRInitStructure.TIM_DeadTime = 60; // 60个周期时间
5 TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
6 TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
7 TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;
8
9 TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);

输出六路PWM波通道映射

 1    /* GPIOA Configuration: TIM1 CH1 (PA8) 、 TIM1 CH1N (PA7) 、TIM1 CH3 (PA10) */
2 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_7 | GPIO_Pin_10 ;
3 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
4 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
5 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
6 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
7 GPIO_Init(GPIOA, &GPIO_InitStructure);
8
9 /* GPIOB Configuration: TIM1 CH2N (PB14) and TIM1 CH3N (PB15) */
10 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_15;
11 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
12 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
13 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
14 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
15 GPIO_Init(GPIOB, &GPIO_InitStructure);
16
17 /* GPIOB Configuration: TIM1 CH2 (PE11) and TIM1 CH3 (PE13) */
18 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_11 | GPIO_Pin_14;
19 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
20 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
21 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
22 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
23 GPIO_Init(GPIOE, &GPIO_InitStructure);
24
25 /* Connect TIM1 pins to AF */
26 GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_TIM1);
27 GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_TIM1);
28 GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_TIM1);
29 GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_TIM1);
30 GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_TIM1);
31 GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_TIM1);
32 GPIO_PinAFConfig(GPIOE, GPIO_PinSource14, GPIO_AF_TIM1);

选择主从模式,TIM1为主选择更新时间作为触发输出

1 TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update);             //选择更新事件作为触发输出(TRGO)
2 TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);

对相关配置进行使能

 1     TIM_CCPreloadControl(TIM1, ENABLE);
2 TIM_ARRPreloadConfig(TIM1, ENABLE);
3
4 TIM_ClearFlag(TIM1,TIM_FLAG_Update);
5
6 TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
7 TIM_ITConfig(TIM1, TIM_IT_CC4, ENABLE);
8
9 TIM_CCxCmd(TIM1, TIM_Channel_4, TIM_CCx_Enable);
10
11 TIM_Cmd(TIM1, ENABLE);
12
13 // Main Output Enable
14 TIM_CtrlPWMOutputs(TIM1, ENABLE); //设置TIM1 的PWM输出使能

定时器8同样的配置过程

 1     RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);
2 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
3
4 TIM_TimeBaseStructure.TIM_Prescaler = 0;
5 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
6 TIM_TimeBaseStructure.TIM_Period = 0xFFFF; //65535
7 TIM_TimeBaseStructure.TIM_ClockDivision = 0;
8 TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
9 TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
10
11 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
12 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
13 TIM_OCInitStructure.TIM_Pulse = 500;
14 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
15 TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
16 TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
17 TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;
18 TIM_OC1Init(TIM8, &TIM_OCInitStructure);
19 TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable);
20 TIM_OC2Init(TIM8, &TIM_OCInitStructure);
21 TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable);
22
23 TIM_ARRPreloadConfig(TIM8, ENABLE);
24 TIM_CCPreloadControl(TIM8, ENABLE);
25
26 // PWM outputs have to be enabled in order to trigger ADC on CCx
27 TIM_CtrlPWMOutputs(TIM8, ENABLE);
28
29 TIM_SelectInputTrigger(TIM8, TIM_TS_ITR0); //选择输入触发源 ITR0
30 TIM_SelectSlaveMode(TIM8, TIM_SlaveMode_Reset); //计数器从模式选择 所选的触发信号上升沿重新初始化
31
32 // TIM_ITRxExternalClockConfig(TIM8, TIM_TS_ITR0); //选择ITR0为触发源提供时钟
33
34 TIM_CCxCmd(TIM8, TIM_Channel_1, TIM_CCx_Enable);
35 TIM_CCxCmd(TIM8, TIM_Channel_2, TIM_CCx_Enable);
36
37 TIM_ITConfig(TIM8, TIM_IT_CC1, ENABLE);
38 TIM_ITConfig(TIM8, TIM_IT_CC2, ENABLE);
39
40 TIM_ClearFlag(TIM8,TIM_FLAG_Update);
41 TIM_GenerateEvent(TIM8, TIM_EventSource_Trigger);
42
43 TIM_Cmd(TIM8, ENABLE);
44 }

如此计算可知:

        

查阅手册可知:

TIM1为主,TIM8为从,内部是通过ITR0连接的,所以在上面的配置过程中,TIM8的触发源要配置为ITR0;

接下来配置ADC

ADC要配置为三重模式

不开启连续转换

ADC1选择外部触发,但ADC2/3必须配置为软件触发

 1     ADC_CommonInitStructure.ADC_Mode = ADC_TripleMode_RegSimult;                 //adc三重模式
2 ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
3 ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1;
4 ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
5 ADC_CommonInit(&ADC_CommonInitStructure);
6
7 // Channel-specific settings
8 ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //ADC分辨率双模式 12位精度
9 ADC_InitStructure.ADC_ScanConvMode = ENABLE; //扫描模式
10 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
11 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Falling; //选择外部触发方式 下降沿触发
12 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T8_CC1; //选择TIM8_CC1触发规则组开始转换的外部事件
13 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据右对齐
14 ADC_InitStructure.ADC_NbrOfConversion = 4; //指定使用规则通道组完成转换的次数 采样通道数
15
16 ADC_Init(ADC1, &ADC_InitStructure);
17 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //不使用外部触发 (多ADC模式中,外部事件触发必须仅触发主ADC,从ADC设置为软件触发)
18 ADC_InitStructure.ADC_ExternalTrigConv = 0;
19 ADC_Init(ADC2, &ADC_InitStructure);
20 ADC_Init(ADC3, &ADC_InitStructure);
21
22 // Enable DMA request after last transfer (Multi-ADC mode) 多ADC模式下 使能 源数据变化时开启DMA传输
23 ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
24
25 // Injected channels for current measurement at end of cycle
26 ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_T1_CC4);
27 ADC_ExternalTrigInjectedConvConfig(ADC2, ADC_ExternalTrigInjecConv_T8_CC2);
28 ADC_ExternalTrigInjectedConvEdgeConfig(ADC1, ADC_ExternalTrigInjecConvEdge_Falling);
29 ADC_ExternalTrigInjectedConvEdgeConfig(ADC2, ADC_ExternalTrigInjecConvEdge_Falling);
30 ADC_InjectedSequencerLengthConfig(ADC1, 2); //设置注入通道长度 1-4
31 ADC_InjectedSequencerLengthConfig(ADC2, 2);
32
33 ADC_Channels();
34
35 // Interrupt
36 ADC_ITConfig(ADC1, ADC_IT_JEOC, ENABLE); //使能ADC的JEOC中断源 注入转换中断屏蔽结束
37
38 // ADC_AutoInjectedConvCmd(ADC1, ENABLE);
39 // ADC_AutoInjectedConvCmd(ADC2, ENABLE);
40
41 ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_T1_CC4);
42 ADC_ExternalTrigInjectedConvConfig(ADC2, ADC_ExternalTrigInjecConv_T8_CC2);
43
44 //Enable ADC_DMA
45 ADC_DMACmd(ADC1, ENABLE);
46 ADC_DMACmd(ADC2, ENABLE);
47 ADC_DMACmd(ADC3, ENABLE);
48
49 // Enable ADC1
50 ADC_Cmd(ADC1, ENABLE);
51
52 // Enable ADC2
53 ADC_Cmd(ADC2, ENABLE);
54
55 // Enable ADC3
56 ADC_Cmd(ADC3, ENABLE);

再配置一下ADC的通道

 1     ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_15Cycles);         //(15+12)/42 = 0.6429 us  总转换时间
2 ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 2, ADC_SampleTime_15Cycles);
3 ADC_RegularChannelConfig(ADC1, ADC_Channel_Vrefint, 3, ADC_SampleTime_15Cycles);
4 ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 4, ADC_SampleTime_15Cycles);
5
6 // ADC2 regular channels
7 ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 1, ADC_SampleTime_15Cycles);
8 ADC_RegularChannelConfig(ADC2, ADC_Channel_9, 2, ADC_SampleTime_15Cycles);
9 ADC_RegularChannelConfig(ADC2, ADC_Channel_6, 3, ADC_SampleTime_15Cycles);
10 ADC_RegularChannelConfig(ADC2, ADC_Channel_5, 4, ADC_SampleTime_15Cycles);
11
12 // ADC3 regular channels
13 ADC_RegularChannelConfig(ADC3, ADC_Channel_2, 1, ADC_SampleTime_15Cycles);
14 ADC_RegularChannelConfig(ADC3, ADC_Channel_3, 2, ADC_SampleTime_15Cycles);
15 ADC_RegularChannelConfig(ADC3, ADC_Channel_12, 3, ADC_SampleTime_15Cycles);
16 ADC_RegularChannelConfig(ADC3, ADC_Channel_3, 4, ADC_SampleTime_15Cycles);
17
18 // Injected channels
19 ADC_InjectedChannelConfig(ADC1, ADC_Channel_9, 1, ADC_SampleTime_15Cycles);
20 ADC_InjectedChannelConfig(ADC1, ADC_Channel_8, 2, ADC_SampleTime_15Cycles);
21 ADC_InjectedChannelConfig(ADC2, ADC_Channel_8, 1, ADC_SampleTime_15Cycles);
22 ADC_InjectedChannelConfig(ADC2, ADC_Channel_9, 2, ADC_SampleTime_15Cycles);

最后配置DMA

 1 DMA_InitStructure.DMA_Channel = DMA_Channel_0;                   //通道0
2 DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC_Value;
3 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC->CDR;
4 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
5 DMA_InitStructure.DMA_BufferSize = 12; //指定DMA通道的DMA缓存的大小
6 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
7 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
8 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设数据宽度
9 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
10 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //循环缓存模式
11 DMA_InitStructure.DMA_Priority = DMA_Priority_High;
12 DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; //关闭FIFO模式
13 DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; //FIFO阈值级别
14 DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
15 DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
16 DMA_Init(DMA2_Stream4, &DMA_InitStructure);
17
18 // DMA2_Stream0 enable
19 DMA_Cmd(DMA2_Stream4, ENABLE);
20
21 // Enable transfer complete interrupt
22 DMA_ITConfig(DMA2_Stream4, DMA_IT_TC, ENABLE);

如此,工程便配置完成了

通过示波器验证:

定时器1的通道1、2、3和他们的互补通道(6路PWM波):

TIM1通道4的波形(ADC1注入通道)  和  TIM8输出的波形(ADC规则通道、ADC2注入通道):

程序验证正常。

定时器同步+触发三ADC采样+输出6路PWM波的更多相关文章

  1. 基于STM32F429+HAL库编写的定时器主从门控模式级联输出固定个数PWM脉冲的程序

    硬件设备   42步进电机,步进电机驱动器,正点原子F429开发板 开发软件    keil5,Cube 综述   一般要精准的控制电机,就要控制单片机的引脚输出指定个数的PWM波,有多种可实现的方法 ...

  2. STM8S003K3用Tim1的通道4输出20KHz的PWM波

    void Init_pwm(){TIM1_DeInit(); TIM1_TimeBaseInit(0, TIM1_COUNTERMODE_UP, 800, 0x00);//250 TIM1_OC4In ...

  3. STM32F103定时器输出PWM波控制直流电机

    这个暑假没有回家,在学校准备九月份的电子设计竞赛.今天想给大家分享一下STM32高级定时器输出PWM波驱动直流电机的问题.. 要想用定时器输出的PWM控制直流电机,,首先要理解“通道”的概念..一个定 ...

  4. 速度上手LM4F LaunchPad 输出多路PWM波

    最近转战到TI的Cortex M4平台后,发现网上关于TI的LM4F120 Launchpad 资料太少了,而且其中大部分都是TI员工或者其合作伙伴提供的,例程太少,导致新手上手很慢. 我只是要实现几 ...

  5. stm32f103_高级定时器——输入捕获/输出比较中断+pwm=spwm生成

    ****************************首选我们了解一下它们的功能吧********************************************************** ...

  6. STM32中基于DMA的ADC采样实例之MQ-2烟雾传感器

    最近学习了一下STM32中的ADC采样,由于手头正好有一个MQ-2的烟雾传感器,所以正好可以测试一把.体验ADC采样的过程.下面介绍一下这个MQ-2烟雾传感器. 1.MQ-2烟雾传感器简介 MQ-2气 ...

  7. MCMC(三)MCMC采样和M-H采样

    MCMC(一)蒙特卡罗方法 MCMC(二)马尔科夫链 MCMC(三)MCMC采样和M-H采样 MCMC(四)Gibbs采样(待填坑) 在MCMC(二)马尔科夫链中我们讲到给定一个概率平稳分布$\pi$ ...

  8. STM32 多通道ADC采样,采用Timer1进行采样率控制,利用DMA进行传输

    http://blog.csdn.net/varding/article/details/17559399 http://www.51hei.com/stm32/3842.html https://w ...

  9. DSP基础学习-ADC采样

    DSP基础学习-ADC采样 彭会锋 2015-04-27 22:30:03 在查看ADC采样例程的时候我发现了下面的代码挺有意思的 EALLOW; GpioCtrlRegs.GPAMUX2.bit.G ...

随机推荐

  1. HowTos/Virtualization/VirtualBox - CentOS Wiki

    https://wiki.centos.org/HowTos/Virtualization/VirtualBox

  2. Windows10下安装VMware虚拟机并搭建CentOS系统环境

    转载: http://blog.51cto.com/10085711/2069270 操作系统 Windows 10专业版(64位) VMware虚拟机 产品:VMware® Workstation ...

  3. AJAX返回值问题

    ajax同步方式获取返回值,必须以同步请求的的方式获取. //主函数部分 function confirm(id,...)//省略部分参数 { //...省略部分代码 //任务涉及专业 var Maj ...

  4. MySQL 字段内容区分大小写

    数据由Oracle 迁入MySQL ,由于之前Oracle区分大小写,MySQL的配置使用了默认配置,导致一些数据导入失败,有的唯一键报错,冲突. 将测试过程记录在下面. 数据库版本:MySQL 5. ...

  5. 堆排序的Python实现

    参考: https://www.jianshu.com/p/d174f1862601

  6. MCV 和 MTV框架基本信息

    一 . MCV # web服务器开发最著名的MVC模式 M : model.py 就是和数据库打交道的, 创建表等操作 V : view 视图(视图函数,就是装HTML文件的) C : control ...

  7. 对于tomcat通过catalina.sh停止服务后,tomcat进程没有退出问题解决办法

    例:tomcat路径及名称为/data/apache-tomcat-7.0.67/ vim /data/apache-tomcat-7.0.67/bin/catalina.sh 找到org.apach ...

  8. 【Spring】——声明式事务配置详解

    项目中用到了spring的事务: @Transactional(rollbackFor = Exception.class, transactionManager = "zebraTrans ...

  9. jdbc工具类2..0

    一.创建外部文件 url=jdbc:mysql:///qy66 use=root password=root driver=com.mysql.jdbc.Driver 二.创建工具类 package ...

  10. centos无网络问题