基于AT91RM9200的CAN通讯程序

发布者:EtherealGaze最新更新时间:2016-08-18 来源: eefocus关键字:AT91RM9200  CAN通讯 手机看文章 扫描二维码
随时随地手机看文章
#include

#include "sja1000.h"
unsigned int T_flag0=0;
unsigned int T_flag1=0;

//unsigned char data[11] = {'\0'};
//unsigned char Rx_Buf0[11] = {'\0'};
unsigned char Tx_Buf0[9] = {'\0'};
unsigned char Tx_Buf1[9] = {'\0'};
//unsigned char Rx_Buf1[11] = {'\0'};


/*writ to the register with tht data
 chanal--通道号,可选CAN总线1,CAN总线2
 reg-----寄存器号
 data----寄存器数据*/
void setcanport(unsigned char chanal, unsigned int reg, unsigned char data1)
{
    if(!chanal)
 BASEADD = 0x50000000;
    else
 BASEADD = 0x60000000;
 
 printf("\nThe %d will be writed to register %d\n ",data1,reg);
    __asm
    {
 STRB reg,[BASEADD,#4]
 STRB data1,[BASEADD]
    }
}

/*read the data of the register to the return
 chanal--通道号,可选CAN总线1,CAN总线2
 reg-----寄存器号
 返回值--寄存器数据*/
unsigned char getcanport(unsigned char chanal, unsigned char reg)
{
    unsigned char temp;
    if(!chanal)
 BASEADD = 0x50000000;
    else
 BASEADD = 0x60000000;
  
    __asm    
    {
 STRB reg,[BASEADD,#4]
 LDRB temp,[BASEADD]
 }
 return (temp);
}

/*Receive one message
 chanal--通道号,可选CAN总线1,CAN总线2
 返回值--数据个数*/
unsigned char getdata(unsigned char chanal, unsigned char *buf)

 int num,i;
 unsigned char data[11] = {'\0'};
 if(!chanal)
 BASEADD = 50000000;
    else
 BASEADD = 60000000;
 
 do 
 {
 }while((getcanport(chanal,StatusReg) & RBS_Bit) != RBS_Bit);
 
 data[0] = getcanport(chanal,RxBuffer1);
 data[1] = getcanport(chanal,RxBuffer2);
 data[2] = getcanport(chanal,RxBuffer3);
 data[3] = getcanport(chanal,RxBuffer4);
 data[4] = getcanport(chanal,RxBuffer5);
 data[5] = getcanport(chanal,RxBuffer6);
 data[6] = getcanport(chanal,RxBuffer7);
 data[7] = getcanport(chanal,RxBuffer8);
 data[8] = getcanport(chanal,RxBuffer9);
 data[9] = getcanport(chanal,RxBuffer10);
 
 num = data[1]&0x0f;

 
 for(i=0;i  {
 *(buf++)=data[i+2];
 }

 setcanport(chanal,CommandReg,RRB_Bit);

 *buf=0;

 return (num);

 
}

/*Transmit one message
 num-----数据个数
 data----数据
 返回值--0 忙*/
unsigned char senddata(unsigned char chanal, unsigned char *buf)
{     
 
 unsigned char temp = 0;
 unsigned char data[11] = {'\0'};
 int i;
 
 if(!chanal)
  BASEADD = 0x50000000;
 else
  BASEADD = 0x60000000;
 //temp = getcanport(chanal, StatusReg);

 if((getcanport(chanal,StatusReg) & TBS_Bit) == TBS_Bit)
 {
  for(i=0;i<8;i++)
  {
  data[i]=*(buf+i);
  }
  temp = getcanport(chanal, StatusReg);
  setcanport(chanal,TxBuffer1,0x00);
  setcanport(chanal,TxBuffer2,0x08);
  setcanport(chanal,TxBuffer3,data[0]);
  setcanport(chanal,TxBuffer4,data[1]);
  setcanport(chanal,TxBuffer5,data[2]);
  setcanport(chanal,TxBuffer6,data[3]);
  setcanport(chanal,TxBuffer7,data[4]);
  setcanport(chanal,TxBuffer8,data[5]);
  setcanport(chanal,TxBuffer9,data[6]);
  setcanport(chanal,TxBuffer10,data[7]);
  
  setcanport(chanal,CommandReg,0x01);
  
  do 
    {
       temp = getcanport(chanal, StatusReg);
       if ((temp & TCS_Bit)==TCS_Bit)
          break;
    } while(1);     //If it is transmitted succeded?

  return (1);
 }
 else if(!chanal)
 {
  if(!T_flag0)
  {
   for(i=0;i<8;i++)
   {
   Tx_Buf0[i]=*(buf+i);
   }
   T_flag0=1;//传输标志,1表示一个报文等待发送
  }
  else return (0);
 }
 else
 {
  if(!T_flag1)
  {
   for(i=0;i<8;i++)
   {
   Tx_Buf1[i]=*(buf+i);
   }
   T_flag1=1;//传输标志,1表示一个报文等待发送
  }
  else return (0);
 }
 
}


/*Initial the SJA1000 It just is BasicCAN */
void init_sja1000(unsigned char chanal)
{
 
 unsigned char temp = 0;
//?SJA中断禁止

//外部中断禁止
 if(!chanal)//禁止can0中断
 {
  __asm
  {
  str 0x00000000,[0xfffff120]
  }
  __asm
  {
  str 0x00000000,[0xfffff124]
  }
 } 
 else//禁止can1中断
 {
  __asm
  {
  str 0x00000000,[0xfffff120]
  }
  __asm
  {
  str 0x00000000,[0xfffff124]
  }
 }


//进入复位请求设置模式
 while((temp&RM_RR_Bit)!=RM_RR_Bit)
 {
 printf("\n0x01 will be set to ModeControlReg\n");
 setcanport(chanal, ModeControlReg,0x07);/*Config MOD&CR register,初始化INT*/
 
 temp = getcanport(chanal, ModeControlReg);
 printf("\nModeControlReg=%d\n",temp);
 
 }
//设置接收码
 setcanport(chanal, AcceptCodeReg, 0x01);
 temp = getcanport(chanal, AcceptCodeReg);
//设置屏蔽码
 setcanport(chanal, AcceptMaskReg, 0xff);
 temp = getcanport(chanal, AcceptMaskReg);
//设置总线bps
 setcanport(chanal, BusTiming0Reg, 0x47);
 temp = getcanport(chanal, BusTiming0Reg);//400kbps
 setcanport(chanal, BusTiming1Reg, 0xaf);
 temp = getcanport(chanal, BusTiming1Reg);
//设置CAN输出模式 
 setcanport(chanal, OutControlReg, 0xda);
 temp = getcanport(chanal,OutControlReg);
//设置时钟分频寄存器
 setcanport(chanal, ClockDivideReg, 0x48);
 temp = getcanport(chanal, ClockDivideReg);

/*清除复位模式位*/
 do
 {
 setcanport(chanal, ModeControlReg, 0X06);/*Config MOD&CR register*/
 temp = getcanport(chanal, ModeControlReg);
 }while(((getcanport(chanal, ModeControlReg)) & RM_RR_Bit)!=ClrByte);

//外部中断使能
 if(!chanal)//禁止can0中断
 {
  __asm
  {
  str 0x00000000,[0xfffff120]
  }
  __asm
  {
  str 0x00000000,[0xfffff124]
  }
 } 
 else//禁止can1中断
 {
  __asm
  {
  str 0x00000000,[0xfffff120]
  }
  __asm
  {
  str 0x00000000,[0xfffff124]
  }
 }

//?SJA中断使能

}

 


int main()
{
 unsigned char *buf;
 int i;
 unsigned char d[5][9]={"bbbbbbbb;","12345678","90123456","78787878","abcdefgh"};

 unsigned long t;
//    init irq1 an irq2 for sja1000 u2 u3

//nIRQ AIC_IECR&AIC_IDCR ENABLE INIT
 __asm
 {
 str 0x00000000,[0xfffff120]
 }
 __asm
 {
 str 0x00000000,[0xfffff124]
 }

//nIRQ AIC_SMR,&AIC_SVR config int
 __asm
 {
 ldr t,[0xfffff004]
 }
 __asm
 {
 orr t,t,#0x03//priority level3,Level Sensitive(interal) Low-level Sensitive(external)
 str t,[0xfffff004]
 }
 __asm
 {
 ldr t,[0xfffff008]
 }
 __asm
 {
 orr t,t,#0x03//priority level3,Level Sensitive(interal) Low-level Sensitive(external)
 str t,[0xfffff008]
 }
//配置AIC_SVR
 __asm
 {
 str t,[0xfffff084]
 }
 __asm
 {
 str t,[0xfffff088]
 }

 
 init_sja1000(0);

//
 for(i=0;i<5;i++)
 {
 buf=&d[i][0];
 senddata(0,buf);
 };
 
 while(1){
 
 getdata(0,buf);

 };
 
}

 

说明:

系统是测试CAN0接口和CAN卡的通信程序

波特率设置为:
   BAR0=0x47=71;
   BAR1=0xaf=175;

接口为:
   9200的CAN口:3脚为CANL,4脚为CANH
   对应CAN卡:  2脚为CANL,4脚为CANH

关键字:AT91RM9200  CAN通讯 引用地址:基于AT91RM9200的CAN通讯程序

上一篇:STM32L151内部RTC时钟
下一篇:基于AT91RM9200的I/O驱动程序(linux)

推荐阅读最新更新时间:2024-03-16 15:06

浅谈电动汽车CAN总线通讯原理及设计方案
1  电动汽车对通讯网络的需求   电动汽车由于储能设备容量有限,在运行过程中对能源的管理十分严格. 效率是衡量电动汽车系统性能的重要指标,国家863“十五”电动汽车重大专项要求电动机系统额定效率为85% ,控制器的额定效率达到95%. 电动汽车电子控制系统的动态信息必须具有实时性,各子系统需要将车辆的公共数据实时共享,如电机转速、车轮转换、油门踏板位置和刹车踏板位置等. 但不同控制单元的控制周期不同,数据转换速度、各控制命令优先级也不同,因此需要一种具有优先权竞争模式的数据交换网络,并且本身具有极高的通信速率.   此外,作为一种载人交通工具,电动汽车必须具有较好的舒适性,整车通讯系统必须具有很强的容错能力和快速处理能力。
[汽车电子]
浅谈电动汽车<font color='red'>CAN</font>总线<font color='red'>通讯</font>原理及设计方案
基于CAN通讯模块的闸间隙报警系统设计
0 引言     在煤矿生产中,矿井提升机是矿山大型关键设备。提升机的制动系统则是保证提升机能否安全运行、实现提升机正常减速停车以及在各种故障情况下执行紧急制动安全停车的最终手段。盘形闸是绞车提升系统中非常重要的配套设备,是保证安全提升的重要部分。盘形闸工作间隙报警有利于缩短故障排除的时间,故开发闸间隙报警模块具有重要的实际意义。CAN总线是一种总线型现场设备控制网络,具有突出的实时性、可靠性和灵活性。鉴于CAN总线的优势,本文开发了一种基于AVR的闸间隙报警CAN通讯模块,其成本低廉,安装方便。 1 模块硬件设计     该模块由处理器ATmega128、CAN总线控制器SJAl000以及CAN收发芯片CTM8251
[嵌入式]
CAN总线与RS485总线的通讯接口设计
1 CAN总线及RS-485总线简介     CAN总线(Controller Area Network)是由德国Bosch公司于20世纪80年代专门为汽车电子控制系统开发的一种串行数据通讯协议,特别适合应用于分布式控制或实时控制领域。它的应用范围遍及高速网络和低本钱的分布式控制系统。CAN具有以下特点:     (1) 无破坏的依据优先权的仲裁;     (2) 多主站点依据优先级进行总线访问;     (3) 严格的错误检测和界定;     (4) 支持远程数据请求;     (5) 借助接收滤波的多地址帧传送;     (6) 通讯介质多样,组合方式灵活;     (7) 全系统数据兼容,系统
[嵌入式]
基于C8051F040的CAN总线通讯系统设计
1 引言 CAN总线,即控制器局域网总线,是一种有效支持分布式控制或实时控制的串行通信网络。由于其高性能、高可靠性及独特的设计和适宜的价格,而广泛应用于工业现场控制、智能楼宇、医疗器械、交通工具以及传感器等领域,并已被公认为几种最有前途的现场总线之一。 目前CAN系统使用较多的是独立CAN控制器,利用单片机的并口控制CAN控制器,除了8条数据线外,还需要几条控制线。采取这样的设计不但占用了单片机的引脚,而且增加了电路板的面积。同时,由于采用了并行通讯,降低了系统的可靠性,因此,采取系统内部集成CAN控制器的单片机势在必行。 本文已Cygnal公司的内部集成CAN控制器的C8051F040单片机为基础,介绍了CAN
[单片机]
基于C8051F040的<font color='red'>CAN</font>总线<font color='red'>通讯</font>系统设计
AT91RM9200理器同步串口SSC的特性分析与应用
1 引言 电信网和因特网是两大网络系统,必然存在两个网络数据或信息的互通问题,例如:VoIP、混合视频会议等新业务。E1接口和以太网接口分别是电信网和因特网使用最为普遍的接入端口,设计一个嵌入式网关设备,通过这两种端口将两大网络连接起来就显得尤为迫切、重要。本文介绍的AT91RM9200处理器处理能力强、接口丰富,内部集成了同步串口和以太网接口,是嵌入式小型网关控制器的理想选择。 2 AT91RM9200和DS21554 AT91RM9200内部集成了一个ARM920T—ARM Thumb处理器,在180 MHz时钟时运行速度高达200 MI/s;内部有16 KB的数据Cache、16 KB指令Cache、写缓冲区、全功
[单片机]
<font color='red'>AT91RM9200</font>理器同步串口SSC的特性分析与应用
基于CAN总线的高压开关柜状态监测单元通讯模块的设计
1. 引言 高压开关柜是电力系统的关键主设备之一,其运行状态对电力系统的可靠性具有重大影响。 统计表明,20世纪90年代中国电力系统开关事故类型分布如下:机械故障(拒分、拒合、误动)33.3%,尽缘故障37.3%,温升故障(载流)8.9%,其它20.5% 。 因此,有必要对高压开关柜的机械、温升及尽缘状态实施在线监测,及时发现事故隐患,防止事故发生。 现有高压开关柜监测单元的核心一般采用单片机(MCU),其处理能力有限、存贮空间很小,只能对数据进行简单的处理和存放少量的历史数据 。为了存放大量的历史数据以便对已有的数据进行复杂的处理(如寿命评估、故障诊断等),也为了对电力系统运行状态进行远程检测和诊断,有必要使监测单元具有通讯能
[单片机]
基于<font color='red'>CAN</font>总线的高压开关柜状态监测单元<font color='red'>通讯</font>模块的设计
CAN总线车载网络通讯组件的研究和实现
   1 引言   目前,汽车电子正朝着网络化的方向发展,车载网络成为汽车电子领域的最大热点。提高控制单元间通讯可靠性并且降低导线成本的网络总线应用中的关键技术包括CAN、LIN、FlexRey、MOST、IDB1394 等。对于汽车整车厂来说,CAN 网络设计是应用CAN 网络通讯的关键。纵观现有的设计技术,可以将其分为两类:一类是以仿真和测试为主的传统设计方法;另一类是以协议设计为主的方法。传统方法将每个节点对协议的要求拼凑起来,通过仿真、测试的方法检验协议的正确性,最终得到通讯协议。新方法通过系统设计技术,用理论方法对系统的时序建模,分析设计系统的通讯协议,保证系统的实时性能以及协议的正确性,最终发布正确的通讯协议。本文
[嵌入式]
AT91RM9200引导程序的建立(一)建立交叉编译工具链
写在前面: 本系列文章将详细的讲述AT91RM9200引导程序的建立过程,其中包括建立交叉编译工具链,gdb+gdbserver的编译安装使用,tftp,NFS的安装使用,超级终端或者minicom的使用,内核的编译升级,U-Boot的移植,Ramdisk、根文件系统的建立制作,busybox的编译、应用等。从而重现完整的开发过程。在写这个文档的过程中,本人参考了许多资料,在这里要感谢互联网,感谢所有社区,论坛里无私提供帮助的同行们。特别感谢一下鲁郁先生,是他让我在AT91RM9200上成功的移植了U-Boot 1.1.4 。本人是从不懂一路走来,走的过程中将开发过程详细记述下来,从一个初学者的角度来写下这个系列的文章,以方
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved