【嵌入式项目-MCU代码2】
■ 显示屏
屏幕资料和参考资料
显示屏代码共享平台 SSD1306驱动器
■ 01. 正点原子资料下载中心
0.96寸OLED模块128*64 http://www.openedv.com/docs/modules/lcd/0.96-OLED-12864.html
■ 02. SSD1306驱动器
■ 03. OLED多级菜单资料V3.2
■ 04. 1.8寸TFT LCD128X160 ST7735S SPI串口屏驱动示例
链接:https://pan.baidu.com/s/10G6apA8plumMz1A8FLoGhg
提取码:1111
■ 05. 元芯电子GD32F303VGT6开发板STM32评估核心板ARM最小系统VCT6例程
CAN
SPi W25Q32
SDIO
W5500芯片 + HR911105A网络 SPI 驱动
LCD模块 ILI19341 触摸屏 SPI驱动 XPT2046
EEPROM 芯片使用AT24C02用于验证IIC协议
开源链接:https://pan.baidu.com/s/1-eRv9octW-Wmv85QZ9L3Rg
提取码:aytk
视频教程:https://space.bilibili.com/621871525
开源资料链接:https://pan.baidu.com/s/1fSEi0KT6yzQ5FwUtIYiNlQ
提取码:b8bv
视频教程:https://space.bilibili.com/621871525
■ 06. 元芯ST7735s显示屏TFT模块IPS彩屏0.96寸四线SPI LCD显示屏80x160
GITEE: https://gitee.com/meta-mcu/st7735s-st7735-096-inch-tft
GITHUB: https://github.com/META-MCU/st7735s-tft-0.96inch
视频教程:https://www.bilibili.com/video/BV11P4y1q7pL
■ SMT32
■ 01.【桥边姑娘】SMT32 ADC+FFT+OLED 音乐频谱显示
■ 02. SMT32-uart 空闲中断(USART_IT_IDLE)
当发送完一包数据后触发空闲中断提示用户去解析数据包
适用于Modebus-RTU解包
typedef struct _UART4_BUF
{
uint8_t cache[BUFFER_MAX];
int size;
int rxdong; //读完成标志
}UART4_BUF;
UART4_BUF gUart4_buff;
volatile int rx_count=0;
void UART4_IRQHandler(void)
{
uint8_t temp;
if(USART_GetITStatus(UART4, USART_IT_RXNE) != RESET) //接收中断,可以扩展来控制
{
gUart4_buff.cache[rx_count++] = USART_ReceiveData(UART4);
if (rx_count > (BUFFER_MAX - 1)) {
rx_count=0;
}
gUart4_buff.rxdong=0;
USART_ClearITPendingBit(UART4, USART_IT_RXNE);
}
if(USART_GetITStatus(UART4, USART_IT_IDLE) != RESET) //模块空闲
{
temp=UART4->SR; //先读SR,再读DR才能完成idle中断的清零,否则一直进入中断。
temp=UART4->DR;
gUart4_buff.size = rx_count;
rx_count=0;
gUart4_buff.rxdong = 1; //读完成中断标识,在其他地方读取这个标识进行数据解析。
}
}
注意事项:
调用库函数USART_ClearITPendingBit(DEBUG_USARTx, USART_IT_IDLE);是不会清除空闲中断标志位的。应该采用42-43两条语句实现,否则会一直进入中断函数。
■ 03. 基于江科大的OLED多级菜单教学
链接:https://pan.baidu.com/s/1efxv9l3XWk9oGQqwQU-rXg?pwd=7544
提取码:7544
■ 04. MPU6050
野火STM32F103标准外设库(SPL)开发教学视频【全集】
■ 05. Modebus-RTU-Slave(从机代码)
采用中断进行接收数据,开启空闲中断,当接收完一包数据后触发空闲中断,主程序去解包处理
定时100ms 发送数据进行解包是OK的
■ 001. rs485.h
#ifndef _rs485_H
#define _rs485_H
#include "sys.h"
#include "stdio.h"
#include "string.h"
#define BUFFER_MAX 256 //数组缓存大小
typedef struct _UART4_BUF
{
uint8_t cache[BUFFER_MAX];
int size;
int rxdong; //读完成标志
}UART4_BUF;
extern u8 RS485_Flag;
extern UART4_BUF gUart4_buff;
//模式控制
#define RS485_TX_EN PBout(8) //485模式控制.0,接收;1,发送.
void RS485_Init(u32 bound);
void RS485_ClearBuf(void);
void RS485_SendStr(uint8_t*SendBuf);
void RS485_SendData(uint8_t*buf,int len);
#endif
■ 002. rs485.c
#include "rs485.h"
#include "delay.h"
#include "usart.h"
UART4_BUF gUart4_buff;
/*******************************************************************************
* 函 数 名 : RS485_Init
* 函数功能 : USART2初始化函数
* 输 入 : bound:波特率
* 输 出 : 无
*******************************************************************************/
void RS485_Init(u32 bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4,ENABLE);//使能UART4时钟
/* 配置GPIO的模式和IO口 */
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10; //TX-485 //串口输出PC10
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStructure); /* 初始化串口输入IO */
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11; //RX-485 //串口输入PC11
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; //模拟输入
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8; //CS-485
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
//USART4 初始化设置
USART_InitStructure.USART_BaudRate = bound;//波特率设置
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(UART4, &USART_InitStructure); //初始化串口2
USART_Cmd(UART4, ENABLE); //使能串口 4
USART_ClearFlag(UART4, USART_FLAG_TC);
USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);//开启接受中断
USART_ITConfig(UART4, USART_IT_IDLE, ENABLE);
//Uart4 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3; //抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority =2; //子优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
RS485_TX_EN=0; //接收
}
void RS485_SendStr(uint8_t* SendBuf) //串口4打印数据
{
RS485_TX_EN=1; //发送
while(*SendBuf)
{
UART4->DR = (u8)*SendBuf;
while((UART4->SR & 0X40)==0); //等待发送完成
SendBuf++;
}
RS485_TX_EN=0; //接收
}
void RS485_SendData(uint8_t* buf,int len) //串口4打印数据
{
int i=0;
RS485_TX_EN=1; //发送
for(i=0; i<len; i++)
{
UART4->DR = (u8)buf[i];
while((UART4->SR & 0X40)==0); //等待发送完成
}
RS485_TX_EN=0; //接收
}
void RS485_ClearBuf()
{
gUart4_buff.size = 0;
memset(gUart4_buff.cache,0,sizeof(gUart4_buff.cache));
}
volatile int rx_count=0;
void UART4_IRQHandler(void)
{
uint8_t temp;
if(USART_GetITStatus(UART4, USART_IT_RXNE) != RESET) //接收中断,可以扩展来控制
{
gUart4_buff.cache[rx_count++] = USART_ReceiveData(UART4);
if (rx_count > (BUFFER_MAX - 1)) {
rx_count=0;
}
gUart4_buff.rxdong=0;
USART_ClearITPendingBit(UART4, USART_IT_RXNE);
}
if(USART_GetITStatus(UART4, USART_IT_IDLE) != RESET) //模块空闲
{
temp=UART4->SR; //先读SR,再读DR才能完成idle中断的清零,否则一直进入中断。
temp=UART4->DR;
gUart4_buff.size = rx_count;
rx_count=0;
gUart4_buff.rxdong = 1;
}
}
■ 003. modbus_RTU.c
#include "modebus_RTU.h"
/* CRC高字节表 */
const static uint8_t crctableh[] =
{
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40
};
/* CRC低字节表 */
const static uint8_t crctablel[] =
{
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,
0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD,
0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7,
0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE,
0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2,
0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB,
0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91,
0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88,
0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80,
0x40
};
//CRC查表函数,返回CRC-16校验码低字节在前
uint16_t modbus_crc16(uint8_t *ptr, uint16_t len)
{
uint8_t crch = 0xFF;
uint8_t crcl = 0xFF;
uint16_t index;
while (len--)
{
index = crcl ^ *ptr++;
crcl = crch ^ crctableh[index];
crch = crctablel[index];
}
return ((uint16_t)(crch | crcl << 8));
}
■ 004. modbus_RTU.h
#ifndef __MODEBUS_RTU_H
#define __MODEBUS_RTU_H
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include "delay.h"
//定义功能码
#define MODBUS_FUNC_READ_COIL_REG 0x01 //读线圈
#define MODBUS_FUNC_READ_DIS_INPUT_REG 0x02 //读离散输入
#define MODBUS_FUNC_READ_HOLD_REG 0x03 //读保持寄存器
#define MODBUS_FUNC_READ_INPUT_REG 0x04 //读输入寄存器
#define MODBUS_FUNC_WRITE_SIN_COIL_REG 0x05 //写单个线圈
#define MODBUS_FUNC_WRITE_SIN_HOLD_REG 0x06 //写单个保持寄存器
#define MODBUS_FUNC_WRITE_MULT_COIL_REG 0x0F //写多个线圈
#define MODBUS_FUNC_WRITE_MULT_HOLD_REG 0x10 //写多个保持寄存器
uint16_t modbus_crc16(uint8_t *ptr, uint16_t len);
#endif
■ 005. modebus_RTU_Slave.c
#include "modebus_RTU_Slave.h"
#include "rs485.h"
modbus_slave_t gRTUslave;
UART4_BUF g_wxcache;
#define REG_HOLDING_COUNT 1024
uint16_t modbus_holding_regs[REG_HOLDING_COUNT]; //寄存器存储区(用户可读写)
uint8_t ModbusRtu_Slave_Init()
{
ModbusRtuSlaveInit(&gRTUslave,0x0A,&gUart4_buff,&g_wxcache);
return 1;
}
uint8_t ModbusRtuSlaveInit(modbus_slave_t* slave,
uint8_t slaveAdd,
UART4_BUF* rxcache,
UART4_BUF* wxcache)
{
slave->slaveID = slaveAdd;
slave->rx_cache = rxcache;
slave->wx_cache = wxcache;
RS485_Init(9600);
RS485_SendStr((uint8_t*)"RS485 Init Successful\r\n");
return 1;
}
void Modbus_slave_task()
{
if(gRTUslave.rx_cache->rxdong){
Modbus_slave_parse_frame(&gRTUslave);
gRTUslave.rx_cache->rxdong=0;
}
// else
// {
// printf("++++++++++++++=%d\r\n",gRTUslave.rx_cache->size);
// }
}
void Modbus_slave_parse_frame(modbus_slave_t* modbusSlave)
{
uint16_t crc_calc=0;
uint16_t crc_recv=0;
UART4_BUF* prx_cache = modbusSlave->rx_cache;
if(prx_cache->size < 6)
return; //最小帧长
crc_calc = modbus_crc16(prx_cache->cache, prx_cache->size - 2);
crc_recv = (prx_cache->cache[prx_cache->size-2] << 8) | prx_cache->cache[prx_cache->size-1];
if(crc_calc == crc_recv) //CRC检验成功 开始分析包
{
if(prx_cache->cache[0] == modbusSlave->slaveID) //检查地址是否时自己的地址
{
switch(prx_cache->cache[1]){ //modbus功能码
case MODBUS_FUNC_READ_COIL_REG: //0x01 读线圈
break;
case MODBUS_FUNC_READ_DIS_INPUT_REG: //0x02 读离散输入
break;
case MODBUS_FUNC_READ_HOLD_REG: //0x03 读保持寄存器
Modbus_Func03(modbusSlave);
break;
case MODBUS_FUNC_READ_INPUT_REG: //0x04 读输入寄存器
break;
case MODBUS_FUNC_WRITE_SIN_COIL_REG: //0x05 写单个线圈
break;
case MODBUS_FUNC_WRITE_SIN_HOLD_REG: //0x06 写单个保持寄存器
Modbus_Func06(modbusSlave);
break;
case MODBUS_FUNC_WRITE_MULT_COIL_REG://0x0F 写多个线圈
break;
case MODBUS_FUNC_WRITE_MULT_HOLD_REG://0x10 写多个保持寄存器
Modbus_Func10(modbusSlave);
break;
}
}
else if(prx_cache->cache[0] == 0) //广播地址不予回应
{
printf("add = 0,,%d\r\n",prx_cache->cache[0]);
}
}
}
void Modbus_Func03(modbus_slave_t* modbusSlave)
{
u16 Regadd,Reglen,crc;
u8 i,j;
UART4_BUF* rx_cache = modbusSlave->rx_cache;
UART4_BUF* wx_cache = modbusSlave->wx_cache;
//得到要读取寄存器的首地址
Regadd = rx_cache->cache[2]*256 + rx_cache->cache[3];
//得到要读取寄存器的数据长度
Reglen = rx_cache->cache[4]*256 + rx_cache->cache[5];
//发送回应数据包
i = 0;
wx_cache->cache[i++] = modbusSlave->slaveID; //发送本机设备地址
wx_cache->cache[i++] = 0x03; //发送功能码
wx_cache->cache[i++] = ((Reglen*2)%256); //返回字节个数
for(j=0;j<Reglen;j++) //返回数据
{
wx_cache->cache[i++] = modbus_holding_regs[Regadd+j]/256;
wx_cache->cache[i++] = modbus_holding_regs[Regadd+j]%256;
}
crc = modbus_crc16(wx_cache->cache,i); //计算要返回数据的CRC
wx_cache->cache[i++] = crc/256;
wx_cache->cache[i++] = crc%256;
wx_cache->size=i;
RS485_SendData(wx_cache->cache,wx_cache->size);
}
void Modbus_Func06(modbus_slave_t* modbusSlave)
{
u16 Regadd;
u16 val;
u16 i=0,crc=0;
UART4_BUF* rx_cache = modbusSlave->rx_cache;
UART4_BUF* wx_cache = modbusSlave->wx_cache;
Regadd = rx_cache->cache[2]*256 + rx_cache->cache[3]; //寄存器地址
val = rx_cache->cache[4]*256 + rx_cache->cache[5]; //修改后的值
modbus_holding_regs[Regadd]=val; //修改本设备相应的寄
//以下为回应主机
wx_cache->cache[i++] = modbusSlave->slaveID; //本设备地址
wx_cache->cache[i++] = 0x06; //功能码
wx_cache->cache[i++] = Regadd/256;
wx_cache->cache[i++] = Regadd%256;
wx_cache->cache[i++] = val/256;
wx_cache->cache[i++] = val%256;
crc = modbus_crc16(wx_cache->cache,i);
wx_cache->cache[i++] = crc/256;
wx_cache->cache[i++] = crc%256;
wx_cache->size=i;
RS485_SendData(wx_cache->cache,wx_cache->size);
}
void Modbus_Func10(modbus_slave_t* modbusSlave)
{
u16 Regadd,RegNum;
u16 bySize,RegNumMax;
u16 i=0,f=0,crc=0;
UART4_BUF* rx_cache = modbusSlave->rx_cache;
UART4_BUF* wx_cache = modbusSlave->wx_cache;
Regadd = rx_cache->cache[2]*256 + rx_cache->cache[3]; //寄存器地址
RegNum = rx_cache->cache[4]*256 + rx_cache->cache[5]; //寄存器数量
bySize = rx_cache->cache[6]; //字节数
RegNumMax = bySize/2;
for(f=0;f<RegNumMax;f++)
{
//修改本设备相应的寄存器
modbus_holding_regs[Regadd+f] = rx_cache->cache[6+f]*256 + rx_cache->cache[6+f+1];
}
//以下为回应主机
wx_cache->cache[i++] = modbusSlave->slaveID; //本设备地址
wx_cache->cache[i++] = 0x10; //功能码
wx_cache->cache[i++] = Regadd/256; //起始地址
wx_cache->cache[i++] = Regadd%256;
wx_cache->cache[i++] = RegNum/256; //寄存器数量
wx_cache->cache[i++] = RegNum%256;
crc = modbus_crc16(wx_cache->cache,i);
wx_cache->cache[i++] = crc/256;
wx_cache->cache[i++] = crc%256;
wx_cache->size=i;
RS485_SendData(wx_cache->cache,wx_cache->size);
}
■ 006. modebus_RTU_Slave.h
#ifndef __MODEBUS_RTU_SLAVE_H
#define __MODEBUS_RTU_SLAVE_H
#include "modebus_RTU.h"
#include "rs485.h"
typedef struct _modbus_slave_t {
uint8_t slaveID;
UART4_BUF* rx_cache; //接收缓冲区
UART4_BUF* wx_cache; //发送缓冲区
uint32_t last_byte_time; // 最后接收字节的时间(ms)
uint8_t debug;
uint8_t error_recovery;
uint8_t quirks;
}modbus_slave_t;
#define MODBUS_MASTER_ADDRESS 0x01 //主机地址为0x01
#define MODBUS_SLAVE1_ADDRESS 0x02 //从机地址为0x02
uint8_t ModbusRtu_Slave_Init(void);
uint8_t ModbusRtuSlaveInit(modbus_slave_t* slave,uint8_t slaveAdd,
UART4_BUF* rxcache,
UART4_BUF* wxcache);
void Modbus_slave_task(void); //主循环调用
void Modbus_slave_parse_frame(modbus_slave_t* modbusSlave);
void Modbus_Func03(modbus_slave_t* modbusSlave);
void Modbus_Func06(modbus_slave_t* modbusSlave);
void Modbus_Func10(modbus_slave_t* modbusSlave);
#endif
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)