外设驱动库开发笔记19:BMP280压力温度传感器驱动

压力和温度监测在嵌入式系统开发中是非常常见的需求,特别是对环境大气压力和温度的检测需求就更常见了。我们一般都会选择一些封装较小操作比较方便的压力传感器。BMP280就是满足这一要求的器件。在这一篇中我们将设计并实现BMP280的驱动。

1、功能概述

BMP280是一款绝对压力传感器产品。BMP280是一款绝对的气压传感器,专为移动应用而设计。传感器模块采用极其紧凑的封装。其小尺寸和低功耗允许在诸如移动电话,GPS模块或手表的电池供电设备中实现。

1.1、硬件接口

BMP280基于博世经过验证的压阻式压力传感器技术,具有高精度和线性度以及长期稳定性和高EMC稳健性。众多器件操作选项提供了最高的灵活性,可针对功耗,分辨率和滤波器性能优化器件。为开发人员提供了一组经过测试的默认设置(例如用例),以便尽可能简化设计。

BMP280压力温度传感器采用了小巧的8引脚LGA封装形式。其引脚排布就功能如下图所示:

BMP280压力温度传感器支持3种通讯接口方式:四线SPI、三线SPI以及I2C。在不同的接口模式下,各引脚的定义也是有差异的,关于这三种接口模式各引脚的定义如下:

对应3种不同的接口方式,BMP280压力温度传感器存在三种与总线连接的方式。首先我们来看四线SPI接口方式,包括CSB片选、SCK时钟、SDI数字输入、SDO数字输出。其总线连接方式如下图:

 

接下来我们来看三线SPI接口方式,包括CSB片选、SCK时钟、SDI数字输入/SDO数字输出。其与4线SPI的区别是数字输入输出使用同一引脚,第3脚就是输入也是输出,而第5脚浮空。其总线连接方式如下图:

最后我们来看I2C接口方式,包括SCL时钟、SDA数字输入输出。在I2C接口模式下,第2CSB连接到高电平,以设置BMP280压力温度传感器使用I2C接口。而第5脚则可以通过连接高电平或低电平来设置设备地址的最后一位,不可以浮空。所以根据第5脚电频不同,BMP280压力温度传感器的I2C设备7位地址为:0x760x77。其总线连接方式如下图:

BMP280压力温度传感器在使用SPI接口时,支持SPI模式0CPOL=CPHA=0)和模式3CPOL=CPHA=1)。而在使用I2C接口时,支持标准模式、快速模式以及高速模式。接口的选择实际上是通过CSB的电位实现的,低电平时就是SPI,高电平时就是I2C

1.2、数据存储结构

BMP280压力温度传感器的所有操作都是通过读写对应的寄存器来实现的。BMP280压力温度传感器中所有的寄存器都是8位的。这些寄存器在存储器中的地址分配如下图所示。

在上图并未包括系统保留的寄存器,这些寄存器不可以进行写操作,读出来的值也是无意义的。接下来我们来详细描述上图中的这些寄存器。

先来看看两个比较特殊的寄存器。首先是ID寄存器,这个寄存器是只读的,而且其存储的值也固定为0x58,用来代表设备为BMP280压力温度传感器。这个寄存器在系统上电后即可读取。还有复位寄存器,这个寄存器是只写的,固定向其写0xB6来实现BMP280压力温度传感器的复位。同样只要系统上电后即可以写复位寄存器。

状态寄存器是只读的,其实只使用了其中的两位,这两位分别表示数据测量是否完成和影响寄存器是否更新。下图是状态寄存器的详细说明:

测量控制寄存器是可读写的,用以配置BMP280压力温度传感器数据获取的方式。分别配置温度采样、压力采样和工作模式。工作模式有三种:休眠模式、强制模式、正常模式。系统上电后即为休眠模式,通过这一寄存器的配置可以使BMP280压力温度传感器进入强制模式或正常模式运行。测量控制寄存器的各位定义如下图:

