同步步兵代码,暂时关闭底盘跟随

This commit is contained in:
2025-11-02 21:21:11 +08:00
parent 456cc96c81
commit 3821589bed
693 changed files with 238044 additions and 2735 deletions

View File

@@ -0,0 +1,440 @@
#include "stm32f4xx.h" // Device header
#include "stm32f4xx_conf.h"
#include "MyI2C.h"
/*
*函数简介:软件I2C专用us延时
*参数说明:延时时长,单位1/21us
*返回类型:无
*备注:参数范围:0~4294967295
*/
void MyI2C_Delay_us(uint32_t us)
{
uint32_t temp;
SysTick->LOAD=us; //时间加载我们要延时n倍的us, 1us是一个fac_ua周期所以总共要延时的周期值为二者相乘最后送到Load中。
SysTick->VAL=0x00; //清空计数器
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; //开启使能位 开始倒数
do temp=SysTick->CTRL;
while((temp&0x01) && !(temp&(1<<16))); //用来判断 systick 定时器是否还处于开启状态然后在等待时间到达也就是数到0的时候,此时第十六位设置为1
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器使能位
SysTick->VAL=0x00; //清空计数器
}
/*
*函数简介:软件I2C写SCL电平
*参数说明:软件I2C配置结构体
*参数说明:高低电平,0-低电平 1-高电平
*返回类型:无
*备注:使用前需要先定义结构体并初始化
*备注:由于I2C速度较慢,在更改电平之后需要加入延时
*/
void MyI2C_SCL(MyI2C_InitTypedef *MyI2C_InitStructure,uint8_t x)
{
GPIO_WriteBit(MyI2C_InitStructure->MyI2C_SCL_GPIOx,MyI2C_InitStructure->MyI2C_SCL_Pin,(BitAction)(x));
MyI2C_Delay_us(1);//延时
}
/*
*函数简介:软件I2C写SDA电平
*参数说明:软件I2C配置结构体
*参数说明:高低电平,0-低电平 1-高电平
*返回类型:
*备注:使用前需要先定义结构体并初始化
*备注:由于I2C速度较慢,在更改电平之后需要加入延时
*/
void MyI2C_SDA(MyI2C_InitTypedef *MyI2C_InitStructure,uint8_t x)
{
GPIO_WriteBit(MyI2C_InitStructure->MyI2C_SDA_GPIOx,MyI2C_InitStructure->MyI2C_SDA_Pin,(BitAction)(x));
MyI2C_Delay_us(1);//延时
}
/*
*函数简介:软件I2C读SDA电平
*参数说明:软件I2C配置结构体
*返回类型:高低电平,0-低电平 1-高电平
*备注:使用前需要先定义结构体并初始化
*备注:由于I2C速度较慢,在电平更改之后需要加入延时,读取时也可以不加
*/
uint8_t MyI2C_Read_SDA(MyI2C_InitTypedef *MyI2C_InitStructure)
{
MyI2C_Delay_us(1);//延时
uint8_t SDA_Status=GPIO_ReadInputDataBit(MyI2C_InitStructure->MyI2C_SDA_GPIOx,MyI2C_InitStructure->MyI2C_SDA_Pin);
return SDA_Status;
}
/*
*函数简介:软件I2C初始化
*参数说明:软件I2C配置结构体
*返回类型:无
*备注:使用前需要先定义结构体并初始化
*/
void MyI2C_Init(MyI2C_InitTypedef *MyI2C_InitStructure)
{
RCC_AHB1PeriphClockCmd(MyI2C_InitStructure->MyI2C_SCL_RCC,ENABLE);//开启SCL时钟
RCC_AHB1PeriphClockCmd(MyI2C_InitStructure->MyI2C_SDA_RCC,ENABLE);//开启SDA时钟
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType=GPIO_OType_OD;//开漏输出
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//默认上拉
GPIO_InitStructure.GPIO_Pin=MyI2C_InitStructure->MyI2C_SCL_Pin;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
GPIO_Init(MyI2C_InitStructure->MyI2C_SCL_GPIOx,&GPIO_InitStructure);//配置SCL
GPIO_InitStructure.GPIO_Pin=MyI2C_InitStructure->MyI2C_SDA_Pin;
GPIO_Init(MyI2C_InitStructure->MyI2C_SDA_GPIOx,&GPIO_InitStructure);//配置SDA
MyI2C_SCL(MyI2C_InitStructure,1);//初始化SCL
MyI2C_SDA(MyI2C_InitStructure,1);//初始化SDA
}
/*
*函数简介:软件I2C起始
*参数说明:软件I2C配置结构体
*返回类型:无
*I2C协议:
* SCL ~~~~/---\___
* SDA ~~/---\_____
*/
void MyI2C_Start(MyI2C_InitTypedef *MyI2C_InitStructure)
{
MyI2C_SDA(MyI2C_InitStructure,1);
MyI2C_SCL(MyI2C_InitStructure,1);//复位SCL和SDA
MyI2C_SDA(MyI2C_InitStructure,0);//起始
MyI2C_SCL(MyI2C_InitStructure,0);//准备接收数据
}
/*
*函数简介:软件I2C终止
*参数说明:软件I2C配置结构体
*返回类型:无
*I2C协议:
* SCL ____/-----
* SDA ~~\___/---
*/
void MyI2C_Stop(MyI2C_InitTypedef *MyI2C_InitStructure)
{
MyI2C_SDA(MyI2C_InitStructure,0);
MyI2C_SCL(MyI2C_InitStructure,1);//准备接收停止信号
MyI2C_SDA(MyI2C_InitStructure,1);//终止
}
/*
*函数简介:软件I2C产生应答
*参数说明:软件I2C配置结构体
*参数说明:是否应答,0-NAck非应答 1-Ack应答
*返回类型:无
*I2C协议:
* Ack:
* SCL____/-\___
* SDA~~\___/---
* NAck:
* SCL____/-\___
* SDA~~/-------
*/
void MyI2C_SendAck(MyI2C_InitTypedef *MyI2C_InitStructure,uint8_t AckBit)
{
MyI2C_SDA(MyI2C_InitStructure,!AckBit);//发送应答情况
MyI2C_SCL(MyI2C_InitStructure,1);//产生时钟
MyI2C_SCL(MyI2C_InitStructure,0);
MyI2C_SDA(MyI2C_InitStructure,1);//释放总线
}
/*
*函数简介:软件I2C接收应答
*参数说明:软件I2C配置结构体
*返回类型:是否应答,0-NAck非应答 1-Ack应答
*I2C协议:
* SCL ____/-\___
* SDA ~~/-|==|~~
* ( )从机
*/
uint8_t MyI2C_ReceiveAck(MyI2C_InitTypedef *MyI2C_InitStructure)
{
uint8_t AckBit;//应答标志位
MyI2C_SDA(MyI2C_InitStructure,1);//释放SDA总线
MyI2C_SCL(MyI2C_InitStructure,1);//提示从机发送Ack
AckBit=!MyI2C_Read_SDA(MyI2C_InitStructure);//接收应答
MyI2C_SCL(MyI2C_InitStructure,0);//置SCL为0,准备下一轮发送
return AckBit;//返回应答情况
}
/*
*函数简介:软件I2C发送一个8bits数据
*参数说明:软件I2C配置结构体
*参数说明:8bits发送数据
*返回类型:无
*I2C协议:
* SCL ____/-\___/-\___/-\___/-\___/-\___/-\___/-\___/-\___
* SDA ~~x=====x=====x=====x=====x=====x=====x=====x=====~~
*/
void MyI2C_Send8bits(MyI2C_InitTypedef *MyI2C_InitStructure,uint8_t Byte)
{
for(uint8_t i=0;i<8;i++)
{
MyI2C_SDA(MyI2C_InitStructure,Byte&(0x80>>i));//发送数据每一位,高位先行
MyI2C_SCL(MyI2C_InitStructure,1);//产生时钟
MyI2C_SCL(MyI2C_InitStructure,0);
}
MyI2C_SDA(MyI2C_InitStructure,1);//释放SDA总线
}
/*
*函数简介:软件I2C读取一个8bits数据
*参数说明:软件I2C配置结构体
*返回类型:8bits接收数据
*I2C协议:
* SCL ____/-\_/-\_/-\_/-\_/-\_/-\_/-\_/-\___
* SDA ~~/-|==============================|~~
* ( )从机
*/
uint8_t MyI2C_Receive8bits(MyI2C_InitTypedef *MyI2C_InitStructure)
{
uint8_t Byte=0x00;
MyI2C_SDA(MyI2C_InitStructure,1);//释放SDA总线
for(uint8_t i=0;i<8;i++)//读取数据每一位,高位先行
{
MyI2C_SCL(MyI2C_InitStructure,1);//产生时钟
if(MyI2C_Read_SDA(MyI2C_InitStructure)){Byte|=(0x80>>i);}//读取SDA
MyI2C_SCL(MyI2C_InitStructure,0);
}
return Byte;
}
/*
*函数简介:软件I2C发送一个字节数据
*参数说明:软件I2C配置结构体
*参数说明:7bits从机地址
*参数说明:8bits发送数据
*返回类型:无
*备注:无
*/
void MyI2C_SendByte(MyI2C_InitTypedef *MyI2C_InitStructure,uint8_t Address,uint8_t Byte)
{
MyI2C_Start(MyI2C_InitStructure);//起始
MyI2C_Send8bits(MyI2C_InitStructure,Address<<1);//发送设备地址(写)
while(MyI2C_ReceiveAck(MyI2C_InitStructure)!=1);//等待Ack应答
MyI2C_Send8bits(MyI2C_InitStructure,Byte);//发送数据
while(MyI2C_ReceiveAck(MyI2C_InitStructure)!=1);//等待Ack应答
MyI2C_Stop(MyI2C_InitStructure);//终止
}
/*
*函数简介:软件I2C发送数据
*参数说明:软件I2C配置结构体
*参数说明:7bits从机地址
*参数说明:发送数据数组
*参数说明:发送数据数组长度
*返回类型:无
*备注:无
*/
void MyI2C_SendData(MyI2C_InitTypedef *MyI2C_InitStructure,uint8_t Address,uint8_t *Data,uint16_t Length)
{
MyI2C_Start(MyI2C_InitStructure);//起始
MyI2C_Send8bits(MyI2C_InitStructure,Address<<1);//发送设备地址(写)
while(MyI2C_ReceiveAck(MyI2C_InitStructure)!=1);//等待Ack应答
for(uint16_t i=0;i<Length;i++)
{
MyI2C_Send8bits(MyI2C_InitStructure,Data[i]);//发送数据
while(MyI2C_ReceiveAck(MyI2C_InitStructure)!=1);//等待Ack应答
}
MyI2C_Stop(MyI2C_InitStructure);//终止
}
/*
*函数简介:软件I2C写寄存器
*参数说明:软件I2C配置结构体
*参数说明:7bits从机地址
*参数说明:8bits寄存器地址
*参数说明:8bits数据
*返回类型:无
*备注:无
*/
void MyI2C_WriteRegister(MyI2C_InitTypedef *MyI2C_InitStructure,uint8_t SlaveAddress,uint8_t RegAddress,uint8_t Data)
{
MyI2C_Start(MyI2C_InitStructure);//起始
MyI2C_Send8bits(MyI2C_InitStructure,SlaveAddress<<1);//发送从机地址(写)
while(MyI2C_ReceiveAck(MyI2C_InitStructure)!=1);//等待Ack应答
MyI2C_Send8bits(MyI2C_InitStructure,RegAddress);//发送寄存器地址
while(MyI2C_ReceiveAck(MyI2C_InitStructure)!=1);//等待Ack应答
MyI2C_Send8bits(MyI2C_InitStructure,Data);//发送数据
while(MyI2C_ReceiveAck(MyI2C_InitStructure)!=1);//等待Ack应答
MyI2C_Stop(MyI2C_InitStructure);//终止
}
/*
*函数简介:软件I2C接收一个字节数据
*参数说明:软件I2C配置结构体
*参数说明:7bits从机地址
*返回类型:8bits接收数据
*备注:无
*/
uint8_t MyI2C_ReceiveByte(MyI2C_InitTypedef *MyI2C_InitStructure,uint8_t Address)
{
uint8_t Byte=0;
MyI2C_Start(MyI2C_InitStructure);//起始
MyI2C_Send8bits(MyI2C_InitStructure,(Address<<1) | 0x01);//发送设备地址(读)
while(MyI2C_ReceiveAck(MyI2C_InitStructure)!=1);//等待Ack应答
Byte=MyI2C_Receive8bits(MyI2C_InitStructure);//接收数据
MyI2C_SendAck(MyI2C_InitStructure,0);//发送NAck
MyI2C_Stop(MyI2C_InitStructure);//终止
return Byte;
}
/*
*函数简介:软件I2C接收数据
*参数说明:软件I2C配置结构体
*参数说明:7bits从机地址
*参数说明:接收数据数组
*参数说明:接收数据数组长度
*返回类型:8bits接收数据
*备注:无
*/
void MyI2C_ReceiveData(MyI2C_InitTypedef *MyI2C_InitStructure,uint8_t Address,uint8_t *Data,uint16_t Length)
{
MyI2C_Start(MyI2C_InitStructure);//起始
MyI2C_Send8bits(MyI2C_InitStructure,(Address<<1) | 0x01);//发送设备地址(读)
while(MyI2C_ReceiveAck(MyI2C_InitStructure)!=1);//等待Ack应答
for(uint16_t i=0;i<Length-1;i++)
{
Data[i]=MyI2C_Receive8bits(MyI2C_InitStructure);//接收数据
MyI2C_SendAck(MyI2C_InitStructure,1);//发送Ack
}
Data[Length-1]=MyI2C_Receive8bits(MyI2C_InitStructure);//接收最后一个数据
MyI2C_SendAck(MyI2C_InitStructure,0);//发送NAck
MyI2C_Stop(MyI2C_InitStructure);//终止
}
/*
*函数简介:软件I2C读寄存器
*参数说明:软件I2C配置结构体
*参数说明:7bits从机地址
*参数说明:8bits寄存器地址
*返回类型:8bits数据
*备注:无
*/
uint8_t MyI2C_ReadRegister(MyI2C_InitTypedef *MyI2C_InitStructure,uint8_t SlaveAddress,uint8_t RegAddress)
{
uint8_t Byte=0;
MyI2C_Start(MyI2C_InitStructure);//起始
MyI2C_Send8bits(MyI2C_InitStructure,SlaveAddress<<1);//发送从机地址(写)
while(MyI2C_ReceiveAck(MyI2C_InitStructure)!=1);//等待Ack应答
MyI2C_Send8bits(MyI2C_InitStructure,RegAddress);//发送寄存器地址
while(MyI2C_ReceiveAck(MyI2C_InitStructure)!=1);//等待Ack应答
MyI2C_Start(MyI2C_InitStructure);//重复起始
MyI2C_Send8bits(MyI2C_InitStructure,(SlaveAddress<<1) | 0x01);//发送设备地址(读)
while(MyI2C_ReceiveAck(MyI2C_InitStructure)!=1);//等待Ack应答
Byte=MyI2C_Receive8bits(MyI2C_InitStructure);//接收数据
MyI2C_SendAck(MyI2C_InitStructure,0);//发送NAck
MyI2C_Stop(MyI2C_InitStructure);//终止
return Byte;
}
/*
*函数简介:软件I2C连续读寄存器
*参数说明:软件I2C配置结构体
*参数说明:7bits从机地址
*参数说明:8bits寄存器首地址
*参数说明:接收数据数组
*参数说明:接收数据数组长度
*返回类型:无
*备注:无
*/
void MyI2C_ContinuousReadRegister(MyI2C_InitTypedef *MyI2C_InitStructure,uint8_t SlaveAddress,uint8_t RegStartAddress,uint8_t *ReceiveData,uint16_t Length)
{
MyI2C_Start(MyI2C_InitStructure);//起始
MyI2C_Send8bits(MyI2C_InitStructure,SlaveAddress<<1);//发送从机地址(写)
while(MyI2C_ReceiveAck(MyI2C_InitStructure)!=1);//等待Ack应答
MyI2C_Send8bits(MyI2C_InitStructure,RegStartAddress);//发送寄存器地址
while(MyI2C_ReceiveAck(MyI2C_InitStructure)!=1);//等待Ack应答
MyI2C_Start(MyI2C_InitStructure);//重复起始
MyI2C_Send8bits(MyI2C_InitStructure,(SlaveAddress<<1) | 0x01);//发送设备地址(读)
while(MyI2C_ReceiveAck(MyI2C_InitStructure)!=1);//等待Ack应答
for(uint16_t i=0;i<Length-1;i++)
{
ReceiveData[i]=MyI2C_Receive8bits(MyI2C_InitStructure);//接收数据
MyI2C_SendAck(MyI2C_InitStructure,1);//发送Ack
}
ReceiveData[Length-1]=MyI2C_Receive8bits(MyI2C_InitStructure);//接收最后一个数据
MyI2C_SendAck(MyI2C_InitStructure,0);//发送NAck
MyI2C_Stop(MyI2C_InitStructure);//终止
}
/*
*函数简介:软件I2C检测设备状态
*参数说明:软件I2C配置结构体
*参数说明:7bits从机地址
*返回类型:工作状态,0-设备不存在或异常工作 1-设备正常工作
*备注:无
*/
uint8_t MyI2C_CheckDevice(MyI2C_InitTypedef *MyI2C_InitStructure,uint8_t Address)
{
uint8_t WorkStatus;//工作标志位
MyI2C_Start(MyI2C_InitStructure);//起始
MyI2C_Send8bits(MyI2C_InitStructure,Address<<1);//发送设备地址(写)
WorkStatus=MyI2C_ReceiveAck(MyI2C_InitStructure);//检测Ack应答
MyI2C_Stop(MyI2C_InitStructure);//终止
return WorkStatus;
}
/*
*函数简介:软件I2C查询Who Am I寄存器
*参数说明:软件I2C配置结构体
*参数说明:7bits从机地址
*参数说明:8bits Who Am I寄存器地址
*返回类型:Who Am I寄存器的值,0-设备不存在或异常工作 其他-返回寄存器值
*备注:无
*/
uint8_t MyI2C_CheckWhoAmI(MyI2C_InitTypedef *MyI2C_InitStructure,uint8_t SlaveAddress,uint8_t WhoAmIAddress)
{
uint8_t WhoAmI;
MyI2C_Start(MyI2C_InitStructure);//起始
MyI2C_Send8bits(MyI2C_InitStructure,SlaveAddress<<1);//发送设备地址(写)
if(MyI2C_ReceiveAck(MyI2C_InitStructure)==0)return 0;//检测Ack应答
MyI2C_Send8bits(MyI2C_InitStructure,WhoAmIAddress);//发送寄存器地址
if(MyI2C_ReceiveAck(MyI2C_InitStructure)==0)return 0;//检测Ack应答
MyI2C_Start(MyI2C_InitStructure);//重复起始
MyI2C_Send8bits(MyI2C_InitStructure,(SlaveAddress<<1) | 0x01);//发送设备地址(读)
if(MyI2C_ReceiveAck(MyI2C_InitStructure)==0)return 0;//检测Ack应答
WhoAmI=MyI2C_Receive8bits(MyI2C_InitStructure);//接收数据
MyI2C_SendAck(MyI2C_InitStructure,0);//发送NAck
MyI2C_Stop(MyI2C_InitStructure);//终止
return WhoAmI;
}