跑马灯和ADC+UART已经在前两个程序做好,接下来RS485读取SHT20并通过串口发送出来。
测试SHT20
由此可以知道协议数据为: 01 04 00 01 00 02
通过 在线计算crc modbus.
故发起请求的数据为:01 04 00 01 00 02 20 0b
获取到的数据为: 01 04 04 00 b0 02 6c fb 2e
温度数据为: 00 b0 对应为0x00b0 获取到的温度值为17.6℃
湿度数据为: 02 6c 对应为0x026c 获取到的湿度值为62%。
硬件原理图 + FSP代码配置
前一篇帖子已经将UART口配置成printf做了说明我这里不再做说明。
RS485接口1
通过原理可以知道RS485使用的是UART5串口,对应的管脚是P502(RXD5)和P501(TXD5),P503是RS485收发状态切换,其中低电平表示收,高电平表示发。
FSP代码配置
UART配置
串口5使能。
New Statck->Connectivity->UART(r_sci_uart)来配置UART模块。
DIR配置(GPIO)
修改RS485 Thread
#include "rs485_thread.h"
#include <stdio.h>
void UART4_Init(void);
void UART5_Init(void);
void sht20_process(void);
void UART4_Init(void)
{
fsp_err_t err = FSP_SUCCESS;
err = R_SCI_UART_Open(&g_uart4_ctrl, &g_uart4_cfg);
assert(FSP_SUCCESS == err);
}
volatile bool uart4_send_complete_flag = false;
void uart4_callback(uart_callback_args_t * p_args)
{
switch (p_args->event)
{
case UART_EVENT_RX_CHAR:
{
break;
}
case UART_EVENT_TX_COMPLETE:
{
uart4_send_complete_flag = true;
break;
}
default:
break;
}
}
#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(uart4_send_complete_flag == false);
uart4_send_complete_flag = false;
return size;
}
#else
int fputc(int ch, FILE *f)
{
(void)f;
R_SCI_UART_Write(&g_uart4_ctrl, (uint8_t *)&ch, 1);
while(uart4_send_complete_flag == false);
uart4_send_complete_flag = false;
return ch;
}
#endif
void UART5_Init(void)
{
fsp_err_t err = FSP_SUCCESS;
err = R_SCI_UART_Open(&g_uart5_ctrl, &g_uart5_cfg);
assert(FSP_SUCCESS == err);
}
volatile bool uart5_send_complete_flag = false;
volatile bool uart5_recv_complete_flag = false;
void uart5_callback(uart_callback_args_t * p_args)
{
switch (p_args->event)
{
case UART_EVENT_RX_CHAR:
{
break;
}
case UART_EVENT_RX_COMPLETE:
{
uart5_recv_complete_flag = true;
break;
}
case UART_EVENT_TX_COMPLETE:
{
uart5_send_complete_flag = true;
break;
}
default:
break;
}
}
void sht20_process(void)
{
uint8_t send_data[] = {0x01, 0x04, 0x00, 0x01, 0x00, 0x02, 0x20, 0x0b};
uint8_t recv_data[9];
uint16_t humid = 0;
uint16_t thermo = 0;
double humid_value = 0.0;
double thermo_value = 0.0;
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_05_PIN_03, BSP_IO_LEVEL_HIGH);
R_SCI_UART_Write(&g_uart5_ctrl, send_data, sizeof send_data);
uart5_send_complete_flag = false;
while(!uart5_send_complete_flag)
{
;
}
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_05_PIN_03, BSP_IO_LEVEL_LOW);
R_SCI_UART_Read(&g_uart5_ctrl, recv_data, sizeof recv_data);
uart5_recv_complete_flag = false;
while(!uart5_recv_complete_flag)
{
;
}
thermo = (uint16_t)recv_data[3] << 8|recv_data[4];
humid = (uint16_t)recv_data[5] << 8|recv_data[6];
humid_value = (double)humid/10.0;
thermo_value = (double)thermo/10.0;
printf("thermo: %f, humid: %f\r\n", thermo_value, humid_value);
}
void rs485_thread_entry(void *pvParameters)
{
FSP_PARAMETER_NOT_USED (pvParameters);
UART4_Init();
UART5_Init();
while (1)
{
sht20_process();
vTaskDelay (1000);
}
}