{"id":25283048,"url":"https://github.com/hotakus/mt6835","last_synced_at":"2025-10-19T21:32:56.104Z","repository":{"id":276803894,"uuid":"930321229","full_name":"Hotakus/mt6835","owner":"Hotakus","description":"首发，纯C语言实现，跨平台（stm32、ESP32），移植灵活，低耦合高内聚的 MT6835（21位磁编） 驱动框架 Soft Framework For Encoder MT6835, Pure C Language, Cross-platform, Flexible Port.","archived":false,"fork":false,"pushed_at":"2025-03-27T09:58:39.000Z","size":30,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-27T10:38:59.626Z","etag":null,"topics":["encoder","esp-idf","esp32","framework","software","stm32"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Hotakus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-02-10T12:55:32.000Z","updated_at":"2025-03-27T09:58:42.000Z","dependencies_parsed_at":null,"dependency_job_id":"26981be4-de7b-42b5-9f3f-6466035a4656","html_url":"https://github.com/Hotakus/mt6835","commit_stats":null,"previous_names":["hotakus/mt6835"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hotakus%2Fmt6835","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hotakus%2Fmt6835/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hotakus%2Fmt6835/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hotakus%2Fmt6835/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Hotakus","download_url":"https://codeload.github.com/Hotakus/mt6835/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247492519,"owners_count":20947544,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["encoder","esp-idf","esp32","framework","software","stm32"],"created_at":"2025-02-12T19:58:43.992Z","updated_at":"2025-10-19T21:32:56.054Z","avatar_url":"https://github.com/Hotakus.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\u003cstrong\u003e\n    \u003ch1\u003eMT6835 Framework\u003c/h1\u003e\n    首发，纯C语言实现，跨平台（stm32、ESP32），移植灵活，低耦合高内聚的 \u003cbr\u003e MT6835（21位磁编） 驱动框架  \u003cbr\u003e\n    若您觉得不错，可以帮忙点个 Star⭐，谢谢！\n\u003c/strong\u003e\n\n\u003c/div\u003e\n\n[![CSDN](https://img.shields.io/badge/%E5%8D%9A%E5%AE%A2-文章-%23FF4D5B.svg?\u0026logo=CSDN\u0026logoColor=white)](https://blog.csdn.net/qq_26106317/article/details/145571140?fromshare=blogdetail\u0026sharetype=blogdetail\u0026sharerId=145571140\u0026sharerefer=PC\u0026sharesource=qq_26106317\u0026sharefrom=from_link)\n\n---\n\n### 1. 获取代码：\n\n请为你的Git账户配置好SSH，然后在你喜欢的项目目录下使用以下命令\n\n```bash\ngit clone git@github.com:Hotakus/mt6835.git\n```\n\n---\n\n### 2. 加入你的项目\n\n#### 2.1 以 STM32 为例:\n\n该项目为标准 CMake 项目，可以很方便的加入你的项目中。  \n例如，STM32CubeMX 可以自动生成 STM32 的 CMake 工程文件，请在你的根目录的`CMakeLists.txt`中(不是该项目)加入以下内容：\n\n```cmake\nadd_subdirectory(mt6835) # 添加子目录，在 add_executable() 之前\n\n# 找到这句话，在上下加入代码\nadd_executable(${PROJECT_NAME}.elf ${SOURCES} ${LINKER_SCRIPT})\n\n# 假设你的项目名为 “your_project”，则添加依赖⬇\n# target_link_libraries 一般放在 add_executable() 之后\ntarget_link_libraries(your_project mt6835) \n```\n\n#### 2.2 以 ESP-IDF 为例:\n\n若你使用其他平台，请跳过该小节  \n若你使用 ESP-IDF 框架进行 ESP32 开发，首先，你的ESP-IDF项目根目录应该会有一个`components`文件夹，\n若没有，请自己创建一个，这个目录用于添加额外组件（拉取的本项目同样要放在这个目录下）。  \n接下来，进入mt6835项目根目录，注意到`CMakeLists_esp_idf.txt`文件，\n然后将`CMakeLists.txt`与该文件名进行交换即可。ESP-IDF 会自动检测\n\n---\n\n### 3. 对接 API\n\n程序预留硬件抽象层 API 给用户对接，对于 MT6835，采用 SPI 全双工通信，可以读出21位的角度原始数据，请确保以下：\n\n- 提前配置好 SPI 全双工通信（例如 STM32 可以使用 STM32CubeMX 配置 SPI1 ）\n- SPI 时钟理论不超过 16MHz，\n- CPOL(1), CPHA(1)，8bit 数据模式，\n- 软 CS，提前配置好一根 CS 引脚，默认拉高\n\n在该项目的 `example` 目录，你可以看到预先实现的对应平台的移植文件，可以直接放到你的项目中使用。若你想要自己实现，可以参考下面的示例：\n\n#### 3.1 以 STM32 为例：\n\n```c++\n#include \u003cmath.h\u003e\n#include \"mt6835.h\" // MT6835 驱动头文件\n#include \"spi.h\"    // STM32CubeMX 生成的 SPI 头文件\n\n#define SPI_INSTANCE hspi1             // STM32CubeMX 生成的 SPI 句柄\n#define SPI_CS       SPI1_CS_Pin       // STM32CubeMX 生成的 CS 引脚\n#define SPI_CS_PORT  SPI1_CS_GPIO_Port // STM32CubeMX 生成的 CS 端口\n\n// 示例 CS 操作函数，可以根据需要进行修改\nstatic void mt6835_cs_control(mt6835_cs_state_enum_t state) {\n    if (state == MT6835_CS_HIGH) {  \n        // 高电平\n        HAL_GPIO_WritePin(SPI_CS_PORT, SPI_CS, GPIO_PIN_SET);\n    } else {\n        // 低电平\n        HAL_GPIO_WritePin(SPI_CS_PORT, SPI_CS, GPIO_PIN_RESET);\n    }\n}\n\n// 示例收发函数，可以根据需要进行修改\nstatic void mt6835_spi_send_recv(uint8_t *tx_buf, uint8_t *rx_buf, uint8_t len) {\n    HAL_StatusTypeDef status = HAL_OK;\n    status = HAL_SPI_TransmitReceive_IT(\u0026SPI_INSTANCE, tx_buf, rx_buf, len);\n    if (status != HAL_OK) {\n        printf(\"spi send_recv failed %d\\n\\r\", status);\n        return;\n    }\n    // wait IT\n    uint32_t tickstart = HAL_GetTick();\n    while (HAL_SPI_GetState(\u0026SPI_INSTANCE) != HAL_SPI_STATE_READY) {\n        if (HAL_GetTick() - tickstart \u003e 1) {\n            printf(\"spi send_recv timeout\\n\\r\");\n            return;\n        }\n    }\n}\n\nint main(void) { \n    /* STM32CubeMX 生成的初始化 */\n    HAL_Init();\n    ......\n    MX_SPI1_Init();\n    \n    /* 创建 MT6835 对象 */\n    mt6835_t *mt6835 = mt6835_create();\n    /* 链接 SPI 的 CS 操作函数 */\n    mt6835_link_spi_cs_control(mt6835, mt6835_cs_control);\n    /* 链接 SPI 收发函数 */\n    mt6835_link_spi_send_recv(mt6835, mt6835_spi_send_recv);\n    \n    /* 可选 */\n    // mt6835_link_spi_send(mt6835, mt6835_spi_send);\n    // mt6835_link_spi_recv(mt6835, mt6835_spi_recv);\n    \n    /* 是否开启 CRC 校验，使用查表法，通常不会有性能影响\n     * 若开启，则会使用 mt6835_t 结构体中的 crc_res 位存储该次角度读取正确性，\n     * 用户可以根据 crc_res 的值进行判断，\n    */\n    mt6835_enable_crc_check(mt6835);\n    // mt6835_disable_crc_check(mt6835);    // 禁用 CRC 校验\n    \n    /* 开始读取角度 */\n    uint32_t raw_angle = 0;\n    float radian_angle = 0.0f;\n    while(1) {\n        /* \n        * 读取原始角度数据\n        * 第二个参数为读取方式, MT6835_READ_ANGLE_METHOD_NORMAL 或 MT6835_READ_ANGLE_METHOD_BURST \n        * MT6835_READ_ANGLE_METHOD_BURST 会更快\n        */\n        raw_angle = mt6835_get_raw_angle(mt6835, MT6835_READ_ANGLE_METHOD_BURST);\n        radian_angle = raw_angle * (M_PI * 2.0f) / MT6835_ANGLE_RESOLUTION;\n        // radian_angle = mt6835_get_angle(motor1_mt6835, MT6835_READ_ANGLE_METHOD_BURST);\n        \n        if (!mt6835-\u003ecrc_res) {\n            printf(\"crc error\\n\\r\");\n        }\n        \n        printf(\"raw_angle: %d, radian_angle: %f\\n\\r\", raw_angle, radian_angle);\n        HAL_Delay(500);\n    }\n}\n```\n\n若不想自己实现，则直接将`example/stm32/mt6835_stm32_spi_port.h`文件中宏定义`MT6835_STM32_SPI_PORT_ENABLE`改为`1`即可：  \n然后按照如下调用：\n\n```c++\nint main() {\n    uint32_t raw_angle = 0;\n    float radian_angle = 0.0f;\n    mt6835_t * mt6835 = mt6835_stm32_spi_port_init();\n    \n    while(1) {\n        raw_angle = mt6835_get_raw_angle(mt6835, MT6835_READ_ANGLE_METHOD_BURST);\n        radian_angle = raw_angle * (M_PI * 2.0f) / MT6835_ANGLE_RESOLUTION;\n        // radian_angle = mt6835_get_angle(motor1_mt6835, MT6835_READ_ANGLE_METHOD_BURST);\n        printf(\"raw_angle: %d, radian_angle: %f\\n\\r\", raw_angle, radian_angle);\n        HAL_Delay(500);\n    }\n}\n```\n\n---\n\n### 4. 更多函数说明\n\n- 创建销毁函数：\n    - `mt6835_create()` 创建一个 mt6835 对象\n    - `mt6835_destroy()` 销毁一个 mt6835 对象\n\n- 链接函数：\n    - `mt6835_link_spi_send()` 链接 SPI 发送函数\n    - `mt6835_link_spi_recv()` 链接 SPI 接收函数\n    - `mt6835_link_spi_send_recv()` 链接 SPI 收发函数\n    - `mt6835_link_spi_cs_control()` 链接 CS 引脚操作函数\n- CRC：\n    - `mt6835_enable_crc_check()` 使能 CRC 校验（查表法）\n    - `mt6835_disable_crc_check()` 失能 CRC 校验\n- GET 和 SET 函数\n    - `mt6835_get_id()` 读取 MT6835 ID 寄存器\n    - `mt6835_set_id()` 暂时写入 MT6835 ID 寄存器（配合 `mt6835_write_eeprom()` 函数）\n    - `mt6835_get_raw_angle()` 读取原始角度数据（21位）\n    - `mt6835_get_angle()` 读取原始角度数据并换算为弧度值（0 ~ 2*PI）\n    - `mt6835_get_raw_zero_angle()` 读取原始零位值（12位）（零位值在 FOC 中很重要，最好是将正确零位固化在EEPROM中）\n    - `mt6835_get_zero_angle()` 读取零位值，并换算成弧度值\n    - `mt6835_set_zero_angle()` 暂时写入零位值（以弧度）到寄存器，（配合 `mt6835_write_eeprom()` 函数）\n- 底层函数：\n    - `mt6835_read_reg()` 单字节读取寄存器\n    - `mt6835_write_reg()` 单字节暂时写入寄存器（配合 `mt6835_write_eeprom()` 函数）\n    - `mt6835_write_eeprom()` 将当前所有的可固化寄存器值写入（固化）到 EEPROM，所有写入操作最后都要额外调用这个函数\n\n---\n\n### 5. 写入 EEPROM 示例\n\n存在寄存器的值断电消失，所以只是写入寄存器并不等于固化到 EEPROM\n```c++\nint main() {\n    /* 写入 ID */\n    mt6835_set_id(mt6835, 0xDA); // 写入 ID 0xDA 到寄存器，只在寄存器，断电消失\n    HAL_Delay(1);\n    uint8_t id = mt6835_get_id(mt6835); // 读取 ID\n    printf(\"id: 0x%x\\r\\n\", id);\n    \n    /* 写入特定零位值，零位值需要你自己校准并读取角度 */\n    // 2.0943951024f 是 120 度，假设 120 度是零位\n    mt6835_set_zero_angle(mt6835, 2.0943951024f); //写入到零位寄存器，断电消失\n    HAL_Delay(1);\n    float zero_angle = mt6835_get_zero_angle(mt6835); // 读取零位值\n    printf(\"zero_angle: %f rad\\r\\n\", zero_angle);\n    \n    /*下面进行统一固化，为保证断电后 MT6835 数据不丢失，需要固化到 EEPROM */\n    /*\n    * 直接调用 mt6835_write_eeprom 发送固化命令，\n    * 命令成功发送则返回 0x55, 若正确收到 0x55，\n    * 则程序 respond 为 true，错误则 false\n    */\n    bool respond = mt6835_write_eeprom(mt6835);\n    if (!respond) {\n        printf(\"write eeprom failed\\r\\n\");\n    } else {\n        printf(\"write eeprom success\\r\\n\");\n    }\n    HAL_Delay(6000);    // 写入后至少 6 秒钟不能断电\n    \n    /* \n     * 将上面的所有写入和固化操作注释掉，重新烧录程序，\n     * 并重新给编码器上电，进行读取验证 \n    */ \n    id = mt6835_get_id(mt6835); // 读取 ID\n    printf(\"id: 0x%x\\r\\n\", id);\n    zero_angle = mt6835_get_zero_angle(mt6835); // 读取零位值\n    printf(\"zero_angle: %f rad\\r\\n\", zero_angle);\n    \n    // 若任何环节失败，请优先检测你的 SPI 初始化代码是否有问题，\n    // 因为所有代码均经过正确验证\n}\n```\n\n最后附上简单的 STM32CubeMX配置图片：  \n注意另配 CS 引脚，任意引脚设置为 OUTPUT 即可\n\n![](./assets/example1.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhotakus%2Fmt6835","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhotakus%2Fmt6835","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhotakus%2Fmt6835/lists"}