STM32F407 2个高级定时器生成2路无刷电机波形以及相电流采集程序(寄存器版)

stm32f407 高级定时1、定时8 生成20k 中心PWM 波形 并分别用其通道4 触发ADC1 ADC2 采样 用于分别两无刷电机foc 电流环控制,ADC1产生50us的电流采集完成中断,用于foc算法周期运算

主要参考高级定时器的寄存器和ADC寄存器

首先,要使用STM32F407的高级定时器1和定时器8生成20kHz的中心PWM波形,你需要进行以下步骤:

  1. 配置时钟:使能GPIO和相应的定时器时钟。

  2. 配置GPIO:选择用于输出PWM的引脚,并将这些引脚配置为复用功能。

  3. 配置定时器:对定时器1和定时器8进行相应的配置,使其能够生成PWM信号。

    • 配置定时器的基本参数:将定时器的模式设置为PWM模式。
    • 配置定时器的时钟分频器。
    • 配置定时器的周期值,并设置PWM信号的占空比。
  4. 配置ADC:使能ADC1和ADC2的时钟,并对它们进行相应的配置。

    • 配置ADC的时钟分频器。
    • 配置ADC的模式:选择连续模式,使得它们能够不间断地进行采样。
    • 配置ADC的触发源:选择定时器的通道4作为触发源。
  5. 配置ADC中断:使能ADC1的转换完成中断,并编写中断处理函数。在中断处理函数中进行foc算法的周期运算。

  6. 启动定时器和ADC

#include <string.h>
#include <MCU_HAL.h>      //for downlayer interface include the CHAL port
#include "CHAL_Config.h"  //#define TIM_1_8_CLOCK_HZ 168000000
// #define TIM_1_8_PERIOD_CLOCKS 3500 //24k
#define TIM_1_8_PERIOD_CLOCKS 4199  // 20k
#define TIM_1_8_DEADTIME_CLOCKS 20
#define TIM_APB1_CLOCK_HZ 84000000
#define TIM_APB1_PERIOD_CLOCKS 4096
#define TIM_APB1_DEADTIME_CLOCKS 40
#define TIM_1_8_RCR 2static void MX_ADC1_Init(void);
static void MX_ADC2_Init(void);void CHAL_Pwm1Init(char *HIVersion, uint32_t runFreq, uint32_t deadTime, uint32_t sampHalfTime)
{uint32_t pwmTiks = CPUFREQ / 2 / runFreq;uint8_t deadTiks = deadTime / CPURATE;// 使能TIM1时钟RCC->APB2ENR |= 1 << 0;// 配置TIM1基本设置TIM1->CR1 = 0;TIM1->CR1 |= (1 << 5);  // 中心对齐模式 1 递减时产生TIM1->CR1 |= (1 << 0);  // 使能计数器// TIM1->CR1 |= TIM_CR1_ARPE; // 自动重载预装载使能// TIM1->CR1 |= TIM_CR1_CKD_0; // 时钟分频因子 = /1// 设置预分频器和周期TIM1->PSC = 0;        // 预分频器 = 0TIM1->ARR = pwmTiks;  // 周期// 重复计数器设置(如适用)TIM1->RCR = TIM_1_8_RCR;// 配置时钟源TIM1->CR2 = 0;// TIM1->CR2 |= TIM_CR2_MMS_1; // 主模式选择:更新事件产生TRGOTIM1->CCMR1 = 0;TIM1->CCMR1 |= 7 << 4;   // PWM模式TIM1->CCMR1 |= 1 << 3;   // 输出比较预装载使能TIM1->CCMR1 |= 7 << 12;  // PWM模式TIM1->CCMR1 |= 1 << 11;  // 输出比较预装载使能8 重复计数器8 重复计数器寄存器 (TIMx_RCR)寄存器 (TIMx_RCR)TIM1->CCMR2 = 0;TIM1->CCMR1 = 0;TIM1->CCMR2 |= 7 << 4;   // PWM模式TIM1->CCMR2 |= 1 << 3;   // 输出比较预装载使能TIM1->CCMR2 |= 7 << 12;  // PWM模式TIM1->CCMR2 |= 1 << 11;  // 输出比较预装载使能// 设置初始脉冲值(通道1、2、3)TIM1->CCR1 = 0;TIM1->CCR2 = 0;TIM1->CCR3 = 0;TIM1->CCR4 = 1;// 设置极性(通道1、2、3)TIM1->CCER = 0;/* 0       1     2      3 *//* CCE=1 CCP=0 CCNE=1 CCPN=0   *//* 0x5 */TIM1->CCER |= 5 << 0;   // 通道1TIM1->CCER |= 5 << 4;   // 通道2TIM1->CCER |= 5 << 8;   // 通道3TIM1->CCER |= 1 << 12;  // 通道4 极性高// 断开与死区时间配置TIM1->BDTR = deadTiks;  // 最大不超过255 tickTIM1->BDTR |= 1 << 15;  // 输出使能/* gpio 初始化 */RCC->AHB1ENR |= 1 << 0;  // 使能PORTA口时钟RCC->AHB1ENR |= 1 << 1;  // 使能PORTB口时钟GPIO_Set(GPIOA, PIN8 | PIN9 | PIN10, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_SPEED_50M,GPIO_PUPD_PD);     // PA9,PA10,复用功能,上拉输出GPIO_AF_Set(GPIOA, 8, 1);   // PA8,AF1GPIO_AF_Set(GPIOA, 9, 1);   // PA8,AF1GPIO_AF_Set(GPIOA, 10, 1);  // PA8,AF1GPIO_Set(GPIOB, PIN13 | PIN14 | PIN15, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_SPEED_50M,GPIO_PUPD_PD);     // PA9,PA10,复用功能,上拉输出GPIO_AF_Set(GPIOB, 13, 1);  // PA8,AF1GPIO_AF_Set(GPIOB, 14, 1);  // PA8,AF1GPIO_AF_Set(GPIOB, 15, 1);  // PA8,AF1MX_ADC1_Init();
}void CHAL_M1_DisPwm123(void) { TIM1->CCER = 0x1000; }void CHAL_M1_EnaPwm123(void) { TIM1->CCER = 0x1555; }void CHAL_Pwm2Init(char *HIVersion, uint32_t runFreq, uint32_t deadTime, uint32_t sampHalfTime)
{uint32_t pwmTiks = CPUFREQ / 2 / runFreq;uint8_t deadTiks = deadTime / CPURATE;// 使能TIM2时钟RCC->APB2ENR |= 1 << 1;// 配置TIM2基本设置TIM8->CR1 = 0;TIM8->CR1 |= (1 << 5);  // 中心对齐模式 1 递减时产生TIM8->CR1 |= (1 << 0);  // 使能计数器// TIM8->CR1 |= TIM_CR1_ARPE; // 自动重载预装载使能// TIM8->CR1 |= TIM_CR1_CKD_0; // 时钟分频因子 = /1// 设置预分频器和周期TIM8->PSC = 0;        // 预分频器 = 0TIM8->ARR = pwmTiks;  // 周期// 重复计数器设置(如适用)TIM8->RCR = TIM_1_8_RCR;// 配置时钟源TIM8->CR2 = 0;// TIM8->CR2 |= TIM_CR2_MMS_1; // 主模式选择:更新事件产生TRGO// PWM模式配置(通道1、2、3)TIM8->CCMR1 = 0;TIM8->CCMR1 |= 7 << 4;   // PWM模式TIM8->CCMR1 |= 1 << 3;   // 输出比较预装载使能TIM8->CCMR1 |= 7 << 12;  // PWM模式TIM8->CCMR1 |= 1 << 11;  // 输出比较预装载使能TIM8->CCMR2 = 0;TIM8->CCMR2 |= 7 << 4;   // PWM模式TIM8->CCMR2 |= 1 << 3;   // 输出比较预装载使能TIM8->CCMR2 |= 7 << 12;  // PWM模式TIM8->CCMR2 |= 1 << 11;  // 输出比较预装载使能// 设置初始脉冲值(通道1、2、3)TIM8->CCR1 = 0;TIM8->CCR2 = 0;TIM8->CCR3 = 0;TIM8->CCR4 = 1;// 设置极性(通道1、2、3)TIM8->CCER = 0;/* 0       1     2      3 *//* CCE=1 CCP=0 CCNE=1 CCPN=0   *//* 0x5 */TIM8->CCER |= 5 << 0;   // 通道1TIM8->CCER |= 5 << 4;   // 通道2TIM8->CCER |= 5 << 8;   // 通道3TIM8->CCER |= 1 << 12;  // 通道4 极性高// 断开与死区时间配置TIM8->BDTR = deadTiks;  // 最大不超过255 tickTIM8->BDTR |= 1 << 15;  // 输出使能/* gpio 初始化 */RCC->AHB1ENR |= 1 << 0;  // 使能PORTA口时钟RCC->AHB1ENR |= 1 << 1;  // 使能PORTB口时钟RCC->AHB1ENR |= 1 << 2;  // 使能PORTc口时钟GPIO_Set(GPIOA, PIN7, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_SPEED_50M,GPIO_PUPD_PD);    // PA9,PA10,复用功能,上拉输出GPIO_AF_Set(GPIOA, 7, 3);  // PA8,AF3GPIO_Set(GPIOB, PIN0 | PIN1 | PIN15, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_SPEED_50M,GPIO_PUPD_PD);    // PA9,PA10,复用功能,上拉输出GPIO_AF_Set(GPIOB, 0, 3);  // PA8,AF1GPIO_AF_Set(GPIOB, 1, 3);  // PA8,AF1GPIO_Set(GPIOC, PIN6 | PIN7 | PIN8, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_SPEED_50M,GPIO_PUPD_PD);    // PA9,PA10,复用功能,上拉输出GPIO_AF_Set(GPIOC, 6, 3);  // PA8,AF1GPIO_AF_Set(GPIOC, 7, 3);  // PA8,AF1GPIO_AF_Set(GPIOC, 8, 3);  // PA8,AF1MX_ADC2_Init();
}void CHAL_M2_DisPwm123(void) { TIM8->CCER = 0x1000; }void CHAL_M2_EnaPwm123(void) { TIM8->CCER = 0x1555; }/*** @brief ADC1 初始化函数* @param 无* @retval 无*/
static void MX_ADC1_Init(void)
{// 使能ADC1时钟RCC->APB2ENR |= 1 << 8;// ADC1->CR1 = 0x180;ADC1->CR1 |= 1 << 8;  // 使能扫描模式ADC1->CR1 |= 1 << 7;  // 注入通道中断完成中断使能ADC1->CR2 = 0;ADC1->CR2 |= 1 << 10;    // ADC 使能ADC1->CR2 |= 2 << 20;    // 下降沿触发 注入通道检测ADC1->CR2 |= 0 << 16;  // 注入通道 TIM1 CC4 事件ADC1->CR2 |= 1 << 0;     // ADC 使能ADC1->HTR = 0x0FFF;// ADC1->CR2 = 0x0200401;ADC1->HTR = 0x0FFF;ADC1->JSQR = 0;ADC1->JSQR |= 1 << 20;     // 注入通道序列长度:2ADC1->JSQR |= (10 << 10);  // 注入通道3   对应 adc 通道ADC1->JSQR |= (11 << 15);  // 注入通道4ADC1->SMPR1 = 0;ADC1->SMPR1 |= 0 << 0;  // 注入通道8采样时间: 3个周期ADC1->SMPR1 |= 0 << 3;  // 注入通道12采样时间:3个周期RCC->AHB1ENR |= 1 << 2;  // 使能PORTC口时钟GPIO_Set(GPIOC, PIN0 | PIN1, GPIO_MODE_AIN, 0, 0, GPIO_PUPD_PU);  //// // 启动ADC1MY_NVIC_Init(0, 0, ADC_IRQn, 0);  // 抢占1,子优先级3,组2
}/*** @brief ADC2 初始化函数* @param 无* @retval 无*/
static void MX_ADC2_Init(void)
{// 使能ADC2时钟RCC->APB2ENR |= 1 << 9;// ADC2->CR1 = 0x180;ADC2->CR1 = 0;ADC2->CR1 |= 1 << 8;  // 使能扫描模式ADC2->CR2 = 0;ADC2->CR2 |= 1 << 10;    // ADC 使能ADC2->CR2 |= 2 << 20;    // 下降沿触发 注入通道检测ADC2->CR2 |= 0xe << 16;  // 注入通道 TIM8 CC4 事件ADC2->CR2 |= 1 << 0;     // ADC 使能ADC2->HTR = 0x0FFF;//    // // 配置注入通道(通道8、12、6、13)ADC2->JSQR = 0;ADC2->JSQR |= 1 << 20;     // 注入通道序列长度:2ADC2->JSQR |= (12 << 10);  // 注入通道3ADC2->JSQR |= (13 << 15);  // 注入通道4ADC2->SMPR1 = 0;ADC2->SMPR1 |= 0 << 0;  // 注入通道8采样时间: 3个周期ADC2->SMPR1 |= 0 << 3;  // 注入通道12采样时间:3个周期RCC->AHB1ENR |= 1 << 2;  // 使能PORTC口时钟GPIO_Set(GPIOC, PIN2 | PIN3, GPIO_MODE_AIN, 0, 0, GPIO_PUPD_PU);  //
}

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

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

相关文章

代码复现|Demucs Music Source Separation

一、背景介绍 Demucs是一个开源的音源分离项目。 Demucs在算法层面前后经历了三次大版本的进化&#xff0c;最原始的V1版本是&#xff1a;编解码LSTM。具体算法原理图如下所示。该版本在时域进行音源分离。关于阅读笔记请点击这篇文章。 V1版本原理图 V2版本是同时使用时域和频…

2、快速搭建Vue框架以及项目工程

本篇文章详细讲解在配置完vue2环境后如何快速搭建一个Vue框架和项目工程。&#xff08;以智慧农业云平台为例&#xff09; 2.1 Vue工程创建 2.1.1创建想要存放的Vue文件夹 找到想要存放的文件夹并在目录搜索框中&#xff0c;并用管理员的方式打开。 2.1.2创建Vue工程 2、安装…

prompt工程策略(一:使用 CO-STAR 框架来搭建 prompt 的结构)

原文&#xff1a;我是如何赢得GPT-4提示工程大赛冠军的 原文的原文&#xff1a; How I Won Singapore’s GPT-4 Prompt Engineering Competition 为了让 LLM 给出最优响应&#xff0c;为 prompt 设置有效的结构至关重要。CO-STAR 框架是一种可以方便用于设计 prompt 结构的模板…

2024最新Kali Linux安装教程(非常详细)从零基础入门到精通(附安装包)!

什么是Kali Linux&#xff1f; Kali Linux是一个高级渗透测试和安全审计Linux发行版&#xff0c;其功能非常强大&#xff0c;能够进行信息取证、渗透测试、攻击WPA / WPA2保护的无线网络、离线破解哈希密码、将android、Java、C编写的程序反编译成代码等等&#xff0c;是黑客的…

Invalid bound statement (not found) 六种解决方法

前五种参考博文&#xff1a; Invalid bound statement (not found) 五种解决方法-CSDN博客 第六种&#xff1a; 在启动类上加上MapperScan&#xff0c;指定扫描包

【C++】list原理讲解及其实现

目录 一、认识list底层结构 二、list的构造类函数 三、迭代器 四、数据的访问 五、容量相关的函数 六、关于数据的增删查改操作 七、list和vector的比较 前言 要模拟实现list&#xff0c;必须要熟悉list的底层结构以及其接口的含义&#xff0c;在上一篇我们仔细讲解了list的…

Gradio 案例——将 dicom 文件转为 nii文件

文章目录 Gradio 案例——将 dicom 文件转为 nii文件界面截图依赖安装项目目录结构代码 Gradio 案例——将 dicom 文件转为 nii文件 利用 SimpleITK 库&#xff0c;将 dicom 文件转为 nii文件更完整、丰富的示例项目见 GitHub - AlionSSS/dcm2niix-webui: The web UI for dcm2…

JavaScript精粹(一)- 基础入门

JavaScript&#xff08;简称为JS&#xff09;是一种广泛应用于网页开发的脚本语言&#xff0c;具有以下几个主要作用&#xff1a; 网页交互&#xff1a;JavaScript 可以用于创建动态的网页效果&#xff0c;例如响应用户的操作&#xff0c;实现页面内容的动态更新&#xff0c;以…

【Java基础】集合(2) —— List

List 存储的对象是有序的&#xff08;集合中存储对象的顺序和使用add方法添加对象的顺序一致&#xff09;&#xff0c;存储的对象是可重复的。 List的特有的功能: 都是可以操作索引的功能。 增: void add(int index, E element )boolean addAll(int index, Collection<? …

