stm32f103zet6芯片驱动mcp41010的代码
以下是一份基于STM32F103标准库的MCP41010驱动代码。
MCP41010是一款通过SPI接口控制的8位(256级)数字电位器,它接收16位(两个字节)数据:第一个字节是命令,第二个字节是数据。
硬件连接部分:
| MCP41010 引脚 | 连接至 STM32F103ZET6 | 说明 |
|---|---|---|
| CS (Pin 1) | PA15 | 片选引脚,低电平有效 |
| SCK (Pin 2) | PB3 | SPI 时钟线 |
| SI (Pin 3) | PB5 | SPI 数据输入线 |
| VDD (Pin 8) | 3.3V | 电源正极 |
| VSS (Pin 4) | GND | 电源地 |
驱动代码部分(封装了MCP41010的初始化与电阻值设置功能):
1.头文件mcp41010.h
#ifndef __MCP41010_H
#define __MCP41010_H
#include "stm32f10x.h"
// 根据您的接线定义引脚
#define MCP41010_CS_PORT GPIOA
#define MCP41010_CS_PIN GPIO_Pin_15
#define MCP41010_SCK_PORT GPIOB
#define MCP41010_SCK_PIN GPIO_Pin_3
#define MCP41010_MOSI_PORT GPIOB
#define MCP41010_MOSI_PIN GPIO_Pin_5
// 操作宏定义
#define MCP41010_CS_LOW() GPIO_ResetBits(MCP41010_CS_PORT, MCP41010_CS_PIN)
#define MCP41010_CS_HIGH() GPIO_SetBits(MCP41010_CS_PORT, MCP41010_CS_PIN)
// 函数声明
void MCP41010_Init(void);
void MCP41010_SetResistance(uint8_t value);
#endif
2.源文件mcp41010.c
#include "mcp41010.h"
// SPI1 初始化配置
static void SPI1_Init(void) {
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
// 1. 使能相关时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_SPI1, ENABLE);
// 2. 配置 CS 引脚 (PA15) 为推挽输出
GPIO_InitStructure.GPIO_Pin = MCP41010_CS_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(MCP41010_CS_PORT, &GPIO_InitStructure);
MCP41010_CS_HIGH(); // 默认不选中
// 3. 配置 SCK (PB3) 和 MOSI (PB5) 为复用推挽输出
GPIO_InitStructure.GPIO_Pin = MCP41010_SCK_PIN | MCP41010_MOSI_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(MCP41010_SCK_PORT, &GPIO_InitStructure);
// 4. SPI1 模式配置: 模式0, 主机模式, 8位数据, 高位先行
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; // 仅发送模式 (MCP41010只需接收)
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // 时钟空闲时为低电平 (CPOL=0)
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; // 第一个时钟沿采样数据 (CPHA=0)
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // 软件管理片选信号
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64; // 分频后约1.125MHz
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // 高位先行
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
}
// 发送一个字节数据
static void SPI1_SendByte(uint8_t byte) {
// 等待发送缓冲区为空
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI1, byte);
// 等待发送完成
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
SPI_I2S_ReceiveData(SPI1);
}
// MCP41010 初始化
void MCP41010_Init(void) {
SPI1_Init();
}
// 设置电位器阻值
// value: 0 ~ 255, 对应电阻值从最低(约100Ω)到最高(10kΩ)
void MCP41010_SetResistance(uint8_t value) {
// 1. 选中设备
MCP41010_CS_LOW();
// 2. 发送命令字节:写数据指令
// 命令字节 = (C1, C0 = 0,1) | (P1, P0 = X,1) | 其他位为 0
// = (0x01) << 4 | (0x01) = 0x10 + 0x01? 等等。
// 根据数据手册, 命令字节格式: [X, X, C1, C0, X, X, P1, P0]
// C1=0, C0=1 (写命令) -> 0b0001xxxx = 0x10
// P1=0(无关), P0=1(选择电位器0) -> 最后两位为 0b01
// 所以命令字节 = 0b00010001 = 0x11
uint8_t cmd_byte = 0x11;
SPI1_SendByte(cmd_byte);
// 3. 发送数据字节
SPI1_SendByte(value);
// 4. 取消选中
MCP41010_CS_HIGH();
}
3.main.c文件中调用方式
#include "mcp41010.h"
int main(void) {
// 初始化系统时钟等...
MCP41010_Init(); // 初始化MCP41010
MCP41010_SetResistance(128); // 设置到中点阻值
// MCP41010_SetResistance(255); // 最大阻值
// MCP41010_SetResistance(0); // 最小阻值
while(1) {
// 您的其他程序代码...
}
}
4.代码要点解析
SPI模式配置:MCP41010支持SPI模式0(空闲时时钟为低,第一个跳变沿采样),在SPI1_Init()完成了相应配置。
数据格式:通信时高位(MSB)先发送,代码中配置SPI_FirstBit_MSB与之匹配。
发送流程:片选拉低后,连续发送命令字节和数据字节,注意两者必须在16个连续时钟周期内完成。发送完两个字节后将CS拉高以执行命令。
命令字节构造:如注释所示,代码发送写数据指令0x11,其中:
高4位中的0x1代表C1=0、C0=1,即“写数据”命令。
低4位中的0x1代表P1=0、P0=1,选择控制唯一的电位器通道0。
软件NSS:选用软件模式SPI_NSS_Soft,让您自由控制PA15作为片选引脚。
关于PA15和PB3引脚的特别提醒:
PA15(JTDI)和PB3(JTDO)在STM32F103中默认是调试端口,直接用作普通GPIO时需要先禁用JTAG功能。建议在系统时钟初始化代码后,调用 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); 来禁用JTAG,使能SWD。请根据调试需求,在“”时参考以下代码:
// 禁用 JTAG 功能,仅保留 SWD (需 SWDIO (PA13) 和 SWCLK (PA14) 接调试器)
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
以上代码可以直接集成到程序项目中测试使用。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)