本帖最后由 swtman 于 2025-8-17 08:31 编辑
#申请原创#
@21小跑堂
室内气压计 1. 前言
1-拿到一款瑞萨的开发板:RA6E2,已经有一段时间了。一直没想好做点啥,整理物品的时候,发现一个闲置的BMP 180气压温度模块。刚好家里也有没有气压计,那就做一个室内气压计吧。顺便把日历时钟也做上了。
2. 实际效果图
本来以为会很简单呢,断断续续的弄了好一阵子才完成啊。果然打工人有点爱好不容易啊,卡克了都没有一起讨论,只能自己为爱发热啊。不过自己还挺满意的,实现最终效果如下:
图 1 项目验证实物图-气压温度海拔功能
图 2 项目验证实物图-日历时钟功能
后续若做成无线模式的,就可以连接手机和电脑,效果会更好。硬件方面可以做一个桌面小盒子,会更方便摆放哦。 3. 系统硬件设计
本项目需要使用一些外设和模块,因此需要进行硬件设计。
3.1. 系统整体设计
主控采用RA-Eco-RA6E2-64PIN-V1.0开发板,通过模拟IIC采集BMP180传感器数据,然后通过OLED显示屏显示计算的气压和温度,并通过串口将数据发送给电脑或者手机等终端。通过按键可以更改显示模式。开发板通过LED闪烁提示系统正常运行。
图 3 整体硬件架构图
3.2. RA6E2开发板
RA-Eco-RA6E2-64PIN-V1.0是一款基于100MHz Arm® Cortex®-M33内核架构的核心板,主控芯片为R7FA6E2BB3CFM。RA6E2组是RA6系列中最新的入门级微控制器,基于带有TrustZone®的200MHz Arm® Cortex®-M33内核。RA6E2 MCU作为入门级微控制器,在追求成本优化的同时提供了最佳的性能。与RA4E2组的引脚和外设兼容,使其成为要求更高性能、小尺寸和低引脚数的应用的理想选择。
以上是官方的介绍,这个开发板的相关接口和资源介绍如下:
·1个复位按键,1个用户按键,2个LED,2个PMOD接口,板载USB转TTL模块,可用于串口通信和烧录,板载SWD接口,方便用户调试与下载,200MHz的Arm Cortex-M33,具有TrustZone功能,256KB的闪存和40KB的SRAM,4KB数据闪存,类似EEPROM数据存储功能,1KB待机SRAM,64引脚封装,USB 2.0全速,CAN FD,I3C,HDMI CEC,SSI,Quad SPI,12位A/D转换器,12位D/A转换器,通用PWM定时器。
本项目只是使用部分接口和资源。
3.3. OLED显示屏
0.96寸OLED显示屏窄白光IIC接口,屏幕分辨率为128X64。这个屏幕从立创商城购买来。链接如下:
https://item.szlcsc.com/5960631.html?spm=sc.ols.it2-1___sc.hm.hd.dd&lcsc_vid=TgJXAgVTFgdaUVFeQVZaBAFfFAJbU11e**MUV0FRlQxVlNTQlBdX1xQQFRaUDtW
相关参数如下:
图 4 OLED显示屏采购
3.4. 气压传感器
本项目采用BMP180传感器,这是是一款高精度、小体积、低能耗的压力传感器可以应用在移动设备中。它的性能卓越,精度可以达到0.03hPa,并且耗电低,只有3uA。建议在淘宝上购买,链接如下:
BMP180 BME280 高精度大气压强传感器模块 气压传感器模块 高度计-淘宝网
规格参数如下:
工作电压:1.8~3.6V
工作电流:0.1~1000uA
温度精度:±1℃
温度范围:0~65℃
气压范围:300~1100 hPa
气压精度:1 hPa
输出方式: IIC
图 5 BMP180传感器模块
3.5. LED灯
这里直接使用开发板上的2个LED灯,不再详述,相关原理图如下图所示:
图 6 LED控制IO
3.6. 按键
这里直接使用开发板上的1个key,不再详述,相关原理图如下图所示:
图 7 KEY控制IO
需要对相关GPIO进行配置,后续软件使用中断模式。
3.7. 调试下载接口
这里直接使用开发板上的SWD接口,不再详述,相关原理图如下图所示:
图 8 SWD接口
需要对相关GPIO进行配置,本项目采用JLINK下载和调试。
4. 系统软件设计
通过RASC进行初始参数配置,基于keil MDK平台使用C语言进行编码。
4.1. OLED的IIC配置与关键代码实现
OLED使用的IIC的IO分别是SDA:P408、SCL:P409。为了屏幕刷新的更快,这里配置速度为FAST-MODE。大约400KBPS。需要注意选择IIC的通道,SLAVE的地址:0x3c,并命名好回调函数。具体配置如下图所示:
图 9 OLED的IIC配置
回调函数实现如下:
i2c_master_event_t i2c_event = I2C_MASTER_EVENT_ABORTED;
void sci_i2c_master_callback(i2c_master_callback_args_t *p_args)
{
i2c_event = I2C_MASTER_EVENT_ABORTED;
if (NULL != p_args)
{
/* capture callback event for validating the i2c transfer event*/
i2c_event = p_args->event;
}
}
int timeout_ms = 100;
当然这里还有屏幕的驱动代码等,由于篇幅所限,不再详述。该屏幕的使用属于常规操作。具体可以查看工程源码。
在这里需要注意一下汉字取模,我采用的是在线进行汉字取模。网站链接如下:
https://www.23bei.com/tool/216.html
我需要使用的汉字是:年月日温度气压海拔桌面电子时钟室内计。通过在线取模,参数配置如下图所示: 4.2. BMP180传感器的IO配置与关键代码实现
该传感器需要2个IO,为了和屏幕区分开来。这里使用了模拟IIC。即SCL:P303,SDA:P304,否则通信会有问题。管脚的软件配件如下图所示:
图 11 BMP180传感器通信IO-SCL
图 12 BMP180传感器通信IO-SDA
该传感器的驱动代码官方已经写好,只需要对IO和延时程序重新移植即可。
相关需要自行配置和修改的函数如下:
#define I2C_SDA_PORT BSP_IO_PORT_03 // SDA引脚
#define I2C_SCL_PORT BSP_IO_PORT_03 // SCL引脚
// 定义I2C引脚 - 根据实际硬件连接修改
#define I2C_SDA_PIN BSP_IO_PORT_03_PIN_04 // SDA引脚
#define I2C_SCL_PIN BSP_IO_PORT_03_PIN_03 // SCL引脚
#define delay_us(N) R_BSP_SoftwareDelay(N, BSP_DELAY_UNITS_MICROSECONDS)
#define delay_1ms(N) R_BSP_SoftwareDelay(N, BSP_DELAY_UNITS_MILLISECONDS)
//设置SDA输出模式
#define SDA_OUT() R_IOPORT_PortDirectionSet(&g_ioport_ctrl, I2C_SDA_PORT,0x0010,0x0010)
//设置SDA输入模式
#define SDA_IN() R_IOPORT_PortDirectionSet(&g_ioport_ctrl, I2C_SDA_PORT,0,0x0010)
//SDA与SCL输出
#define SDA(x) R_IOPORT_PinWrite(&g_ioport_ctrl, I2C_SDA_PIN, (x?BSP_IO_LEVEL_HIGH:BSP_IO_LEVEL_LOW))
#define SCL(x) R_IOPORT_PinWrite(&g_ioport_ctrl, I2C_SCL_PIN, (x?BSP_IO_LEVEL_HIGH:BSP_IO_LEVEL_LOW))
bsp_io_level_t SDA_GET(void)
{
bsp_io_level_t x=0;
if(R_IOPORT_PinRead(&g_ioport_ctrl,I2C_SDA_PIN,&x)==FSP_SUCCESS){
return x;
}
return 1;
}
4.3. LED的GPIO配置与关键代码实现
这里需要配置2个IO分别是P207、P113分别对应LED1、LED2。配置起来非常简单,将设置为输出即可,配置分别如下图所示:
图 13 LED1控制IO配置
图 14 LED2控制IO配置
具体代码实现控制LED亮灭非常简单,如下所示:
#define LED1_TOGGLE R_PORT2->PODR ^= 1<<(BSP_IO_PORT_02_PIN_07 & 0xFF)
#define LED2_TOGGLE R_PORT1->PODR ^= 1<<(BSP_IO_PORT_01_PIN_13 & 0xFF)
4.4. KEY的GPIO配置与关键代码实现
这里需要配置1个IO是P0055。配置起来非常简单,将设置为输入,类型位中断即可,配置分别如下图所示:
图 15 KEY控制IO配置
图 16 KEY中断配置
需要自己编写中断初始化和回调函数,如下所示:
/* KEY 外部中断初始化函数 */
void Key_IRQ_Init(void)
{
/* Open ICU module */
err = R_ICU_ExternalIrqOpen(&g_external_irq10_ctrl, &g_external_irq10_cfg);
/* 允许中断 */
err = R_ICU_ExternalIrqEnable(&g_external_irq10_ctrl);
}
uint8_t key_cnt=0;
uint8_t key_clr=0;
/* 按键中断回调函数 */
void key_external_irq_callback(external_irq_callback_args_t *p_args)
{
/* 判断中断通道 */
if (10 == p_args->channel)
{
key_cnt++;
key_cnt %=2;
key_clr=1;
}
}
4.5. UART接口配置与关键代码实现
UART的相关配置如下:
图 17 UART通信接口配置
相关的回调函数需要自己进行实现,相关代码如下:
fsp_err_t err = FSP_SUCCESS;
unsigned char send_buff[100];
volatile bool uart_send_complete_flag = false;
void g_uart9_callback (uart_callback_args_t * p_args)
{
if(p_args->event == UART_EVENT_TX_COMPLETE)
{
uart_send_complete_flag = true;
}
}
为了方便调试,和打印相关信息。这里对printf函数进行了重定向,相关代码如下所示:
/* 重定向 printf 输出 */
#if defined __GNUC__ && !defined __clang__
int _write(int fd, char *pBuffer, int size); //防止编译警告
int _write(int fd, char *pBuffer, int size)
{
(void)fd;
R_SCI_UART_Write(&g_uart4_ctrl, (uint8_t *)pBuffer, (uint32_t)size);
while(uart_send_complete_flag == false);
uart_send_complete_flag = false;
return size;
}
#else
int fputc(int ch, FILE *f)
{
(void)f;
R_SCI_UART_Write(&g_uart9_ctrl, (uint8_t *)&ch, 1);
while(uart_send_complete_flag == false);
uart_send_complete_flag = false;
return ch;
}
#endif
4.6. SWD调试与下载接口配置
由于我手头上有j-link调试器,所以配置SWD接口,不仅能适配我的调试器,还可以节省IO。具体配置如下图所示:
图 18 SWD调试下载接口配置
4.7. RTC配置
为了实现日历和时钟功能,需要进行如下配置:
图 19 RTC配置
RTC还需要进行初始化和各种配置函数,如下所示:
/* rtc_time_t is an alias for the C Standard time.h struct 'tm' */
rtc_time_t set_time =
{
.tm_sec = 50, /* 秒,范围从 0 到 59 */
.tm_min = 58, /* 分,范围从 0 到 59 */
.tm_hour = 10, /* 小时,范围从 0 到 23*/
.tm_mday = 9, /* 一月中的第几天,范围从 1 到 31*/
.tm_mon = 7, /* 月份,范围从 0 到 11*/
.tm_year = 125, /* 自 1900 起的年数,2021为121*/
// .tm_wday = 5, /* 一周中的第几天,范围从 0 到 6*/
// .tm_yday=0, /* 一年中的第几天,范围从 0 到 365*/
// .tm_isdst=0; /* 夏令时*/
};
/* Initialize the RTC module*/
err = R_RTC_Open(&g_rtc0_ctrl, &g_rtc0_cfg);
/* Handle any errors. This function should be defined by the user. */
assert(FSP_SUCCESS == err);
/* R_RTC_CalendarTimeSet must be called at least once to start the RTC */
R_RTC_CalendarTimeSet(&g_rtc0_ctrl, &set_time);
/* Set the periodic interrupt rate to 1 second */
R_RTC_PeriodicIrqRateSet(&g_rtc0_ctrl, RTC_PERIODIC_IRQ_SELECT_1_SECOND);
4.8. 低功耗模式配置
为了板子的功耗更低,这里采用了空闲时候让系统进入休眠模式,通过RTC中断可以唤醒。
图 20 低功耗模式配置
4.9. 主程序设计
由于在RASC中已经配置了相关的外设,这里只需要调用即可。因此主程序实现如下:
/*******************************************************************************************************************//**
* main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used. This function
* is called by main() when no RTOS is used.
**********************************************************************************************************************/
void hal_entry(void)
{
/* TODO: add your own code here */
err = R_SCI_UART_Open(&g_uart9_ctrl, &g_uart9_cfg);
assert(FSP_SUCCESS == err);
/* Initialize the RTC module*/
err = R_RTC_Open(&g_rtc0_ctrl, &g_rtc0_cfg);
/* Handle any errors. This function should be defined by the user. */
assert(FSP_SUCCESS == err);
/* R_RTC_CalendarTimeSet must be called at least once to start the RTC */
R_RTC_CalendarTimeSet(&g_rtc0_ctrl, &set_time);
/* Set the periodic interrupt rate to 1 second */
R_RTC_PeriodicIrqRateSet(&g_rtc0_ctrl, RTC_PERIODIC_IRQ_SELECT_1_SECOND);
uint8_t rtc_second= 8; //秒
uint8_t rtc_minute =8; //分
uint8_t rtc_hour =12; //时
uint8_t rtc_day =30; //日
uint8_t rtc_month =06; //月
uint16_t rtc_year =122; //年
uint8_t rtc_week =0; //周
rtc_time_t get_time;
/* IIC初始化*/
err = R_SCI_I2C_Open(&g_i2c0_ctrl, &g_i2c0_cfg);
assert(FSP_SUCCESS == err);
WriteCmd();//OLED初始化
OLED_Clear();//清屏
BMP180_GPIO_Init();
BMP180_Get_param();
printf("start\r\n");
R_BSP_PinAccessEnable(); //启用对PFS寄存器的访问,因为后面写IO口都用BSP内联函数
R_LPM_Open(sleep.p_ctrl, sleep.p_cfg); //打开LPM
Key_IRQ_Init();
while(1)
{
if(rtc_flag)
{
R_RTC_CalendarTimeGet(&g_rtc0_ctrl, &get_time);//获取RTC计数时间
rtc_flag=0;
rtc_second=get_time.tm_sec;//秒
rtc_minute=get_time.tm_min;//分
rtc_hour=get_time.tm_hour;//时
rtc_day=get_time.tm_mday;//日
rtc_month=get_time.tm_mon;//月
rtc_year=get_time.tm_year; //年
rtc_week=get_time.tm_wday;//周
printf ("\r\n%4d年%02d月%02d日 %02d:%02d:%02d\r\n", get_time.tm_year + 1900, get_time.tm_mon + 1, get_time.tm_mday,
get_time.tm_hour, get_time.tm_min, get_time.tm_sec);
if(1==key_clr)
{
printf("Key Press:%d\r\n",key_cnt);
key_clr=0;
OLED_Clear();//清屏
}
switch(key_cnt){
case 1:
OLED_ShowCHinese(16,1,9);//桌面电子时钟
OLED_ShowCHinese(32,1,10);//
OLED_ShowCHinese(48,1,11);//
OLED_ShowCHinese(64,1,12);//
OLED_ShowCHinese(80,1,13);//
OLED_ShowCHinese(96,1,14);//
OLED_ShowCHinese(40,5,0);//年
OLED_ShowCHinese(72,5,1);//月
OLED_ShowCHinese(104,5,2);//日
OLED_ShowNum(8,5,rtc_year+1900,4,16);//年
OLED_ShowNum(56,5,rtc_month,2,16);//月
OLED_ShowNum(88,5,rtc_day,2,16);//日
OLED_ShowChar(48,3,':',16);
OLED_ShowChar(72,3,':',16);
OLED_ShowNum(32,3,rtc_hour,2,16);//时
OLED_ShowNum(56,3,rtc_minute,2,16);//分
OLED_ShowNum(80,3,rtc_second,2,16);//秒
break;
case 0:
char str[16]={0};
OLED_ShowCHinese(16,0,15);//室内气压计
OLED_ShowCHinese(32,0,16);//
OLED_ShowCHinese(48,0,5);//
OLED_ShowCHinese(64,0,6);//
OLED_ShowCHinese(80,0,17);//
BMP180_Get_Pressure();
printf("temp = %.2f\r\n", T);
printf("Pressure = %.2f\r\n",P);
BMP180_Get_Altitude();
printf("altitude = %.2f\r\n",H);
OLED_ShowCHinese(0,2,3);//温
OLED_ShowCHinese(16,2,4);//度
sprintf(str,":%7.2fC",T);
OLED_ShowString(32,2,str,16);
OLED_ShowCHinese(0,4,5);//气
OLED_ShowCHinese(16,4,6);//压
sprintf(str,":%6.0fPa",P);
OLED_ShowString(32,4,str,16);
OLED_ShowCHinese(0,6,7);//海
OLED_ShowCHinese(16,6,8);//拔
sprintf(str,":%7.2fm",H);
OLED_ShowString(32,6,str,16);
break;
default:break;
}
/*打印当前时间*/
LED1_TOGGLE;
LED2_TOGGLE;
}
/*睡眠前打印*/
printf("MCU进入睡眠模式\r\n");
/*执行完流水灯任务,进入睡眠模式*/
R_LPM_LowPowerModeEnter(sleep.p_ctrl);
/*被唤醒后打印*/
printf("MCU已被唤醒\r\n");
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
代码编译成功后,会有如下提示:
图 21 代码编译成功提示
程序下载成功后会有提示,并需要重新手动复位:
图 23 程序下载成功提示
需要注意的是,下载器必须支持ARMV8,否则下载不了。
程序调试,可以观测到串口输出如下:
图 24 程序调试输出验证
切换模式正常,低功耗模式进入和唤醒正常。说明程序运行正常。
最终的效果图参见第二章节的最终成品图。
系统演示可以查看如下链接:
https://www.bilibili.com/video/BV1rYYezeEqB/?vd_source=e36622a05269c0356d6cd566056a2488
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注册
×
|