STM32F103C6T6之PWM+DMA篇

这篇具有很好参考价值的文章主要介绍了STM32F103C6T6之PWM+DMA篇。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

最近在学习PWM+DMA配合生成可改变占空比的PWM波形。找了很多很多资料但是感觉对初学者不是很友善,只是提供了很多原理。这边使用的代码是固件库版的,也是学习STM32最基础的固件库代码了吧!

  1. 预分频器(TIMx_PSC)
  1. 自动重装载寄存器(TIMx_ARR)
  1. 捕获/比较寄存器x(TIMx_CCRx)

一、原理

当PWM计数到CCR寄存器的设定值后触发对应DMA请求,将下次CCR值装入就是了。

二、函数(结构体)

PWM:时基初始化结构体、输出比较寄存器结构体

DMA:DMA初始化结构体

三、踩到的坑(真的是绝)

1、确定定时器

高级控制定时器(TIM1、TIM8)、通用定时器(TIMx)、基本定时器(TIM6、TIM7)---我选用的是TIM2

2、确定引脚(查用户手册)

我选择的是:TIM2-CH4 PA3

STM32F103C6T6之PWM+DMA篇

3、确定DMA以及通道(查询参考手册)

根据上述选择觉得DMA1还是DMA2,这边是DMA1 通道为 Channel7

STM32F103C6T6之PWM+DMA篇
STM32F103C6T6之PWM+DMA篇

4、确定APBx(查询参考手册)

决定外设和GPIO的时钟使能

STM32F103C6T6之PWM+DMA篇

5、总结

选择TIM2 - CH4(PA3) - DMA1和Channel7 - APB1和APB2(都要使能)

四、代码

1、PWM.c文件(涉及定时器PWM初始化、GPIO初始化化)(其实这边中断都不需要要)

#include "pwm.h"

static void TIM2_PWM_GPIO_Init(void);
static void TIM2_PWM_Mode(void);
static void TIM2_NVIC_Config(void);

static void TIM2_NVIC_Config(void)
{
#include "stm32f10x.h"                  // Device header
    NVIC_InitTypeDef NVIC_InitStruct;
    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
    
    NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQ;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 3;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    
    NVIC_Init(&NVIC_InitStruct);
}

static void TIM2_PWM_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    //开启GPIO时钟
    PWM_TIMx_APBxClk(PWM_TIMx_Clkx, ENABLE);
    
    GPIO_InitStruct.GPIO_Pin = PWM_TIMx_GPIOx;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(PWM_TIMx_PORPx, &GPIO_InitStruct);
}

static void TIM2_PWM_Mode(void)
{
//-------------------结构体------------------------------------//
    TIM_TimeBaseInitTypeDef      TIM_TimeBase_InitSturct;
    TIM_OCInitTypeDef                    TIM_OC_InitSturct;
    
//----------------------开启定时器时钟---------------------//
    ADVANCE_TIMx_APBxClk(ADVANCE_TIMx_Clk, ENABLE);

//-------------------时基初始化结构体-------------------------//
    //信号周期
    TIM_TimeBase_InitSturct.TIM_Period = TIM2_Period;
    //分频周期,记一次的时间
    TIM_TimeBase_InitSturct.TIM_Prescaler    =    (9);
    //计数模式
    TIM_TimeBase_InitSturct.TIM_CounterMode    =    TIM_CounterMode_Up;
    //死区(普通,通用定时器不需要配置)
    //TIM_TimeBase_InitSturct.TIM_ClockDivision    =    TIM_CKD_DIV1;                //CR1
    //重复寄存器,没用到不要管
    TIM_TimeBase_InitSturct.TIM_RepetitionCounter = 0;                                    //RCR
    TIM_TimeBaseInit(ADVANCE_TIMx, &TIM_TimeBase_InitSturct);
    
//--------------------输出比较寄存器结构体-----------------//
    //模式选择
    TIM_OC_InitSturct.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OC_InitSturct.TIM_OutputState = TIM_OutputState_Enable;
    //
    TIM_OC_InitSturct.TIM_Pulse = TIM2_Pulse;    //占空比
    TIM_OC_InitSturct.TIM_OCPolarity = TIM_OCPolarity_High;
    //
    TIM_OC_InitSturct.TIM_OCIdleState = TIM_OCIdleState_Set;
    //
    TIM_OC4Init(ADVANCE_TIMx, &TIM_OC_InitSturct);
    TIM_OC4PreloadConfig(ADVANCE_TIMx, TIM_OCPreload_Enable);
    
//-----------------------------------------------------------//
    TIM_Cmd(ADVANCE_TIMx, ENABLE);
    TIM_CtrlPWMOutputs(ADVANCE_TIMx, ENABLE);
}

