一、RA2L1瑞萨新近推出M23核芯片
瑞萨芯片给我的第一印象是车规级的,日本车上使用得多
Cortex-M23 =
Cortex-M0/M0 + 硬件除法器 + 性能提升 +
专门的栈溢出硬件检测+
指令集不可忽略的小动作 +
安全扩展(TrustZone for Armv8-M) +
MPU开发者模型的友好化改进
二、rt-thread studio已经对RA2L1进行SDK适配,安装瑞萨的配置包及BSP包即可进行开发
2-1 灵活配置软件包 (FSP) 安装
可快速配置开发板的外设功能,请使用 v3.5.0 版本,目前可在github上下载3.5.0版本(下载地址:https://github.com/renesas/fsp/releases/tag/v3.5.0
(注意文件名称为:setup_fsp_v3_5_0_rasc_v2021-10.exe)
1、找到下载的文件打开(注意文件名称包含为rasc):setup_fsp_v3_5_0_rasc_v2021-10.exe
2、配置安装路径,安装完成后找到此路径,之后添加 CPK-RA2L1 板级支持包时会用到
3、勾选 Licenese
4、点击 install 等待安装完成。
5、运行 rasc.exe,验证是否安装成功。路径:\eclipse\rasc.exe
6、成功启动后关闭即可,继续接下来的操作
2-2 CPK-RA2L1 板级支持包安装
此部分,你可以参考Renesas官网文档《向FSP中添加CPK评估板的BSP 》https://www2.renesas.cn/cn/zh/document/gde/1596896″ />
2、在下载的支持包中可以找到以下三个文件
3、此时找到 FSP 的安装路径,进入 \internal\projectgen\ra\ ,将文件复制到对应的文件夹中。
4、再次打开 rasc.exe,查看是否添加成功。点击 next 进入工程创建
5、确认是否存在已添加的 CPK-RA2L1 开发板的支持包,此步骤仅为验证是否添加成功,不必继续创建工程,关闭即可。
到此基本将瑞萨开发板相关的环境搭建完成。
2-3 在rt-studio安装RA2L1的SDK包
完成以上操作,即可使用rt_thread studio进行开发工作
三、一个简单实例通过串口读取PM2.5模组空气质量的数据显示于数码管上
3-1、通过串口读取传感器数值解释完后,显示到数码管,数码管驱动为595串行动态扫描方式
程序分为2个线程,一个数据解释线程,一个数码管扫描显示线程
3-2、硬件连接
数码管模组原理图
3-3、rt-thread studio驱动配置
RT_Thread settings中打开UART0
3-4、RA Smart Configurator配置
添加g_uart0 UART驱动
配置SC0为异步串口,选择101 100引脚
3-5、代码编写
PM2.5 接收及解释
#include #include #include #include "display.h"#define DBG_TAG "app.pm25"#define DBG_LVL DBG_LOG#include static rt_device_t serial;static pm25_state_t pm25_state;uint16_t pm25_data_convert(uint8_t h, uint8_t l){ return h<<8|l;}void pm25_thread_entry(void *parameter){ uint8_t ch; serial = rt_device_find("uart0"); if (!serial) { LOG_E("find %s failed!\n", "uart1"); return; } else{ struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; /* 初始化配置参数 */ /* step2:修改串口配置参数 */ config.baud_rate = BAUD_RATE_9600; //修改波特率为 9600 config.data_bits = DATA_BITS_8; //数据位 8 config.stop_bits = STOP_BITS_1; //停止位 1 config.tx_bufsz = 0; //修改缓冲区 buff size 为 128 config.rx_bufsz = 128; //修改缓冲区 buff size 为 128 config.parity = PARITY_NONE; //无奇偶校验位 /* step3:控制串口设备。通过控制接口传入命令控制字,与控制参数 */ rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config); rt_device_open(serial, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); } while(1){// rt_thread_delay(10); if( rt_device_read(serial, -1, &ch, 1) > 0 ){ pm25_state.recv_time = 10; switch( pm25_state.recv_state ) { case RECV_START1: if( ch==0x42 ){ pm25_state.recv_state++; pm25_state.recv_buf[pm25_state.recv_index++] = ch; } break; case RECV_START2: if( ch==0x4d ){ pm25_state.recv_state++; pm25_state.recv_buf[pm25_state.recv_index++] = ch; } break; case RECV_LEN1: pm25_state.recv_state++; pm25_state.recv_buf[pm25_state.recv_index++] = ch; pm25_state.recv_len = ch<<8; break; case RECV_LEN2: pm25_state.recv_state++; pm25_state.recv_buf[pm25_state.recv_index++] = ch; pm25_state.recv_len |= ch; break; case RECV_DATA: if( pm25_state.recv_index < pm25_state.recv_len ){ pm25_state.recv_buf[pm25_state.recv_index++] = ch; if( pm25_state.recv_index == pm25_state.recv_len ){ pm25_state.recv_state++; } } break; case RECV_END:// LOG_HEX("REPLY", 16, pm25_state.recv_buf, 32); pm25_state.recv_state = 0; pm25_state.recv_index = 0; pm25_decode_t *pm25_decode_ptr = (pm25_decode_t *)pm25_state.recv_buf; pm25_state.pm25_data.pm1_0 = pm25_data_convert(pm25_decode_ptr->pm1_0_h,pm25_decode_ptr->pm1_0_l); pm25_state.pm25_data.pm2_5 = pm25_data_convert(pm25_decode_ptr->pm2_5_h,pm25_decode_ptr->pm2_5_l); pm25_state.pm25_data.pm10 = pm25_data_convert(pm25_decode_ptr->pm10_h,pm25_decode_ptr->pm10_l); pm25_state.pm25_data.pm1_0_air = pm25_data_convert(pm25_decode_ptr->pm1_0_air_h,pm25_decode_ptr->pm1_0_air_l); pm25_state.pm25_data.pm2_5_air = pm25_data_convert(pm25_decode_ptr->pm2_5_air_h,pm25_decode_ptr->pm2_5_air_l); pm25_state.pm25_data.pm10_air = pm25_data_convert(pm25_decode_ptr->pm10_air_h,pm25_decode_ptr->pm10_air_l); pm25_state.pm25_data.quantity_0_3 = pm25_data_convert(pm25_decode_ptr->quantity_0_3_h,pm25_decode_ptr->quantity_0_3_l); pm25_state.pm25_data.quantity_0_5 = pm25_data_convert(pm25_decode_ptr->quantity_0_5_h,pm25_decode_ptr->quantity_0_5_l); pm25_state.pm25_data.quantity_1_0 = pm25_data_convert(pm25_decode_ptr->quantity_1_0_h,pm25_decode_ptr->quantity_1_0_l); pm25_state.pm25_data.quantity_2_5 = pm25_data_convert(pm25_decode_ptr->quantity_2_5_h,pm25_decode_ptr->quantity_2_5_l); pm25_state.pm25_data.quantity_5_0 = pm25_data_convert(pm25_decode_ptr->quantity_5_0_h,pm25_decode_ptr->quantity_5_0_l); pm25_state.pm25_data.quantity_10 = pm25_data_convert(pm25_decode_ptr->quantity_10_h,pm25_decode_ptr->quantity_10_l); pm25_state.pm25_data.version = pm25_decode_ptr->version; pm25_state.pm25_data.err_code = pm25_decode_ptr->err_code; display_dig(pm25_state.pm25_data.pm2_5_air);//// LOG_D("pm1_0 = %d",pm25_state.pm25_data.pm1_0);// LOG_D("pm2_5 = %d",pm25_state.pm25_data.pm2_5);// LOG_D("pm10 = %d",pm25_state.pm25_data.pm10);//// LOG_D("pm1_0_air = %d",pm25_state.pm25_data.pm1_0_air);// LOG_D("pm2_5_air = %d",pm25_state.pm25_data.pm2_5_air);// LOG_D("pm10_air = %d",pm25_state.pm25_data.pm10_air);//// LOG_D("quantity_0_3 = %d",pm25_state.pm25_data.quantity_0_3);// LOG_D("quantity_0_5 = %d",pm25_state.pm25_data.quantity_0_5);// LOG_D("quantity_1_3 = %d",pm25_state.pm25_data.quantity_1_0);// LOG_D("quantity_2_5 = %d",pm25_state.pm25_data.quantity_2_5);// LOG_D("quantity_5_0 = %d",pm25_state.pm25_data.quantity_5_0);// LOG_D("quantity_10 = %d",pm25_state.pm25_data.quantity_10);// LOG_D("\n"); break; default: break; } if( pm25_state.recv_time > 0 ){ pm25_state.recv_time --; if( pm25_state.recv_time==0 ){ pm25_state.recv_state = RECV_START1; pm25_state.recv_index = 0; LOG_E("recv timeout"); } } }// rt_device_write(serial, 0,"hello world",11); rt_thread_delay(10); }}void pm25_init(void){ rt_thread_t tid1 = RT_NULL; tid1 = rt_thread_create("pm25", pm25_thread_entry, RT_NULL, 512, 10, 10); if (tid1 != RT_NULL) rt_thread_startup(tid1);}INIT_APP_EXPORT(pm25_init);
595动态扫描显示线程
/* * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2023-02-18 dmjku the first version */#include #include #include "display.h"disp_buf_t disp_buf;#define SERIAL_RCLK_PIN "P302"#define SERIAL_SCLK_PIN "P303"#define SERIAL_DIO_PIN "P301"rt_uint32_t rclk_pin;rt_uint32_t sclk_pin;rt_uint32_t dio_pin;#define serial_rclk_pin(sta) rt_pin_write(rclk_pin, sta)#define serial_sclk_pin(sta) rt_pin_write(sclk_pin, sta)#define serial_dio_pin(sta) rt_pin_write(dio_pin, sta)const uint8_t dig_code[]={ /********生成 0-f 的编码********/ 0xC0,0 0xF9,1 0xA4,2 0xB0,3 0x99,4 0x92,5 0x82,6 0xF8,7 0x80,8 0x90,9 0x88,A 0x80,B 0xC6,C 0xC0,D 0x86,E 0x8E,F};void display_dig(uint16_t dig){ uint8_t zero=0; if( dig/1000 ){ disp_buf.dig[0] = dig_code[dig/1000]; dig %= 1000; zero = 1; } else{ disp_buf.dig[0] = 0xff; } if( dig/100 ){ disp_buf.dig[1] = dig_code[dig/100]; dig %= 100; zero = 1; } else if(zero){ disp_buf.dig[1] = dig_code[0]; } else{ disp_buf.dig[1] = 0xff; } if( dig/10 ){ disp_buf.dig[2] = dig_code[dig/10]; dig %= 10; zero = 1; } else if(zero){ disp_buf.dig[2] = dig_code[0]; } else{ disp_buf.dig[2] = 0xff; } if( dig ){ disp_buf.dig[3] = dig_code[dig]; } else if(zero){ disp_buf.dig[3] = dig_code[0]; } else{ disp_buf.dig[3] = 0xff; }}void display_led(void){ const uint8_t pos_v[] = {0x08,0x04,0x02,0x01}; static uint8_t pos = 0; disp_buf.output[0] = pos_v[pos]; disp_buf.output[1] = disp_buf.dig[pos]; pos++; if( pos>=4 ) pos = 0;}static void display_wr_byte(uint8_t data){ for( uint8_t i=0; i<8; i++ ){ serial_dio_pin(data&0x80?1:0);// rt_hw_us_delay(1); serial_sclk_pin(1);// rt_hw_us_delay(1); serial_sclk_pin(0); data <<= 1; }}static void display_refresh(void){ for( uint8_t i=DISP_BUF_LEN; i>0; i-- ){ display_wr_byte(disp_buf.output[i-1]); } serial_rclk_pin(1);// rt_hw_us_delay(1); serial_rclk_pin(0);}void display_thread_entry(void *paramter){ display_dig(1); while( 1 ){ display_led(); display_refresh(); rt_thread_delay(5); }}void display_init(void){ rclk_pin = rt_pin_get(SERIAL_RCLK_PIN); sclk_pin = rt_pin_get(SERIAL_SCLK_PIN); dio_pin = rt_pin_get(SERIAL_DIO_PIN);// serial_rclk_pin(1);// serial_rclk_pin(0);// serial_sclk_pin(1);// serial_sclk_pin(0);// serial_dio_pin(1);// serial_dio_pin(0); rt_thread_t tid1 = RT_NULL; tid1 = rt_thread_create("disp", display_thread_entry, RT_NULL, 512, 10, 10); if (tid1 != RT_NULL) rt_thread_startup(tid1);}INIT_APP_EXPORT(display_init);
3-6、在RT-thread studio的加持下结合RA Smart Configurator,简单应用无需过多关注硬件,可以快速上手开发,真心好用,比keil+evn+stm32cubeMX还要顺手