PCA9685 16路PWM 控制板 STM32F103 驅動

PCA9685 擁有16路PWM,通過 IIC 與 STM32 進行通信,以下驅動代碼已通過測試,你可以進行更多代碼優化

#include "pca9685.h"// 向 PCA9685 寫入一個字節數據
static void PCA9685_write8( uint8_t addr, uint8_t d) {while (I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));  // 等待總線空閑I2C_GenerateSTART(I2C2, ENABLE);  // 產生起始信號while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));  // 等待起始信號發送完成I2C_Send7bitAddress(I2C2, PCA9685_ADRESS << 1, I2C_Direction_Transmitter);  // 發送從機地址while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));  // 等待地址發送完成I2C_SendData(I2C2, addr);  // 發送寄存器地址while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));  // 等待寄存器地址發送完成I2C_SendData(I2C2, d);  // 發送數據while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));  // 等待數據發送完成I2C_GenerateSTOP(I2C2, ENABLE);  // 產生停止信號delay_ms(1);  // 延時一段時間
}// 從 PCA9685 讀取一個字節數據
static uint8_t PCA9685_read8( uint8_t addr) {uint8_t data;while (I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));  // 等待總線空閑I2C_GenerateSTART(I2C2, ENABLE);  // 產生起始信號while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));  // 等待起始信號發送完成I2C_Send7bitAddress(I2C2, PCA9685_ADRESS << 1, I2C_Direction_Transmitter);  // 發送從機地址while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));  // 等待地址發送完成I2C_SendData(I2C2, addr);  // 發送寄存器地址while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));  // 等待寄存器地址發送完成I2C_GenerateSTART(I2C2, ENABLE);  // 再次產生起始信號while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));  // 等待起始信號發送完成I2C_Send7bitAddress(I2C2, PCA9685_ADRESS << 1 | 0x01, I2C_Direction_Receiver);  // 發送從機地址(讀模式)while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));  // 等待地址發送完成I2C_AcknowledgeConfig(I2C2, DISABLE);  // 關閉應答I2C_GenerateSTOP(I2C2, ENABLE);  // 產生停止信號while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED));  // 等待數據接收完成data = I2C_ReceiveData(I2C2);  // 讀取數據return data;
}// 初始化 PCA9685 結構體
void PCA9685_Init() {GPIO_InitTypeDef GPIO_InitStructure;I2C_InitTypeDef I2C_InitStructure;// 使能 I2C2 和 GPIOB 時鐘RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);// 配置 I2C2 引腳(PB10 - SCL, PB11 - SDA)GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);// 配置 I2C2I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;I2C_InitStructure.I2C_OwnAddress1 = 0x00;I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;I2C_InitStructure.I2C_ClockSpeed = 100000;I2C_Init(I2C2, &I2C_InitStructure);// 使能 I2C2I2C_Cmd(I2C2, ENABLE);delay_ms(5);PCA9685_begin();
}// 開始使用 PCA9685
void PCA9685_begin() {PCA9685_reset();
}// 復位 PCA9685
void PCA9685_reset() {PCA9685_write8(PCA9685_MODE1, 0x0);
}// 設置 PWM 頻率
void PCA9685_setPWMFreq( float freq) {freq *= 0.9;  // 校正頻率設置中的過沖float prescaleval = 25000000;prescaleval /= 4096;prescaleval /= freq;prescaleval -= 1;uint8_t prescale = (uint8_t)floor(prescaleval + 0.5);uint8_t oldmode = PCA9685_read8( PCA9685_MODE1);uint8_t newmode = (oldmode & 0x7F) | 0x10; // 進入睡眠模式PCA9685_write8( PCA9685_MODE1, newmode); // 進入睡眠模式PCA9685_write8( PCA9685_PRESCALE, prescale); // 設置預分頻器PCA9685_write8( PCA9685_MODE1, oldmode);delay_ms(5);PCA9685_write8( PCA9685_MODE1, oldmode | 0xa1);  // 開啟自動遞增模式
}// 設置單個通道的 PWM 值  4095
void PCA9685_setPWM( uint8_t num, uint16_t on, uint16_t off) {PCA9685_write8( LED0_ON_L + 4 * num, on & 0xFF);PCA9685_write8( LED0_ON_H + 4 * num, on >> 8);PCA9685_write8( LED0_OFF_L + 4 * num, off & 0xFF);PCA9685_write8( LED0_OFF_H + 4 * num, off >> 8);
}// 工具函數,根據占空比設置 PWM
// channel: 0- 15     dutyCycle:0-1.0
void setPCA9685PWMWithDutyCycle(uint8_t channel, float dutyCycle) {// 檢查占空比是否在有效范圍內if (dutyCycle < 0.0) {dutyCycle = 0.0;} else if (dutyCycle > 1.0) {dutyCycle = 1.0;}// PCA9685 的 PWM 分辨率是 12 位,最大值為 4095const uint16_t pwmMax = 4095;uint16_t offValue = (uint16_t)(dutyCycle * pwmMax);// 調用 PCA9685_setPWM 函數設置 PWMPCA9685_setPWM(channel, 0, offValue);
}// 設置引腳的 PWM 值
void PCA9685_setPin( uint8_t num, uint16_t val, uint8_t invert) {// 限制值在 0 到 4095 之間if (val > 4095) val = 4095;if (invert) {if (val == 0) {// 信號全高的特殊值PCA9685_setPWM(num, 4096, 0);} else if (val == 4095) {// 信號全低的特殊值PCA9685_setPWM( num, 0, 4096);} else {PCA9685_setPWM( num, 0, 4095 - val);}} else {if (val == 4095) {// 信號全高的特殊值PCA9685_setPWM( num, 4096, 0);} else if (val == 0) {// 信號全低的特殊值PCA9685_setPWM(num, 0, 4096);} else {PCA9685_setPWM(num, 0, val);}}
}
#ifndef PCA9685_H
#define PCA9685_H
#include "stm32f10x.h"
#include <math.h>
#include "delay.h"// PCA9685 寄存器地址
#define PCA9685_SUBADR1 0x2
#define PCA9685_SUBADR2 0x3
#define PCA9685_SUBADR3 0x4#define PCA9685_ADRESS 0x40#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_Init(void);
void PCA9685_begin(void);
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, uint8_t invert);
void setPCA9685PWMWithDutyCycle(uint8_t channel, float dutyCycle);
#endif

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/895017.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/895017.shtml
英文地址,請注明出處:http://en.pswp.cn/news/895017.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用 Apache Spark 進行大數據分析

使用 Apache Spark 進行大數據分析 環境準備 為了能夠在本地環境中運行Spark程序&#xff0c;需要先完成環境搭建。確保已經安裝了Jupyter Notebook和Apache Spark&#xff0c;并完成了兩者之間的集成。 創建 SparkSession 在 Python 中使用 PySpark 時&#xff0c;通常會創…

2025 專業的物聯網軟件開發公司有哪些

物聯網&#xff08;Internet of Things&#xff0c;簡稱IoT&#xff09;具有多個顯著的優勢&#xff0c;主要包括提高效率、節省成本、數據收集與分析、自動化控制、改善用戶體驗、增強決策能力和創新業務模式?。2025&#xff0c;有哪些比較專業的物聯網開發公司呢&#xff1f…

7.PPT:“中國夢”學習實踐活動【20】

目錄 NO1234? NO5678? NO9\10\11 NO1234 考生文件夾下創建一個名為“PPT.pptx”的新演示文稿Word素材文檔的文字&#xff1a;復制/挪動→“PPT.pptx”的新演示文稿&#xff08;藍色、黑色、紅色&#xff09; 視圖→幻燈片母版→重命名&#xff1a;“中國夢母版1”→背景樣…

學習筆記十九:K8S生成pod過程

K8S生成pod過程 流程圖具體生成過程用戶提交 Pod 定義API Server 處理請求調度器分配節點&#xff08;Scheduling&#xff09;目標節點上的 Pod 創建網絡配置狀態上報與監控控制器管理&#xff08;Controller Manager&#xff09;就緒與服務發現 關鍵錯誤場景高級特性 流程圖 具…

封裝descriptions組件,描述,靈活

效果 1、組件1&#xff0c;dade-descriptions.vue <template><table><tbody><slot></slot></tbody> </table> </template><script> </script><style scoped>table {width: 100%;border-collapse: coll…

21.2.6 字體和邊框

版權聲明&#xff1a;本文為博主原創文章&#xff0c;轉載請在顯著位置標明本文出處以及作者網名&#xff0c;未經作者允許不得用于商業目的。 通過設置Rang.Font對象的幾個成員就可以修改字體&#xff0c;設置Range.Borders就可以修改邊框樣式。 【例 21.6】【項目&#xff…

FPGA VGA timing

概念 VGA(Video Graphics Array)時序是控制VGA接口顯示圖像的關鍵參數,它主要包括行時序和場時序兩部分。以下是對VGA時序的詳細解釋: 一、VGA接口簡介 VGA接口是IBM公司在1987年推出的一種使用模擬信號的視頻傳輸標準,具有成本低、結構簡單、應用靈活等優點,至今仍被廣…

中級通信工程師綜合教材(5、6章節)

五、現代通信網 1、通信網的構成要素 通信網在硬件設備方面的構成要素是交換設備、傳輸鏈路和終設備。 構成要素 功能作用 常見設備舉例 終端設備 通信的源點和目的地 電話機、傳真機、計算機、視頻終端、多媒體終端等 交換設備 通信網的核心設備,主要完成呼叫處理、信令處理…

360手機刷機 360手機解Bootloader 360手機ROOT

360手機刷機 360手機解Bootloader 360手機ROOT 問&#xff1a;360手機已停產&#xff0c;現在和以后&#xff0c;能刷機嗎&#xff1f; 答&#xff1a;360手機&#xff0c;是肯定能刷機的 360手機資源下載網站 360手機-360手機刷機RootTwrp 360os.top 360rom.github.io 一、…

.net一些知識點5

1.dot Net帶out的參數如何使用 string name;//假設這個參數帶out TestMethod(1,out name);//一定要有out 方法體中&#xff0c;一定要有out參數的賦值&#xff0c;并且能輸出 2.參數的傳遞方式有哪些 a.值傳遞 b.引用傳遞 ref c.輸出傳遞 out 3.設計模式知道哪些 3.us…

鏈表專題-02

鏈表專題 /*** 鏈表的節點* param <E>*/ public class ListNode<E> {public E element;public ListNode<E> next;public ListNode() {}public ListNode(E element) {this.element element;}public ListNode(E element, ListNode<E> next) {this.eleme…

外部中斷實驗 #STM32F407

外部中斷實驗 此實驗將外部中斷配置為按鍵輸入&#xff0c;通過按鍵輸入觸發外部中斷&#xff0c;在外部中斷里面實施相應的處理&#xff0c;具體功能&#xff1a; 按下KEY0&#xff0c;翻轉LED0狀態按下KEY1&#xff0c;翻轉LED1狀態按下KEY2&#xff0c;同時翻轉LED0和LED1…

java中如何給內部類的屬性賦值

在 Java 中&#xff0c;內部類的屬性賦值方式取決于該屬性的訪問修飾符、內部類的類型&#xff08;非靜態或靜態&#xff09;&#xff0c;以及賦值的時機。以下是幾種常見的方式&#xff1a; 1. 通過構造方法賦值 class Outer {class Inner {private String name;// 構造方法賦…

機器學習8-卷積和卷積核1

機器學習8-卷積和卷積核1 卷積與圖像去噪卷積的定義與性質定義性質卷積的原理卷積步驟卷積的示例與應用卷積的優缺點優點缺點 總結 高斯卷積核卷積核尺寸的設置依據任務類型考慮數據特性實驗與調優 高斯函數標準差的設置依據平滑需求結合卷積核尺寸實際應用場景 總結 圖像噪聲與…

SVN 提交與原有文件類型不一樣的文件時的操作

SVN 提交與原有文件類型不一樣的文件時的操作 背景 SVN 服務器上原本的文件是軟鏈接類型的&#xff0c;但是我將它改成普通文件再上傳。出現了以下提示&#xff1a; 解決過程 本來想著通過 svn rm 和 svn add 來解決&#xff0c;但是行不通。 最終解決方案 svn rm --keep-…

阿里云專有云網絡架構學習

阿里云專有云網絡架構 葉脊&#xff08;spine-leaf&#xff09;網絡和傳統三層網絡拓撲對比 阿里云網絡架構V3拓撲角色介紹推薦設備設備組網舉例帶外管理網絡帶外網和帶內網對比設備介紹 安全網絡設備介紹 參考 后續更新流量分析葉脊&#xff08;spine-leaf&#xff09;網絡和傳…

Deepseek本地部署指南:在linux服務器部署,在mac遠程web-ui訪問

1. 在Linux服務器上部署DeepSeek模型 要在 Linux 上通過 Ollama 安裝和使用模型&#xff0c;您可以按照以下步驟進行操作&#xff1a; 步驟 1&#xff1a;安裝 Ollama 安裝 Ollama&#xff1a; 使用以下命令安裝 Ollama&#xff1a; curl -sSfL https://ollama.com/download.…

3D數字化營銷:重塑家居電商新生態

隨著電商的蓬勃發展&#xff0c;網上訂購家具已成為眾多消費者的首選。然而&#xff0c;線上選購家具的諸多挑戰&#xff0c;如風格不匹配、尺寸不合適、定制效果不如預期以及退換貨不便等&#xff0c;一直困擾著消費者。為解決這些問題&#xff0c;家居行業急需一種全新的展示…

重塑“景區+商業”模式,打造特色文旅新體驗

重塑“景區商業”模式&#xff0c;打造特色文旅新體驗 近年來&#xff0c;旅游業蓬勃發展&#xff0c;旅游熱潮不斷升溫&#xff0c;游客消費觀念也隨之升級。為順應這一趨勢&#xff0c;各大景區紛紛探索打造特色文旅項目&#xff0c;以期吸引更多游客。然而&#xff0c;“景…

在亞馬遜云科技上云原生部署DeepSeek-R1模型(下)

在本系列的上篇中&#xff0c;我們介紹了如何通過Amazon Bedrock部署并測試使用了DeepSeek模型。在接下來的下篇中小李哥將繼續介紹&#xff0c;如何利用亞馬遜的AI模型訓練平臺SageMaker AI中的&#xff0c;Amazon Sagemaker JumpStart通過腳本輕松一鍵式部署DeepSeek預訓練模…