配置寄存器用于设置BMP280压力温度传感器的速率、过滤器以及接口模式。在休眠模式下写配置寄存器是允许的,但在正常模式下会被忽略,所以在系统复位后,进入正常模式前先写配置寄存器。配置寄存器各位的定义如下图所示:

压力数据寄存器存储有压力测量数据输出的原始值。使用了三个寄存器中的20位来下存储压力数据。压力数据寄存器各位的定义如下图所示:

温度数据寄存器存储有温度测量数据输出的原始值。使用了三个寄存器中的20位来下存储温度数据。温度数据寄存器各位的定义如下图所示:

此外还有校准数据寄存器,总共是26个寄存器,存储了计算压力温度最终值的厂家校准数据。这些校准寄存器的定义及地址分配如下图所示:

我们已经说过面向BMP280压力温度传感器的所有操作都是基于寄存器进行的,我们已经了解了BMP280压力温度传感器的各个寄存器,现在可以来实现它的操作了。

2、驱动设计与实现

我们已经比较详细的说明了BMP280的引脚定义、通讯接口、数据存储格式,在此基础上我们将设计并实现BMP280压力温度传感器的驱动程序。

2.1、对象定义

在使用一个对象之前我们需要获得一个对象。同样的我们想要BMP280压力温度传感器就需要先定义BMP280压力温度传感器的对象。

2.1.1、对象类型抽象

我们要得到BMP280压力温度传感器对象,需要先分析其基本特性。一般来说,一个对象至少包含两方面的特性:属性与操作。接下来我们就来从这两个方面思考一下BMP280压力温度传感器的对象。

先来考虑属性,作为属性肯定是用于标识或记录对象特征的东西。我们来考虑BMP280压力温度传感器对象属性。BMP280压力温度传感器的ID寄存器用于标识设备是否为BMP280;配置寄存器和测量控制寄存器都用关于系统配置,指示了设备的工作状态,所以我们将这三个寄存器定义为对象的属性。而使用的通讯接口决定了访问BMP280压力温度传感器的行为,所以我们需要记住这一配置;而校准数据则在计算数据时所要使用的,我们也需要记住这些参数,所以我们将它们也都定义为属性。在I2C接口模式时,设备地址是区分总线上设备的唯一标志,所以我们将其定义为属性。同样测量数据指示了设备当前的工作状态,我们将器作为属性。

接着我们还需要考虑BMP280压力温度传感器对象的操作问题。我们需要与BMP280压力温度传感器通讯就需要向其写数据并从其读数据,而不论是SPI接口还是I2C接口,读写操作都以来与具体的硬件平台,所以我们将他们作为对象的操作。此外,为控制时序,我们需要延时操作,而延时行为的实现亦依赖于具体的软硬件平台,所以我们将延时也作为对象的操作。

根据上述我们对BMP280压力温度传感器的分析,我们可以定义BMP280压力温度传感器的对象类型如下:

/*定义BMP280操作对象*/
typedef struct BMP280Object{uint8_t bmpAddress; //I2C接口时设备地址uint8_t chipID;   //芯片IDuint8_t config;    //配置寄存器uint8_t ctrlMeas; //测量控制寄存器BMP280PortType port;    //接口选择Bmp280CalibParamType caliPara;       //校准参数float pressure;     //压力值float temperature;      //温度值void (*Read)(struct BMP280Object *bmp,uint8_t regAddress,uint8_t *rData,uint16_t rSize);  //读数据操作指针void (*Write)(struct BMP280Object *bmp,uint8_t regAddress,uint8_t command);   //写数据操作指针void (*Delayms)(volatile uint32_t nTime);    //延时操作指针void (*ChipSelect)(BMP280CSType en);   //使用SPI接口时,片选操作
}BMP280ObjectType;

2.1.2、对象初始化

