1,SPI接口参数
主控板是SPI的MASTER、交流采集板是SLAVE
SPI接口用到了4个通信线:片选线、时钟线、MISO线、MOSI线
用模式1,波特率为100K,8字节,路径为"/dev/spidev2.0",
2,SPI通信的交互帧格式
2.1 交互方式
采用一问一答的方式,帧格式类似于MOUDBUS,但不完全相同
主控发送请求帧,交采板发应答帧
2.2 宏定义
#define SPI_ADDR_JC 1 //地址
#define SPI_FRM_HEAD 0xfefefefe // 帧头
#define SPI_FRM_END 0xfcfcfcfc // 帧尾
#define SPI_FC_RD 0x03 // 功能码 读
#define SPI_FC_WR 0x10 // 功能码 写
#define SPI_DI_REAL1 0x0100 // 读实时数据1的DI
#define SPI_DI_REAL2 0x0101 // 读实时数据2的DI
#define SPI_DI_RD_EVENT 0x0500 // 读开入量变位事件的DI
typedef struct // 时间
{
uint8_t year; // 1表示2001年
uint8_t month; // 1 12
uint8_t date; // 1 31
uint8_t hour; // 0 23
uint8_t minute;
uint8_t second;
uint8_t week;
uint8_t state; // 多用途
uint32_t sec; // 从2000年1月1日0点0分0秒开始的秒数
uint32_t usec; // 微妙 从0到1000000
} ac_time3_t;
2.2 读实时数据1
发送帧格式为:
typedef struct {
uint32_t head;
uint8_t addr;
uint8_t fc; // 功能码
uint16_t di; // 数据标识
uint16_t datalen; //数据域长度,datalen后、crc之前的字节数
ac_time3_t tm;
uint16_t crc; //累加和 从head到crc前 按字节累加 取低2个字节
uint32_t end;
} frm_rd_03_t;
发送帧内容如下:
frm_rd_03_t frm_rd_real =
{
SPI_FRM_HEAD,
SPI_ADDR_JC,
SPI_FC_RD,
SPI_DI_REAL1,
sizeof(ac_time3_t),
{ 0 },
(0),
SPI_FRM_END
};
发送frm_rd_real完毕后 等待20毫秒后 发送(sizeof(frm_rd_real_response_t)+1)个0xf8来读响应帧
响应帧格式如下:
typedef struct {
uint8_t addr;
uint8_t fc; // 3
uint16_t di; // 数据标识
uint16_t datalen;
ac_real_t real;
uint16_t crc;
} frm_rd_real_response_t;
typedef struct
{
uint32_t head;
uint32_t sn; // 序号 上电时从0开始
ac_time3_t tim; // 时标
uint32_t state; // 计量模块状态 异常 告警 事件
float32_t freq; // 频率 单位Hz
float32_t vol[3 + 1]; // 电压 单位V [0]A相电压 [3]零序电压
float32_t cur[3 + 1]; // 电流 单位A
float32_t pwr_p[3 + 1]; // 有功率 单位kW [0]A相 [3]总
float32_t pwr_q[3 + 1]; // 无功率
float32_t pwr_s[3 + 1]; // 视在功率
float32_t pwr_f[3 + 1]; // 功率因数
float32_t angle_vol[3]; // 相角 单位度
float32_t angle_cur[3]; // 相角
float32_t thd_vol[3]; /// 电压谐波畸变率
float32_t thd_cur[3]; /// 电流谐波畸变率
float32_t har_vol[3][1 + 19]; /// 谐波电压 [][0]总 [][1]基波 [][2]2次
float32_t har_cur[3][1 + 19]; /// 谐波电流
union {
enrg_t enrg;
enrg_imp_t imp;
};
uint32_t di_sta; // di的输入状态 位0对应第1个输入的状态
uint32_t di_event_num; // di事件缓冲区内事件个数
uint32_t end;
} ac_real_t;
typedef struct {
uint32_t p_pos[3]; // 正向有功电能脉冲数 A B C相
uint32_t p_neg[3]; // 反向有功
uint32_t q_pos[3]; // 正向无功
uint32_t q_neg[3]; // 反向无功
uint32_t q1[3]; // 1象限无功
uint32_t q2[3];
uint32_t q3[3];
uint32_t q4[3];
} enrg_imp_t;
2.3 读实时数据2
发送如下帧
frm_rd_03_t frm_rd_real2 =
{
SPI_FRM_HEAD,
SPI_ADDR_JC,
SPI_FC_RD,
SPI_DI_REAL2,
sizeof(ac_time3_t),
{ 0 },
(0),
SPI_FRM_END
};
应答帧格式为:
typedef struct {
uint8_t addr;
uint8_t fc; // 3
uint16_t di; // 数据标识
uint16_t datalen;
ac_real2_t real2;
uint16_t crc;
} frm_rd_real_response2_t;
typedef struct {
enrg_imp2_t imp;
union{
uint32_t voidd[64];
struct{
float32_t r_ItRms; // 零序电流
};
};
} ac_real2_t;
typedef struct {
uint32_t r_Ept; // 正向有功电能脉冲数 总
uint32_t r_Ept_; // 反向
uint32_t q1t; // 1象限总
uint32_t q2t;
uint32_t q3t;
uint32_t q4t;
uint32_t r_Est; // 正向视在电能脉冲数 总
uint32_t r_Est_; // 反向
uint32_t r_LineEpt; // 基波有功电能脉冲数总
uint32_t r_LineEpt_; // 反向
uint32_t r_Esa[3]; // 正向视在电能脉冲数 a b c
//uint32_t r_Esb;
//uint32_t r_Esc;
uint32_t r_Esa_[3]; // 反向视在电能脉冲数
//uint32_t r_Esb_;
//uint32_t r_Esc_;
uint32_t r_LineEpa[3]; //正向基波有功电能脉冲数
//uint32_t r_LineEpb;
//uint32_t r_LineEpc;
uint32_t r_LineEpa_[3]; // 反向基波有功电能脉冲数
//uint32_t r_LineEpb_;
// uint32_t r_LineEpc_;
} enrg_imp2_t;
2.4 读开入事件
发送帧格式如下:
typedef struct {
uint32_t head;
uint8_t addr;
uint8_t fc; // 3
uint16_t di; // 数据标识
uint16_t datalen;
ac_time3_t tm;
uint16_t di_lowtm; // 开关量低判断时间
uint16_t di_hightm; // 开关量高判断时间
uint16_t crc;
uint32_t end;
} frm_rd_event_t;
发送帧内容如下:
frm_rd_event_t frm_rd_event =
{
SPI_FRM_HEAD,
SPI_ADDR_JC,
SPI_FC_RD,
SPI_DI_RD_EVENT,
sizeof(ac_time3_t) + 4,
{ 0 },
300,
300,
(0),
SPI_FRM_END
};
响应帧格式如下:
typedef struct {
uint8_t addr;
uint8_t fc; // 3
uint16_t di; // 数据标识
uint16_t datalen;
di_event_send_t event;
uint16_t crc;
} frm_rd_event_response_t;
typedef struct {
uint32_t rdptr; // 表示交流采集板上电以来检测到的开入变位个数
uint32_t num; // 本帧中事件的个数 小于等于20
ac_time3_t tm[20]; //表示事件发生时间,其中state格式为:bit0到bit3标识第几路开入,0对应第1路,3对应第4路,bit4标识开入状态
} di_event_send_t;