IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 2022/10/2 --- PWM A7核复习 -> 正文阅读

[嵌入式]2022/10/2 --- PWM A7核复习

创作本文目的:记录自己的学习历程


一、A7实现PWM器件启动的步骤

1.相关概念

1.PWM:脉冲宽度调制定时器
2.脉冲:方波信号,高低电平的变化产生方波信号
3.周期:高低电平变化所需要的时间,单位:ms
4.频率:周期和频率之间是倒数关系,1S钟可以产生的多少个方波信号,单位:HZ
5.占空比:高电平占整个周期的百分比
6.本次实验中:PWM/风扇/马达

2.分析硬件

在这里插入图片描述

蜂鸣器:TIM4_CH1----> PB6 gpio toggle gpiob6
风扇:TIM1_CH1----> PE9 gpiotoggle gpioe9
马达:TIM16_CH1----> PF6 gpio toggle gpiof6

3.分析芯片手册

分析RCC章节:相关控制器组使能
分析GPIO章节:复用模式/复用功能
分析TIM章节:产生特定的方波

3.1 RCC时钟使能

GPIOB组和TIM4组时钟使能---蜂鸣器
GPIOF组和TIM16组时钟使能---马达
GPIOE组,TIM1组时钟使能---风扇

3.2 GPIO复用功能

MODER寄存器
AFRL/AFRH寄存器

3.3 TIM*产生方波

BDTR(风扇和马达需要)
CCR1 --- 影响PWM方波占空比
ARR --- 影响PWM方波的周期和频率
PSC --- 设置预分频器
CCER --- 设置输出PWM方波的极性
CCMR1 --- 设置指定通道为PWM1模式 和 输出捕获预加载使能
CR1 --- 配置tim计数器方式(自动重载计数器预加载使能,设置边沿对齐模式,设置递减计数器,设置计数器使能)

4.PWM方波的产生

1.当定时器启动之后,自动重载计数器中的值,会自动加载到递减计数器中
2.递减计数器在CK_CNT时钟驱动下进行工作
3.每来一个时钟周期,递减计数器中的值减1
4.如果减到和比较/捕获寄存器中的值相等之后,电平发生翻转,这样就可产生PWM方波信号

5.部分程序

#include "beep.h"

void my_fan_tim1_init()
{
	// 1. 设置GPIOE,TIM1的时钟使能   RCC_MP_AHB4ENSETR  RCC_MP_APB2ENSETR
	RCC->MP_AHB4ENSETR |= (0x1 << 4);
	RCC->MP_APB2ENSETR |= (0x1 << 0);
	// 2. 设置PE9引脚为复用功能       GPIOE_MODER
	GPIOE->MODER &= (~(0x3 << 18));
	GPIOE->MODER |= (0x2 << 18);
	// 3. 设置PE9引脚为TIM1_CH1功能   GPIOE_AFRH
	GPIOE->AFRH &= (~(0xF << 4));
	GPIOE->AFRH |= (0x1 << 4);

	// 主输出使能
	TIM1->BDTR |= (0x1 << 15);
	// 4. 设置预分频寄存器,TIM1_PSC[15:0]  CK_PSC = 209MHz  
	// 		提供给TIM1的时钟源的频率是209MHz
	TIM1->PSC = 209 - 1;	
	// 5. 设置PWM方波的最终的周期  TIM1_ARR[16:0]
	// 		得到一个1000-2000Hz的方波
	TIM1->ARR = 10000;
	// 5. 设置PWM方波的占空比   TIM1_CCR1[16:0]
	TIM1->CCR1 = 5000;

	// 6. 设置TIM1_CH1通道为PWM1模式  
	// 		TIM1_CCMR1[16]  TIM1_CCMR1[6:4]  pwm模式1  = 0b0110
	TIM1->CCMR1 &= (~(0x1 << 16));
	TIM1->CCMR1 &= (~(0x7 << 4));
	TIM1->CCMR1 |= (0x6 << 4);
	TIM1->CCMR1 &= (~(0x3 << 0));
	
	// 7. 设置TIM1_CH1通道使能TIMx_CCR1预加载使能寄存器
	// 		TIM1_CCMR1[3] = 0x1
	TIM1->CCMR1 |= (0x1 << 3);
	// 8. 设置TIM1_CH1通道输出PWM方波的极性,
	// 	  TIM_CCER[3] = 0b0	TIM1_CCER[1] = 0x1 or 0x0
	TIM1->CCER &= (~(0x1 << 3));
	//TIM1->CCER |= (0x1 << 1);
	TIM1->CCER &= ~(0x1 << 1);
	// 9. 设置TIM1_CH1通道的输出使能位,输出PWM方波 
	// 		TIM1_CCER[0] = 0x1 
	TIM1->CCER |= (0x1 << 0);
	
	// 10. 设置TIM1_CH1通道的预装载寄存器的缓冲区的使能
	// 		TIM1_CR1[7] = 0x1 
	TIM1->CR1 |= (0x1 << 7);
	// 11. 设置定时器的计数方式,边沿对齐
	// 		TIM1_CR1[6:5] = 0x0
	TIM1->CR1 &= (~(0x3 << 5));
	// 12 设置定时器计数的方向,采用递减计数/递增计数 
 	//TIM1_CR1 &= (~(0x1 << 4)); 
	TIM1->CR1 |= (0x1 << 4);
	// 13. 使能TIM1_CH1计数器 
	// 		TIM1_CR1[0] = 0x1
	TIM1->CR1 |= (0x1 << 0);
}