我们知道,一个对象仅作声明是不能使用的,我们需要先对其进行初始化,所以这里我们来考虑BMP280压力温度传感器对象的初始化函数。一般来说,初始化函数需要处理几个方面的问题。一是检查输入参数是否合理;二是为对象的属性赋初值;三是对对象作必要的初始化配置。据此我们设计BMP280压力温度传感器对象的初始化函数如下:

/* 实现BMP280初始化配置 */void BMP280Initialization(BMP280ObjectType *bmp,       //BMP280对象uint8_t bmpAddress,          //I2C接口是设备地址BMP280PortType port,         //接口选择TimeStandbyType t_sb,        //间隔周期IIRFilterCoeffType filter,   //过滤器UseSPI3wType spi3W_en,       //3线SPI控制TemperatureSampleType osrs_t,//温度精度PressureSampleType osrs_p,   //压力精度PowerModeType mode,          //电源模式BMP280Read Read,             //读数据操作指针BMP280Write Write,           //写数据操作指针BMP280Delayms Delayms,       //延时操作指针BMP280ChipSelect ChipSelect   //片选操作指针)
{uint8_t try_count = 5;uint8_t regAddress=0;uint8_t command=0;bmp->chipID=0x00bmp->pressure=0.0;bmp->temperature=0.0;bmp->bmpAddress=0x00;bmp->port=port;if(bmp->port==I2C){if((bmpAddress==0xEC)||(bmpAddress==0xEE)){bmp->bmpAddress=bmpAddress;}bmp->ChipSelect=NULL;}else{bmp->ChipSelect=ChipSelect;}bmp->Read=Read;bmp->Write=Write;bmp->Delayms=Delayms;bmp->caliPara.t_fine=0;if(!ObjectIsValid(bmp)){return;}while(try_count--){bmp->chipID=ReadBMP280Register(bmp,REG_BMP280_ID);if(0x58==bmp->chipID){BMP280SoftReset(bmp);break;}}if(try_count){/*配置配置寄存器:间隔周期0.5ms、IIR滤波系数16、不使用SPI3线通讯*/regAddress=REG_CONFIG;command=t_sb|filter|spi3W_en;WriteBMP280Register(bmp,regAddress,command);/*配置测量控制寄存器:温度20位,压力20位,电源正常模式*/regAddress=REG_CTRL_MEAS;command=osrs_t|osrs_p|mode;WriteBMP280Register(bmp,regAddress,command);bmp->Delayms(10);bmp->config=ReadBMP280Register(bmp,REG_CONFIG);bmp->Delayms(10);bmp->ctrlMeas=ReadBMP280Register(bmp,REG_CTRL_MEAS);bmp->Delayms(10);/*读取校准值*/GetBMP280CalibrationData(bmp);}
}

2.2、对象操作

我们已经完成了BMP280压力温度传感器对象类型的定义和对象初始化函数的设计。但我们的主要目标是获取对象的信息,接下来我们还要实现面向BMP280压力温度传感器的各类操作。

2.2.1、写寄存器

我们已经说过了,对BMP280的操作都是通过读写寄存器实现的。这里我们先来看写寄存器。在I2C接口方式下,写寄存器操作是在从站地址的最后一位来识别的,再加上要写的寄存器地址和数据来实现的,这也是I2C协议的标准做法。其时序图如下所示:

而在SPI接口方式下,由于SPI并未有设备地址,也不存在用从还在那地址最后为来标记读写的模式。通常一些设备需要定义操作码来实现读写区分,但BMP280采取了将寄存器地址的最高位置零表示为写。之所以可以这样定义,是因为BMP280寄存器地址分配的特殊性决定的。改变寄存器地址的最高位也能区分不同的寄存器,绝不会重复。在SPI接口方式下,写寄存器的时序图如下所示:

根据上述描述和时序图,我们可以实现写BMP280压力温度传感器寄存器的程序。

/* 向BMP280寄存器写一个字节 */
static void WriteBMP280Register(BMP280ObjectType *bmp,uint8_t regAddress,uint8_t command)
{if(ObjectIsValid(bmp)){if(bmp->port==BMP280_SPI){regAddress&=0x7F;bmp->ChipSelect(BMP280CS_Enable);bmp->Delayms(1);bmp->Write(bmp,regAddress,command);bmp->Delayms(1);bmp->ChipSelect(BMP280CS_Disable);}else{bmp->Write(bmp,regAddress,command);}}
}

2.2.2、读寄存器

读寄存器的处理方式与写寄存器是类似。在I2C接口方式下,将从站地址的最低位置1来表示读。在I2C接口方式下,读寄存器的时序图如下所示:

而在SPI接口方式下,通过将寄存器地址的最高位1来标识为读操作。事实上,所有寄存器地址的最高位都是1,所以在读操作时实际不需要做处理。在SPI接口方式下,读寄存器的时序图如下所示:

根据上述描述和时序图,我们可以实现读BMP280压力温度传感器寄存器的程序。

/*从BMP280寄存器读取一个字节*/
static uint8_t ReadBMP280Register(BMP280ObjectType *bmp,uint8_t regAddress)
{uint8_t regValue=0xFF;if(ObjectIsValid(bmp)){if(bmp->port==BMP280_SPI){regAddress |= 0x80;bmp->ChipSelect(BMP280CS_Enable);bmp->Delayms(1);bmp->Read(bmp,regAddress,&regValue,1);bmp->Delayms(1);bmp->ChipSelect(BMP280CS_Disable);}else{bmp->Read(bmp,regAddress,&regValue,1);}}return regValue;
}

3、驱动的使用

我们已经设计了BMP280压力温度传感器的驱动程序,接下来这一节我们将基于BMP280压力温度传感器的驱动程序设计一个简单的验证应用。

3.1、声明并初始化对象

使用基于对象的操作我们需要先得到这个对象,所以我们先要使用前面定义的BMP280压力温度传感器对象类型声明一个BMP280压力温度传感器对象变量,具体操作格式如下:

BMP280ObjectType bmp280;

声明了这个对象变量并不能立即使用,我们还需要使用驱动中定义的初始化函数对这个变量进行初始化。这个初始化函数所需要的输入参数如下:

BMP280ObjectType *bmpBMP280对象

uint8_t bmpAddressI2C接口是设备地址

BMP280PortType port,接口选择

BMP280TimeStandbyType t_sb,间隔周期

BMP280IIRFilterCoeffType filter,过滤器

BMP280UseSPI3wType spi3W_en3线SPI控制

BMP280TemperatureSampleType osrs_t,温度精度

BMP280PressureSampleType osrs_,压力精度

BMP280PowerModeType mode,电源模式

BMP280Read Read,读数据操作指针

BMP280Write Write,写数据操作指针

BMP280Delayms Delayms,延时操作指针

BMP280ChipSelect ChipSelect,片选操作指针

对于这些参数,对象变量我们已经定义了。接口选择、间隔周期、过滤器、3线SPI控制、温度精度、压力精度、电源模式等都是枚举量我们根据实际情况输入即可。而使用I2C接口时需要的设备地址,也按具体地址给入就好。主要的是我们需要定义几个函数,并将函数指针作为参数。这几个函数的类型如下:

/* 定义读数据操作函数指针类型 */
typedef void (*BMP280Read)(BMP280ObjectType *bmp,uint8_t regAddress,uint8_t *rData,uint16_t rSize);/* 定义写数据操作函数指针类型 */
typedef void (*BMP280Write)(BMP280ObjectType *bmp,uint8_t regAddress,uint8_t command);/* 定义延时操作函数指针类型 */
typedef  void (*BMP280Delayms)(volatile uint32_t nTime);/* 定义使用SPI接口时,片选操作函数指针类型 */
typedef  void (*BMP280ChipSelect)(BMP280CSType cs);

对于这几个函数我们根据样式定义就可以了,具体的操作可能与使用的硬件平台有关系。若采用的SPI接口则需注意片选操作,片选操作函数用于多设备需要软件操作时,如采用硬件片选可以传入NULL即可。同样如果采用的是I2C接口,则片选可以传入NULL即可。具体函数定义如下:

/*读BMP280寄存器值*/
static void ReadDataFromBMP280(BMP280ObjectType *bmp280,uint8_t regAddress,uint8_t *rData,uint16_t rSize)
{HAL_I2C_Master_Transmit(&bmp280hi2c, bmp280->bmpAddress,&regAddress,1,1000);HAL_I2C_Master_Receive(&bmp280hi2c, bmp280->bmpAddress+1,rData, rSize, 1000);
}/*写BMP280寄存器值*/
static void WriteDataToBMP280(BMP280ObjectType *bmp280,uint8_t regAddress,uint8_t command)
{uint8_t pData[2];pData[0]=regAddress;pData[1]=command;HAL_I2C_Master_Transmit(&bmp280hi2c,bmp280->bmpAddress, pData, 2,1000);
}

对于延时函数我们可以采用各种方法实现。我们采用的STM32平台和HAL库则可以直接使用HAL_Delay()函数。于是我们可以调用初始化函数如下:

BMP280Initialization(&bmp280,  //BMP280对象0xEC,           //I2C接口是设备地址BMP280_I2C,     //接口选择BMP280_T_SB_0P5,       //间隔周期BMP280_IIR_FILTER_COEFF_X16,         //过滤器BMP280_SPI3W_DISABLE,                //3线SPI控制BMP280_TEMP_SAMPLE_X16,  //温度精度BMP280_PRES_SAMPLE_X16,          //压力精度BMP280_POWER_NORMAL_MODE,      //电源模式ReadDataFromBMP280,  //读数据操作指针WriteDataToBMP280,     //写数据操作指针HAL_Delay,                     //延时操作指针NULL                                //片选操作指针);

3.2、基于对象进行操作

我们定义了对象变量并使用初始化函数给其作了初始化。接着我们就来考虑操作这一对象获取我们想要的数据。我们在驱动中已经将获取数据并转换为转换值的比例值,接下来我们使用这一驱动开发我们的应用实例。

/*获取大气压力和温度*/
void BMP280GetEnvironmentalData(void)
{float pressure;                   //压力值float temperature;      //温度值GetBMP280Measure(&bmp280);pressure=bmp280.pressure;temperature=bmp280.temperature;
}

4、应用总结

BMP280压力温度传感器的驱动已经实现并做了简单的应用。在我们测试时,得到的数据与其它方法获得的温度压力数据基本是一致的,这说明我们的驱动程序总体来说是正确的。

BMP280压力温度传感器支持SPII2C两种接口,而且SPI也支持3线和4线模式,但我们在测试应用中只使用了I2C接口,SPI接口还有待测试。

在使用驱动时需注意,采用SPI接口的器件需要考虑片选操作的问题。如果片选信号是通过硬件电路来实现的,我们在初始化时给其传递NULL值。如果是软件操作片选则传递我们编写的片选操作函数。而如果采用I2C接口,那么在初始化时也应传递NULL值。

BMP280压力温度传感器在使用SPI接口时,支持SPI模式0CPOL=CPHA=0)和模式3CPOL=CPHA=1)。而在使用I2C接口时,支持标准模式、快速模式以及高速模式。而且在使用I2C接口时,SDO引脚必须接高电平或低电平,以确定设备地址。

源码获取:https://github.com/foxclever/ExPeriphDriver

欢迎关注:

 

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

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

相关文章

一个简单的空气质量数据监测站项目

大气质量数据监测站用于测试空气质量监测及数据采集,实现野外或者室内空气质量的检测。并通过网络将数据上传到OneNet​显示。​ 1、项目概述 本项目是一个定制项目,要求采集大气的压力、温度、湿度、PM25、位置等数据并上传到指定的后台服务器。但有时…

一个基于STM32实现的多组分气体分析仪项目

本篇将简要的总结一下一个基于STM32F412ZG实现的多组分气体分析仪的项目。简要描述该项目的软硬件设计及其验证。 一、项目概述 多组分气体分析仪是我公司近期研发的三个主要产品之一。采用模块化设计,可增减配置,可分析混合气体中的氧气、氢气、甲烷、…

外设驱动库开发笔记20:BME280压力湿度温度传感器驱动

嵌入式产品开发中,我们常常会有检测环境温度、压力、湿度的需求。如果有一个集成有这3个传感器的元件,无疑将是很方便的。博世的BME280就能实现这一要求。在这一篇中我们将讨论BME280的驱动设计与实现。 1、功能概述 BME280是一款专为移动应用而开发的…

外设驱动库开发笔记21:BME680环境传感器驱动

环境传感器是一类我们很常用的传感器。它可以方便我们获取压力、温度、湿度以及空气质量等数据。在这一篇中,我们将分析BME680环境传感器的功能,并设计和实现BME680环境传感器的驱动。 1、功能概述 BME680是一款专为移动应用和可穿戴设备开发的集成环境…

外设驱动库开发笔记22:ADXL345三轴数字加速度计驱动

移动设备的广泛应用增加对移动过程中各种参数的检测需求。ADXL345三轴数字加速度计可以用来检测加速度、进而测量倾斜角度等。在这一篇中,我们将讨论ADXL345三轴数字加速度计驱动程序的设计与实现。 1、功能概述 ADXL345是一款小而薄的超低功耗3轴加速度计&#x…

外设驱动库开发笔记23:AT24Cxx外部存储器驱动

在我们的应用开发过程中,经常会使用到外部的EEPROM外部存储器来保存一些参数和配置数据等。而比较常用的就是AT24Cxx系列产品,这一节我们来开发用于操作AT24Cxx系列产品的驱动。 1、功能概述 AT24Cxx系列EEPROM包括从1Kbit到2Mbit的各种容量。AT24Cxx系…

外设驱动库开发笔记24:FM24xxx系列FRAM存储器驱动

虽然说使用EEPROM保存参数很有效,但操作及使用次数均有一下限制。当我们的一些参数需要不定时修改或存储时,使用FRAM就更为方便一点。这一节我们就来设计并实现FM24xxx系列FRAM的驱动。 1、功能概述 我们首先说一下铁电随机存取存储器,F-RA…

