【Cortex-A7核PWM实验】

news2024/11/8 22:57:45

Cortex-A7核PWM实验 ---蜂鸣器、风扇、震动马达

  • PWN概念
  • PWM硬件电路图
  • 如何产生PWM方波
    • 捕获/比较寄存器工作原理
  • 代码实现

PWN概念

PWM是指脉冲宽度调制(Pulse Width Modulation),是一种常用的模拟信号转换为数字信号的方法。
1.脉冲:
方波信号,高低电平变化就产生方波信号
2.周期
高低电平变化所需要的时间,就叫做周期,单位:ms
3.频率
周期和频率成倒数关系
1s钟可以产生方波的个数,就叫做频率,单位:HZ
4.占空比
在一个方波内,高电平占整个方波周期的百分比,单位:%
高电平0.3s,低电平0.7s,占空比:30%
5.本次实验使用PWM完成:风扇,蜂鸣器,马达

PWM硬件电路图

在这里插入图片描述
在这里插入图片描述

如何产生PWM方波

在STM32微控制器中,TIM模块可以通过配置寄存器并使用PWM输出模式来产生PWM信号。
大致步骤如下:
1、在STM32的寄存器中配置TIM模块,包括设置时钟源、分频系数、计数器模式等。
2、使用PWM输出模式(Output Compare),并设置脉冲宽度。这通常需要设置输出比较寄存器(CCR)的值。
3、启动TIM模块,开始产生PWM信号。这通常需要在寄存器中设置启动位。
具体实现如图:
在这里插入图片描述

捕获/比较寄存器工作原理

如果想产生PWM方波,需要使用捕获/比较寄存器
1.当定时器启动之后,自动重载计数器中的值,自动加载到递减计数器中
2.递减计时器在CK_CNT(分频之后的值)时钟驱动下进行工作
3.每来一个时钟周期,递减计数器中的值,进行减1的操作
4.减到某一时刻,和捕获/比较寄存器中的值相等之后
5.电平发生翻转,这样产生PWM方波

代码实现

pwm.c

#include "pwm.h"
void hal_beep_init()
{
	/*******RCC章节***/
	//1.使能GPIOB组控制器 MP_AHB4ENSETR[1] = 1
	RCC->MP_AHB4ENSETR |= (0x1 << 1);
	//2.使能TIM4组控制器 MP_APB1ENSETR[2] = 1
	RCC->MP_APB1ENSETR |= (0x1 << 2);

	/*******GPIO章节**/
	//1.设置PB6引脚为复用功能模式 MODER[13:12] = 10
	GPIOB->MODER &= (~(0x3 << 12));
	GPIOB->MODER |= (0x1 << 13);
	//2.设置PB6引脚复用功能为TIM4_CH1 AFRL[27:24] = 0010
	GPIOB->AFRL &= (~(0xf << 24));
	GPIOB->AFRL |= (0x1 << 25);

	/*******TIM4章节**/
	//1.设置预分频器值209 - 1 PSC[15:0] = 209 - 1
	//系统提供的时钟源为209MHZ
	TIM4->PSC = 209 - 1;
	//2.输出PWM方波频率1000HZ,设置自动重载计数器值 ARR[15:0] = 1000 
	TIM4->ARR = 1000;
	//3.输出PWM方波占空比 CCR1[15:0] = 700
	TIM4->CCR1 = 700;
	//4.设置TIM4_CH1通道输出PWM方波模式 CCMR1[16][6:4] = 0110
	TIM4->CCMR1 &= (~(0x1 << 16));
	TIM4->CCMR1 |= (0x7 << 4);
	TIM4->CCMR1 &= (~(0x1 << 4));
	//5.设置TIM4_CH1通道TIMX_CCR1寄存器使能 CCMR1[3] = 1
	TIM4->CCMR1 |= (0x1 << 3);
	//6.设置TIM4_CH1通道配置为输出模式 CCMR1[1:0] = 00
	TIM4->CCMR1 &= (~(0x3 << 0));
	//7.设置TIM4_CH1通道捕获比较寄存器输出极性,默认为高电平
	// CCER[3]=0  CCER[1] = 0
	TIM4->CCER &= (~(0x1 << 3));
	TIM4->CCER &= (~(0x1 << 1));
	// 8.设置TIM4_CH1通道捕获比较寄存器输出使能 CCER[0] = 1
	TIM4->CCER |= (0x1 << 0);
	// 9.设置TIM4_CH1通道自动重载预加载使能 CR1[7] = 1
	TIM4->CR1 |= (0x1 << 7);
	// 10.设置TIM4_CH1通道计数器为边沿对齐方式 CR1[6:5] = 00 
	TIM4->CR1 &= (~(0x3 << 5));
	// 11.设置TIM4_CH1通道为递减计数方式 CR1[4] = 1
	TIM4->CR1 |= (0x1 << 4);
	// 12.设置TIM4_CH1通道计数器使能 CR1[0] = 1
	TIM4->CR1 |= (0x1 << 0);

}
void hal_fan_init()
{
	/*******RCC章节***/
	//1.使能GPIOB组控制器 MP_AHB4ENSETR[4] = 1
	RCC->MP_AHB4ENSETR |= (0x1 << 4);
	//2.使能TIM1组控制器 MP_APB2ENSETR[0] = 1
	RCC->MP_APB2ENSETR |= (0x1);

	/*******GPIO章节**/
	//1.设置PE9引脚为复用功能模式 MODER[19:18] = 10
	GPIOE->MODER &= (~(0x3 << 18));
	GPIOE->MODER |= (0x1 << 19);
	//2.设置PE9引脚复用功能
	GPIOE->AFRH &= (~(0xf << 4));
	GPIOE->AFRH |= (0x1 << 4);

	/*******TIM4章节**/
	//1.设置预分频器值209 - 1 PSC[15:0] = 209 - 1
	//系统提供的时钟源为209MHZ
	TIM1->PSC = 209 - 1;
	//2.输出PWM方波频率1000HZ,设置自动重载计数器值 ARR[15:0] = 1000 
	TIM1->ARR = 1000;
	//3.输出PWM方波占空比 CCR1[15:0] = 700
	TIM1->CCR1 = 700;
	//4.设置TIM1_CH1通道输出PWM方波模式 CCMR1[16][6:4] = 0110
	TIM1->CCMR1 &= (~(0x1 << 16));
	TIM1->CCMR1 |= (0x7 << 4);
	TIM1->CCMR1 &= (~(0x1 << 4));
	//5.设置TIM1_CH1通道TIMX_CCR1寄存器使能 CCMR1[3] = 1
	TIM1->CCMR1 |= (0x1 << 3);
	//6.设置TIM1_CH1通道配置为输出模式 CCMR1[1:0] = 00
	TIM1->CCMR1 &= (~(0x3 << 0));
	//7.设置TIM4_CH1通道捕获比较寄存器输出极性,默认为高电平
	// CCER[3]=0  CCER[1] = 0
	TIM1->CCER &= (~(0x1 << 3));
	TIM1->CCER &= (~(0x1 << 1));
	// 8.设置TIM4_CH1通道捕获比较寄存器输出使能 CCER[0] = 1
	TIM1->CCER |= (0x1 << 0);
	// 9.设置TIM4_CH1通道自动重载预加载使能 CR1[7] = 1
	TIM1->CR1 |= (0x1 << 7);
	// 10.设置TIM4_CH1通道计数器为边沿对齐方式 CR1[6:5] = 00 
	TIM1->CR1 &= (~(0x3 << 5));
	// 11.设置TIM4_CH1通道为递减计数方式 CR1[4] = 1
	TIM1->CR1 |= (0x1 << 4);
	// 12.设置TIM4_CH1通道计数器使能 CR1[0] = 1
	TIM1->CR1 |= (0x1 << 0);
	// 13.风扇寄存器设置
	TIM1->BDTR |= (0x1 << 15);
}
void hal_motor_init()
{
	/*******RCC章节***/
    RCC->MP_AHB4ENSETR |= (0x1 << 5);
    RCC->MP_APB2ENSETR |= (0x1 << 3);
    /*******GPIO章节**/
    GPIOF->MODER &= (~(0x3 << 12));
    GPIOF->MODER |= (0x1 << 13);
    GPIOF->AFRL &= (~(0xf << 24));
    GPIOF->AFRL |= (0x1 << 24);
    /*----PSC------*/
    TIM16->PSC &= (~(0xffff));
    TIM16->PSC |= (0xD << 4);

    /*-----ARR-----*/
    // 配置寄存器数值
    TIM16->ARR &= (~(0xffff));
    TIM16->ARR |= (0x3E8);

    /*-----CCR1------*/
    TIM16->CCR1 &= (~(0xffff));
    TIM16->CCR1 |= (0x384);

    /*-----CCMR1-----*/
    // 设置为PWM1模式
    TIM16->CCMR1 &= (~(0x1 << 16));
    TIM16->CCMR1 &= (~(0x7 << 4));
    TIM16->CCMR1 |= (0x3 << 5);
    // 设置预加载使能
    TIM16->CCMR1 |= (0x1 << 3);
    // 设置为输出模式
    TIM16->CCMR1 &= (~(0x3));

    /*-----CCER-----*/
    // 设置为输出模式
    TIM16->CCER &= (~(0x1 << 3));
    // 配置起始状态高电平
    TIM16->CCER &= (~(0x1 << 1));
    // 配置输出使能
    TIM16->CCER |= (0x1);

    /*----CR1-----*/
    // 使能自动重载计数器预加载
    // 边沿对其方式
    // 设置递减计数器
    TIM16->CR1 |= (0x1 << 7);
    // 设置计数器使能
    TIM16->CR1 |= (0x1 << 0);
    // 马达寄存器设置
    TIM16->BDTR |= (0x1 << 15);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/141867.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C#WinForm实现多语言切换

因项目需要&#xff0c;所以在网上找了一些方法实现了该功能&#xff0c;本文也是做一个总结和记录。使用resx文件实现Winform多语言切换&#xff0c;以实现简体中文、英文、泰语的切换为例。如果后续需要增加其它语言的切换&#xff0c;只需要按照步骤重复操作即可。 效果图如…

【Kotlin】函数 ⑨ ( Kotlin 语言中的闭包概念 | Java 语言中函数作为参数的替代方案 )

文章目录一、闭包概念二、Java 中函数作为参数的替代方案 ( 匿名内部类 )一、闭包概念 匿名函数 就是 Lambda 表达式 , 同时也是 闭包 , 三者的是相同的概念 ; 闭包意义 : 在 Java 中 , 通过 Package 包 , Class 类 , 将作用域区分开 , 将变量 定义在 不同的 包 或 类中 , 可…

阿里云创世纪之盘古传奇

文章目录飞天(Apsara)云计算平台简介面向私有云的Apsara Stack盘古横空出世盘古的架构盘古基本介绍盘古API基于C语言的SDK基于命令行的文件操作接口pu盘古中的目录和文件盘古目录盘古中的文件盘古中的文件类型盘古应用场景盘古的功能特性盘古主要性能盘古的数据安全盘古的边界盘…

Docker - Docker网络

一、Docker网络介绍 Docker是基于Linux Kernel&#xff08;内核&#xff09;的namespace&#xff0c;CGroups,UnionFileSystem等技术封装成的一种自定义容器格式&#xff0c;从而提供了—套虚拟运行环境。 1、namespace&#xff1a;用来做隔离的&#xff0c;比如pid[进程].、…

Java多线程案例之阻塞队列

文章目录一. 认识阻塞队列1. 什么是阻塞队列2. 生产者消费者模型3. 标准库中阻塞队列类二. 基于循环队列实现的简单阻塞队列1. 循环队列的简单实现2. 阻塞队列的简单实现一. 认识阻塞队列 1. 什么是阻塞队列 阻塞队列本质上还是一种队列, 和普通队列一样, 遵循先进先出, 后进…

291. 蒙德里安的梦想(状态压缩dp详解)

求把 NM 的棋盘分割成若干个 12 的长方形&#xff0c;有多少种方案。 例如当 N2&#xff0c;M4 时&#xff0c;共有 5 种方案。当 N2&#xff0c;M3 时&#xff0c;共有 3 种方案。 如下图所示&#xff1a; 输入格式 输入包含多组测试用例。 每组测试用例占一行&#xff0c…

龙芯机器JDK安装和配置

龙芯机器&#xff1a;[rootlocalhost j2sdk-image]# cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c4 Loongson-3A R4 (Loongson-3A4000) 1800MHz龙芯机器JDK安装和配置下载地址&#xff1a;http://www.loongnix.cn/zh/api/java/选择JDK8&#xff0c;选择MIPS64进行下…

2-3进程管理-进程同步

文章目录一.进程同步、互斥二.实现临界区互斥的基本方法&#xff08;一&#xff09;软件实现方法&#xff08;二&#xff09;硬件实现方法三.互斥锁四.信号量机制五.经典同步问题&#xff08;一&#xff09;生产者-消费者问题&#xff08;二&#xff09;读者-写者问题&#xff…

流逝的一年

昨天远方的大哥打来了电话&#xff0c;我们聊了下近况。当他问及去年是否有新的著作问世&#xff0c;我不禁有些赧然&#xff0c;解释说还在学习中… 放下电话后&#xff0c;我陷入了思索&#xff1a;又是一年划上了句号&#xff0c;这一年我做了什么&#xff1f;我又有什么收…

数据库的一些基本概念

一、服务器&#xff1a;&#xff08;更正大家头脑中的一个错误认识&#xff09; 1、服务器是一种软件&#xff0c;不是硬件&#xff0c;不是计算机。 2、不同服务器负责调用不同类型的文件。 二、表文件、数据库、数据库服务器以及SQL语句&#xff1a; 1、表文件: …

一条 select 语句的执行过程

MySQL 从大方向来说&#xff0c;可以分为 Server 层和存储引擎层。而 Server 层包括连接器、查询缓存、解析器、预处理器、优化器、执行器等&#xff0c;最后 Server 层再通过 API 接口形式调用对应的存储引擎层提供的接口来执行增删改查操作。 如下即为一个简略的 select 语句…

Android动态运行时权限

android 6.0(API 级别 23)开始&#xff0c;android引入了运行时权限&#xff0c;应用安装时不向其授予权限&#xff0c;应用运行时向其授予权限。如果在运行时该功能没有动态地申请相应的权限&#xff0c;就会抛出SecurityException异常。 android的运行时权限的申请过程主要有…

C语言画一个正方体

程序截图 操作方法 鼠标拖动。左键拖动及滚轮能看到不同角度下正方体的形状&#xff0c;右键拖动能将最近的正方体顶点挪到这个投影面的相应位置。 按键控制。wasd 控制投影面旋转&#xff0c;ws 关于 x 轴旋转&#xff0c;ad 关于 y 轴旋转。 个人思路 首先投影面的确立需…

【寒假第一天】LeetCode刷题

&#x1f308;一.选择题&#x1f47f;1.1.堆是一种有用的数据结构。下列那个关键码序列是一个堆&#xff08; &#xff09;。 A. 94,31,53,23,16,72 B. 94,53,31,72,16,23 C. 16,53,23,94,31,72 D. 16,31,23,94,53,72D堆排序有两种排序方法&#xff1a;大堆排序-----根结点要大…

【Kotlin】Kotlin 函数总结 ( 具名函数 | 匿名函数 | Lambda 表达式 | 闭包 | 内联函数 | 函数引用 )

文章目录一、函数头声明二、函数参数1、默认参数值2、具名参数三、Unit 函数四、TODO 函数抛出异常返回 Nothing 类型五、反引号函数名六、匿名函数七、匿名函数的函数类型八、匿名函数的隐式返回九、匿名函数参数十、匿名函数 it 关键字十一、匿名函数变量类型推断十二、匿名函…

JS中BOM 浏览器对象 提供的定时器

window对象提供了2个定时器方法&#xff1a; settTimeout()和setInterval() 1.setTimeout()定时器 语法&#xff1a; window.setTimeout(调用函数,[延迟的毫秒数]);延迟时间可以省略&#xff0c;省略则为0 用于设置一个定时器&#xff0c;该定时器再定时器到期后执行调用函数 …

【nodejs】npm与包

1、什么是包 Node.js中的第三方模块又叫包 2、包的来源 由第三方个人或团队开发出来的&#xff0c;免费供所有人使用 3、为什么需要包 由于Node.js的内置模块仅提供了一些底层的API&#xff0c;导致在基于内置模块进行项目开发时&#xff0c;效率很低。 包是基于内置模块封装出…

杨校老师课堂之IntellJ IDEA的使用技巧

下载地址&#xff1a; https://www.jetbrains.com.cn/idea/download/#sectionwindows 一、常规操作 1、忽略大小写&#xff0c;进行提示 2、启用Idea时&#xff0c;默认不再打开上次项目 3、设置主题 4、设置默认的字体 5、修改类头的文档注释信息 6、设置项目文件编码 7、统一…

electron与jquery起冲突,使用jquery报错解决方法

问题原因&#xff1a;Electron 为了整合 Node.js&#xff0c;会在 DOM 加入 module、exports、require 等模块和函数&#xff0c;和jQuery、RequireJS、Meteor、AngularJS 等发生冲突。 暴力解决方法&#xff1a;去除node功能加持&#xff0c;在加载browserWindow或者browserVi…

C++:闭包:闭包Closure理解

一&#xff1a;什么是闭包 闭包有很多定义&#xff0c;一种说法是&#xff1a;闭包是带有上下文的函数&#xff0c;说白了&#xff0c;就是有状态的函数&#xff0c;这其实就是一个类&#xff0c;换个名字而已。 一个函数&#xff0c;带上一个状态&#xff0c;就变成了闭包&…