Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
瑞萨_RA6M4
使用RT-thread基于RA6M4设计的温度检测设备
发布于 2022-07-19 01:33:15 浏览:564
订阅该版
[tocm] # 一、 产品需求设计 ## 本次设计的主要产品主要要求如下几点: 1、 发热管中的温度大概在200-300摄氏度之间,需要设备可以检测的范围在150-330摄氏度。 2、 产品加热过程中,需要监测产品外部的温度,外部的温度范围是0-60摄氏度范围。 3、 产品读取的温度数据要可以直接以曲线的方式展示,测试数据可以保存以便做更多分析。 ## 根据分析,我们做了如下几点资源的准备: 1、 需要驱动至少两个串口,一个是输出温度曲线,一个是输出测试过程中的log。 2、 要使用NTC测温(可以使用热电偶,不过热电偶太复杂在此次设计中不考虑)。NTC分为高温NTC和低温NTC两种,两种都要用。 3、 驱动一个按键,按键的作用是曲线输出还是停止。 4、 驱动两个LED,LED指示的是正在测试还是停止测试。本次使用一个双色灯来表示。 # 二、 硬件驱动: 本次硬件驱动主要是使用RT-Thread Studio加上瑞萨的RA Smart Configurator进行辅助配置,以下截图基本是这两个软件的界面配置。。 ## 1、 按键驱动 按键配置需要设置按键脚为输入,模式为上拉就可以了。如下是瑞萨的RA Smart Configurator截图所示: ![1.jpg](https://oss-club.rt-thread.org/uploads/20220719/d5ec9c4f6f29ce775a989a8507de63e2.jpg.webp "1.jpg") 配置好了之后,使用如下程序读取IO口状态就可以了: `Key = rt_pin_read(BSP_IO_PORT_08_PIN_00);` ## 2、 LED驱动 本次设计所用到的事两个LED灯,所以驱动两个IO脚为输出,模式为低就可以了,因为我们输出的频率很低没必要做高,本次使用的输出脚为P104和P107。如下是瑞萨的RA Smart Configurator截图所示: ![2.jpg](https://oss-club.rt-thread.org/uploads/20220719/c5932b425782e214b728c2b64b36bf5d.jpg.webp "2.jpg") 配置好了之后,使用RT-Thread的写IO口函数就可以写IO口的状态,如下程序: ```c #define LEDR_PIN BSP_IO_PORT_01_PIN_07 #define LEDY_PIN BSP_IO_PORT_01_PIN_04 if(UserM_var.Work_St == 1) { rt_pin_write(LEDR_PIN, PIN_HIGH); rt_pin_write(LEDY_PIN, PIN_LOW); } else { rt_pin_write(LEDR_PIN, PIN_LOW); rt_pin_write(LEDY_PIN, PIN_HIGH); } ``` ## 3、 串口驱动 串口的配置比按键配置和IO口配置要复杂得多,需要RT-Thread Studio和RA Smart Configurator软件共同配置。 ### 1) RT-Thread Studio配置 其中,有个需要注意的点是把360软件关掉,不然配置不了。截图如下: ![3.jpg](https://oss-club.rt-thread.org/uploads/20220719/39ee485873e6386c772a922f53172b42.jpg.webp "3.jpg") ### 2) RA Smart Configurator配置 配置RT-Thread Studio完毕之后,需要配置RA Smart Configurator并且生成代码,不然编译通不过。如下图所示: ![4.jpg](https://oss-club.rt-thread.org/uploads/20220719/3d634f90f13e566c8a9867308ae0f681.jpg.webp "4.jpg") 通钢如上步骤之后,串口会自动生成一个串口初始化,还需要自己配置准确的串口号,比如此次我就使用了串口9。如下配置: ![5.jpg](https://oss-club.rt-thread.org/uploads/20220719/d5c9a68f9b76b0ad2a6ff80592f30206.jpg.webp "5.jpg") ## 4、 ADC驱动 ADC的驱动需要在RT-Thread Studio使能以外,还需要在RA Smart Configurator做如下配置,特别是第五部做使能配置。不然读取的ADC值是0. ![6.jpg](https://oss-club.rt-thread.org/uploads/20220719/cd62e3275f1a6b7921180cc26f9fff0b.jpg.webp "6.jpg") # 三、 软件实现 ## 1、 串口实现 串口是通钢文档中的串口例程修改而来的,不过需要做一些更改。如下程序是串口0和串口9的程序修改后的代码: ```c #include
#include "user_main.h" #define SAMPLE_UART0_NAME "uart0" #define SAMPLE_UART1_NAME "uart1" #define SAMPLE_UART9_NAME "uart9" /* 用于接收消息的信号量 */ extern struct rt_semaphore rx0_sem,rx9_sem; extern rt_device_t serial0,serial9; /* 接收数据回调函数 */ static rt_err_t uart0_input(rt_device_t dev, rt_size_t size) { /* 串口接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */ rt_sem_release(&rx0_sem); return RT_EOK; } static void serial0_thread_entry(void *parameter) { char ch; while (1) { /* 从串口读取一个字节的数据,没有读取到则等待接收信号量 */ while (rt_device_read(serial0, -1, &ch, 1) != 1) { /* 阻塞等待接收信号量,等到信号量后再次读取数据 */ rt_sem_take(&rx0_sem, RT_WAITING_FOREVER); } /* 读取到的数据通过串口错位输出 */ //ch = ch + 1; //rt_device_write(serial0, 0, &ch, 1); user_USART_var[u_UART0].RX_BUF[user_USART_var[u_UART0].RX_LEN++]=ch ; user_USART_var[u_UART0].OverTimes=UART_TIMEOUT; } } /* 接收数据回调函数 */ static rt_err_t uart9_input(rt_device_t dev, rt_size_t size) { /* 串口接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */ rt_sem_release(&rx9_sem); return RT_EOK; } static void serial9_thread_entry(void *parameter) { char ch; while (1) { /* 从串口读取一个字节的数据,没有读取到则等待接收信号量 */ while (rt_device_read(serial9, -1, &ch, 1) != 1) { /* 阻塞等待接收信号量,等到信号量后再次读取数据 */ rt_sem_take(&rx9_sem, RT_WAITING_FOREVER); } /* 读取到的数据通过串口错位输出 */ //ch = ch + 2; //rt_device_write(serial9, 0, &ch, 1); user_USART_var[u_UART9].RX_BUF[user_USART_var[u_UART9].RX_LEN++]=ch ; user_USART_var[u_UART9].OverTimes=UART_TIMEOUT; } } int uart0_init(void) { char uart_name[RT_NAME_MAX]; char str[] = "hello uart0!\r\n"; rt_strncpy(uart_name, "uart0", RT_NAME_MAX); /* 查找系统中的串口设备 */ serial0 = rt_device_find(uart_name); if (!serial0) { rt_kprintf("find %s failed!\n", uart_name); return RT_ERROR; } else { rt_kprintf("find %s OK!\n", uart_name); } /* 初始化信号量 */ rt_sem_init(&rx0_sem, "rx_sem0", 0, RT_IPC_FLAG_FIFO); /* 以中断接收及轮询发送模式打开串口设备 */ rt_device_open(serial0, RT_DEVICE_FLAG_INT_RX); /* 设置接收回调函数 */ rt_device_set_rx_indicate(serial0, uart0_input); /* 发送字符串 */ rt_device_write(serial0, 0, str, (sizeof(str) - 1)); /* 创建 serial 线程 */ rt_thread_t thread = rt_thread_create("serial", serial0_thread_entry, RT_NULL, 1024, 25, 10); /* 创建成功则启动线程 */ if (thread != RT_NULL) { rt_thread_startup(thread); } return RT_EOK; } INIT_ENV_EXPORT(uart0_init); int uart9_init(void) { char uart_name[RT_NAME_MAX]; char str[] = "hello uart9!\r\n"; rt_strncpy(uart_name, "uart9", RT_NAME_MAX); /* 查找系统中的串口设备 */ serial9 = rt_device_find(uart_name); if (!serial9) { rt_kprintf("find %s failed!\n", uart_name); return RT_ERROR; } else { rt_kprintf("find %s OK!\n", uart_name); } /* 初始化信号量 */ rt_sem_init(&rx9_sem, "rx_sem9", 0, RT_IPC_FLAG_FIFO); /* 以中断接收及轮询发送模式打开串口设备 */ rt_device_open(serial9, RT_DEVICE_FLAG_INT_RX); /* 设置接收回调函数 */ rt_device_set_rx_indicate(serial9, uart9_input); /* 发送字符串 */ rt_device_write(serial9, 0, str, (sizeof(str) - 1)); /* 创建 serial 线程 */ rt_thread_t thread9 = rt_thread_create("serial", serial9_thread_entry, RT_NULL, 1024, 25, 10); /* 创建成功则启动线程 */ if (thread9 != RT_NULL) { rt_thread_startup(thread9); } return RT_EOK; } INIT_ENV_EXPORT(uart9_init); ``` ## 2、 ADC的读取和温度转换实现 ADC的读取曾经因为在FSP软件上没有使能的原因,一直读到的是0,后来经过仔细研读网上教程和例程,终于实现了ADC的正确读取。源码如下: ```c #define ADC_DEV_NAME "adc0" /* ADC 设备名称 */ #define ADC_DEV_CHANNEL0 0 /* ADC 通道 */ #define ADC_DEV_CHANNEL1 1 /* ADC 通道 */ #define ADC_DEV_CHANNEL2 2 /* ADC 通道 */ #define ADC_DEV_CHANNEL3 3 /* ADC 通道 */ #define ADC_DEV_CHANNEL4 4 /* ADC 通道 */ #define ADC_DEV_CHANNEL5 5 /* ADC 通道 */ #define ADC_DEV_CHANNEL6 7 /* ADC 通道 */ #define ADC_DEV_CHANNEL7 9 /* ADC 通道 */ #define REFER_VOLTAGE 330 /* 参考电压 3.3V,数据精度乘以100保留2位小数*/ #define CONVERT_BITS (1 << 12) /* 转换位数为12位 */ static rt_adc_device_t adc_dev; static int adc_vol_init(void)// { rt_err_t ret = RT_EOK; /* 查找设备 */ adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME); if (adc_dev == RT_NULL) { rt_kprintf("adc sample run failed! can't find %s device!\n", ADC_DEV_NAME); return RT_ERROR; } else { rt_kprintf("%s sample run OK!\n", ADC_DEV_NAME); } /* 使能设备 */ ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL0); ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL1); ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL2); ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL3); ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL4); ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL5); //ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL6); //ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL7); return ret; } INIT_DEVICE_EXPORT(adc_vol_init); static int adc_vol_sample(void)//(int argc, char *argv[])//(void)// { // rt_uint32_t value[8];//, vol; rt_err_t ret = RT_EOK; /* 读取采样值 */ vDev_ADC.Read_ADC[0] = (rt_uint32_t)rt_adc_read(adc_dev, ADC_DEV_CHANNEL0); vDev_ADC.Read_ADC[1] = (rt_uint32_t)rt_adc_read(adc_dev, ADC_DEV_CHANNEL1); vDev_ADC.Read_ADC[2] = (rt_uint32_t)rt_adc_read(adc_dev, ADC_DEV_CHANNEL2); vDev_ADC.Read_ADC[3] = (rt_uint32_t)rt_adc_read(adc_dev, ADC_DEV_CHANNEL3); vDev_ADC.Read_ADC[4] = (rt_uint32_t)rt_adc_read(adc_dev, ADC_DEV_CHANNEL4); vDev_ADC.Read_ADC[5] = (rt_uint32_t)rt_adc_read(adc_dev, ADC_DEV_CHANNEL5); ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL0); ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL1); ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL2); ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL3); ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL4); ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL5); //value[6] = rt_adc_read(adc_dev, ADC_DEV_CHANNEL6); //value[7] = rt_adc_read(adc_dev, ADC_DEV_CHANNEL7); //rt_kprintf("adc0:%d=%dmV adc1:%d adc2:%d adc3:%d adc4:%d adc5:%d \n",value[0],value[0]*3300/4096,value[1],value[2],value[3],value[4],value[5]); return ret; } ``` 读取ADC之后,需要吧ADC转换成温度数据,转换函数如下: ```c int uGetHeaterTemperature(uint8_t ch)//NTC测温 { int data_len,x=0; static uint16_t Adcn; data_len=M_COUNT_OF(list_N_V); Adcn = vDev_ADC.Read_ADC[ch];//userADC_var.ADC_uDATA[ch]; if((Adcn<=list_N_V[0])&&(Adcn>=list_N_V[data_len-1])) { for(x=0;x
=list_N_V[x]) { break; } } } return x; } ``` ## 3、 串口曲线实现 串口曲线是按照软件的要求输出的,输出的是ASCALL码就能实现,程序如下: ```c temp0 = uGetNTC_Temperature(ADC_CH0); temp1 = uGetHeaterTemperature(ADC_CH1); rt_device_write(serial0, 0, test_buff, sprintf(test_buff, "ADC0=%d,ADC1=%d,T0=%0.2F,T1=%d\n", vDev_ADC.Read_ADC[ADC_CH0],vDev_ADC.Read_ADC[ADC_CH1],temp0,temp1)); if(UserM_var.Work_St == 1) { rt_device_write(serial9, 0, test_buff, sprintf(test_buff, "%0.2F,%d\r\n",temp0,temp1)); } ``` # 四、 项目功能展示: 本项目使用本次提供的开发板以外,还配合了一个4合一的串口工具,以及两个焊接在板子上的NTC器件。外接了一个按键,使用的是扫描方式。再加上一个双色LED灯。如下图所示 ![7.jpg](https://oss-club.rt-thread.org/uploads/20220719/e53d5c792c45667ea260c19959159652.jpg.webp "7.jpg") 通钢测试出来的曲线图如下: ![8.jpg](https://oss-club.rt-thread.org/uploads/20220719/1778e3533fe1f57b821167f8d32763fe.jpg.webp "8.jpg") # 五、 项目总结 本次项目的难点是通钢两个软件的组合来实现硬件驱动配置。刚开始的时候确实非常不习惯。最主要的是之前没接触过瑞萨的单片机,所以使用起来有很多障碍。经过此次的接触,不止了解了RT-Thread系统的开发,还对瑞萨的单片机了解了很多。 最后上传工程源码: [T006_RA6M4_TestV2.18_20220719.rar](https://club.rt-thread.org/file_download/c06ca2c6d137ca82)
1
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
longzhi
每天进步一点点
文章
1
回答
0
被采纳
0
关注TA
发私信
相关文章
1
瑞萨RA2E1芯片移植发生的问题
2
自动创建项目后添加串口出现找不到头文件board_cfg.h
3
CPK-RA6M4的J-Link驱动没有了,每次更新都会缺少头文件
4
瑞萨RA6M4使用RC522软件包示例无反馈
5
瑞萨的EK-RA6M4和CPK-RA6M4开发上有区别吗?
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
freemodbus
PWM
flash
cubemx
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
中断
编译报错
Debug
SFUD
rt_mq_消息队列_msg_queue
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
a1012112796
10
个答案
1
次被采纳
踩姑娘的小蘑菇
4
个答案
1
次被采纳
红枫
4
个答案
1
次被采纳
张世争
4
个答案
1
次被采纳
Ryan_CW
4
个答案
1
次被采纳
本月文章贡献
catcatbing
3
篇文章
5
次点赞
YZRD
2
篇文章
5
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
Woshizhapuren
1
篇文章
5
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部