外设驱动库开发笔记25:FM25xxx FRAM存储器驱动

在我们的项目中,时常会有参数或数据需要保存。铁电存储器的优良性能和操作方便常常被我们选用。FM25xxx FRAM存储器就是我们经常使用到的一系列铁电存储器,这一篇我们将讨论FM25xxx FRAM存储器的驱动设计、实现及使用。 1、功能概述 FM25xxx FRAM存储器…

步进电机驱动技术1:基于TMC2660的步进电机驱动

步进电机的应用非常广泛,在各种设备中经常会遇到,而步进电机的驱动则是使用步进电机必不可少的部分,可以有多种方式来实现步进电机的驱动,在这里我们来考虑一下基于TMC2660驱动芯片的步进电机驱动。 1、功能概述 TMC2660是德国T…

外设驱动库开发笔记26:nRF24L01无线通讯驱动

现在无线在我们的生活中无处不在。而我们开发的物联网产品也大量使用无线通讯。在这一篇文章中,我们将讨论nRF24L01无线通讯模块驱动程序的开发与实现。 1、功能概述 nRF24L01是一款工作在2.4~2.5GHz世界通用ISM 频段的单片无线收发器芯片无线收发器包括&#xff…

外设驱动库开发笔记27:ESP8266无线通讯驱动

我们的物联网产品所使用的平台都支持无线通讯,而且无线通讯本身更的成本较低,受到大家的欢迎。在本篇文章中,我们将详细讨论并实现ESP8266无线通讯模块的驱动。 1、功能概述 ESP8266是由乐鑫公司出品的一款物联网芯片,因为价格较…

外设驱动库开发笔记28:W5500以太网控制器

以太网通讯是一种被广泛使用的数据通讯方式。在嵌入式应用中也经常使用,但协议栈的实现并不是一件容易的事。不过有些以太网控制器就带有协议栈,如W5500。在本篇中我们将讨论如何设计并实现W5500以太网控制器的驱动。 1、功能概述 W5500是WIZnet开发的…

外设驱动库开发笔记29:DS17887实时时钟驱动

一些时候,在我们的嵌入式产品中需要记录时间,所以我们就需要获取时钟,当然实现的方式多种多样,有的MCU本身就有这一功能,不过精度较低。当我们的应用要求较高时就需要使用专门的实时时钟芯片,如DS17887。在…

外设驱动库开发笔记30:宇电AI-BUS通讯驱动

嵌入式系统通常都会与外部设备进行通讯,这就涉及到通讯协议的问题。这些通讯协议有的是标准协议有的厂家自定义的协议,如宇电的AI-BUS。在本篇中,我们将讨论AI-BUS的驱动,以便于与宇电设备的通讯。 1、功能概述 宇电的设备使用基…

步进电机驱动技术3:基于ULN2003的步进电机驱动

在我们的项目中,经常使用到低电压小功率的步进电机,此类步进电机若采用驱动器控制不断成本高也过于复杂,我们可以直接使用场效应管或者达林顿管来实现对其的驱动。在本篇中,我们就来讨论一下基于ULN2003A达林顿管实现对步进电机的…

通讯接口应用笔记2:MAX3160实现多协议通讯

在一些应用需求中,我们需要对外部提供串行通讯端口,但这些端口所通讯的目标设备各有不同,接口协议也有RS232以及RS485和RS422多种。面对这种情况,我们当然可以同时设计多个串口以适应不同需要,但无疑对硬件资源是一种浪…

电机速度曲线规划1:梯形速度曲线设计与实现

电机驱动是很常见的应用,在很多系统中我们都会碰到需要改变电机的速度以实现相应的控制功能,这就涉及到电机速度曲线规划的问题。在这篇中我们就来简单讨论一下电机的梯形曲线规划的问题。 1、基本原理 梯形速度曲线控制算法是工业控制领域应用最为广泛…

文件系统应用笔记之一:FatFS在STM32F4上的移植

在实现如U盘文件读写,SD卡的文件读写等工作时,我们往往需要一个文件系统来支持我们的工作。特别在一些MCU应用中,文件系统的加入能明显改善系统交互的友好性。在这一篇中,我们就来讨论FatFS文件系统在STM32F4上的移植和应用。 1、…

通讯接口应用笔记3:使用W5500实现Modbus TCP服务器

前面我们设计实现了W5500的驱动程序,也讲解了驱动的使用方式。在最近一次的项目应用中,正好有一个使用W5500实现TCP通讯的需求,所以我们就使用该驱动程序轻松实现。这一篇中我们就来说一说基于我们W5500通讯驱动程序实现TCP通讯的过程。 1、…

电机速度曲线规划2:S形速度曲线设计与实现

电机驱动是很常见的应用,在很多系统中我们都会碰到需要改变电机的速度以实现相应的控制功能,这就涉及到电机速度曲线规划的问题。在这篇中我们就来简单讨论一下电机的S型曲线规划的问题。 1、基本原理 S型速度曲线控制算法是工业控制领域另一种常用的加…