cubemx stm32 pca9685pw模块 16路PWM 可用于舵机驱动 驱动代码

这篇具有很好参考价值的文章主要介绍了cubemx stm32 pca9685pw模块 16路PWM 可用于舵机驱动 驱动代码。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

资料

淘宝链接请点这里
淘宝资料资料:
链接:https://pan.baidu.com/s/1Kda-c7QdZdQ03FBMa0zeRA
提取码:1234

pca9685pw介绍

这个模块是 I2C 通信控制 16 路 PWM 的模块。
所有路的 频率 是统一设置的,所以每一路的频率都一样,但是每一路可以设置不同的占空比。

  1. PCA9685的分辨率是12位,即占空比控制时,0-4096对应的占空比为0-100,在控制舵机的时候,控制信号是0.5ms-2.5ms,周期 20ms,所以控制舵机角度不会有太高的分辨率,对舵机控制精度较高的地方不建议使用。
  2. PCA9685地址位和很多描述的不一样,根据芯片手册,地址位的寄存器一共 8 位,其中最高位固定是1,A0-A5这六位是用户可更改的,而其中最关键的一位是 R/W 位,这一位主要是决定了读还是写,置1时为读,置0时为写,所以我们在写程序的时候,PCA9685 的地址应把 R/W位加上,是 0x80,而不是 0x40,在写的时候,发送地址位是 0x80,在读的时候,发送的地址位是0x81。

cubemx stm32 pca9685pw模块 16路PWM 可用于舵机驱动 驱动代码

硬件

硬件连接

  • OE,低电平有效输出使能。
  • SDA,I2C 的 SDA 引脚。
  • SCL,I2C 的 SCL 引脚。
  • V+,接入 5V 电源,若是驱动的 16 路全是舵机,这个电源的电流就要求很大了(不晓得这个模块到底能不能承受这么多舵机的电流)。
  • VCC,单片机 3V3 电源。
  • GND,对于 V+ 的地平面。

原理图截屏如下:
cubemx stm32 pca9685pw模块 16路PWM 可用于舵机驱动 驱动代码

软件编写

pca9685pw.c

#include "pca9685pw.h"
#include <math.h>
#include <stdio.h>

#define min(_X_, _Y_)	(_X_>=_Y_?_Y_:_X_)

static uint8_t read16(uint8_t addr);
static void write16(uint8_t addr, uint8_t d);


// 设置为true可打印一些调试消息,设置为false可禁用这些消息。
#define ENABLE_DEBUG_OUTPUT false

// 初始化。频率,转动角度(0~360)
void pca9685_init(float hz, uint16_t angle)
{
	uint32_t off = 0;
	// 这一步很关键,如果没有这一步PCA9685就不会正常工作。
	pca9685_reset();
	
	write16(PCA9685_MODE1,0x00);
	pca9685_setPWMFreq(hz);
	off = (uint32_t)(102.4+angle*1.14);
	
	pca9685_setPWM(0,0,off);
	pca9685_setPWM(1,0,off);
	pca9685_setPWM(2,0,off);
	pca9685_setPWM(3,0,off);
	pca9685_setPWM(4,0,off);
	pca9685_setPWM(5,0,off);
	pca9685_setPWM(6,0,off);
	pca9685_setPWM(7,0,off);
	pca9685_setPWM(8,0,off);
	pca9685_setPWM(9,0,off);
	pca9685_setPWM(10,0,off);
	pca9685_setPWM(11,0,off);
	pca9685_setPWM(12,0,off);
	pca9685_setPWM(13,0,off);
	pca9685_setPWM(14,0,off);
	pca9685_setPWM(15,0,off);
	
	HAL_Delay(100);
}

// 软件复位
void pca9685_reset(void)
{
	write16(PCA9685_MODE1, 0x0);
}

// 设置PCA9685的输出频率,
// PCA9685的16路PWM输出频率是一致的,
// 所以是不能实现不同引脚不同频率的。
void pca9685_setPWMFreq(float freq)
{
	//printf("Attempting to set freq ");
	//printf(freq);
	// 输出周期实际是有误差的,对于20ms(50Hz)的周期来说这里乘个0.94为20ms
	// 可以用示波器观看调试
	freq *= 0.942;
	double prescaleval = 25000000;
	prescaleval /= 4096;
	prescaleval /= freq;
	prescaleval -= 1;

	if (ENABLE_DEBUG_OUTPUT)
	{
		printf("Estimated pre-scale: %f\r\n", prescaleval);
	}
	// floor()总是返回小于等于一个给定数字的最大整数。
	// 这里是四舍五入
	uint8_t prescale = floor(prescaleval + 0.5);
	
	if (ENABLE_DEBUG_OUTPUT)
	{
		printf("Final pre-scale: %d\r\n", prescale);
	}

	uint8_t oldmode = read16(PCA9685_MODE1);
	uint8_t newmode = (oldmode&0x7F) | 0x10; // sleep
	write16(PCA9685_MODE1, newmode); // go to sleep
	write16(PCA9685_PRESCALE, prescale); // set the prescaler
	write16(PCA9685_MODE1, oldmode);
	HAL_Delay(5);
	write16(PCA9685_MODE1, oldmode | 0xa1);  //  This sets the MODE1 register to turn on auto increment.
										  // This is why the beginTransmission below was not working.
	//  printf("Mode now 0x"); printf(read16(PCA9685_MODE1), HEX);
}

// 输出PWM占空比的调节。通常on都设为0,改变off即可。
// 因为PCA9685是12位分辨率,所以off的值0~4096就代表了占空比0-100.
void pca9685_setPWM(uint8_t num, uint16_t on, uint16_t off)
{
	//printf("Setting PWM "); printf(num); printf(": "); printf(on); printf("->"); printf(off);
	uint8_t d[4] = {(on&0xFF), (on>>8), (off&0xFF), (off>>8)};
	
	HAL_I2C_Mem_Write(&PCA9685_HI2C, PCA9685_IIC_ADDR_W, (LED0_ON_L+4*num), 1, d, 4, 0xff);
}

// num:序号;angle:角度
void setAngle(uint8_t num, uint16_t angle)
{
	// 补误差
//	angle /= 2;
	uint32_t off = 0;

	// off范围是:0~4096
	// 舵机占空比范围是:0.5~2.5ms
	// 所以设置off在 102.4~512范围内
	// x/(512-102.4) = 1/360
	// 所以每一度步进值为:1.137777 约等于 1.14
	off = (uint32_t)(102.4+angle*1.14);
	pca9685_setPWM(num, 0, off);
}

static uint8_t read16(uint8_t addr)
{
	uint8_t d;
	HAL_I2C_Mem_Read(&PCA9685_HI2C, PCA9685_IIC_ADDR_R, addr, 1, &d, 1, 0xff);
	return d;
}

static void write16(uint8_t addr, uint8_t d)
{
	HAL_I2C_Mem_Write(&PCA9685_HI2C, PCA9685_IIC_ADDR_W, addr, 1, &d, 1, 0xff);
}

pca9685pw.h

#ifndef _PCA9685_PW_H
#define _PCA9685_PW_H

#include "stdbool.h"
#include "main.h"
#include "i2c.h"

// I2C 句柄,用户自己修改
#define PCA9685_HI2C	hi2c1
// I2C 地址
#define PCA9685_IIC_ADDR_W	0x80
#define PCA9685_IIC_ADDR_R	0x81


// 寄存器地址
#define PCA9685_SUBADR1 0x2
#define PCA9685_SUBADR2 0x3
#define PCA9685_SUBADR3 0x4

#define PCA9685_MODE1 0x0
#define PCA9685_PRESCALE 0xFE

#define LED0_ON_L 0x6
#define LED0_ON_H 0x7
#define LED0_OFF_L 0x8
#define LED0_OFF_H 0x9

#define ALLLED_ON_L 0xFA
#define ALLLED_ON_H 0xFB
#define ALLLED_OFF_L 0xFC
#define ALLLED_OFF_H 0xFD



// 函数
void pca9685_reset(void);
void pca9685_setPWMFreq(float freq);
void pca9685_setPWM(uint8_t num, uint16_t on, uint16_t off);
void pca9685_setPin(uint8_t num, uint16_t val, bool invert);// =false


// 初始化。频率,转动角度(0~360)
void pca9685_init(float hz, uint16_t angle);
// num:序号;angle:角度(0~360)
void setAngle(uint8_t num,uint16_t angle);

#endif	/* _PCA9685_PW_H */

main

void main(void)
{
	uint16_t xxx = 0;
	// 初始50Hz,角度 180 度
	pca9685_init(50, 180);

	while(1)
	{
		// 设置 1 号口输出
		setAngle(1, xxx);
		xxx += 10;
		xxx>360?xxx=0:xxx;
		HAL_Delay(10);
	}
}

参考

PCA9685模块使用(Arduino和STM32)文章来源地址https://www.toymoban.com/news/detail-464096.html

到了这里,关于cubemx stm32 pca9685pw模块 16路PWM 可用于舵机驱动 驱动代码的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • ESP32(或ESP32CAM)使用PCA9685模块arduino,自定义I2C引脚

    文章目录 前言 一、PCA9685是什么? 二、使用步骤 1.引入库 2.接线 3.代码 4.讲解   舵机驱动板也可以生成PWM波控制LED等,但也仅仅只是一个驱动板,我们还需要一个控制板,ESP32是个不错的选择,ESP32CAM也是,但ESP32CAM没有引出I2C的引脚,需要自己去设置。  这个图是随便找的

    2024年02月12日
    浏览(43)
  • stm32 舵机 cubemx

    stm32对舵机进行控制,很简单直接一个pwm就可以实现 pwm的周期是50HZ占空比分别对应 一个0.5ms的高电平对应于0度 一个1.5ms的高电平对应于90度 一个2.5ms的高电平对应于180度 因此,您可以通过改变PWM信号的占空比来改变舵机的角度。占空比是PWM信号的高电平时间与PWM信号的总周

    2024年02月15日
    浏览(35)
  • STM32输出PWM波控制180°舵机

    时间记录:2024/2/8 (1)脉冲宽度调制 (2)占空比:高电平时间占整个周期时间的比例 (3)STM32通过定时器实现PWM时具有两种模式 PWM1模式:向上计数模式下,CNT当前计数寄存器的值小于CCR比较寄存器的值时输出有效电平,大于时输出无效电平,向下计数模式下,CNT当前计数

    2024年02月21日
    浏览(47)
  • 学习stm32 pwm 多路舵机的控制(PWM 的频率的理解)

    接着上一节,pwm 的使用,控制多路舵机进行角度旋转和设置。 参考stm32f103x中文说明时钟树如下图 1.当HSI被用于作为PLL时钟的输入时,系统时钟能得到的最大频率是64MHz。 2.对于内部和外部时钟源的特性,请参考相应产品数据手册中“电气特性”章节。 用户可通过多个预分

    2024年02月13日
    浏览(32)
  • STM32第七课:PWM控制SG90舵机

            学习完上一课的PWM控制LED小灯实现呼吸灯的效果,我们就可以进一步学习PWM控制舵机的效果了。PWM控制舵机相信会是一个更有意思的小实验的。          舵机是一种位置(角度)伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统。目前在高档

    2024年04月17日
    浏览(31)
  • stm32HAL库学习笔记----pwm驱动舵机

    目录 一、目标 二、准备 三、原理 四、cubemx 五、程序 实现stm32驱动舵机旋转0°,45°,90°,135°,180°等角度。 stm32f103(c8t6),舵机(SG90 9g),杜邦线 接线:舵机红线-----------5V(mcu)            舵机棕线-----------GND(mcu)            舵机黄线-----------PA1(视情况而定

    2023年04月26日
    浏览(36)
  • stm32——pwm驱动LED灯、舵机、直流电机

    改为PA15,选择重映射方式1或完全重映射 在时钟开启后写入 PWM频率=计数器更新频率 比如要产生一个频率为1KHz,占空比为50%,分辨率为1%的PWM波形 72M/(PSC+1)/ (ARR+1)=1000 CCR/(ARR+1)=0.5 1/(ARR+1)=0.01 计算得:ARR=99,CCR=50, PSC=720-1; 常用模式为 PWM1模式1 PWM.c PWM.h main.c 参数计算 PWM.c Servo.

    2024年02月04日
    浏览(41)
  • 12.[STM32]PWM脉宽调制-舵机控制(一篇足以)

    🍌 🍌🍌 作者简介:大家好啊,我叫DW,每天分享一些我新学到的知识,期待和大家一起进步 🍋 🍋🍋 系列专栏: STM32 🍎 🍎🍎 🍎🍎🍎 🌞小实验目标:控制舵机旋转🌞 🍊如有写得不好的地方欢迎大家指正🍊 创作时间:🍊🍊🍊2022年5月2日🍊🍊🍊 在机器人机电控

    2023年04月15日
    浏览(35)
  • 【STM32单片机】STM32控制SG90舵机的PWM部分参数的设置解答

    我们要知道,SG90舵机接收的PWM信号的参数:f=50Hz,T=1/f,所以周期为20ms。 当高电平的脉宽在0.5ms-2.5ms之间时舵机就可以对应旋转到不同的角度。 换句话说,我们要用单片机产生一个 周期(20ms) 的PWM波,然后获得对应这些时长(分别是 0.5ms 、 1ms 、 1.5ms 、 2ms 、 2.5ms )的 高电

    2024年02月13日
    浏览(52)
  • STM32CubeIDE学习笔记——使用HAL库PWM输出驱动舵机

    目录 PWM驱动简介 工程配置 代码编写 这里我采用的是STM32F103C8T6最小系统板,SG-90舵机实现功能。 舵机驱动角度和PWM占空比有关系,具体对应为50--0度  150--90度  250--180度,通过STM32的定时器功能输出PWM波来控制舵机进行转动。  时钟选择外部高速时钟 系统映射配置 时钟树设

    2024年02月13日
    浏览(38)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包