STM32、GD32驱动PCA9685控制舵机源码分享

一、PCA9685介绍

PCA9685是一种16通道PWM(脉宽调制)控制器芯片,由NXP Semiconductors公司生产。它具有高速I2C总线接口,可以通过I2C总线与微控制器或其他设备进行通信。PCA9685广泛应用于各种需要精确控制多路PWM信号的应用,如LED灯控制、舵机控制、电机控制等。

PCA9685芯片具有以下主要特点:

  1. 16个独立的PWM输出通道,每个通道可以独立设置频率和占空比。
  2. 可以设置PWM输出频率的范围从24Hz到1526Hz。
  3. 可以通过I2C接口进行配置和控制,使得系统设计更加简单。
  4. 支持输出使能和禁用功能,方便对PWM信号进行控制。
  5. 高精度的PWM输出,可以实现精确的电平控制。
  6. 内部集成了晶振,无需外部元件。

PCA9685芯片的工作原理是通过调整PWM的占空比来控制输出信号的电平。用户可以设置PWM输出频率和占空比,通过改变占空比来改变输出信号的电平。此外,PCA9685还具有外部触发功能,可以通过外部触发引脚来触发特定的操作或事件。

总之,PCA9685是一款功能丰富且易于使用的PWM控制器芯片,适用于各种需要精确控制多路PWM信号的应用。它的高精度、高可靠性和简单的接口使其成为许多电子设备和机器人应用的理想选择。

二、PCA9685原理图

在这里插入图片描述

三、源码

iic.h

#ifndef _MYIIC_H
#define _MYIIC_H
#include "sys.h"//IO方向设置
#define SDA_IN()  {GPIOG->MODER&=~(3<<(13*2));GPIOG->MODER|=0<<13*2;}	//PH5输入模式
#define SDA_OUT() {GPIOG->MODER&=~(3<<(13*2));GPIOG->MODER|=1<<13*2;}  //PH5输出模式
//IO操作
#define IIC_SCL(n)  (n?HAL_GPIO_WritePin(GPIOG,GPIO_PIN_14,GPIO_PIN_SET):HAL_GPIO_WritePin(GPIOG,GPIO_PIN_14,GPIO_PIN_RESET)) //SCL
#define IIC_SDA(n)  (n?HAL_GPIO_WritePin(GPIOG,GPIO_PIN_13,GPIO_PIN_SET):HAL_GPIO_WritePin(GPIOG,GPIO_PIN_13,GPIO_PIN_RESET)) //SDA
#define READ_SDA    HAL_GPIO_ReadPin(GPIOG,GPIO_PIN_13)  //输入SDA//IIC所有操作函数
void IIC_Init(void);                //初始化IIC的IO口				 
void IIC_Start(void);				//发送IIC开始信号
void IIC_Stop(void);	  			//发送IIC停止信号
void IIC_Send_Byte(u8 txd);			//IIC发送一个字节
u8 IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
u8 IIC_Wait_Ack(void); 				//IIC等待ACK信号
void IIC_Ack(void);					//IIC发送ACK信号
void IIC_NAck(void);				//IIC不发送ACK信号void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
u8 IIC_Read_One_Byte(u8 daddr,u8 addr);	 
#endif

iic.c

