【RA-Eco-RA6M4开发板评测】DS18B20 温度计
# 【RA-Eco-RA6M4开发板评测】DS18B20 温度计本文介绍了 RA-Eco-RA6M4-100PIN-V2.0 开发板通过单总线协议驱动 DS18B20 温度传感器和数码管,实现环境温度检测的项目设计,包括项目介绍、工程创建、参数配置、工程调试以及效果演示等。
## 项目介绍
- 模块设计:DS18B20 传感器、模块 PCB 设计、原理图、数码管模块;
- 准备工作:硬件连接、环境搭建;
- 工程测试:工程创建、工程配置、流程图、代码、编译上传、效果演示。
!(//m.qjumbo.com/forum/data/attachment/forum/202607/21/174305ufnbp7ky79x99cne.jpg)
## DS18B20 模块
DS18B20 是一款高精度、单总线协议的数字温度传感器。
!(//m.qjumbo.com/forum/data/attachment/forum/202607/21/174321eigkpvzivigbez1r.jpg)
更多参数详见:(https://www.analog.com/cn/products/DS18B20.html) .
原理图
!(//m.qjumbo.com/forum/data/attachment/forum/202607/21/174336rz4vfj088fvol11l.jpg)
PCB 项目详见:(https://oshwhub.com/jinleili/ds18b20-module) .
### 数码管模块
两位数码管由两个 74HC595 驱动,适用于需要高密度并行输出的应用场景。 74HC595 包含一个8位移位寄存器和一个存储器,每个部分都有独立的时钟信号,确保数据处理的精确性。 数据通过 SHCP 输入并在STCP上升沿时写入存储器。 移位寄存器的 DS 引脚接受串行数据,Q7 输出串行移位结果。
!(//m.qjumbo.com/forum/data/attachment/forum/202607/21/174349civvb2db1lzdkkib.jpg)
在驱动两位数码管时,关键在于位选控制。
## 硬件连接
使用杜邦线连接 DS18B20 模块与 RA6M4-Eco 开发板;
| DS18B20 | RA6M4 | Note |
| ------- | ----- | ------ |
| Data | P500| Data |
| GND | GND | Ground |
| VCC | 3V3 | Power|
使用杜邦线连接两位数码管模块和 RA6M4 开发板,接线方式如下
| 74HC595 | RA6M4 | Note |
| ------- | ----- | -------------- |
| SDI | P501| Serial Data In |
| SCLK | P502| Serial Clock |
| LOAD | P503| Load / Latch |
| GND | GND | Ground |
| VCC | 3V3 | Power |
使用杜邦线连接 JLINK-OB 和 RA6M4,实现工程调试、固件上传、串口通信,接线方式如下
| Jlink-OB | RA6M4 | Note |
| :------- | :--------- | :-------- |
| DIO | SWDIO | Data I/O|
| CLK | SWCLK | Clock |
| RXD | TXD (P109) | Transmite |
| TXD | RXD (P110) | Receive |
| GND | GND | Ground |
| 3V3 | VCC | Power |
实物图
!(//m.qjumbo.com/forum/data/attachment/forum/202607/21/175152flww6sap31papi7u.jpg)
自制 JLINK-OB 工程详见:(https://oshwhub.com/jinleili/j-link-ob-gai-jin-ban) .
## 环境搭建
搭建和使用 e^2^ studio IDE 开发环境。
- 下载并安装 [瑞萨FSP (flexible software package) 灵活配置软件包](https://www.renesas.cn/zh/software-tool/flexible-software-package-fsp) ;
- 安装时注意选择 GNU ARM 工具链;
## 工程创建
- 文件 - 新建 - 瑞萨 C/C++ 项目 - `Renesas RA ` ;
- 自定义设备选择 `R7FA6M4AF3CFP` ,调试器选择 J-Link ;
- 项目创建完成后,选择进入透视图模式;
## 工程配置
工程配置包括引脚 GPIO 配置、时钟配置、串口配置。
### 引脚配置
- 进入 FSP 配置界面,打开 Pins 标签页,根据原理图,选择 P500 作为数据通信引脚;
- 将 P500 引脚配置为输出模式,初始为低电平;
### 时钟配置
根据原理图可知,板载 XTAL 晶振频率为 12MHz,需要重新配置 IDE 时钟树。
!(//m.qjumbo.com/forum/data/attachment/forum/202607/21/175218iwsb7uys7yhxslr7.jpg)
### 串口配置
- 进入 FSP 配置界面,打开 Pins 标签页,根据原理图,板载 CH340 对应串口引脚为 P109 和 P110,因此将 SCI9 配置为异步串口模式;
!(//m.qjumbo.com/forum/data/attachment/forum/202607/21/175234ksst6cr3r9evc8rr.jpg)
- 打开 `Stacks` 标签页,新建串口通信堆栈 `New Stack` - `Connectivity` - `UART (r_sci_uart)` ;
- 串口属性配置,General 标签下的 Channel 改为 9,名称改为 `g_uart9`,中断回调函数命名为 `user_uart9_callback`;
- 进入 BSP 标签页,配置 RA Common 属性,RA Common 标签下的 Heap size 改为 `0x2000`;
- 点击 `Generate Project Content` ;
- 右键项目文件夹,构建工程,确认无报错;
详见:[瑞萨RA-Eco-RA6M4评测 - 介绍、环境搭建、工程测试](//m.qjumbo.com/forum/thread-235881-1-1.html) .
## 流程图
!(//m.qjumbo.com/forum/data/attachment/forum/202607/21/175252wnodiin7qdijit7q.jpg)
## 工程代码
包括主程序和 DS18B20 传感器驱动程序。
### 主程序
打开 `./src/hal_entry.c` 文件,添加如下代码
```c++
#include "hal_data.h"
#include "ds18b20.h"
#include <stdio.h>
/********************************
* UART Configurations
* see
* //m.qjumbo.com/forum/thread-235881-1-1.html
* for details
********************************/
void hal_entry(void)
{
err = R_SCI_UART_Open(&g_uart9_ctrl, &g_uart9_cfg);
assert(FSP_SUCCESS == err);
int timeOut = 10;
while(DS18B20_Init() && timeOut--)
{
printf("\r\nNo module was detected!!\r\n");
delay_ms(1000);
}
if(!timeOut)
printf("\r\nTimeOut!!!\n");
else
printf("\r\nDS18B20_Init successfull!!!\n");;
while(1)
{
printf("\r\nTemperature = %.2f °C\r\n", DS18B20_GetTemperture());
delay_1ms(500);
}
}
```
保存文件。
### 驱动程序
在 `./src` 文件夹新建 `ds18b20.h` 驱动头文件,添加如下代码
```c++
#ifndef DS18B20_H_
#define DS18B20_H_
#include "hal_data.h"
#include <stdio.h>
#ifndef u8
#define u8 uint8_t
#endif
#ifndef u16
#define u16 uint16_t
#endif
#ifndef u32
#define u32 uint32_t
#endif
#ifndef delay_ms
#define delay_ms(x) R_BSP_SoftwareDelay(x, BSP_DELAY_UNITS_MILLISECONDS)
#endif
#ifndef delay_1ms
#define delay_1ms(x)R_BSP_SoftwareDelay(x, BSP_DELAY_UNITS_MILLISECONDS)
#endif
#ifndef delay_us
#define delay_us(x) R_BSP_SoftwareDelay(x, BSP_DELAY_UNITS_MICROSECONDS)
#endif
#ifndef delay_1us
#define delay_1us(x)R_BSP_SoftwareDelay(x, BSP_DELAY_UNITS_MICROSECONDS)
#endif
#define Module_DQ_PIN BSP_IO_PORT_05_PIN_00 //DS18B20数据引脚
// 设置DQ输出模式
#define DQ_OUT() { \
fsp_err_t err = R_IOPORT_PinCfg(&g_ioport_ctrl, Module_DQ_PIN, \
((uint32_t) IOPORT_CFG_DRIVE_HIGH \
| (uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT \
| (uint32_t) IOPORT_CFG_PORT_OUTPUT_HIGH)); \
if(err != FSP_SUCCESS) { \
printf("Out Mode Set Failed!!\r\n"); \
} \
}
// 设置DQ输入模式
#define DQ_IN() { \
fsp_err_t err = R_IOPORT_PinCfg(&g_ioport_ctrl, Module_DQ_PIN, \
(uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT); \
if(err != FSP_SUCCESS) { \
printf("In Mode Set Failed!!\r\n"); \
} \
}
// 获取DQ引脚的电平变化
static inline bsp_io_level_t DQ_GET(void) {
bsp_io_level_t p_pin_value;
fsp_err_t err = R_IOPORT_PinRead(&g_ioport_ctrl, Module_DQ_PIN, &p_pin_value);
if(err != FSP_SUCCESS) {
printf("GPIO Input Read Failed!!\r\n");
}
return p_pin_value;
}
// DQ输出
#define DQ(x) R_IOPORT_PinWrite(&g_ioport_ctrl, Module_DQ_PIN, x)
void DS18B20_Reset(void);
uint8_t DS18B20_Check(void);
char DS18B20_Init(void);
float DS18B20_GetTemperture(void);
#endif /* DS18B20_H_ */
```
保存文件。
#### 源文件
在 `./src` 文件夹新建 `ds18b20.c` 驱动源文件,并添加如下代码
```c++
#include "ds18b20.h"
#include "stdio.h"
/******************************************************************
* 函 数 名 称:DS18B20_Init
* 函 数 说 明:DS18B20 的初始化
* 函 数 形 参:无
* 函 数 返 回:1未检测到器件 0检测到器件
******************************************************************/
char DS18B20_Init(void)
{
char ret;
DQ_OUT();//设置为输出模式
DQ(1);
delay_ms(100); // 等待传感器稳定
ret = DS18B20_Check();//检测器件是否存在
if (ret) {
printf("\r\nDS18B20 Check Failed!!\r\n");
} else {
printf("\r\nDS18B20 Check Successful!!\r\n");
}
return ret;
}
/******************************************************************
* 函 数 名 称:DS18B20_Read_Byte
* 函 数 说 明:从DS18B20读取一个字节
* 函 数 形 参:无
* 函 数 返 回:读取到的字节数据
******************************************************************/
uint8_t DS18B20_Read_Byte(void)
{
uint8_t i=0,dat=0;
for (i=0;i<8;i++)
{
DQ_OUT();//设置为输入模式
DQ(0); //拉低
delay_us(2);
DQ(1); //释放总线
DQ_IN();//设置为输入模式
delay_us(12);
dat>>=1;
if( DQ_GET() )
{
dat=dat|0x80;
}
delay_us(50);
}
return dat;
}
/******************************************************************
* 函 数 名 称:DS18B20_Write_Byte
* 函 数 说 明:写一个字节到DS18B20
* 函 数 形 参:dat:要写入的字节
* 函 数 返 回:无
******************************************************************/
void DS18B20_Write_Byte(uint8_t dat)
{
uint8_t i;
DQ_OUT();//设置输出模式
for (i=0;i<8;i++)
{
if ( (dat&0x01) ) //写1
{
DQ(0);
delay_us(10);
DQ(1);
delay_us(60);
}
else //写0
{
DQ(0);//拉低60us
delay_us(60);
DQ(1);//释放总线
delay_us(10);
}
dat=dat>>1;//传输下一位
}
}
/******************************************************************
* 函 数 名 称:DS18B20_Check
* 函 数 说 明:检测DS18B20是否存在
* 函 数 形 参:无
* 函 数 返 回:1:未检测到DS18B20的存在0:存在
******************************************************************/
uint8_t DS18B20_Check(void)
{
uint8_t timeout=0;
//复位DS18B20
DQ_OUT(); //设置为输出模式
DQ(0); //拉低DQ
delay_us(750); //拉低750us
DQ(1); //拉高DQ
delay_us(15);//15us
//设置为输入模式
DQ_IN();
//等待拉低,拉低说明有应答
while ( DQ_GET() &&timeout<200)
{
timeout++;//超时判断
delay_us(1);
};
//设备未应答
if(timeout>=200)
return 1;
else
timeout=0;
//等待18B20释放总线
while ( !DQ_GET() &&timeout<240)
{
timeout++;//超时判断
delay_us(1);
};
//释放总线失败
if(timeout>=240)
return 1;
return 0;
}
/******************************************************************
* 函 数 名 称:DS18B20_GetTemperture
* 函 数 说 明:从ds18b20得到温度值
* 函 数 形 参:无
* 函 数 返 回:温度数据
******************************************************************/
float DS18B20_GetTemperture(void)
{
uint16_t temp;
uint8_t dataL=0,dataH=0;
float value;
if(DS18B20_Check()) //查询是否有设备应答
printf("\r\nDS18B20_Check ERROR!\r\n");
delay_ms(5); // 天猛星80MHz必须加这个延时
DS18B20_Write_Byte(0xcc); //对总线上所有设备进行寻址
DS18B20_Write_Byte(0x44); //启动温度转换
if(DS18B20_Check())
printf("\r\nDS18B20_Check ERROR!\r\n");
delay_ms(5); // 天猛星80MHz必须加这个延时
DS18B20_Write_Byte(0xcc); //对总线上所有设备进行寻址
DS18B20_Write_Byte(0xbe); //读取数据命令
dataL=DS18B20_Read_Byte();//LSB
dataH=DS18B20_Read_Byte();//MSB
temp=(dataH<<8)+dataL;//整合数据
if(dataH&0X80)//高位为1,说明是负温度
{
temp=(~temp)+1;
value=temp*(-0.0625);
}
else
{
value=temp*0.0625;
}
return value;
}
```
保存文件。
### 数码管驱动
在 `./src` 文件夹新建 `hc595.h` 驱动头文件,添加如下代码
```c++
#ifndef HC595_H
#define HC595_H
#include "hal_data.h"
#include <stdint.h>
// 引脚定义
#define DATA_PIN BSP_IO_PORT_05_PIN_01 // data = Pin(2)
#define CLOCK_PIN BSP_IO_PORT_05_PIN_02 // clock = Pin(0)
#define LATCH_PIN BSP_IO_PORT_05_PIN_03 // latch = Pin(1)
// 共阳段码
extern uint8_t smgduan;
// 底层移位输出
void shift_out(uint8_t byte);
// 显示:left十位,right个位,dot小数点
void show(uint8_t left, uint8_t right, _Bool dot);
// 初始化595引脚
void hc595_init(void);
#endif
```
保存文件。
#### 源文件
在 `./src` 文件夹新建 `hc595.c` 驱动源文件,添加如下代码
```c++
#include "hc595.h"
// 数码管段码数组
uint8_t smgduan = {
0xC0, // 0 0b11000000
0xF9, // 1 0b11111001
0xA4, // 2 0b10100100
0xB0, // 3 0b10110000
0x99, // 4 0b10011001
0x92, // 5 0b10010010
0x82, // 6 0b10000010
0xF8, // 7 0b11111000
0x80, // 8 0b10000000
0x90// 9 0b10010000
};
static void pin_write(bsp_io_port_pin_t pin, uint8_t val)
{
R_IOPORT_PinWrite(&g_ioport_ctrl, pin, val);
}
void hc595_init(void)
{
pin_write(DATA_PIN,0);
pin_write(CLOCK_PIN, 0);
pin_write(LATCH_PIN, 0);
}
// 移位寄存器
void shift_out(uint8_t byte)
{
for(uint8_t i = 0; i < 8; i++)
{
uint8_t bit = (byte >> (7 - i)) & 1;
pin_write(DATA_PIN, bit);
pin_write(CLOCK_PIN, 1);
pin_write(CLOCK_PIN, 0);
}
}
// 显示函数
void show(uint8_t left, uint8_t right, _Bool dot)
{
uint8_t seg_l = smgduan;
uint8_t seg_r = smgduan;
if(dot)
{
seg_r &= 0x7F; // 0b01111111 点亮小数点
}
pin_write(LATCH_PIN, 0);
shift_out(seg_r);// 先发个位段码
shift_out(seg_l);// 再发十位段码
pin_write(LATCH_PIN, 1);
}
// 动态扫描显示两位整数 0~99
void display_temp_num(uint8_t num)
{
uint8_t ten = num / 10;
uint8_t one = num % 10;
show(ten, one, 0);
R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MILLISECONDS);
}
```
保存文件。
## 工程编译
- 右键项目文件夹,选择 `属性` ,进入 `C/C++ 构建` - `设置` 选项;
- 进入 `GNU Arm Cross Create Flash Image - General` 选项;
- 在输出格式中选择 `Intel HEX` ,应用并关闭;
- 右键项目文件夹,构建工程,确认无报错;
- 查看工程目录下的 `Debug` 文件夹,生成相应的 HEX 格式的固件;
## 固件上传
开发板支持串口烧录、J-Link、EZ-Cube 调试器烧录等,这里使用 JLINK-OB 调试工程。
- 点击工具栏的小虫子 Debug 按钮,进入调试界面;
- 或右键项目文件夹,选择调试配置,选中当前项目对应的 elf 文件,调试工具为 JLINK,开始调试;
- 进入调试界面,点击菜单栏的运行按钮,程序开始执行;
使用 USB 烧录固件的方案详见:[瑞萨RA-Eco-RA6M4评测 - 介绍、环境搭建、工程测试](//m.qjumbo.com/forum/thread-235881-1-1.html) .
## 效果演示
- 运行串口调试助手软件,连接 Jlink CDC 虚拟串口,配置波特率等参数;
- 打开串口,接收 DS18B20 温度数据;
!(//m.qjumbo.com/forum/data/attachment/forum/202607/21/175324ubz3sburbsqbcbve.gif)
- 同时数码管显示当前温度整数
!(//m.qjumbo.com/forum/data/attachment/forum/202607/21/175341qss6715xx6md4465.jpg)
## 总结
本文介绍了 RA-Eco-RA6M4-100PIN-V2.0 开发板通过单总线协议驱动 DS18B20 温度传感器和数码管,实现环境温度检测计的项目设计,包括项目介绍、工程创建、参数配置、工程调试以及效果演示等,为相关产品的快速开发和应用设计提供了参考。
页:
[1]