📄 gateway.c
字号:
/****************************************Copyright (c)**************************************************
** 广州周立功单片机发展有限公司
** 研 究 所
** 产品一部
**
** http://www.zlgmcu.com
**
**--------------文件信息--------------------------------------------------------------------------------
**文 件 名: GateWay.C
**创 建 人: 滕欣欣
**最后修改日期: 2004年2月26日
**描 述: 实现简单的RS232 TO CAN,CAN T0 RS232的数据转换。通过RS232将一帧固定格式固定长度的数据发给
** ARM,下位机将数据发往指定的CAN通道,CAN通过自接收将接收到的数据发往RS232.
** 该系统中下位机的UART0\CAN全部工作在查询模式下.
** RS232发送的数据格式必须为HEX格式,长度必须为17个字节
**RS232发送数据格式: 帧起始(SOF)+CAN帧信息(1byte)+CAN标识符(4byte)+ 数据(8 byte)=14byte
** CAN通道号 <4 : 0=CAN1; 1=CAN2; 2=CAN3;
** 3=CAN4;
** CAN帧信息格式 : 位偏移 7 6 5 4 3210
** 功能 FF RTR x x DLC
** FF =0标准帧; =1扩展帧;
** RTR=0数据帧; =1远程帧;
** DLC <=8 表示要发送的字节数
**
**--------------当前版本修订------------------------------------------------------------------------------
** 修改人: 滕欣欣
** 日 期: 2004年8月17日
** 描 述: 修正了
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#define _GATEWAY_GLOBAL_
#include "..\..\src\config.h"
//测试代码
//12 00 88 12 34 56 78 00 11 22 33 44 55 66 77 02 00
INT32U RcvCounter=0;
const char strHelloArmCan [ ] = "Wellcome to ZLG ARMLPC2119 CAN Demo Program!\n";
const char strCanErr [ ] = "Err CAN Chunnel!! \n";
const char strCheckSunErr[] = "CheckSunErr !! \n";
const char strCANChunl[ ] = "CAN:";
const char strCANFif[ ] = "FIF:";
const char strCANFid[ ] = "FID:";
const char strCANData[ ] = "Dat:";
/*
************************************************************************************************************************
**函数原型 : void UartComPol(void)
**参数说明 :
**返回 值 :
**说 明 : 该函数用于解析RS232数据到CAN数据的协议
************************************************************************************************************************
*/
INT32U UartComPol (INT8U *UARTBuf)
{
INT32U i = 0;
INT32U status = 0;
INT8U CheckSum = 0;
INT8U *Point ;
Point = UARTBuf;
if (*(Point + 1) < CAN_MAX_NUM)
{
//简单的校验,采用累加和方式
for (i = 0; i<16; i++)
{
CheckSum = *(Point + i) + CheckSum;
}
if (CheckSum == *(Point + 16))
{
CANChunel = *(Point + 1);
CanSendFlag = 1;
}
else
{
//校验错误处理
memcpy(UARTSendBuf, strCheckSunErr, strlen (strCheckSunErr));
UARTSend (UART0,strlen (strCheckSunErr),UARTSendBuf);
CanSendFlag = 0;
status = 1;
goto exit;
}
}
else //CAN通道号错误处理
{
memcpy(UARTSendBuf, strCanErr, strlen (strCanErr));
UARTSend (UART0,strlen (strCanErr),UARTSendBuf);
status = 1;
CanSendFlag = 0;
}
exit:
return status;
}
/*
************************************************************************************************************************
**函数原型 : void CanHexToRs232ASCII(UINT8 *Buf,UINT8 iBYTE)
**参数说明 :
**返回 值 :
**说 明 : 将HEX格式的CAN数据转换为RS232ASCII码格式
************************************************************************************************************************
*/
void CanHexToRs232ASCII(INT8U *Buf,INT8U iBYTE)
{
INT8U i= iBYTE >> 4;
if(i<0x0A)
{
*Buf = 0x30 +i; //数字0--9
}
else
{
*Buf = 0x37 +i; //字母A--Z(大写)
}
i = iBYTE &0x0F;
if(i<0x0A)
{
*(Buf+1) = 0x30 +i;
}
else
{
*(Buf+1) = 0x37 +i;
}
}
/*
************************************************************************************************************************
**函数原型 : UINT32 Rs232toCANDataConver (void)
**参数说明 :
**返回 值 : 0;成功发送;1;发送失败
**说 明 : 将接收到的232数据发送到CAN
************************************************************************************************************************
*/
INT32U Rs232toCANDataConver (stcRxBUF *CANBuf, INT8U *UARTBuf)
{
INT32U statue,i;
statue = 0;
statue = UartComPol( UARTBuf);
if (statue == 0)
{
CANBuf->CANRcvFS.Bits.FF= ((*(UARTBuf + 2)&0x80)>>7);
CANBuf->CANRcvFS.Bits.RTR=((*(UARTBuf + 2)&0x40)>>6);
CANBuf->CANRcvFS.Bits.DLC=(*(UARTBuf + 2)&0x0f);
for(i=0;i<4;i++)
{
*((INT8U *)(&CANBuf->RxCANID)+ 3- i) = *(UARTBuf + 3 + i);
*((INT8U *)(&CANBuf->RDA) + i ) = *(UARTBuf + 7 + i);
*((INT8U *)(&CANBuf->RDB) + i ) = *(UARTBuf + 11 + i);
}
}
return statue;
}
/*
************************************************************************************************************************
**函数原型 : void CanDataToRs232(void)
**参数说明 :
**返回 值 :
**说 明 : 将接收收到的CAN数据发送到RS232
************************************************************************************************************************
*/
INT32U CANtoRs232DataConver(eCANNUM CanNum, stcRcvCANCyBuf *RcvCyBuf )
{
INT8U i,len,point;
INT8U TempBuf[15];
INT8U TransCounter = 0;
len = strlen(strCANChunl);
point = RcvCyBuf->ReadPoint;
/****************************************
** 显示CAN通道号
****************************************/
memcpy(UARTSendBuf, strCANChunl, len); //显示CAN通道标题“CAN:”
TransCounter += len;
CanHexToRs232ASCII(&UARTSendBuf[TransCounter], CanNum); //实际CAN通道号转换为ASII码
TransCounter += 2;
UARTSendBuf[TransCounter++]=0x0D; //回车
UARTSendBuf[TransCounter++]=0x0A; //换行
/******************************************
** 从CAN的环形缓冲区读取信息
*******************************************/
//读取帧信息FIF
TempBuf[0] = (INT8U)RcvCyBuf->RcvBuf[point].CANRcvFS.Bits.DLC|
((INT8U)RcvCyBuf->RcvBuf[point].CANRcvFS.Bits.FF<< 7)|
((INT8U)RcvCyBuf->RcvBuf[point].CANRcvFS.Bits.RTR<< 6);
for(i=0;i<4;i++)
{ //读取帧标识符FID
TempBuf[1+i]=*((INT8U *)(&RcvCyBuf->RcvBuf [point].RxCANID) + 3 - i);
//读取帧数据Dat
TempBuf[5+i]=*((INT8U *)(&RcvCyBuf->RcvBuf [point].RDA) + i );
TempBuf[9+i]=*((INT8U *)(&RcvCyBuf->RcvBuf [point].RDB) + i );
}
/******************************************
*** 显示帧信息
*******************************************/
memcpy(&UARTSendBuf[TransCounter],strCANFif,len); //帧信息标题“FID:”
TransCounter += len;
if((TempBuf[0]&0x0f)>8)
{
TempBuf[0] = (TempBuf[0]&0xf0) + 8;
}
CanHexToRs232ASCII(&UARTSendBuf[TransCounter],TempBuf[0]);//帧信息转换为ASCII码
TransCounter += 2;
UARTSendBuf[TransCounter++]=0x0D; //回车
UARTSendBuf[TransCounter++]=0x0A; //换行
/****************************************
** 显示帧标识符
*****************************************/
memcpy(&UARTSendBuf[TransCounter],strCANFid, len); //帧标识符标题“FID:”
TransCounter+= len;
for(i=1;i<5;i++)
{ //帧标识符转化为ASCII码
CanHexToRs232ASCII(&UARTSendBuf[TransCounter],TempBuf[i]);
TransCounter += 2;
}
UARTSendBuf[TransCounter++]=0x0D; //回车
UARTSendBuf[TransCounter++]=0x0A; //换行
/****************************************
** 显示帧数据
*****************************************/
memcpy(&UARTSendBuf[TransCounter],strCANData,len);//帧数据标题“Dat:”
TransCounter += len;
for(i=5; i<(TempBuf[0]&0x0f)+5; i++) //数据转换成ASCII码
{
CanHexToRs232ASCII(&UARTSendBuf[TransCounter],TempBuf [i]);
TransCounter += 2;
}
UARTSendBuf[TransCounter++]=0x0D;
UARTSendBuf[TransCounter++]=0x0A;
UARTSendBuf[TransCounter++]=0x0D;
UARTSendBuf[TransCounter++]=0x0A; //发送完一帧相隔一行
return TransCounter;
}
/*
************************************************************************************************************************
**函数原型 : CANSendToRS232
**参数说明 :
**返回 值 :
**说 明 : 将接收收到的CAN数据发送到RS232
************************************************************************************************************************
*/
void CANSendToRS232 (eCANNUM CanNum, eUARTNUM UARTNum, stcRcvCANCyBuf *RcvCyBuf )
{
INT32U Len;
Len = CANtoRs232DataConver(CanNum, RcvCyBuf );
if(++RcvCyBuf->ReadPoint >= USE_CAN_cycRCV_BUF_SIZE)
{
RcvCyBuf->ReadPoint =0;
}
RcvCyBuf->FullFlag=0;
//调用串口发送函数
UARTSend(UARTNum,Len, UARTSendBuf); //调用UART发送程序
}
/*
************************************************************************************************************************
**函数原型 : CANSendToRS232
**参数说明 :
**返回 值 :
**说 明 : 将接收收到的CAN数据发送到RS232
************************************************************************************************************************
*/
void RS232SendToCAN (eCANNUM CanNum, INT32U Cmd,stcRxBUF *CANBuf, INT8U *UARTBuf )
{
if (!Rs232toCANDataConver (CANBuf, UARTBuf))
{
CANSendData(CanNum,Cmd,CANBuf);
}
}
/*********************************************************************************************************
** End Of File
********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -