📄 rs232.c
字号:
/*********************************************************************
* 串行通信模块
*功能:完成通信协议的组合和解释执行,发送和接收数据
*占用资源:串行通信口
**********************************************************************/
/*********************************************************************
* 通信协议(数据格式)
*可读寄存器 12个
*读寄存器指令:0x03
* 地址 内容
* 0x00 A相电压值
0x01 B相电压值
0x02 C相电压值
0x03 A相电流值
0x04 B相电流值
0x05 C相电流值
0x06 三相总有功功率
0x07 三相总视在功率
0x08 三相平均功率因数
0x09 三相总有功率电能
0x0a 三相总视在率电能
0x0b 当前浪涌个数
0x0c 当前电流互感器所设置的变比大小
*可写寄存器 18个
*写寄存器指令:0x10
* 地址 内容
* 100 A相电流补偿寄存器
101 B................
102 C................
103 A相电压补偿寄存器
104 B................
105 C................
106 A相电流校准寄存器
107 B................
108 C................
109 A相电压补偿寄存器
110 B................
111 C................
112 A相有功电能校准寄存器
113 B....................
114 C....................
115 A相视在电能校准寄存器
116 B....................
117 C....................
118 改变当前电流互感器变比的大小
***********************************************************************/
#define MODE422
#include "REG52.H"
#include "ade7758.h"
//#include "stdio.h"
#define NULL 0
#define uchar unsigned char
#define uint unsigned int
#define RECEIVE_BUF_SIZE 50
extern bit bWorkModel;//工作模式标志位 1:校准模式;0:正常工作模式;启动时检测键盘口状态,确定该位状态
unsigned char xdata receive_buff[RECEIVE_BUF_SIZE];
unsigned char idata begin_trans_buff,end_trans_buff;
unsigned char idata end_rec_buff,begin_rec_buff;
uchar tran_buf_size = 0;
bit tr_begin_flag = 0;
void transmit(void);
void receive(void);
void putchar(char c);
unsigned char getchar();
unsigned int CRC_16(unsigned char * p,unsigned char len);
/****************************************************************************************
* 串行中断服务程序
*功能:负责接收和发送数据
****************************************************************************************/
sbit rec_led = P3^6;
sbit trx_led = P3^7;
void serial() interrupt 4 using 3
{
//EA = 0;
if(TI)
{
TI = 0;
transmit();
}
if(RI)
{
rec_led = 0;
RI = 0;
receive();
rec_led = 1;
}
EA = 1;
}
/**************************************************************************************
数据发送子函数,在串口中断中调用
***************************************************************************************/
bit bSendingData = 0; //正在发数据,这时不允许改变缓冲区中的数据
uchar xdata *pComData = &rwdata;//将指针指向数据结构体
uchar data pOffset = 0;
void transmit(void) using 3 /* serial interrupt routine */
{
if( /*( pComData != NULL )*/ 1 && ( pOffset < tran_buf_size) )
{//指针不为空,并且没有结束
trx_led = 0;
SBUF = *( pComData + pOffset );
pOffset++;
}//end of if( pComData != NULL && pOffset < tran_buf_size )
else
{//发送完成,恢复数据接收功能
trx_led = 1;
bSendingData = 0;//数据发送完成
///////////////////
rwdata.working.surge.data32 = 0;//浪涌值清零,重新开始计数
////////////////////
#ifdef MODE422
REN = 1;//Enable receiver
#endif
}//end of else
}//end of transmit(void)
/**************************************************************************************
数据接收子函数,在串口中断中调用
***************************************************************************************/
void receive(void) using 3 /* serial interrupt routine */
{
if( end_rec_buff + 1 == begin_rec_buff || ( end_rec_buff == RECEIVE_BUF_SIZE-1 &&
!begin_rec_buff ) )
{
; /* input overrun code */
}
else
{
/* The next statement makes the buffer circular by starting over when the
index reaches the end of the buffer. */
if( ++end_rec_buff > RECEIVE_BUF_SIZE - 1 )
end_rec_buff = 0;
receive_buff[end_rec_buff] = SBUF; /* place character in buffer */
}
}
void putchar(char c)
{
uchar i;
i = c;
}
unsigned char getchar()
{
unsigned char c_temp = 0;
while(begin_rec_buff==end_rec_buff); /* remain in loop01 while there is
not a character avaliable. */
if(++begin_rec_buff>RECEIVE_BUF_SIZE - 1) /* make buffer appear */
begin_rec_buff=0; /* circular. */
return(receive_buff[begin_rec_buff]); /* return the character in
buffer. */
}
//**************************
//接收缓冲区空返回1
//**************************
unsigned char rc_buf_empty()
{
if(begin_rec_buff==end_rec_buff)
return (1);
else
return (0);
}
/*********************************************************************
* 串行口初始化程序
*功能:设置波特率,将相关标志置位
*晶振:11.0592MHz
*波特率:9600
*波特率发生器:T2
**********************************************************************/
void init_UART()
{
ES = 0;
RI = 0;
TI = 0;
end_rec_buff = 0; /* initialize buffer pointers */
begin_rec_buff = 0;
end_trans_buff = 0;
begin_trans_buff = 0;
tr_begin_flag = 0;
T2CON = 0x30;
RCAP2H= 0xFF;
RCAP2L= 0xDC;
TH2 = 0xFF;
TL2 = 0xDC;
T2CON = 0x30;
TR2 = 1; //开时钟
SCON = 0x50; //SHIFT REGETER
PCON = 0x80;
ES = 1; //开中断
}//end of init_UART()
/***************************************************************************************
软件产生中断,启动数据发送功能
****************************************************************************************/
void send_data()
{
bSendingData = 1;//正在发送数据
TI = 1;
#ifdef MODE422
REN = 0;//Disable receiver
#endif
}//end of send_data()
//key value table
#define KeyUp 0xfd
#define KeyDown 0xfb
#define KeyEnter 0xf7
#define KeyCancel 0xef
/*******************************************************************
* 获取并返回本机地址
*地址存放在EEPROM中
********************************************************************/
uchar slave_address=8;
unsigned char address()
{
uchar temp;
P2 = 0xff;
temp = P2;
return (~temp);//本机地址由P2口的拨码开关状态确定
}//end of address()
//*********************************************************
//串行通讯数据定义
//*********************************************************
#define CORRECT_START_ADDRESS 200
unsigned char idata loop01 = 0;
unsigned char idata data_num1 = 0;
unsigned char idata function_code1 = 0;
bit data_ok1 = 0;
bit begin_flag1 = 0;
bit end_flag1 = 0;
//read register
#define READ_REGISTER 0X03 //order of read register
#define READ_DATA_START 0
#define READ_DATA_END 12
#define READ_DATA_LONG 13 //可以读操作的寄存器的最多个数
//write register
#define WRITE_REGISTER 0X10 //order of write register
#define WRITE_DATA_START 100 //写寄存器的开始地址
#define WRITE_DATA_END 113 //写寄存器的结束地址
#define WRITE_DATA_LONG 14 //可以连续写的数据长度
#define broadcast_addr 0x00
bit bit_read_order = 0;
bit bit_write_order = 0;
unsigned char xdata rc_buf[50];
/************************************************************************
* 串口通讯程序
*功能:将从下位机接收到的数据,按昭MODBUS协议的数据格式存放到RAM中
*
*************************************************************************/
void command_receive_explain()
{
union read_16add
{
unsigned int add16;
unsigned char add8[2];
};
union read_16add begin_address;
union read_16add register_num; //read or write register's start address and long
union read_16add crc_temp; //
unsigned char i;
if( !data_ok1 )
{//命令解释处理未完
while( ( loop01 < 50 ) && ( !rc_buf_empty() ) && ( !end_flag1 ) )
{
if(!rc_buf_empty())
{
if( begin_flag1 == 1 )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -