nodebus.h
#ifndef __MODBUS_H
#define __MODBUS_H
#define NET_ADDR 0xA5
#define SLAVE1_ADDR 0x01
#define BROADCAST_ADDR 0xFF
#define OP_W_COILS 0x02
#define OP_R_SENSOR 0x01
#define PRAM_R_TEMPERATURE 0x01
#define PRAM_R_HUMIDITY 0x02
#define PRAM_R_LUX 0x04
#define PRAM_R_ALL 0x07
#define PRAM_W_RELAY1 0x01
#define PRAM_W_RELAY2 0x02
typedef enum
{
FRAME_OK = 0x00,
FRAME_NETADDR_ERR = 0x01,
FRAME_SLAVEADDR_ERR = 0x02,
FRAME_CRC_ERR = 0x03,
FRAME_EMPTY = 0xFF
}FrameStatus;
typedef struct
{
unsigned char Coils;
unsigned char Temperature;
unsigned char Humidity;
unsigned short int Lux;
}DeviceBlock;
void sendMasterAsk(unsigned char slave_addr,unsigned char op_code,unsigned char pram);
FrameStatus receiveSlaveAck(unsigned char slave_addr,unsigned char op_code,unsigned char pram,DeviceBlock * pdevblock);
FrameStatus processMasterAsk(DeviceBlock * pdevblock);
#endif
nodebus.c
#include "NodeBus.h"
#include "SX1278/SX1278.h"
#include "UART/uart.h"
static unsigned short int getModbusCRC16(unsigned char *_pBuf, unsigned short int _usLen)
{
unsigned short int CRCValue = 0xFFFF;
unsigned char i,j;
for(i=0;i<_usLen;++i)
{
CRCValue ^= *(_pBuf+i);
for(j=0;j<8;++j)
{
if((CRCValue & 0x01) == 0x01)
{
CRCValue = (CRCValue >> 1)^0xA001;
}else
{
CRCValue >>= 1;
}
}
}
if(CRCValue&0xFF==0)
{
CRCValue |= 0xA5;
}
return CRCValue;
}
static unsigned char getFrameLength(unsigned char* pbuffer,unsigned char buffer_len)
{
unsigned char len = buffer_len-1;
while(len)
{
if(*(pbuffer+len)!=0)
{
break;
}
--len;
}
return len+1;
}
void sendMasterAsk(unsigned char slave_addr,unsigned char op_code,unsigned char pram)
{
unsigned char sendbuffer[6] = {NET_ADDR,slave_addr,op_code,pram,0,0};
unsigned short int CRC16 = getModbusCRC16(sendbuffer,4);
sendbuffer[4] = CRC16>>8;
sendbuffer[5] = CRC16;
transmitPackets(sendbuffer,sizeof(sendbuffer));
}
FrameStatus receiveSlaveAck(unsigned char slave_addr,unsigned char op_code,unsigned char pram,DeviceBlock * pdevblock)
{
unsigned char receivebuffer[9];
unsigned char len;
unsigned char i;
if(receivePackets(receivebuffer)==1)
{
if(receivebuffer[0] != NET_ADDR)
{
return FRAME_NETADDR_ERR;
}
if(receivebuffer[1] != slave_addr)
{
return FRAME_SLAVEADDR_ERR;
}
len = getFrameLength(receivebuffer,sizeof(receivebuffer));
if(getModbusCRC16(receivebuffer,len-2) != (receivebuffer[len-2]<<8 | receivebuffer[len-1]))
{
return FRAME_CRC_ERR;
}
if(op_code==OP_W_COILS)
{
(pdevblock+slave_addr)->Coils = receivebuffer[3];
}else if(op_code==OP_R_SENSOR)
{
for(i=0;i<8;++i)
{
switch(pram & (0x01<<i))
{
case PRAM_R_TEMPERATURE:(pdevblock+slave_addr)->Temperature = receivebuffer[3]; break;
case PRAM_R_HUMIDITY :(pdevblock+slave_addr)->Humidity = receivebuffer[4]; break;
case PRAM_R_LUX :(pdevblock+slave_addr)->Lux = receivebuffer[5]<<8 | receivebuffer[6]; break;
default : break;
}
}
}else
{
}
return FRAME_OK;
}else
{
return FRAME_EMPTY;
}
return FRAME_EMPTY;
}
FrameStatus processMasterAsk(DeviceBlock * pdevblock)
{
unsigned char Askbuffer[6];
unsigned char Ackbuffer[9] = {NET_ADDR,SLAVE1_ADDR};
unsigned char len;
unsigned short int CRC16;
unsigned char i;
if(receivePackets(Askbuffer)==1)
{
if(Askbuffer[0] != NET_ADDR)
{
return FRAME_NETADDR_ERR;
}
if(Askbuffer[1] != SLAVE1_ADDR)
{
return FRAME_SLAVEADDR_ERR;
}
len = getFrameLength(Askbuffer,sizeof(Askbuffer));
if(getModbusCRC16(Askbuffer,len-2) != (Askbuffer[len-2]<<8 | Askbuffer[len-1]))
{
return FRAME_CRC_ERR;
}
if(Askbuffer[2]==OP_W_COILS)
{
Ackbuffer[2] = OP_W_COILS;
pdevblock->Coils = Askbuffer[3];
Ackbuffer[3] = pdevblock->Coils;
CRC16 = getModbusCRC16(Ackbuffer,4);
Ackbuffer[4] = CRC16>>8;
Ackbuffer[5] = CRC16;
}else if(Askbuffer[2]==OP_R_SENSOR)
{
Ackbuffer[2] = OP_R_SENSOR;
for(i=0;i<8;++i)
{
switch(Askbuffer[3] & (0x01<<i))
{
case PRAM_R_TEMPERATURE:Ackbuffer[3] = pdevblock->Temperature;break;
case PRAM_R_HUMIDITY :Ackbuffer[4] = pdevblock->Humidity; break;
case PRAM_R_LUX :{
Ackbuffer[5] = pdevblock->Lux>>8;
Ackbuffer[6] = pdevblock->Lux;
} break;
default : break;
}
}
CRC16 = getModbusCRC16(Ackbuffer,7);
Ackbuffer[7] = CRC16>>8;
Ackbuffer[8] = CRC16;
}else
{
}
transmitPackets(Ackbuffer,sizeof(Ackbuffer));
return FRAME_OK;
}else
{
return FRAME_EMPTY;
}
return FRAME_EMPTY;
}
main。c
#include "DELAY/Delay.h"
#include "ADC/ADC.h"
#include "LED/LED.h"
#include "KEY/key.h"
#include "UART/uart.h"
#include "IIC/IIC.h"
#include "OLED/OLED.h"
#include "SPIx/SPIx.h"
#include "SX1278/SX1278.h"
#include "NodeBus.h"
DeviceBlock DeviceBlock_StructureArray[2];
int main(void)
{
u8 keyvalue;
u8 i = 0;
u8 j = 0;
initSysTick();
initADC();
initLED();
initUART();
initKey();
initIIC();
initOLED();
initSPIx(SPI2);
initSX1278();
formatScreen(0x00);
for(i=0;i<=128;i+=2)
{
showImage(0,0,i,8,FM_LOGO_ENUM);
}
formatScreen(0x00);
showCNString(32,0,"风媒电子",FONT_16_CN);
showString(0,2,"Hum :",FONT_16_EN);
showString(0,4,"Temp:",FONT_16_EN);
showString(0,6,"Lux :",FONT_16_EN);
while (1)
{
if(++i==40)
{
i=0;
sendMasterAsk(SLAVE1_ADDR,OP_R_SENSOR,PRAM_R_ALL);
receiveSlaveAck(SLAVE1_ADDR,OP_R_SENSOR,PRAM_R_ALL,DeviceBlock_StructureArray);
Delay_ms(100);
while(receiveSlaveAck(SLAVE1_ADDR,OP_R_SENSOR,PRAM_R_ALL,DeviceBlock_StructureArray)!=FRAME_OK && ++i<10)
{
Delay_ms(100);
}
i = 0;
}
keyvalue = getKeyValue(KEY_RELEASE);
if(keyvalue==KEY_UP)
{
j=0;
DeviceBlock_StructureArray[SLAVE1_ADDR].Coils ^= 0x01;
sendMasterAsk(SLAVE1_ADDR,OP_W_COILS,DeviceBlock_StructureArray[SLAVE1_ADDR].Coils);
receiveSlaveAck(SLAVE1_ADDR,OP_R_SENSOR,PRAM_R_ALL,DeviceBlock_StructureArray);
Delay_ms(100);
while(receiveSlaveAck(SLAVE1_ADDR,OP_W_COILS,0,DeviceBlock_StructureArray)!=FRAME_OK && ++j<30)
{
Delay_ms(100);
}
}else if(keyvalue==KEY_DOWN)
{
j=0;
DeviceBlock_StructureArray[SLAVE1_ADDR].Coils ^= 0x02;
sendMasterAsk(SLAVE1_ADDR,OP_W_COILS,DeviceBlock_StructureArray[SLAVE1_ADDR].Coils);
receiveSlaveAck(SLAVE1_ADDR,OP_R_SENSOR,PRAM_R_ALL,DeviceBlock_StructureArray);
Delay_ms(100);
while(receiveSlaveAck(SLAVE1_ADDR,OP_W_COILS,0,DeviceBlock_StructureArray)!=FRAME_OK && ++j<30)
{
Delay_ms(100);
}
}else if(keyvalue==KEY_ALL)
{
j=0;
DeviceBlock_StructureArray[SLAVE1_ADDR].Coils ^= 0x03;
sendMasterAsk(SLAVE1_ADDR,OP_W_COILS,DeviceBlock_StructureArray[SLAVE1_ADDR].Coils);
receiveSlaveAck(SLAVE1_ADDR,OP_R_SENSOR,PRAM_R_ALL,DeviceBlock_StructureArray);
Delay_ms(100);
while(receiveSlaveAck(SLAVE1_ADDR,OP_W_COILS,0,DeviceBlock_StructureArray)!=FRAME_OK && ++j<30)
{
Delay_ms(100);
}
}else
{
}
showNumber(40,2,DeviceBlock_StructureArray[SLAVE1_ADDR].Humidity,DEC,3,FONT_16_EN);
showNumber(40,4,DeviceBlock_StructureArray[SLAVE1_ADDR].Temperature,DEC,3,FONT_16_EN);
showNumber(40,6,DeviceBlock_StructureArray[SLAVE1_ADDR].Lux,DEC,5,FONT_16_EN);
toggleLED();
Delay_ms(50);
}
}