mysql的explain

explain可以用于select&#xff0c;delete&#xff0c;insert&#xff0c;update的statement。 当explain用于statement时&#xff0c;mysql将会给出其优化器&#xff08;optimizer&#xff09;的执行计划。 通过explain字段生成执行计划表。下面来解析这个执行计划表的每一列…

提升用户体验:Xinstall免邀请码功能详解

在移动互联网时代&#xff0c;App的推广和运营显得尤为重要。然而&#xff0c;传统的App推广方式往往需要用户填写繁琐的邀请码&#xff0c;这不仅降低了用户体验&#xff0c;还影响了推广效果。幸运的是&#xff0c;Xinstall作为国内专业的App全渠道统计服务商&#xff0c;推出…

汽车电子都应用哪些频点的贴片晶振

晶振通过与其它元器件的连接使用&#xff0c;产生脉冲起到信号源的作用&#xff0c;所以在电子圈中有一个很形象的比喻: 如果把芯片比如电路的控制大脑&#xff0c;那晶振产生的信号就是给大脑持续供需的血液。平时&#xff0c;在我们使用的手机&#xff0c;蓝牙耳机&#xff0…

没有疯狂内卷的日本智能机市场,小屏与设计仍旧是主流

如果聊起国内的智能机市场&#xff0c;我想大多数人的印象就是疯狂内卷。卷影像、卷屏幕、卷快充、卷性能……客观地说&#xff0c;国内的3C产品还是很有质价比的。不过在没有如此内卷的日本市场&#xff0c;各种小屏手机仍旧是主流。 除了苹果外&#xff0c;日本本土品牌的夏普…

python中内置函数简要介绍

pyton3.11版本中常用的内置函数&#xff0c;不需要导入&#xff0c;可直接使用。这些函数大多数都是比较常用的&#xff0c;很多在之前的文章都有介绍过。 大家也可直接到官网查看学习 https://docs.python.org/zh-cn/3.11/library/functions.html。 内置函数 abs() min() …

高质量新闻数据集OpenNewsArchive:880万篇主流新闻报道,国产大模型开源数据又添猛料

在构建国产大语言模型的道路上&#xff0c;高质量新闻是不可或缺的重要语料之一。这类语料集准确性、逻辑性、时效性于一体&#xff0c;同时包含丰富的事实知识&#xff0c;可以大幅提升模型的文本生成质量、词汇表达能力、事件理解分析能力以及时序内容的适应性和预测能力&…

《Python编程从入门到实践》day29

# 昨日知识点回顾 修改折线图文字和线条粗细 矫正图形 使用内置格式 # 今日知识点学习 15.2.4 使用scatter()绘制散点图并设置样式 import matplotlib.pyplot as plt import matplotlib matplotlib.use(TkAgg)plt.style.use(seaborn-v0_8) # 使用内置格式 fig, ax plt.subpl…

LeetCode494:目标和

题目描述 给你一个非负整数数组 nums 和一个整数 target 。 向数组中的每个整数前添加 ‘’ 或 ‘-’ &#xff0c;然后串联起所有整数&#xff0c;可以构造一个 表达式 &#xff1a; 例如&#xff0c;nums [2, 1] &#xff0c;可以在 2 之前添加 ‘’ &#xff0c;在 1 之…

力扣刷题 day2

快乐数 202. 快乐数 - 力扣&#xff08;LeetCode&#xff09;   图: java // 快乐数 --> 19 > 1^2 9 ^2 82 > 82 > 8 ^ 2 2 ^ 2 ......public boolean isHappy(int n) {// 使用快慢指针int slow n, fast getSum(n);while (slow ! fast) {slow getSum(slo…

【计算机毕业设计】springboot二手家电管理平台

时代在飞速进步&#xff0c;每个行业都在努力发展现在先进技术&#xff0c;通过这些先进的技术来提高自己的水平和优势&#xff0c;二手家电管理平台当然不能排除在外。二手家电管理平台是在实际应用和 软件工程的开发原理之上&#xff0c;运用java语言以及前台VUE框架&#xf…

基于SSM的婚恋网站的设计与实现(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的婚恋网站的设计与实现&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spri…