#include "myiic.h"
#include "delay.h"//IIC初始化
void IIC_Init(void)
{GPIO_InitTypeDef GPIO_Initure;__HAL_RCC_GPIOG_CLK_ENABLE();   //使能GPIOH时钟//PH4,5初始化设置GPIO_Initure.Pin=GPIO_PIN_14|GPIO_PIN_13;GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  //推挽输出GPIO_Initure.Pull=GPIO_PULLUP;          //上拉GPIO_Initure.Speed=GPIO_SPEED_FREQ_VERY_HIGH;    //快速HAL_GPIO_Init(GPIOG,&GPIO_Initure);IIC_SDA(1);IIC_SCL(1);  
}//产生IIC起始信号
void IIC_Start(void)
{SDA_OUT();     //sda线输出IIC_SDA(1);	  	  IIC_SCL(1);delay_us(4);IIC_SDA(0);//START:when CLK is high,DATA change form high to low delay_us(4);IIC_SCL(0);//钳住I2C总线,准备发送或接收数据 
}	  
//产生IIC停止信号
void IIC_Stop(void)
{SDA_OUT();//sda线输出IIC_SCL(0);IIC_SDA(0);//STOP:when CLK is high DATA change form low to highdelay_us(4);IIC_SCL(1); IIC_SDA(1);//发送I2C总线结束信号delay_us(4);							   	
}
//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
u8 IIC_Wait_Ack(void)
{u8 ucErrTime=0;SDA_IN();      //SDA设置为输入  IIC_SDA(1);delay_us(1);	   IIC_SCL(1);delay_us(1);	 while(READ_SDA){ucErrTime++;if(ucErrTime>250){IIC_Stop();return 1;}}IIC_SCL(0);//时钟输出0 	   return 0;  
} 
//产生ACK应答
void IIC_Ack(void)
{IIC_SCL(0);SDA_OUT();IIC_SDA(0);delay_us(2);IIC_SCL(1);delay_us(2);IIC_SCL(0);
}
//不产生ACK应答		    
void IIC_NAck(void)
{IIC_SCL(0);SDA_OUT();IIC_SDA(1);delay_us(2);IIC_SCL(1);delay_us(2);IIC_SCL(0);
}					 				     
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答			  
void IIC_Send_Byte(u8 txd)
{                        u8 t;   SDA_OUT(); 	    IIC_SCL(0);//拉低时钟开始数据传输for(t=0;t<8;t++){              IIC_SDA((txd&0x80)>>7);txd<<=1; 	  delay_us(2);   //对TEA5767这三个延时都是必须的IIC_SCL(1);delay_us(2); IIC_SCL(0);	delay_us(2);}	 
} 	    
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
u8 IIC_Read_Byte(unsigned char ack)
{unsigned char i,receive=0;SDA_IN();//SDA设置为输入for(i=0;i<8;i++ ){IIC_SCL(0); delay_us(2);IIC_SCL(1);receive<<=1;if(READ_SDA)receive++;   delay_us(1); }					 if (!ack)IIC_NAck();//发送nACKelseIIC_Ack(); //发送ACK   return receive;
}

pca9685.h

#ifndef __NCA9555_H
#define __NCA9555_H
#include "sys.h"
#include "myiic.h"#define PCA9685_MODE1 0x00
#define PCA9685_PRESCALE 0xFE
#define LED0_ON_L 0x06
#define LED0_ON_H 0x07
#define LED0_OFF_L 0x08
#define LED0_OFF_H 0x09void pca9685_init(u8 slaveAddr,float hz,uint8_t angle);
void pca9685_set_servo_angle(u8 slaveAddr,uint8_t num,uint8_t angle);#endif

pca9685.c

#include "pca9685.h"
#include "delay.h"
#include "math.h"void pca9685_write(u8 slaveAddr,u8 adrr,u8 data)//向PCA写数据,adrrd地址,data数据
{ IIC_Start();IIC_Send_Byte(slaveAddr);IIC_Wait_Ack();IIC_Send_Byte(adrr);IIC_Wait_Ack();IIC_Send_Byte(data);IIC_Wait_Ack();IIC_Stop();
}u8 pca9685_read(u8 slaveAddr,u8 adrr)//从PCA读数据
{u8 data;IIC_Start();IIC_Send_Byte(slaveAddr);IIC_Wait_Ack();IIC_Send_Byte(adrr);IIC_Wait_Ack();IIC_Start();IIC_Send_Byte(slaveAddr|0x01);IIC_Wait_Ack();data=IIC_Read_Byte(0);IIC_Stop();return data;
}
void pca9685_set_freq(u8 slaveAddr,float freq)//设置PWM频率
{uint8_t prescale,oldmode,newmode;double prescaleval;freq *= 0.83f; 			//实际使用过程中存在偏差需要×矫正系数=0.83prescaleval = 25000000;prescaleval /= 4096;prescaleval /= freq;prescaleval -= 1;prescale =floor(prescaleval + 0.5f);			//floor向下取整函数oldmode = pca9685_read(slaveAddr,PCA9685_MODE1);newmode = (oldmode&0x7F) | 0x10; // sleep睡眠pca9685_write(slaveAddr,PCA9685_MODE1, newmode); // go to sleep(需要进入随眠状态才能设置频率)pca9685_write(slaveAddr,PCA9685_PRESCALE, prescale); // 设置预分频系数pca9685_write(slaveAddr,PCA9685_MODE1, oldmode);HAL_Delay(2);pca9685_write(slaveAddr,PCA9685_MODE1, oldmode | 0xA1); 
}/*num:舵机PWM输出引脚0~15,on:PWM上升计数值0~4096,off:PWM下降计数值0~4096*/
void pca9685_set_duty(u8 slaveAddr,uint8_t num, uint32_t on, uint32_t off)
{pca9685_write(slaveAddr,LED0_ON_L+4*num,on);pca9685_write(slaveAddr,LED0_ON_H+4*num,on>>8);pca9685_write(slaveAddr,LED0_OFF_L+4*num,off);pca9685_write(slaveAddr,LED0_OFF_H+4*num,off>>8);
}
/*函数作用:初始化舵机驱动板参数:1.PWM频率2.初始化舵机角度*/
void pca9685_init(u8 slaveAddr,float hz,uint8_t angle)
{uint32_t off=0;pca9685_write(slaveAddr,PCA9685_MODE1,0x0);pca9685_set_freq(slaveAddr,hz);//设置PWM频率off=(uint32_t)(145+angle*2.4);pca9685_set_duty(slaveAddr,0,0,off);pca9685_set_duty(slaveAddr,1,0,off);pca9685_set_duty(slaveAddr,2,0,off);pca9685_set_duty(slaveAddr,3,0,off);pca9685_set_duty(slaveAddr,4,0,off);pca9685_set_duty(slaveAddr,5,0,off);pca9685_set_duty(slaveAddr,6,0,off);pca9685_set_duty(slaveAddr,7,0,off);pca9685_set_duty(slaveAddr,8,0,off);pca9685_set_duty(slaveAddr,9,0,off);pca9685_set_duty(slaveAddr,10,0,off);pca9685_set_duty(slaveAddr,11,0,off);pca9685_set_duty(slaveAddr,12,0,off);pca9685_set_duty(slaveAddr,13,0,off);pca9685_set_duty(slaveAddr,14,0,off);pca9685_set_duty(slaveAddr,15,0,off);}
/*函数作用:控制舵机转动;参数:1.输出端口,可选0~15; 2.结束角度,可选0~180;*/
void pca9685_set_servo_angle(u8 slaveAddr,uint8_t num,uint8_t angle)
{uint32_t off=0;	off=(uint32_t)(158+angle*2.2);pca9685_set_duty(slaveAddr,num,0,off);
}

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

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

相关文章

npm install 卡在reify:rxjs: timing reifyNode的解决办法

今天要逆向跑一个electron&#xff0c;但是npm install一直卡在 reify:element-plus: timing reifyNode:node_modules/lodash Completed in 6664ms这里一动不动&#xff0c;一番研究之后发现可能跟用的镜像有关系&#xff0c;我原本是官方镜像&#xff0c;总感觉第三方镜像有一…

伪装目标检测论文阅读之Dual-SAM(CVPR-2024)

论文&#xff1a;link code&#xff1a;code Fantastic Animals and Where to Find Them:Segment Any Marine Animal with Dual SAM 摘要 作为水下智能的重要支柱&#xff0c;海洋动物分割(MAS)涉及对海洋环境中的动物进行分割。以往的方法在提取长范围上下文特征方面表现不佳…

Python | Leetcode Python题解之第77题组合

题目&#xff1a; 题解&#xff1a; class Solution:def combine(self, n: int, k: int) -> List[List[int]]:ans []path []def dfs(x):remain k - len(path)if not remain:ans.append(list(path))returnif n 1 - x > remain:dfs(x 1)path.append(x)dfs(x 1)path.…

宁夏编程培训中心联络及介绍

版权宁夏编程培训中心 宁夏编程培训中心介绍 AI DuLuo&#xff1a;您好&#x1f91d; 欢迎咨询宁夏编程培训中心&#xff0c;创始人账号 公司介绍及创始人介绍&#xff1a; 在职某地区阿里云计算机有限公司 国内&#xff0c;南非发明专利各一项&#xff0c;腾讯云阿里云专家&am…

vue视图不刷新强制更新数据this.$forceUpdate()

在vue中&#xff0c;更新视图数据&#xff0c;不刷新页面&#xff0c;需要强制更新数据才可以 前言 在对数据就行添加和删除时&#xff0c;发现页面视图不更新&#xff0c;排除发现需要强制更新才可以 点击添加或删除&#xff0c;新增数据和删除就行&#xff0c;但在不使用fo…

内容安全(AV)

防病毒网关&#xff08;AV&#xff09;简介 基于网络侧 识别 病毒文件&#xff0c;工作范围2~7层。这里的网关指的是内网和外网之间的一个关口&#xff0c;在此进行病毒的查杀。在深信服中就有一个EDR设备&#xff0c;该设备就是有两种部署&#xff0c;一个部署在网关&#xf…

51单片机keil编程中遇到的问题(持续更新)

字符无法打印报错 查看特殊功能寄存器名字的时候也会报错&#xff0c;因为无法编译通过&#xff0c;导致头文件的定义内容无法查找 keil编译中 error C127: ‘xx’: invalid storage class 这种一般是在编写头文件或源文件时&#xff0c;在声明函数的结尾没有添加分号&…

在阿里云K8S容器中,部署websocket应用程序的总结

一、背景 有一个websocket应用程序&#xff0c;使用spring boot框架开发&#xff0c;http端口号是6005&#xff0c;提供的是websocket服务&#xff0c;所以它还监听一个8889端口的tcp协议。 现在要把它部署到阿里云的k8s容器里&#xff0c;本文着重描述service层的配置。 因…

《intel开发手册卷1》学习笔记1

1、操作模式 IA-32架构支持三种基本操作模式:保护模式、实地址模式和系统管理模式。操作模式决定了哪些指令和体系结构功能是可访问的: 1&#xff09;保护模式&#xff1a;该模式是处理器的自然状态。保护模式的功能之一是能够在受保护的多任务环境中直接执行“实地址模式”80…

Mac 电脑安装 Raptor 流程图软件的方法

0. 安装逻辑 &#xff08;1&#xff09;运行 raptor&#xff0c;本质上需要 mac 能够运行 windows 程序&#xff0c;因此需要安装 .NET Runtime 7.0&#xff0c;这是微软程序运行必须的文件。 &#xff08;2&#xff09;运行 raptor 还需要安装依赖文件 mono-libgdiplus。 &am…

RabbitMQ - 以 MQ 为例,手写一个 RPC 框架 demo

目录 前言 一、再谈自定义应用层协议 二、再谈 BrokerServer 三、再谈 Connection、Channel 四、Demo a&#xff09;启动服务器 b&#xff09;客户端连接 前言 本篇文章来自于笔者之前写过的一个系列 —— “根据源码&#xff0c;模拟实现 RabbitMQ” 系列&#xff0c…

CentOs9编译C指令报错的一种解决方案

今天使用centos9编译c代码时&#xff0c;显示bash: gcc: command not found... 下图是我的报错页面&#xff0c;依据提示信息安装gcc之后依旧显示失败 找到其中一种解决方式&#xff0c;完美解决&#xff0c;供参考 输入以下指令更新软件包列表&#xff0c;这里需要等待几分…

MT3031 AK IOI

思路&#xff1a;把每个节点存到堆&#xff08;大根堆&#xff09;里。 如果节点放入后总时间没有超过m则放入堆中&#xff1b;如果总时间超过了&#xff0c;就看堆头元素是否比新元素大。如果大&#xff0c;则删除堆头&#xff08;反悔贪心&#xff09;。 注意别忘记开long l…

keystone学习小结

1 keystone middleware 1.1 工作流程 middleware在客户端和服务端之间&#xff0c;会拦截客户端请求并判断请求身份是否是正确合法的&#xff0c;若是&#xff0c;则继续将请求发给其他middleware或app 具体看&#xff0c;干了这些事 1将请求里的auth header去除&#xff0c…

爬虫:爬取豆瓣电影

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 上篇我们将到如何利用xpath的规则&#xff0c;那么这一次&#xff0c;我们将通过案例来告诉读者如何使用Xpath来定位到我们需要的数据&#xff0c;就算你不懂H5代码是怎么个嵌套或者十分复…

C++新特性-线程

主要内容 thread、condition、mutexatomicfunction、bind使用新特性实现线程池&#xff08;支持可变参数列表&#xff09;异常协程其他 1 C11多线程thread 重点&#xff1a; join和detach的使用场景thread构造函数参数绑定c函数绑定类函数线程封装基础类互斥锁mutexconditi…

计算机组成原理网课笔记

无符号整数的表示与运算 带符号整数的表示与运算 原反补码的特性对比 移码

搜狗输入法 PC端 v14.4.0.9307 去广告绿化版.

软件介绍 搜狗拼音输入法作为众多用户计算机配置的必备工具&#xff0c;其功能的全面性已为众所周知&#xff0c;并且以其高效便捷的输入体验受到广大使用者的青睐。然而&#xff0c;该软件在提供便利的同时&#xff0c;其内置的广告元素常常为用户带来一定的干扰。为此&#…

Linux中动态库的用法及优缺点?怎样制作动态库和静态库?

一、什么是gcc gcc的全称是GNU Compiler Collection&#xff0c;它是一个能够编译多种语言的编译器。最开始gcc是作为C语言的编译器&#xff08;GNU C Compiler&#xff09;&#xff0c;现在除了c语言&#xff0c;还支持C、java、Pascal等语言。gcc支持多种硬件平台. 在 Linux…

航空电子ARINC818采集卡

ARINC818采集卡是针对航空电子数字视频总线协议&#xff08;Avionics Digital Video BUS&#xff0c;ADVB&#xff09;的高性能PCIe视频光纤采集测试设备。ARINC818协议主要应用于机载设备间的实时高清图像传输&#xff0c;目前已经成功应用于多款民用、军用机型当中&#xff0…