void PWM_Init(void)
{
    TIM2_NVIC_Config();
    TIM2_PWM_GPIO_Init();
    TIM2_PWM_Mode();
    
    //TIM_DMAConfig(ADVANCE_TIMx, TIM_DMABase_CCR4, TIM_DMABurstLength_1Transfer);
    TIM_DMACmd(ADVANCE_TIMx, TIM_DMA_CC4, ENABLE);
}

2、DMA.c文件(涉及DMA结构初始化)RGB_Buff内存存储的缓存要发给PWM改变占空比的

#include "dma.h"

#define RGB_Size 25
//1码:0x06    0码:0x02
const uint16_t RGB_G_Buff[RGB_Size] = { 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
                                                                            0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
                                                                            0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
                                                                            0x00 };
const uint16_t RGB_R_Buff[RGB_Size] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
                                                                            0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
                                                                            0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
                                                                            0x00 };
const uint16_t RGB_B_Buff[RGB_Size] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
                                                                            0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
                                                                            0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
                                                                            0x00 };
const uint16_t RGB_0_Buff[RGB_Size] = { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
                                                                            0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
                                                                            0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
                                                                            0x00 };

void Dma_Init(void)
{
    DMA_InitTypeDef DMA_InitStruct;
    
    TIM_DMA_APBxCLK(TIM_DMA_CLK ,ENABLE);    
    
    DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&TIM2->CCR4;
    DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)RGB_B_Buff;
    DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralDST;//从存储器读
    DMA_InitStruct.DMA_BufferSize = RGB_Size;
    DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStruct.DMA_Priority = DMA_Priority_High;
    DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
    
    DMA_Init(MTM_DMA_Channe, &DMA_InitStruct);
    DMA_Cmd(MTM_DMA_Channe, ENABLE);
    //DMA_ClearFlag(MTM_DMA_TCx);
}

3、PWM.h

#ifndef __PWM_H
#define __PWM_H

#include "stm32f10x.h"

//GPIO定义
#define PWM_TIMx_PORPx          GPIOA
#define PWM_TIMx_GPIOx          GPIO_Pin_3
#define PWM_TIMx_APBxClk        RCC_APB2PeriphClockCmd
#define PWM_TIMx_Clkx                RCC_APB2Periph_GPIOA
//TIM2定义
#define ADVANCE_TIMx                TIM2        //TIM2_CH4
#define ADVANCE_TIMx_APBxClk        RCC_APB1PeriphClockCmd
#define ADVANCE_TIMx_Clk            RCC_APB1Periph_TIM2
//中断定义
#define TIM2_IRQ                     TIM2_IRQn
#define TIM2_IRQandle                TIM2_IRQHandler
//PWM配置
//PWM时钟频率 = TIM_CLK/(ARR+1)(PSC+1)
#define TIM2_Period                (8-1)        // 周期
#define TIM2_Psc                    (9-1)        //分频因子
#define TIM2_Pulse                    0            //CCR占空比

void PWM_Init(void);

#endif /* __PWM_H */

4、DMA.h

#ifndef __DMA_H
#define __DMA_H

#include "stm32f10x.h"

#define MTM_DMA_Channe      DMA1_Channel7
#define MTM_DMA_TCx                DMA1_FLAG_TC7
#define    TIM_DMA_CLK                RCC_AHBPeriph_DMA1
#define    TIM_DMA_APBxCLK        RCC_AHBPeriphClockCmd

void Dma_Init(void);

#endif /* __DMA_H */

5、main.c

#include "stm32f10x.h"
#include "pwm.h"
#include "dma.h"

uint16_t time = 0;

int main()
{
    Dma_Init();
    PWM_Init();

    while(1)
    {
        
    }
}

五、测试波形

之前是使用0x06, 0x02,0x00各八组的数据组测量的,可以明显看到下述测量波形占空比的变化文章来源地址https://www.toymoban.com/news/detail-417652.html

STM32F103C6T6之PWM+DMA篇
STM32F103C6T6之PWM+DMA篇

六、后续补充、、、

到了这里,关于STM32F103C6T6之PWM+DMA篇的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于STM32F103C8T6的端口重映射及定时器输出PWM控制

    #一、端口重映射原理及部分/完全重映射 #二、端口重映射的配置 #三、PWM控制 ##1、通用定时器输出PWM ##2、PWM的工作原理 ##3、PWM的内部运作机制 ##4、PWM的模式 ##5、自动加载的预载寄存器 #四、定时器输出PWM结构体及库函数的配置 #五、项目硬件 #六、项目代码 一、端口重映射

    2024年02月13日
    浏览(48)
  • STM32 DMA1和DMA2通道一览表、STM32F103C8T6定时器通道对应的引脚

    TIM1_BRK_IRQn               = 24,      TIM1_UP_IRQn                = 25,      TIM1_TRG_COM_IRQn           = 26,     TIM1_CC_IRQn                = 27,     TIM2_IRQn                   = 28,     TIM3_IRQn                   = 29,    这个函数TIM_SetCompare1,这个函数有四个,分别是TIM_SetC

    2024年02月05日
    浏览(47)
  • STM32系列(HAL库)——F103C8T6驱动WS2812全彩RGB模块(PWM+DMA方式)

    (1)编程平台:Keil5 (2)CubeMX (1)某宝买的RGB模块(4个灯珠级联) (2)F1的板子,本例使用经典F103C8T6 (3)ST-link 下载器 (4)杜邦线若干 (1)模块简介: 没什么比手册讲得更加清楚了,模块中文数据手册:ws2812b中文资料_数据手册_参数 (2)驱动原理:          以上这是数据手册中提到

    2023年04月11日
    浏览(42)
  • STM32F103C8T6定时器实现led的周期闪烁及PWM实现流水灯

    通过定时器Timer方式实现时间的精准控制,相当于给CPU上了一个闹钟,CPU平时处理其它任务,当定时时间到了以后,处理定时相关的任务。请设置一个5秒的定时器,每隔5秒从串口发送“hello windows!”;同时设置一个2秒的定时器,让LED等周期性地闪烁。 使用TIM3和TIM4,分别输

    2024年01月23日
    浏览(53)
  • STM32开发(1)----stm32f103c6t6开发板介绍和环境搭建

    接下来将用一个专栏来介绍STM32开发,前面是一些基础介绍,后面将结合具体物联网项目进行介绍 stm32f103c6t6 是一款基于 ARM Cortex M3 内核的 32 位通用微控制器芯片: STM32F103系列芯片,优异的性能,资源丰富,性价比超高,本文和后续教程选用stm32f103c6t6这款芯片的开发板是因

    2024年02月02日
    浏览(38)
  • 基于STM32F103C8T6四路AD采集数据显示在oled屏上非DMA传输方式(附百度网盘下载链接)

    本文采用四路AD采集 光照强度、烟雾浓度、一氧化碳、空气质量 等四个物理量,并采用 中位值平均滤波(防脉冲干扰平均滤波法)算法 对偶然出现的脉冲性干扰,消除由其引起的采样值偏差。 STM32F103C8T6有两个ADC,12位ADC是一种逐次逼近型模拟数字转换器。它有多达18个通道,

    2024年02月13日
    浏览(38)
  • 【沧海拾昧】STM32F103C8T6/C6T6的ISP烧录

    #C0105 沧海茫茫千钟粟,且拾吾昧一微尘 ——《沧海拾昧集》@CuPhoenix 【阅前敬告】 沧海拾昧集仅做个人学习笔记之用,所述内容不专业不严谨不成体系 【如有问题必是本集记录有谬,切勿深究】   对于某种STM32F103C8T6/C6T6最小系统板,没有配置J-LINK/ST-LINK烧录口,此时可以

    2024年02月03日
    浏览(68)
  • stm32f103VET6和stm32f103c8t6有什么区别?

    我来终结下这个问题。 这两款单片机我都用过,其中无际单片机特训营其中一款wifi报警主机项目就是用了stm32f103c8t6。  stm32f103VET6和stm32f103c8t6都是STMicroelectronics公司推出基于ARM Cortex-M3内核的单片机。 它们在硬件规格和性能上存在一些差异,下面我详细讲解下它们的差异之处

    2024年02月15日
    浏览(58)
  • 功耗测评 | STM32F103C8T6

    STM32F103C8T6 MCU越来越广泛的应用在生产生活的各个领域,外接丰富的传感器、功能模块、通信模块、显示存储等可以形成各种可样的产品项目应用。对于功耗要求比较高的产品,一般会选择STM32L系列的MCU,但是从功耗的评测角度,逻辑上是基本相似的。 在很多应用场合中都对

    2024年02月07日
    浏览(41)
  • STM32F103C8T6系统板

    1.电源部分 2.复位 3.晶振 4. 电源电路——防反接 有关二极管 漫谈二极管防电源反接电路 本次采用上图右下角的NMOS防反接电路。 电源电路——电源芯片 AMS1117是AMS公司的 ,LM1117是NS(美国国家半导体)的,LM1117要贵很多,所以一般的用AMS1117就可以了。 (以下分析参考STM32F10

    2024年02月02日
    浏览(69)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包