CAN转COM或CAN-1
来源:互联网 发布:天池大数据竞赛2017 编辑:程序博客网 时间:2024/06/07 18:14
前段时间在做了一个使用CAN接收数据,然后通过KEY选择是另一个CAN或者COM发送处理的数据。
我会通过连载的方式发布整个过程。
部分文件著作权归所属个人!(在注释中有)
首先,我们准备环境:
MDK3.5 + AK100(ZLG的ARM牛X仿真器)
其次,我整理思绪... ...
最基本,需要三个主要模块:CAN、UART、KEY。
CAN code:
/****************************************Copyright (c)**************************************************** 广州致远电子有限公司** 工业通信网络事业部** http://www.embedcontrol.com**-------------------------------------文件信息--------------------------------------------------------**文 件 名:LPC2300CAN.c** 当 前 版 本:v1.0** 日 期:2007年5月06日**描 述:**-------------------------------------历史创建--------------------------------------------------------**文 件 名:LPC2300CAN.c** 版 本:v1.0** 日 期:2007年4月27日**创 建 人:滕欣欣**描 述:LPC2300开发板实验教程实例代码**-------------------------------------历史修改--------------------------------------------------------**文 件 名:** 版 本:** 日 期:**修 改 人:**描 述:********************************************************************************************************/#include "../can/LPC2300CAN.h"#include "LPC2300CANReg.h"#include "lpc23xx.h"#include "../common/type.h"static struct _MessageDetail MessageDetailT,MessageDetailR;unsigned char dataAB[8];unsigned long dataRID;extern CAN_FIFOMailBox_TypeDef sFIFOMailBox;/************************************************************************************************************函数原型: unsigned char Enter_SWRst(unsigned char Ch);**参数说明: Ch:CAN控制器号,0表示第一路CAN**返回值:0:失败**:1: 成功**说明:CAN控制器进入软件复位模式*********************************************************************************************************/unsigned char Enter_SWRst(unsigned char Ch){unsigned long regaddr;REG_CANMOD regmod;regaddr = (unsigned long)(&CAN1MOD)+Ch*CANOFFSET;regmod.DWord = RGE(regaddr);//读取CAN1MOD寄存器regmod.Bits.RM = 1;//RM位置“1”RGE(regaddr) = regmod.DWord;//回写CAN1MOD寄存器regmod.DWord = RGE(regaddr);//验证写入值return (0 != regmod.Bits.RM)? 1:0; }/************************************************************************************************************函数原型: unsigned char Quit_SWRst(unsigned char Ch);**参数说明: Ch:CAN控制器号,0表示第一路CAN**返回值:0:失败**:1: 成功**说明:CAN控制器退出软件复位模式*********************************************************************************************************/unsigned char Quit_SWRst(unsigned char Ch){unsigned long regaddr;REG_CANMOD regmod;regaddr = (unsigned long)(&CAN1MOD)+Ch*CANOFFSET;regmod.DWord = RGE(regaddr);//读取CAN1MOD寄存器regmod.Bits.RM = 0;//RM位置“0”RGE(regaddr) = regmod.DWord;//回写CAN1MOD寄存器regmod.DWord = RGE(regaddr);//验证写入值return (0 != regmod.Bits.RM)? 0:1; }/************************************************************************************************************函数原型: unsigned char CAN_Init(unsigned char Ch, unsigned long Baud);**参数说明: Ch:CAN控制器号,0表示第一路CAN**:Baud:CAN波特率值**返回值:无**说明:CAN控制器退出软件复位模式*********************************************************************************************************/void CAN_Init(unsigned char Ch, unsigned long Baud){unsigned long regaddr;PCONP |= 0x01L<<13;//打开CAN控制器电源switch(Ch)//配置CAN控制器引脚{case 0:PINSEL0 &= ~(0x03L<<0);/*RD1*/PINSEL0 |= (0x01L<<0);PINSEL0 &= ~(0x03L<<2);/*TD1*/PINSEL0 |= (0x01L<<2);break;case 1:PINSEL1 &= ~(0x03L<<10);/*RD1*/PINSEL1 |= (0x03L<<10);PINSEL1 &= ~(0x03L<<12);/*TD1*/PINSEL1 |= (0x03L<<12);break;default:break;}Enter_SWRst(Ch);regaddr = (unsigned long)(&CAN1BTR)+Ch*CANOFFSET;RGE(regaddr) = Baud;CAN_AFMR &= ~0x07;//设置为旁路模式CAN_AFMR|=(1<<1);Quit_SWRst(Ch);}/************************************************************************************************************函数原型: unsigned char CANRCVANDSEND(unsigned char Ch, unsigned char BUFNum);**参数说明: Ch:CAN控制器号,0表示第一路CAN**:BUFNum 选择缓冲区**返回值:无**说明:CAN将收到的信息再发送出去 *********************************************************************************************************/unsigned char CANRCVANDSEND(unsigned char Ch, unsigned char BUFNum){unsigned long mes, CAN32reg;unsigned long regaddr;unsigned char i=5;unsigned char i2 = 0;BUFNum-=1;// 计算地址方便。regaddr = (unsigned long)(&CAN1RFS)+Ch*CANOFFSET;//处理DLC、RTR、FFmes = RGE(regaddr);mes &= 0Xffff0000;regaddr = (unsigned long)(&CAN1TFI1)+Ch*CANOFFSET+0X10*BUFNum;RGE(regaddr)=mes;regaddr = (unsigned long)(&CAN1RID)+Ch*CANOFFSET;//处理IDmes = RGE(regaddr);regaddr = (unsigned long)(&CAN1TID1)+Ch*CANOFFSET+0X10*BUFNum;RGE(regaddr)=mes;dataRID = mes;regaddr = (unsigned long)(&CAN1RDA)+Ch*CANOFFSET;//处理 数据Ames = RGE(regaddr);regaddr = (unsigned long)(&CAN1TDA1)+Ch*CANOFFSET+0X10*BUFNum;RGE(regaddr)=mes;// MessageDetailR.DATAA = mes;for (i2 = 0; i2 < 4; i2++) {dataAB[i2] = mes >> 8 * i2;} regaddr = (unsigned long)(&CAN1RDB)+Ch*CANOFFSET;//处理 数据Bmes = RGE(regaddr);regaddr = (unsigned long)(&CAN1TDB1)+Ch*CANOFFSET+0X10*BUFNum;RGE(regaddr)=mes;// MessageDetailR.DATAB = mes;for (i2 = 0; i2 < 4; i2++) {dataAB[4 + i2] = mes >> 8 * i2;} regaddr = (unsigned long)(&CAN1GSR)+Ch*CANOFFSET;//查 接收缓冲区状态mes = RGE(regaddr);while(mes&(1<<0))// RBS为1 接收缓冲区满{regaddr = (unsigned long)(&CAN1CMR)+Ch*CANOFFSET;mes=RGE(regaddr);mes |= (1<<2);//释放接收缓冲区RGE(regaddr)=mes;if(!(i--)){return(0);}}// regaddr = (unsigned long)(&CAN1CMR)+Ch*CANOFFSET;// mes=RGE(regaddr);// mes &= (~(1<<2));// RGE(regaddr)=mes;return(1);}/************************************************************************************************************函数原型: unsigned char writedetail(unsigned char LEN,unsigned char FF, unsigned int ID,unsigned char *data);**参数说明: LEN:数据长度**:*data 发送数据所在的数组 : **返回值:操作成功返回 1 失败返回 0**说明: 用户填写发送 帧信息*********************************************************************************************************/ unsigned char writedetail(unsigned char LEN,unsigned char FF, unsigned int ID,unsigned char *data){unsigned char i;if(LEN>8){return(0);}else{MessageDetailT.LEN=LEN;MessageDetailT.FF=FF;MessageDetailT.CANID=ID;MessageDetailT.DATAA=0;//先清零MessageDetailT.DATAB=0;for(i=0;i<LEN;i++){if(i<4){MessageDetailT.DATAA |= (*(data+i)<<(i*8)); }else{MessageDetailT.DATAB |= (*(data+i)<<((i-4)*8));}}//MessageDetailT.DATAB = ID;return(1);}}/************************************************************************************************************函数原型: unsigned char CANSend(unsigned char Ch, unsigned char BUFNum);**参数说明: Ch:CAN控制器号,0表示第一路CAN**:BUFNum 选择缓冲区: MessageDetailT 报文的特征信息及数据**返回值:无**说明:CAN控制器退出软件复位模式*********************************************************************************************************/unsigned char CANSend(unsigned char Ch, unsigned char BUFNum){unsigned long CAN32reg;unsigned long regaddr;unsigned char FFflag;BUFNum-=1;// 计算地址方便。regaddr = (unsigned long)(&CAN1TFI1)+Ch*CANOFFSET+0X10*BUFNum;// 3缓冲区间地址差 0x10CAN32reg = RGE(regaddr);CAN32reg &= ~((0x0fL<<16) | (0x01L<<30) | (0x80000000)); //清 DLC,RTR.FF位?CAN32reg |= ((unsigned long)MessageDetailT.LEN<<16) | ((unsigned long)MessageDetailT.FF<<31);RGE(regaddr)=CAN32reg;FFflag = MessageDetailT.FF;regaddr = (unsigned long)(&CAN1TID1)+Ch*CANOFFSET+0X10*BUFNum;//写帧IDCAN32reg = RGE(regaddr);if(FFflag)//FF为1,ID为29位{CAN32reg &=0x70000000;CAN32reg |= (MessageDetailT.CANID & 0x1fffffff);}else{CAN32reg &= 0xfffff800;//FF为0 ,ID为11位CAN32reg |= (MessageDetailT.CANID & 0x000007ff);}RGE(regaddr)=CAN32reg;regaddr = (unsigned long)(&CAN1TDA1)+Ch*CANOFFSET+0X10*BUFNum;// 写帧数据ARGE(regaddr) = MessageDetailT.DATAA;regaddr = (unsigned long)(&CAN1TDB1)+Ch*CANOFFSET+0X10*BUFNum;// 写帧数据BRGE(regaddr) = MessageDetailT.DATAB;regaddr = (unsigned long)(&CAN1CMR)+Ch*CANOFFSET;//写控制寄存器,发送CAN32reg = RGE(regaddr);CAN32reg &= ~0x03;CAN32reg |= 0x03;CAN32reg &= ~((1<<5)|(1<<6)|(1<<7));switch(BUFNum){case 0: CAN32reg |= 01<<5;break;case 1: CAN32reg |= 01<<6;break;case 2: CAN32reg |= 01<<7;break;default: break;}RGE(regaddr)=CAN32reg;regaddr = (unsigned long)(&CAN1GSR)+Ch*CANOFFSET;//查询发送状态CAN32reg = RGE(regaddr);/*/if(CAN32reg&(1<<5))//等待所有请求的发送已经完成{;}*/if(CAN32reg&(1<<3))//所有的请求已成功完成{return(1);//发送成功返回 1}else { return (0);}//发送失败返回 0 }/*---------------------------------------------------------------------------- read a message from CAN peripheral and release it *----------------------------------------------------------------------------*/void CAN_rdMsg (CAN_msg *msg) { // Read identifier information if ((CAN1->sFIFOMailBox[0].RIR & CAN_ID_EXT) == 0) { // Standard ID msg->format = STANDARD_FORMAT; msg->id = (DWORD)0x000007FF & (CAN1->sFIFOMailBox[0].RIR >> 21); } else { // Extended ID msg->format = EXTENDED_FORMAT; msg->id = (DWORD)0x0003FFFF & (CAN1->sFIFOMailBox[0].RIR >> 3); } // Read type information if ((CAN1->sFIFOMailBox[0].RIR & CAN_RTR_REMOTE) == 0) { msg->type = DATA_FRAME; // DATA FRAME } else { msg->type = REMOTE_FRAME; // REMOTE FRAME } // Read length (number of received bytes) msg->len = (unsigned char)0x0000000F & CAN1->sFIFOMailBox[0].RDTR; // Read data bytes msg->data[0] = (unsigned int)0x000000FF & (CAN1->sFIFOMailBox[0].RDLR); msg->data[1] = (unsigned int)0x000000FF & (CAN1->sFIFOMailBox[0].RDLR >> 8); msg->data[2] = (unsigned int)0x000000FF & (CAN1->sFIFOMailBox[0].RDLR >> 16); msg->data[3] = (unsigned int)0x000000FF & (CAN1->sFIFOMailBox[0].RDLR >> 24); msg->data[4] = (unsigned int)0x000000FF & (CAN1->sFIFOMailBox[0].RDHR); msg->data[5] = (unsigned int)0x000000FF & (CAN1->sFIFOMailBox[0].RDHR >> 8); msg->data[6] = (unsigned int)0x000000FF & (CAN1->sFIFOMailBox[0].RDHR >> 16); msg->data[7] = (unsigned int)0x000000FF & (CAN1->sFIFOMailBox[0].RDHR >> 24); CAN1->RF0R |= CAN_RF0R_RFOM0; // Release FIFO 0 output mailbox}
此模块主要用到的函数为:CANRCVANDSEND()提供接收CAN总线的数据,在原例中为接收发送一体。我们需要稍微改造一下,
// MessageDetailR.DATAA = mes;
for (i2 = 0; i2 < 4; i2++) {
dataAB[i2] = mes >> 8 * i2;
}
我们知道CAN分数据A部分与数据B部分,每部分各为4个Byte数组。
上面即数据A部分的分离数组。
同理,我们只需要增加4,即可取到数据B部分的每个数组值。
// MessageDetailR.DATAB = mes;
for (i2 = 0; i2 < 4; i2++) {
dataAB[4 + i2] = mes >> 8 * i2;
}
至此,CAN模块处理完。
- CAN转COM或CAN-1
- CAN转COM或CAN-2
- CAN转COM或CAN-3
- CAN转COM或CAN-完结篇
- Can
- CAN
- CAN
- CAN
- CAN
- AndroidStudio或IDEA中连接github失败:Can't login: Connect to api.github.com:443
- can 转usb【can-usb】【usb can转换】
- can not load com.mysql.jdbc.Driver
- SLCAN 串口转CAN
- (1)can总线基本概念
- CAN总线(1)
- can学习日志1
- Supply VAG COM 8124 HEX CAN USB form uobd2.com
- 关于com.jacob.com.ComFailException:Can't find moniker问题
- Date和Calendar
- extjs4.0 文件上传
- 广州中国科学院软件应用技术研究所笔经
- (C#)实现时间复杂度为O(n)空间复杂度为O(1)的数组中奇偶数分离
- Ubuntu下RMI Server 抛出java.rmi.ConnectException: Connection refused to host: 127.0.0.1解决办法
- CAN转COM或CAN-1
- 计算机系统层次结构
- WCF基本任务
- logiclock设计方法
- 用emial登陆openfire
- IE与Google Chrome在像素上不相同
- Create admin user in OpenNebula
- 对Cookie操作的封装
- Sqlite使用命令个别大全