void my_motor_tim16_init()
{
	// 1. 设置GPIOF,TIM16的时钟使能   RCC_MP_AHB4ENSETR  RCC_MP_APB2ENSETR
	RCC->MP_AHB4ENSETR |= (0x1 << 5);
	RCC->MP_APB2ENSETR |= (0x1 << 3);
	// 2. 设置PF6引脚为复用功能       GPIOF_MODER
	GPIOF->MODER &= (~(0x3 << 12));
	GPIOF->MODER |= (0x2 << 12);
	// 3. 设置PF6引脚为TIM16_CH1功能   GPIOF_AFRL
	GPIOF->AFRL &= (~(0xF << 24));
	GPIOF->AFRL |= (0x1 << 24);

	// . 主输出使能
	TIM16->BDTR |= (0x1 << 15);
	// 4. 设置预分频寄存器,TIM16_PSC[15:0]  CK_PSC = 209MHz  
	// 		提供给TIM16的时钟源的频率是209MHz
	TIM16->PSC = 209 - 1;	
	// 5. 设置PWM方波的最终的周期  TIM16_ARR[16:0]
	// 		得到一个1000-2000Hz的方波
	TIM16->ARR = 1000;
	// 5. 设置PWM方波的占空比   TIM16_CCR1[16:0]
	TIM16->CCR1 = 300;

	// 6. 设置TIM16_CH1通道为PWM1模式  
	// 		TIM16_CCMR1[16]  TIM16_CCMR1[6:4]  pwm模式1  = 0b0110
	TIM16->CCMR1 &= (~(0x1 << 16));
	TIM16->CCMR1 &= (~(0x7 << 4));
	TIM16->CCMR1 |= (0x6 << 4);
	TIM16->CCMR1 &= (~(0x3 << 0));

	// 7. 设置TIM16_CH1通道使能TIMx_CCR1预加载使能寄存器
	// 		TIM16_CCMR1[3] = 0x1
	TIM16->CCMR1 |= (0x1 << 3);
	// 8. 设置TIM16_CH1通道输出PWM方波的极性,
	// 	  TIM_CCER[3] = 0b0	TIM16_CCER[1] = 0x1 or 0x0
	TIM16->CCER &= (~(0x1 << 3));
	//TIM16->CCER |= (0x1 << 1);
	TIM16->CCER &= ~(0x1 << 1);
	// 9. 设置TIM16_CH1通道的输出使能位,输出PWM方波 
	// 		TIM4_CCER[0] = 0x1 
	TIM16->CCER |= (0x1 << 0);
	
	// 10. 设置TIM16_CH1通道的预装载寄存器的缓冲区的使能
	// 		TIM16_CR1[7] = 0x1 
	TIM16->CR1 |= (0x1 << 7);

	// 13. 使能TIM16_CH1计数器 
	// 		TIM16_CR1[0] = 0x1
	TIM16->CR1 |= (0x1 << 0);
}

void my_beep_tim4_init()
{
	//RCC
	RCC->MP_AHB4ENSETR |= (0x1 << 1);
	RCC->MP_APB1ENSETR |= (0x1 << 2);

	//GPIO
	GPIOB->MODER &= (~(0x3 << 12));
	GPIOB->MODER |= (0x1 << 13);
	GPIOB->AFRL &= (~(0xf <<24));
	GPIOB->AFRL |= (0x1 << 25);

	//TIM
	//TIM4_CR1
	TIM4->CR1 &= (~(0xf << 4));
	TIM4->CR1 |= (0x9 << 4);
	TIM4->CR1 |= 0x1;
	
	//TIM4_CCMR1
	TIM4->CCMR1 &= (~(0x1 << 16));
	TIM4->CCMR1 &= (~(0x7 << 4));
	TIM4->CCMR1 |= (0x3 << 3);
	TIM4->CCMR1 |= (0x1 << 3);
	TIM4->CCMR1 &= (~(0x3 << 0));
	
	//TIM4_CCER
	TIM4->CCER |= (0x1 << 3);
	TIM4->CCER &= (~(0x3 << 0));
	TIM4->CCER |= (0x1 << 0);
	
	//TIM4_PSC
	TIM4->PSC &= (~(0x0 << 15));
	TIM4->PSC |= 0xD0;
	
	//TIM4_ARR
	TIM4->ARR &= (~(0x0 << 31));
	TIM4->ARR |= 0x3E8;

	//TIM4_CCR1
	TIM4->CCR1 &=(~(0x0 << 31));
	TIM4->CCR1 |= 0x12C;
}

在主函数调用即可

6.效果

在这里插入图片描述


  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-10-08 20:58:04  更:2022-10-08 21:01:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 21:30:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码