📄 16f877_modbus.c
字号:
/******************** (C) COPYRIGHT 2008 yuanlin ************************
* File Name : main_slave_uart.c
* Author : 袁林
* Version : V1.0
* Date : 27/10/2008
* Description : This file provides all the main and slave uart functions.
********************************************************************************/
#include "pic18.h"
#include "pic18fxx8.h"
#include "stdio.h"
#include "string.h"
__CONFIG(1,HSPLL&OSCSDIS);
__CONFIG(2,PWRTEN&BORV42&BOREN&WDTPS128&WDTEN);
__CONFIG(4,DEBUGDIS&LVPDIS&STVREN);
__CONFIG(5,UNPROTECT);
__CONFIG(6,WPU);
__CONFIG(7,PTBRU);
#define CLRWDT asm("CLRWDT")
#define _40M
#define SD RC5
#define SCK RC3
#define KEYMASK 0x07
#define KEYUP 0x01
#define KEYENTER 0x02
#define KEYDOWN 0x04
#define E2RAM ee_toram()
#define E2CRC eecrc()
#define line1 0x80 //80 81 82 83 84 85 86 87
#define line2 0x90 //90 91 92 93 94 95 96 97
#define line3 0x88 //88 89 8a 8b 8c 8d 8e 8f
#define line4 0x98 //98 99 9a 9b 9c 9d 9e 9f
/* 200ms,if Focs is 20MHz,the value is 85ee,if Focs is 40MHz,the value is 0x0bdc */
//#define T0LValue 0xee
//#define T0HValue 0x85
#define T0LValue 0xdc
#define T0HValue 0x0b
/* 100us,if Focs is 20MHz,the value is fe0b,if Focs is 40MHz,the value is fc18*/
//#define T1LValue 0x0b
//#define T1HValue 0xfe
#define T1LValue 0x18
#define T1HValue 0xfc
/* 5ms,if Focs is 20MHz,the value is 9e58,if Focs is 40MHz,the value is 0x3cb0 */
//#define T3LValue 0x58
//#define T3HValue 0x9e
#define T3LValue 0xb0
#define T3HValue 0x3c
#define CURRENT 0x1c
#define VOLTAGE 0x1b
#define uchar unsigned char
#define uint unsigned int
uchar bank1 data_buf[11];
uchar bank1 *DataPoint;
uchar data_buf0[11];
uchar bank1 Buffer[160];
uchar bank1 *BufferPointIn;
uchar bank1 *BufferPointOut;
uchar bank1 address;
uchar bank1 rece_timer=0;
uchar bank1 wait_redo=0;
uchar bank1 rece_counter=0;
uchar bank1 send_number=0;
uchar bank1 send_counter=1;
uchar Flag10ms=0;
uchar Buffer0[160];
uchar* Buffer0PointIn;
uchar* Buffer0PointOut;
uchar DorrFlag=0;
uint DorrCounter=0;
uchar Tree=0;
uchar Menu=0;
uchar XValue=0;
uint * point;
uchar SendFlag=0;
uchar Delay200=0;
/* a=0x1234,b[0]=0x34 is low,b[1]=0x12 is high */
union data
{
uint a;
uchar b[2];
}buffer;
uint x_number[130];
uint x_number1[33];
uint x_number2[33];
uint x_number3[33];
uchar KeyValue=0xff;
uchar KeyValueBuf=0xff;
uchar KeyScanTime=0;
uchar KeyScanCnt=0;
uchar LcdScanTime=0;
uchar State=0;
uchar MainSlave=0;
uchar NumberBuffer[16]={0xa2,0xa0,0xa2,0xa0,0xa2,0xa0,0xa2,0xa0,0xa2,0xa0,0xa2,0xa0,0xa2,0xa0,0xa2,0xa0};
uchar num_xi[8];
bit rece_start=0;
bit MainSendNoack=0;
bit rece_ok=0;
bit send_ok=0;
bit KeySetFlag=0;
uchar PidStartFlag=0;
bit KeyScanFlag=0;
bit KeyPress=0;
uchar LcdFlag=0;
bit MenuIn=0;
bit ChangeFlag=0;
uchar LcdErro=0;
void GlobalInit(void);
void UsartInit(void);
void UsartSendSlave(uchar n);
void UsartSendMain(uchar n);
void UsartReceveSlave(void);
void Function_slave(void);
uint get_crc(uchar n);
uchar Function_03(uchar addr_8);
uchar Function_06(uchar addr_8);
void LcdInit(void);
void WriteCommand(uchar value);
void WriteData(uchar value);
void writeee2b(uint eevalue,uchar eeaddr);
void eecrc(void);
void ee_toram(void);
uchar readee(uchar eeaddr);
void writee(uchar eevalue,uchar eeaddr);
void ram_toee(uchar u);
void rom_toram(uchar u);
void delay(uint t);
void WriteByte(uchar value);
void WriteCommand(uchar value);
void WriteData(uchar value);
void KeyScan(void);
void KeyFunction(void);
void ChangeF(void);
void Init(void);
uint readee2b(uchar eeaddr);
void NumberDivide(uint n);
void NumberNoPointMain(uint number);
void LcdSelectBrush(uchar line,uchar num);
void LcdMain(void);
void LcdSlave(void);
#define pid_t x_number[0x00] //10.0软起动时间
#define pid_pu x_number[0x01] //50%起始电压百分比
#define pid_1i x_number[0x02] //300额定电流
#define pid_cuti x_number[0x03] //7限流倍数
#define pid_gb x_number[0x04] //刮板机选择:0---不选择,5---点动5次
//#define pid_485 x_number[0x05] //0通讯方式选择:0---modbus_ main,0x11---modbus_slave,2---485
#define pid_yt x_number[0x06] //1.0延时启动时间
#define pid_wd x_number[0x07] //10温度保护动作时间
#define pid_ch4 x_number[0x08] //10甲烷保护动作时间
#define pidi_k x_number[0x09] //30强制旁路切换时间
#define pid_lt x_number[0x0a] //0软停止时间
#define pid_save x_number[0x0b] //退出
#define pid_nosa x_number[0x0c] //退出
#define pid_mode x_number[0x0d] //2启动模式:0---双环,1---电流环,2---电压斜坡
#define pidv_k x_number[0x0e] //1.0速度系数
#define pid1_p x_number[0x0f] //1.00速度环比例
#define pid1_i x_number[0x10] //3.0速度环积分
#define pid0_ia x_number[0x11] //0电流环选择
#define pid0_p x_number[0x12] //1.0电流环比例
#define pid0_i x_number[0x13] //0.05电流环积分
#define pid_pb x_number[0x14] //1保护屏蔽
#define pid_za x_number[0x15] //500互感器匝比[800:0.1],[500:0.1]
#define pid_bycd2 x_number[0x16] //主从模式 0 主 / 1 从 上电默认值0
#define pid_bycd3 x_number[0x17] //站号
#define pid_gya x_number[0x18] //130过压保护
#define pid_qya x_number[0x19] //60欠压保护
#define pid_plc x_number[0x1a] //恢复出厂值
#define pid_u x_number[0x1b] //电压采样
#define pid_i x_number[0x1c] //电流采样
#define pid_flag x_number[0x1d] //保护变量
#define pid_key x_number[0x1e] //键盘变量
#define pid_bld x_number[0x1f] //备用变量
#define p_de RB0 //485通讯口方向控制,0输入,1输出
const uint pre_number[26]={ 100, 40, 300, 70, 0, 0, 10, 10, 10, 30, 0, 1, 0, 2, 10, 100, 10, 0, 100, 20, 2, 800, 0, 0, 130, 60};
//出厂设置
const uint max_dat[27]={ 1800, 90,1000, 80, 20, 13, 600, 60, 60, 600, 20, 1, 1, 2, 99, 999, 999, 3, 999, 9999, 10, 1000, 999, 999, 500, 500,1};
const uchar dot_x[27]={ 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 2, 2, 0, 0, 0, 0, 0, 0,0};
// Pt-,su--,ie--,cut-,gb-,485-,yt--,wdu-,ch4, aux_,soft,save,nosa,mode-,v_k , v_p, v_i, ia, i_p, i_i, pb, iza,aux,dis,u_over,u_self
// s, %, A, no, no, no, s, s, s, no, s,no, no, no, no, no, s, no, no, s, no, no, x
const uchar dat_tale[26]={0x73,0x25,0x41,0x20,0x20,0x20,0x73,0x73,0x73,0x20,0x73,0x20,0x20,0x20,0x20,0x20,0x73,0x20,0x20,0x73,0x20,0x20,0x73,0x20,0x20,0x20};
const uchar PointTable[27]={1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 2, 2, 0, 0, 0, 0, 0, 0,0};
/* s % A bei ci s s s s s */
const uint NumberH[27]={1800,90,1000,80,20,0,600,60,60,600,20,55,55,2,99,999,999,3,999,9999,10,1000,1,3,500,500,1};
const uint NumberL[27]={ 1, 0, 0, 1, 0, 0,0, 0, 0, 0, 0,55,55,0, 1, 0, 1, 0,0, 0, 0, 0, 0,0,0, 0,0};
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12 13 14 15 16 17 18 19*/
const uchar SigneTable[27]={0xd3,0xa5,0xc1,0xa0,0xa0,0xa0,0xd3,0xd3,0xd3,0xd3,0xd3,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xd6,0xd6,0xa0};
const uchar ValueTable[27][16]={
/* 启 */
{0x30,0x31,0x29,0x20,0xC6,0xF4,0xB6,0xAF,0xCA,0xB1,0xBC,0xE4,0x20,0x20,0x20,0x20}, //1启动时间 00 pid_t
{0x30,0x32,0x29,0x20,0xC6,0xF4,0xB6,0xAF,0xB3,0xF5,0xCA,0xBC,0xB5,0xE7,0xD1,0xB9}, //2启动初始电压 01 pid_pu
{0x30,0x33,0x29,0x20,0xB6,0xEE,0xB6,0xA8,0xB5,0xE7,0xC1,0xF7,0x20,0x20,0x20,0x20}, //3额定电流 02 pid_1i
{0x30,0x34,0x29,0x20,0xC6,0xF4,0xB6,0xAF,0xcf,0xde,0xC1,0xF7,0xB1,0xB6,0xCA,0xFD}, //4电流限流倍数 03 pid_cuti
{0x30,0x35,0x29,0x20,0xb9,0xce,0xb0,0xe5,0xbb,0xfa,0xD1,0xA1,0xD4,0xF1,0x20,0x20}, // 5刮板机选择 04 pid_gb
{0x30,0x36,0x29,0x20,0xCD,0xA8,0xD1,0xB6,0xB7,0xBD,0xCA,0xBD,0x20,0x20,0x20,0x20}, //6通讯方式 05 pid_485
{0x30,0x37,0x29,0x20,0xD1,0xD3,0xCA,0xB1,0xC6,0xF4,0xB6,0xAF,0xCA,0xB1,0xBC,0xE4}, //7延时启动时间 06 pid_yt
{0x30,0x38,0x29,0x20,0xCE,0xC2,0xB6,0xC8,0xB1,0xA3,0xBB,0xA4,0xD1,0xD3,0xCA,0xB1}, //8温度保护延时 07 pid_wd
{0x30,0x39,0x29,0x20,0xbc,0xd7,0xcd,0xe9,0xB1,0xA3,0xBB,0xA4,0x20,0x20,0x20,0x20}, //9甲烷保护 08 pid_ch4
{0x31,0x30,0x29,0x20,0xcf,0xb5,0xcd,0xb3,0xd7,0xd4,0xbc,0xec,0x20,0x20,0x20,0x20}, //a强制切换时间 09 pidi_k
{0x31,0x31,0x29,0x20,0xc8,0xed,0xcd,0xa3,0xca,0xb1,0xbc,0xe4,0x20,0x20,0x20,0x20}, //a 软停止时间 0a
/* b返回到上一层 3*/
{0x31,0x32,0x29,0x20,0xb7,0xb5,0xbb,0xd8,0xb5,0xbd,0xc9,0xcf,0xd2,0xbb,0xb2,0xe3},
/* c返回到上一层 3*/
{0x31,0x35,0xa1,0xb5,0xb7,0xb5,0xbb,0xd8,0xb5,0xbd,0xc9,0xcf,0xd2,0xbb,0xb2,0xe3},
{0x30,0x31,0xa1,0xb5,0xC6,0xF4,0xB6,0xAF,0xc4,0xa3,0xCA,0xBD,0x20,0x20,0x20,0x20},//1启动模式d 0d pid_mode
{0x30,0x32,0xa1,0xb5,0xCB,0xD9,0xB6,0xC8,0xBB,0xB7,0xB1,0xB6,0xCA,0xFD,0x20,0x20},//2速度环倍数e 0e pidv_k
{0x30,0x33,0xa1,0xb5,0xCB,0xD9,0xB6,0xC8,0xBB,0xB7,0xB1,0xC8,0xC0,0xFd,0x50,0x20},//3速度环比例pf 0f pid1_p
{0x30,0x34,0xa1,0xb5,0xCB,0xD9,0xB6,0xC8,0xBB,0xB7,0xBB,0xFD,0xB7,0xD6,0x49,0x20},//4速度环积分i10 010 pid1_i
{0x30,0x35,0xa1,0xb5,0xB5,0xE7,0xC1,0xF7,0xBB,0xB7,0xD1,0xA1,0xD4,0xF1,0x20,0x20},//5电流环选择 0x11
{0x30,0x36,0xa1,0xb5,0xB5,0xE7,0xC1,0xF7,0xBB,0xB7,0xB1,0xC8,0xC0,0xFd,0x50,0x20},//6电流环比例p 0x12 pid0_p
{0x30,0x37,0xa1,0xb5,0xB5,0xE7,0xC1,0xF7,0xBB,0xB7,0xBB,0xFD,0xB7,0xD6,0x49,0x20},//7电流环积分i 0x13 pid0_i
{0x30,0x38,0xa1,0xb5,0xB1,0xA3,0xBB,0xA4,0xc6,0xc1,0xb1,0xce,0x20,0x20,0x20,0x20},//8保护屏蔽 0x14 pid_pb
{0x30,0x39,0xa1,0xb5,0xBB,0xA5,0xB8,0xD0,0xC6,0xF7,0xD4,0xD1,0xCA,0xFD,0xB1,0xC8},//9互感器匝数比 0x15 pid_za
{0x31,0x30,0xa1,0xb5,0xc4,0xa3,0x3a,0x30,0xd6,0xf7,0xbb,0xfa,0x2f,0x31,0xb4,0xd3}, //工作模式 0x16 pid_ont
{0x31,0x31,0xa1,0xb5,0xca,0xdc,0xbf,0xd8,0xd5,0xbe,0xba,0xc5,0xd1,0xa1,0xd4,0xf1},//受控站选择 0x17
{0x31,0x32,0xa1,0xb5,0xB9,0xFD,0xD1,0xb9,0xc9,0xe8,0xb6,0xA8,0x20,0x20,0x20,0x20},//过压保护 0x18
{0x31,0x33,0xa1,0xb5,0xc7,0xb7,0xD1,0xb9,0xc9,0xe8,0xb6,0xA8,0x20,0x20,0x20,0x20}, //欠压保护 0x19
{0x31,0x34,0xa1,0xb5,0xbb,0xd6,0xb8,0xb4,0xb3,0xf6,0xb3,0xa7,0xd6,0xb5,0x20,0x20}//恢复出厂值0x1a
};
const uchar SelectTable[25][16]={
/*《空空用户设定》 0*/
{0x20,0x11,0x20,0x20,0x20,0x20,0xCF,0xB5,0xCD,0xB3,0xC9,0xE8,0xB6,0xA8,0x10,0x20},
/*《空空技术界面》 1 */
{0x20,0x11,0x20,0x20,0x20,0x20,0xBC,0xBC,0xCA,0xF5,0xBD,0xE7,0xC3,0xE6,0x10,0x20},
/* 返回到上一层 3*/
{0x20,0x11,0xb7,0xb5,0xbb,0xd8,0xb5,0xbd,0xc9,0xcf,0xd2,0xbb,0xb2,0xe3,0x10,0x20},
/* 主/从机功能设置 2*/
{0xd6,0xf7,0xa3,0xaf,0xb4,0xd3,0xbb,0xfa,0xb9,0xa6,0xc4,0xdc,0xc9,0xe8,0xd6,0xc3},
/*****************************************************************************
* DRK 软启动控制器 0
* #中文版
* tel:64397382
* *上海久辉电气*
*****************************************************************************/
{0x44,0x52,0x4b,0x20,0xC8,0xED,0xC6,0xF4,0xB6,0xAF,0xBF,0xD8,0xD6,0xC6,0xC6,0xF7},
{0x20,0x20,0x20,0x20,0x20,0x04,0xD6,0xD0,0xCE,0xC4,0xB0,0xE6,0x20,0x20,0x20,0x20},
{0x20,0x20,0x54,0x65,0x6c,0x3a,0x36,0x34,0x33,0x39,0x37,0x33,0x38,0x32,0x20,0x20},
{0xa1,0xee,0xC9,0xCF,0xBA,0xA3,0xBE,0xC3,0xBB,0xD4,0xB5,0xE7,0xC6,0xF8,0xa1,0xee},
/* 空空系统菜单 8*/
{0x20,0x2a,0xcf,0xb5,0xcd,0xb3,0xb2,0xcb,0xb5,0xa5,0xd1,0xa1,0xd4,0xf1,0x2a,0x20},
/* 空空空 9 */
{0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20},
/* #上翻 #下翻 10*/
{0x20,0x1e,0xc9,0xcf,0xb7,0xad,0x20,0x20,0x20,0x1f,0xcf,0xc2,0xb7,0xad,0x20,0x20},
/* #减少 #增加 11 */
{0x20,0x1e,0xbc,0xf5,0xc9,0xd9,0x20,0x20,0x20,0x1f,0xd4,0xf6,0xbc,0xd3,0x20,0x20},
/*电流 0 A 0a 12 */
{0xB5,0xE7,0xC1,0xF7,0xa3,0xba,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa3,0xc1},
/* 电压 0 V 0b 13 */
{0xB5,0xE7,0xD1,0xB9,0xa3,0xba,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa3,0xd6},
/* 《启动延时 15s》 0c 14 */
{0x11,0x20,0xC6,0xF4,0xB6,0xAF,0xd1,0xd3,0xCA,0xB1,0x20,0x3e,0x3e,0x3e,0x20,0x10},
/* 《软启动正运行》 0d 15 */
{0x11,0x20,0xC8,0xED,0xC6,0xF4,0xB6,0xAF,0xd5,0xfd,0xD4,0xCB,0xD0,0xD0,0x20,0x10},
/* 《磁力器正运行》 0e 16 */
{0x11,0x20,0xb4,0xc5,0xC1,0xa6,0xc6,0xf7,0xd5,0xfd,0xD4,0xCB,0xD0,0xD0,0x20,0x10},
/* 单机运行 17 */
{0x20,0x20,0x20,0x20,0xb5,0xa5,0xbb,0xfa,0xd4,0xcb,0xd0,0xd0,0x20,0x20,0x20,0x20},
/* 主机模式 18*/
{0x20,0x20,0x20,0x20,0xd6,0xf7,0xbb,0xfa,0xc4,0xa3,0xca,0xbd,0x20,0x20,0x20,0x20},
/* 从机模式 19*/
{0x20,0x20,0x20,0x20,0xb4,0xd3,0xbb,0xfa,0xc4,0xa3,0xca,0xbd,0x20,0x20,0x20,0x20},
/* 通讯无应答! 20*/
{0x20,0x20,0xcd,0xa8,0xd1,0xb6,0xce,0xde,0xd3,0xa6,0xb4,0xf0,0xa3,0xa1,0x20,0x20},
/* 站号选择 21*/
{0x31,0x31,0xa1,0xb5,0xd5,0xbe,0xba,0xc5,0xc9,0xe8,0xd6,0xc3,0x20,0x20,0x20,0x20},
/*《 系统故障 》22*/
{0x20,0x11,0x20,0x20,0xcf,0xB5,0xCD,0xB3,0xB9,0xCA,0xD5,0xcf,0x20,0x20,0x10,0x20},
/*23*/
{0x20,0x20,0xcd,0xa8,0xd1,0xb6,0xb9,0xca,0xd5,0xcf,0xa3,0xa1,0x20,0x20,0x20,0x20},
};
/*******************************************************************************
* Function Name : UsartInit
* Description : UsartInit
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void UsartInit(void)
{
rece_start=0;
rece_timer=0;
rece_counter=0;
send_number=0;
send_counter=1;
rece_start=0;
MainSendNoack=0;
rece_ok=0;
send_ok=0;
BufferPointIn=Buffer;
BufferPointOut=Buffer;
DataPoint=data_buf;
rece_counter=0;
send_counter=1;
buffer.a=x_number[0x17];
address=buffer.b[0];
/* RC7 is RX,RC6 is TX */
TRISC7=1;
TRISC6=0;
RC6=1;
/* low speed */
BRGH=0;
/* Asynchronous mode */
SYNC=0;
SPEN=1;
/* 32,-1.36,9.47,20M..64,+0.16,9.62,40M..9600 */
//SPBRG=32;
SPBRG=64;
PEIE=1;
TXIE=0;
RCIE=0;
CREN=0;
TXEN=0;
/* 200ms timer */
TMR0L=0;
TMR0H=0;
T0CON=0x08;
TMR0IF=0;
TMR0IE=1;
/* 5mS timer */
TMR3L=T3LValue;
TMR3H=T3HValue;
T3CON=0x80;
TMR3IE=1;
TMR3IF=0;
GIE=1;
TRISB0=0;
RB0=0;
RCIE=1;
TXIE=0;
CREN=1;
}
/*******************************************************************************
* Function Name : UsartSendSlave
* Description : UsartSendSlave
* Input : the bytes number of want to send
* Output : None
* Return : None
*******************************************************************************/
void UsartSendSlave(uchar n)
{
uchar i;
/* reset the equipment's NO. */
if(n==0x01){
n=0x06;
RB0=1;
send_number=n+2;
send_ok=0;
buffer.a=get_crc(n);
data_buf[n+1]=buffer.b[1];
data_buf[n]=buffer.b[0];
TXREG=data_buf[0];
TXIE=1;
TXEN=1;
while(send_ok!=0);
while(TRMT==0);
for(i=20;i>0;i--);
TXEN=0;
send_counter=1;
UsartInit();
return;
}
/* the equipment has erro,must be reset */
if(n==0){
n=0x06;
RB0=1;
send_number=n+2;
send_ok=0;
buffer.a=get_crc(n);
data_buf[n+1]=buffer.b[1];
data_buf[n]=buffer.b[0];
TXREG=data_buf[0];
TXIE=1;
TXEN=1;
while(send_ok!=0);
while(TRMT==0);
TXEN=0;
send_counter=1;
RB0=0;
asm("RESET");
}
/* the normal work and send */
RB0=1;
send_number=n+2;
send_ok=0;
buffer.a=get_crc(n);
data_buf[n+1]=buffer.b[1];
data_buf[n]=buffer.b[0];
TXREG=data_buf[0];
TXIE=1;
TXEN=1;
while(send_ok!=0);
while(TRMT==0);
for(i=20;i>0;i--);
TXEN=0;
send_counter=1;
RB0=0;
data_buf[0]=0;
data_buf[1]=0;
RCIE=1;
CREN=1;
}
/*******************************************************************************
* Function Name : UsartSendMain
* Description : UsartSendMain
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void UsartSendMain(uchar n)
{
/* send the n bytes command */
RB0=1;
send_number=n+2;
send_ok=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -