📄 discom.c
字号:
T4CON = 0x30; // Stop Timer; clear int flags; enable
// UART baudrate mode; enable 16-bit
// auto-reload timer function; disable
// external count and capture modes
RCAP4 = -(SYSCLK/19200/32); // set Timer reload value for baudrate
T4 = RCAP4; // initialize Timer value
CKCON |= 0x40; // Timer4 uses SYSCLK as time base
T4CON |= 0x04; // TR4 = 1; start Timer4
PCON |= 0x10; // SMOD1 = 1
EIE2 |= 0x40; // enable UART1 interrupts
TX1_Ready = 1; // indicate TX ready for transmit
RX1_Ready = 0; // indicate RX string not ready
// SCON1 &= 0xef; // Serial Port 1 Control Register
}
//-----------------------------------------------------------------------------
// Interrupt Handlers
//-----------------------------------------------------------------------------
//------------------------------------------------------------------------------------
//Timer0中断服务程序
//1ms计数
//------------------------------------------------------------------------------------
void Timer0_ISR (void) interrupt 1 //1ms
{
TH0 = (-SYSCLK/1000) >> 8;
TL0 = -SYSCLK/1000;
/*
Count1ms_Profi++;
if(Count1ms_Profi>=30)
{
Count1ms_Profi=0;
PLC_Timer_OK=1;
}
*/
}
//------------------------------------------------------------------------------------
// Timer1中断服务程序
// 1ms计数
// 串口1从无线模块中接收数据的帧头检测
//------------------------------------------------------------------------------------
void Timer1_ISR (void) interrupt 3 //1ms
{
TH1 = (-SYSCLK/1000) >> 8;
TL1 = -SYSCLK/1000;
if (IsPlay)
{
if ( (PlayTime++) > 4000 )
{
IsPlay=0 ;
PlayStart=0;
}
}
else
{
PlayTime=0;
//PlayStart=0;
}
if (PLC_COM_START)
{
Count1ms_PLC++;
}
if (Count1ms_PLC>=500)
{
Count1ms_PLC = 0;
PLC_COM_OVER = 1;
}
Count1ms_Modem++;
if (wire==1)
{
Count1ms_Modem=0;
wire=0;
}
if (RX1_index !=0)
{
if(Count1ms_Modem>=5)
{
Count1ms_Modem=0;
RX1_index=0;
RX1_CHK_ADD=0; // 从无线模块收到的数据和校
RX1_CHK_XOR=0; // 从无线模块收到的数据异或校
}
}
}
//-----------------------------------------------------------------------------
// UART0_ISR
//-----------------------------------------------------------------------------
//
// Interrupt Service Routine for UART0:
// Transmit function is implemented as a NULL-terminated string transmitter
// that uses the global variable <TX_ptr> and the global semaphore <TX_Ready>.
// Example usage:
// while (TX_Ready == 0); // wait for transmitter to be available
// TX_Ready = 0; // claim transmitter
// TX_ptr = <pointer to string to transmit>;
// TI0 = 1; // initiate transmit
//
// Receive function is implemented as a CR-terminated string receiver
// that uses the global buffer <RX_Buf> and global indicator <RX_Ready>.
// Once the message is received, <RX_Ready> is set to '1'. Characters
// received while <RX_Ready> is '1' are ignored.
//
void UART0_ISR (void) interrupt 4 using 3
{
if (RI0 == 1)
{ // handle receive function
RI0 = 0; // clear RX complete indicator
rebox[RX0_index] =SBUF0; // store the character
//------------------------------------------------------------------------------
//读PLC数据:
//40101----工作车号(0x0101)
//40102----状态(0x1234)
//40103----推焦电流/焦杆长度(0x5678)
//40104----平煤电流/平杆长度(0x9ABC)
//发送命令(08字节):01 03 00 64 00 04 (CRC)
//回送数据(13字节):01 03 08 01 01 12 34 56 78 9A BC (CRC)
// 01 03 08 00 00 00 00 00 00 00 00 95 D7
//------------------------------------------------------------------------------
if (READ && (RX0_index==12) && rebox[2]==8 ) // 收到读取的数据
{
Address = rebox[4] & 0x0f; // 本车地址
Car = rebox[4] >> 4; // 本车种类
//data_in[0] = rebox[4]; // 本车地址
data_in[1] = rebox[5]; // 状态高字节
data_in[2] = rebox[6]; // 状态低字节
data_in[3] = rebox[7]; // 推焦电流
data_in[4] = rebox[8]; // 焦杆长度 语//
data_in[5] = rebox[9]; // 平煤电流
data_in[6] = rebox[10]; // 平杆长度
if (rebox[8]== 0)
{
Voice = 0;
P5 = 0x0FF;
}
else
{
if (!IsPlay)
{
if (Voice != rebox[8])
{
Voice = rebox[8];
PlayStart = 1;
P5 = 0x0FF;
}
}
}
RX0_index = 0;
PLC_COM_OK = 1;
}
//------------------------------------------------------------------------------
//写PLC数据:
//40200----推焦车炉号(0x1234)
//40201----拦焦车炉号(0x5678)
//40202----熄焦车炉号(0x9ABC)
//40203----状态(0xDEF0)
//40204----系统时间(0x1234)
//40205----计划时间(0x0123)
//40206----计划炉号/平杆长度(0x4567)
//40207----(0x89AB)
//发送命令(25字节):01 10 00 C8 00 08 0F 12 34 56 78 9A BC DE F0 12 34 01 23 45 67 89 AB (CRC)
//回送数据(08字节):01 10 00 C8 00 08 (CRC)
// 01 90 03 0C 01
//------------------------------------------------------------------------------
else if ( !READ && (RX0_index==7) && rebox[5]==8 ) // 收到写PLC的应答数据
{
RX0_index = 0;
PLC_COM_OK = 1;
RX0_index=0;
}
else
{ // increment buffer pointer and wrap if necessary
RX0_index++;
if (RX0_index>40)
{
RX0_index=40;
}
}
}
else if (TI0 == 1) //发送数据
{ // handle transmit function
TI0 = 0; // clear TX complete indicator
if (TX0_index < TX0_NUMBER )
{
SBUF0 = trbox[TX0_index]; // transmit it
TX0_index++; // get ready for next character
}
else
{ // character is NULL
}
}
}
//-----------------------------------------------------------------------------
// UART1_ISR
//-----------------------------------------------------------------------------
//
// Interrupt Service Routine for UART1:
// Transmit function is implemented as a NULL-terminated string transmitter
// that uses the global variable <TX_ptr> and the global semaphore <TX_Ready>.
// Example usage:
// while (TX_Ready == 0); // wait for transmitter to be available
// TX_Ready = 0; // claim transmitter
// TX_ptr = <pointer to string to transmit>;
// SCON1 |= 0x02; // TI1 = 1; initiate transmit
//
// Receive function is implemented as a CR-terminated string receiver
// that uses the global buffer <RX_Buf> and global indicator <RX_Ready>.
// Once the message is received, <RX_Ready> is set to '1'. Characters
// received while <RX_Ready> is '1' are ignored.
//
void UART1_ISR (void) interrupt 20 using 3
{
UBYTE data jjj;
if ((SCON1 & 0x01) == 0x01) // handle receive function
{
SCON1 &= ~0x01; // RI1 = 0; clear RX complete
// indicator
wire=1;
if (RX1_Ready != 1)
{ // check to see if message pending
rebuf[RX1_index] =SBUF1; // store the character
if ( RX1_index <=RX1_NUMBER-3)
{
RX1_CHK_ADD +=rebuf[RX1_index]; // 从无线模块收到的数据和校
RX1_CHK_XOR ^=rebuf[RX1_index]; // 从无线模块收到的数据异或校
}
if (RX1_index==RX1_NUMBER-1) // 无线模块收到RX1_NUMBER个字节
{
if ( ( (rebuf[0] & 0xf0) == 0x00) )
//&& (RX1_CHK_XOR == rebuf[RX1_NUMBER-2])
//&& (RX1_CHK_ADD == rebuf[RX1_NUMBER-1]) )
{
if (rebuf[0]==Address) //是本车数据
{
data_out[0]= rebuf[1]; // 读取有效数据,推焦车炉号
data_out[1]= rebuf[2]; // 读取有效数据
data_out[2]= rebuf[3]; // 读取有效数据,拦焦车炉号
data_out[3]= rebuf[4]; // 读取有效数据
data_out[4]= rebuf[5]; // 读取有效数据,熄焦车炉号
data_out[5]= rebuf[6]; // 读取有效数据
data_out[6]= rebuf[7]; // 读取有效数据,状态
data_out[7]= rebuf[8]; // 读取有效数据
data_out[8]= rebuf[9]; // 读取有效数据,系统时间
data_out[9]= rebuf[10]; // 读取有效数据
data_out[10]= rebuf[11]; // 读取有效数据,计划时间
data_out[11]= rebuf[12]; // 读取有效数据
data_out[12]= rebuf[13]; // 读取有效数据,计划炉号
data_out[13]= rebuf[14]; // 读取有效数据,焦杆长度
data_out[14]= rebuf[15]; // 读取有效数据
data_out[15]= rebuf[16]; // 读取有效数据
data_out[16]= rebuf[17]; // 读取有效数据,
data_out[17]= rebuf[18]; // 读取有效数据,
Position_XJC = (UWORD)data_out[16]* 256 +data_out[17];
/*
for (jjj=0; jjj<14; jjj++ )
{
data_out[jjj]= rebuf[jjj+1]; // 读取有效数据,推焦车炉号
}*/
//TX1_CHK_ADD=0; // 发送到无线模块的数据和校
//TX1_CHK_XOR=0; // 发送到无线模块的数据异或校
trbuf[0]=Address; //加上站号
TX1_CHK_ADD = trbuf[0];
TX1_CHK_XOR = 0 ^ trbuf[0];
for (jjj=1; jjj<(TX1_NUMBER-2); jjj++)
{
trbuf[jjj] = data_in[jjj]; //从data_in[]中取数据
TX1_CHK_ADD += trbuf[jjj];
TX1_CHK_XOR ^= trbuf[jjj];
}
trbuf[TX1_NUMBER-2]=TX1_CHK_XOR;
trbuf[TX1_NUMBER-1]=TX1_CHK_ADD;
if ( ++Run >= 200)
{
TX1_index = 0;
SCON1 |= 0x02; // TI1 = 1; initiate transmit
}
}
/*
else // 不是本车信息,只取本车地址
{
if (Address == 0) // 是1号车
{
if (Car == 2) // 是拦焦车
{
data_out[2]= rebuf[15]; // 读取有效数据,炉号
data_out[3]= rebuf[16]; // 读取有效数据
}
else if (Car == 4 ) // 是煤车 熄焦车不处理
{
data_out[4]= rebuf[15]; // 读取有效数据,炉号
data_out[5]= rebuf[16]; // 读取有效数据
}
}
else // 是2号车或3号车
{
if (Car == 2) // 是拦焦车
{
data_out[2]= rebuf[17]; // 读取有效数据,炉号
data_out[3]= rebuf[18]; // 读取有效数据
}
else if (Car == 4 ) //是煤车 熄焦车不处理
{
data_out[4]= rebuf[18]; // 读取有效数据,炉号
data_out[5]= rebuf[17]; // 读取有效数据
}
}
}
*/
RX1_index=0;
}
}
else
{ // increment buffer pointer and wrap if necessary
RX1_index++;
if (RX1_index>=25)
{
RX1_index=25;
}
}
}
}
else if ((SCON1 & 0x02) == 0x02) // handle transmit function
{
SCON1 &= ~0x02; // TI1 = 0; clear TX complete
if (TX1_index<TX1_NUMBER) // 回送TX1_NUMBER个数据
{
SBUF1 =trbuf[TX1_index]; // transmit it
TX1_index++; // get ready for next character
}
else
{ // character is NULL
//TX1_Ready = 1; // indicate ready for next TX
TX1_index=0;
RX1_Ready = 0; // post message ready
RX1_index = 0; // reset RX message index
RX1_CHK_ADD = 0; // 从无线模块收到的数据和校
RX1_CHK_XOR = 0; // 从无线模块收到的数据异或校
}
}
}
/************************************************************************/
void GetCRC16(unsigned char *puchMsg, int DataLen)
{
unsigned int IndexCRC ; /* will index into CRC16 lookup table */
CRCHi = 0xFF ; /* high byte of CRC16 initialized */
CRCLo = 0xFF ; /* low byte of CRC16 initialized */
while (DataLen--)
{
IndexCRC = CRCHi ^ *puchMsg++ ; /* calculate the CRC16 */
CRCHi = CRCLo ^ CRC16Hi[IndexCRC] ;
CRCLo = CRC16Lo[IndexCRC] ;
}
}
/************************************************************************/
void SPI_WRITE(char Val)
{
SPIF =0;
SPI0DAT = Val;
while (SPIF == 0);
for (nw=0;nw<5;nw++) // 延时1uS
{
}
}
//---------------------------------------------------------------------------------------
void SendT( )
{
// 推焦车 HHMM 123 XXXX(状态)
/************************************************************************/
// 推焦车状态 //
// 3位 右二 2位 右一 1位 左一 0位 左1 //
// 3位 对准 2位 推焦请求8-0 1位 摘门7-5 0位 推焦连锁7-3 //
/************************************************************************/
union
{
UWORD SPI_WORD;
UBYTE SPI_BYTE[2];
}SPI_DATA;
int MMM;
bit IsDot;
Tcar[0]= data_out[8]>>4; //系统时间
Tcar[1]= data_out[8] & 0x0f;
Tcar[2]= data_out[9]>>4;
Tcar[3]= data_out[9] & 0x0f;
SPI_DATA.SPI_BYTE[0]=data_out[0]; //推焦车位置
SPI_DATA.SPI_BYTE[1]=data_out[1];
KKK=SPI_DATA.SPI_WORD/100;
if ( ( (KKK > 155) && (KKK<201) ) // 在虚拟炉号
|| ((KKK >255) && (KKK <301) )
|| (KKK < 101) || (KKK>355) )
{
IsDot = 1;
}
else
{
IsDot = 0;
}
if (KKK<100)
{
KKK += 900;
}
else if (KKK < 178 )
{
KKK -= 100;
}
else if (KKK < 278 )
{
KKK -= 145;
}
else
{
KKK -= 190;
}
if ( KKK >= 999)
{
KKK = 999;
}
Tcar[4] = KKK / 100;
Tcar[5] = (KKK % 100) / 10;
Tcar[6] = KKK % 10;
KKK = SPI_DATA.SPI_WORD; // 推焦车炉号
MMM = (UWORD)data_out[12] * 100 + 50; // 计划炉号
if (MMM <= 5550)
{
MMM += 10000;
}
else if (MMM <= 11050)
{
MMM += 14500;
}
else
{
MMM += 19000;
}
KKK -= MMM;
if ( (DIS_DOT & 5) == 5 )
{
if (KKK >= 50) // 左二、左一 00
{
Tcar[7] = 0x03;
Tcar[8] &= 0x07;
}
else if (KKK <= -50) // 右二、右一
{
Tcar[7] = 0x0c;
Tcar[8] &= 0x07;
}
else if ( (KKK < 50) && (KKK >12) ) // 左一
{
Tcar[7] = 0x02;
Tcar[8] &= 0x07;
}
else if ( (KKK > -50) && (KKK < -12) ) // 右一
{
Tcar[7] = 0x04;
Tcar[8] &= 0x07;
}
else // 对中
{
Tcar[7] = 0x00;
Tcar[8] |= 0x08;
}
if ( (data_out[7] & 0x02) == 0x02 ) // 对中
{
Lcar[7] = 0x00;
Lcar[8] |= 0x08;
}
}
else
{
Tcar[7] = 0x00;
Tcar[8] &= ~0x08;
}
if ( (data_out[7] & 0x01) == 0)
{
Tcar[8] &= ~0x04; // 2位 推焦请求8-0
}
else
{
Tcar[8] |= 0x04; // 2位 推焦请求8-0
}
if ( (data_out[6] & 0x10) == 0)
{
Tcar[8] &= ~0x02; // 1位 摘门7-4
}
else
{
Tcar[8] |= 0x02; // 1位 摘门7-4
}
if ( (data_out[6] & 0x08) == 0)
{
Tcar[8] &= ~0x01; // 0位 推焦连锁7-3
}
else
{
Tcar[8] |= 0x01; // 0位 推焦连锁7-3
}
DIS_DOT++;
if ( (DIS_DOT & 10) == 10 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -