📄 modbus.c
字号:
//修正了一上电就发大批数据的错误,把void UART0_Init (void)里的TI0=1改为TI0=。
//-----------------------------------------------------------------------------
// UART1_Int1.c
//-----------------------------------------------------------------------------
// Target: C8051F02x
// Tool chain: KEIL C51 6.03 / KEIL EVAL C51
//
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <c8051f020.h> // SFR declarations
#include <stdio.h>
#include <string.h>
#include <intrins.h>
#include <absacc.h>
//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F02x
//-----------------------------------------------------------------------------
sfr16 DP = 0x82; // data pointer
sfr16 TMR3RL = 0x92; // Timer3 reload value
sfr16 TMR3 = 0x94; // Timer3 counter
sfr16 ADC0 = 0xbe; // ADC0 data
sfr16 ADC0GT = 0xc4; // ADC0 greater than window
sfr16 ADC0LT = 0xc6; // ADC0 less than window
sfr16 RCAP2 = 0xca; // Timer2 capture/reload
sfr16 T2 = 0xcc; // Timer2
sfr16 RCAP4 = 0xe4; // Timer4 capture/reload
sfr16 T4 = 0xf4; // Timer4
sfr16 DAC0 = 0xd2; // DAC0 data
sfr16 DAC1 = 0xd5; // DAC1 data
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
#define RX1_LENGTH 64 // 485 length of UART RX buffer
#define RX1_START 0X7E // 485 帖起始符
#define RX1_END 0X0D // 485 帖结束符
#define RX0_LENGTH 5 // command length of UART RX buffer
#define RX0_START 0X7E // command 帖起始符
#define RX0_END 0X0D // command 帖结束符
//-----------------------------------------------------------------------------
// Global VARIABLES
//-----------------------------------------------------------------------------
bit TX1_Ready; // '1' means okay to TX
char *TX1_ptr; // pointer to string to transmit
bit RX1_Ready; // '1' means RX string received
bit TX0_Ready; // '1' means okay to TX
char *TX0_ptr; // pointer to string to transmit
bit RX0_Ready; // '1' means RX string received
unsigned char xdata RX1_Buf[RX1_LENGTH]; // receive string storage buffer
unsigned char xdata modbusRX1_Buf[RX1_LENGTH]; // receive string storage buffer
unsigned char xdata RX0_Buf[RX0_LENGTH]; // receive string storage buffer
static unsigned char RX1_index = 0; // uart1 receive buffer index
static unsigned char RX0_index = 0; // uart1 receive buffer index
bit cdma=1; //间隔采集定时时间开标志,初始化时应为1
bit sendinterval; //发送时间到标志。初始化时应为1
bit sendinterva2; //T2定时到
bit addend; //发送最后一个地址标志,1为发送了最后一个地址,0为没有发送到最后一个地址
bit addrnd; //收到最后一个地址标志位,0为没有收到,1为收到
bit qkhg1_16;
bit hkqg1_16;
bit qkhg17_20;
bit hkqg17_20;
unsigned char xdata SENDNUM1; //uart1要发送数据的数目
unsigned char xdata RECEIVENUM1; //uart1收到数据的数目
unsigned int xdata SENDNUM0; //uart0要发送数据的数目
unsigned char xdata RECEIVENUM0; //uart0收到数据的数目
sbit RE485=P2^0;
sbit WP=P2^1;
unsigned int xdata time; //间隔采集时间累计
unsigned int xdata tend; //设置间隔时间长短
unsigned int xdata temp;
unsigned int xdata time2; //间隔采集时间累计
unsigned int xdata tend2; //设置间隔时间长短
unsigned int xdata temp2;
unsigned char xdata addr; //传感器地址
unsigned char xdata addh; //传感器高地址
unsigned char xdata addl; //传感器低地址
unsigned char xdata p7pas; //定义P7口开始数据
unsigned char xdata p7pan; //定义P7口指令数据
unsigned char xdata p6pas; //定义P6口开始数据
unsigned char xdata p6pan; //定义P6口指令数据
unsigned char xdata p5pas; //定义P5口开始数据
unsigned char xdata p5pan; //定义P5口指令数据
unsigned char xdata waddr[2]; //写传感器地址
unsigned char xdata raddr[2]; //读传感器地址
unsigned int xdata packge; //数据打包数
unsigned char xdata ardata[2048]; //定义数组用于打包向总控中心发送的数据
int *PRX0;
unsigned char xdata onoff; //两输入开关量
unsigned char xdata firstoff1_8;
unsigned char xdata firstoff9_16;
unsigned char xdata firstoff17_20;
unsigned char code even[256]=
{0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
};
unsigned char address;
//unsigned char xdata status[12];
//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------
void SYSCLK_Init (void);
void PORT_Init (void);
void Timer0_Init (void);
void Timer0_ISR (void);
void Timer2_Init(void);
void Timer2_ISR(void);
void UART0_Init (void);
void UART0_ISR (void);
void modbusUART1_Init (void);
void UART1_ISR (void);
void RX0_BufClear(void);
void RX1_BufClear(void);
void FlashWrite(unsigned char xdata *pwrite,unsigned char *BufFrom);
void FlashRead(unsigned char code *pread,unsigned char *BufTo);
void SendCgqAddr(void);
void modbuscgqsend(unsigned char addr);
//void ReadStatus(void);
//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------
void main (void)
{
WDTCN = 0xde; // disable watchdog timer
WDTCN = 0xad;
sendinterval=1;
time=0x0000;
temp=0x0064;
//////////////////
time2=0x0000;
temp2=0x0064;
qkhg1_16=0;
hkqg1_16=0;
qkhg17_20=0;
hkqg17_20=0;
////////////////////
packge=0x0000;
addend=0;
addrnd=0;
RX1_Ready=0;
FlashRead(0x0000,raddr);
//addl=0x00; //调试时用
//addh=0x01; //调试时用
addl=raddr[1];
addh=raddr[0]; //高在前;低在后
addr=addl;
cdma=1;
SYSCLK_Init (); // initialize oscillator
PORT_Init (); // initialize crossbar and GPIO
modbusUART1_Init ();
Timer0_Init ();
UART0_Init ();
Timer2_Init();
EA = 1; // enable global interrupts
p7pas=0x00;
P7=p7pas;
p6pas=0x00;
P6=p6pas;
p5pas=0x00;
P5=p5pas;
while (1)
{
//--------------------------------------------------------------------------------------
if(RX0_Ready == 1)
{ PRX0=RX0_Buf;
switch(RX0_Buf[1])
{
case 0XF0: //设置间隔时间
TR0=0;
temp=*(PRX0+1);
RX0_Ready=0;
TR0=1;
break;
case 0XF1: //关闭定时上传数据
TR0=0;
tend=0x64; //定时设为系统默认值
cdma=0; //定时采集标志位
RX0_Ready=0;
break;
case 0XF2: //打开定时采集数据
TR0=1;
cdma=1;
RX0_Ready=0;
break;
case 0XF3: //打开编号为1--16的12伏控制开关
p7pan=RX0_Buf[3];
p6pan=RX0_Buf[2];
p7pas=p7pas|p7pan;
p6pas=p6pas|p6pan;
P7=p7pas;
P6=p6pas;
RX0_Ready=0;
break;
case 0XF4: //关闭编号为1--16的12伏控制开关,遇0不变,遇1变1
p7pan=RX0_Buf[3];
p7pas=~((~p7pas)|p7pan);
P7=p7pas;
p6pan=RX0_Buf[2];
p6pas=~((~p6pas)|p6pan);
P6=p6pas;
RX0_Ready=0;
break;
case 0XF5: //设置传感器的起始地址和终止地址
waddr[0]=RX0_Buf[2]; //高在前
waddr[1]=RX0_Buf[3];
FlashWrite(0x0000,waddr);
RX0_Ready=0;
break;
case 0XF6: //打开编号为17--20的12伏控制开关
p5pan=RX0_Buf[3];
p5pas=p5pas|p5pan;
P5=p5pas;
RX0_Ready=0;
break;
case 0XF7: //关闭编号为17--20的12伏控制开关
p5pan=RX0_Buf[3];
p5pas=~((~p5pas)|p5pan);
P5=p5pas;
RX0_Ready=0;
break;
case 0XF8: //打开编号为21--36的12伏控制开关
RX0_Ready=0;
break;
case 0XF9: //关闭编号为21--36的12伏控制开关
RX0_Ready=0;
break;
case 0XFA: //打开编号为37--40的12伏控制开关
RX0_Ready=0;
break;
case 0XFB: //关闭编号为37--40的12伏控制开关
RX0_Ready=0;
break;
case 0XFC: //远程遥控集中器复位命令*/
RSTSRC |=0X10;
RX0_Ready=0;
break;
case 0XFD: //读两输入开关量
P4=0XFF;
onoff=P4;
RX0_Ready=0;
break;
case 0XFE: //读地址范围
FlashRead(0x0000,raddr);
SendCgqAddr();
RX0_Ready=0;
break;
case 0XD0: //防盗1
RX0_Ready=0;
break;
case 0XD1: //防盗2
RX0_Ready=0;
break;
case 0XD2: //设置继电器互锁时间
temp2=*(PRX0+1);
RX0_Ready=0;
break;
case 0XD3: //1-16个继电器前关后开指令
p7pan=RX0_Buf[3];
firstoff1_8=p7pan;
p7pas=~((~p7pas)|p7pan);
P7=p7pas;
p6pan=RX0_Buf[2];
firstoff9_16=p6pan;
p6pas=~((~p6pas)|p6pan);
P6=p6pas;
qkhg1_16=1;
TR2=1;
RX0_Ready=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -