⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aaa.asm

📁 关于can总线2.0的发送和接受程序,经项目验证通过,具有极大的参考价值.
💻 ASM
📖 第 1 页 / 共 2 页
字号:
#include  "def21060.h"


#define addr 0x10800000
#define buttonstate 0x600000
#define   N1     0xa
#define   N2     0xa
#define   N3     0x18
#define   N4     0x10
#define   N      0x8        //这个N不能为7,要比7大一点才好
#define   N5     0x4        //将一个32分四次发送给SJA1000
.segment/dm	seg_dmda;

.var zw1[1]=0;
.var zw2[1]=0xa;
.var zw3[1]=0x3;
.var REG_TxBuffer[N2]=0xa,0xb,0xc,0xd,0xe,0xf,0x10,0x11,0x12,0x13;       //发送缓冲区地址
.var REG_RxBuffer[N2]=0x14,0x15,0x16,0x17,0x18,0x29,0x20,0x21,0x22,0x23;       //接收缓冲区地址
//.var cansend[10]=0x67881234,0x56789abcd,0x12340000,0x67881234,0x56789abcd,0x12340000,0x67881234,0x56789abcd,0x12340000;
     //发送方是6,接受方是7,所以帧源地址是6,帧目的地址是7
.var cansend[12]=0x67828040,0x67822010,0x67820804,0x67820401,0x6782ffff,0x6782a0a0,0x67825050,0x6782c0c0,0x67823030,0x67821234,0x67821234,0x67821234;
    //在这里,一个报文只有4个字节
.var canreceive[10]=0,0,0,0,0,0,0,0,0,0;
.var source[N]=0x0,0x1f,0x4,0x5,0x6,0x7,0x8,0x0;
.var data1[N]=0x01,0x00,0x06,0xff,0x40,0xe7,0x1a,0x2;
.endseg;

.segment/pm seg_rth;
			nop;nop;nop;nop;	//保留的中断矢量地址
_lib_RSTI:  nop;				//引导时的临时存储单元
			jump _main(DB);		//跳转到正式程序		
			nop;nop;
			
			nop;nop;nop;nop;	//保留的中断矢量地址
_lib_SOVFI: rti;rti;rti;rti;
_lib_TMZHI: rti;jump dsq;rti;rti;	//高优先级定时器中断矢量地址
_lib_VIRPTI:rti;rti;rti;rti;	//矢量中断的矢量地址
_lib_IRQ2I: rti;rti;rti;rti;	//外部中断2的矢量地址
_lib_IRQ1I: rti;rti;rti;rti;	//外部中断1的矢量地址
_lib_IRQ0I: rti;rti;rti;rti;	//外部中断0的矢量地址
	
			nop;nop;nop;nop;	//保留的中断矢量地址
_lib_SPR0I: rti;rti;rti;rti;	//串口0接收中断的矢量地址
_lib_SPR1I: rti;rti;rti;rti;	//串口1接收/链路0中断矢量地址
_lib_SPT0I: rti;rti;rti;rti;	//串口0发送中断的矢量地址
_lib_SPT1I: rti;rti;rti;rti;	//串口1发送/链路1中断矢量地址	
_lib_LPT2I: rti;rti;rti;rti;	//链路2中断矢量地址
_lib_LPT3I: rti;rti;rti;rti;	//链路3中断矢量地址
_lib_EPT0I: rti;rti;rti;rti;	//外部口0/链路4中断矢量地址
_lib_EPT1I: rti;rti;rti;rti;	//外部口1/链路5中断矢量地址
_lib_EPT2I: rti;rti;rti;rti;	//外部口2中断矢量地址
_lib_EPT3I: rti;rti;rti;rti;	//外部口3中断矢量地址
_lib_LSRQ:  rti;rti;rti;rti;	//链路服务请求中断矢量地址
_lib_CB7I:  rti;rti;rti;rti;	//循环缓冲7溢出中断矢量地址
_lib_CB15I: rti;rti;rti;rti;	//循环缓冲7溢出中断矢量地址
_lib_TMZLI: rti;rti;rti;rti;		//低优先级定时器中断矢量地址
.endseg;   

.segment/dm seg_aaa;           //定义4个外部段,每段的大小在主程序里面进行设定
.endseg;
.segment/dm seg_bbb;
.endseg;
.segment/dm seg_ccc;
.endseg;
.segment/dm seg_ddd;
.endseg;
.segment/pm seg_pmco;

_main:
 r1=0x0000f000;
 r2=dm(SYSCON);
 R3=R1 OR R2;
 DM(SYSCON)=r3;       //定义4个外部块的大小
 i3=cansend;m3=1;         //我把这个东西放在外面是为了更好的使发送和接受子程序有更强的通用性
 r14=0;                //用于计数的,比如我要传10个报文,则就靠这个来计数
 
/***********************************************************************************
以下是在发送开始前的一个由按键控制的小程序,目的是为使得在按键按下以后才开始CAN的
发送程序
*************************************************************************************/

testbutton:
 r1=0x0000f000;
 r2=dm(SYSCON);
 R3=R1 OR R2;
 DM(SYSCON)=r3;       //定义4个外部块的大小
 
 r1=0x80000000;
 r0=dm(buttonstate);
 nop;nop;
 r0=r0 and r1;
 nop;nop;
 if eq jump initialcan;
 nop;nop;
 jump testbutton;         //由板子上的最边上一个按键控制,靠近SJA1000的那个
 nop;nop;

//*************************************************************************************
initialcan:

 r1=0x0000f000;
 r2=dm(SYSCON);
 R3=R1 OR R2;
 DM(SYSCON)=r3;       //定义4个外部块的大小
computation:
 bit set mode2 FLG0O; //设置flag0输出
 bit set mode2 FLG1O; //设置flag1输出
 i0=source;
 m0=1;
 i1=data1;
 m1=1;

 lcntr=N,do aaa until lce;

 bit clr astat FLG0;
 bit set astat FLG1;

 r0=dm(i0,m0);           //从source缓冲区取得数据,事后修改
 dm(addr)=r0;           //写地址


 bit set astat FLG0;
 bit clr astat FLG1;
 

 r1=dm(i1,m1);               //从data缓冲区取得数据
 dm(addr)=r1;               //写数据
 nop;nop;nop;nop;            
 bit set astat FLG1;         //禁止读写SJA1000,即不选种SJA1000的CS
 aaa:nop;                    //搞清楚循环体的用法

  delay:
  lcntr=N4,do bbb until lce;
  nop;
  bbb:nop;

 /*************************************************************************************************
  以上是初始化程序,以下是检测初始化是否完成的程序,方法是:循环的读控制寄存器的复位位,看是不是回到
   0的了,如果回到0,说明已经初始化完成,如果仍然是1,那么说明初始化不成功,则需要再次进行一次初始化
 ************************************************************************************************/

//************************************************************************************************
/*
readback:
 bit set mode2 FLG0O; //设置flag0输出
 bit set mode2 FLG1O; //设置flag1输出
 i0=source;
 m0=1;
 i1=canreceive;
 m1=1;


lcntr=N,do ccc until lce;

 bit clr astat FLG0;
 bit set astat FLG1;

 r0=dm(i0,m0);           //从source缓冲区取得数据,事后修改
 dm(addr)=r0;           //写地址


 bit set astat FLG0;
 bit clr astat FLG1;
 

              
 r1=dm(addr);  
 dm(i1,m1)=r1;            
 nop;nop;nop;nop;            
 bit set astat FLG1;        
 ccc:nop;               */    

//************************************************************************************************
 test:
 i0=source;
 r15=1;
 bit clr astat FLG0;
 bit set astat FLG1;
 r2=dm(i0,0);           
 dm(addr)=r2;   

 bit set astat FLG0;
 bit clr astat FLG1;
 r3=dm(addr);
 nop;nop;
 r3=r3 and r15;
 nop;nop;
 if NE jump computation;            //NE 是指AZ=0,对通用寄存器进行的操作是会影响ASTAT的
 nop;nop;
//************************************************************************************
start:

bit set mode2 FLG0O;           //设置flag0输出
bit set mode2 FLG1O;           //设置flag1输出
r4=dm(zw1);
r5=dm(zw2);
r6=dm(zw3);
r7=dm(zw1);

detectTBS:
  bit clr astat FLG0;
  bit set astat FLG1;

  
  r0=0x2;
  dm(addr)=r0;
  bit set astat FLG0;
 
  bit clr astat FLG1;
  r1=dm(addr);
  bit set astat FLG1;          //将SJA1000的状态寄存器的值读回来

  r2=0x4;
  r4=r1 and r2;
  nop;nop;nop;
  if eq jump chaxun1;

send:
 r4=0;                    //当检查到TBS为1,可以发送数据了,在发送程序的开头把r4清0,目的是为了为下一次的计数做准备
 r10=N3;
 r10=-r10;
 r9=0x8;
 r12=0;
 r7=0x9;
 R12=0;        
 r13=dm(i3,1);           //先把要发送的数移到r13里面去,事后修改I3的值
 i0=REG_TxBuffer;         //初始化要发送的地址的值
 nop;nop;nop;
 lcntr=N5,do sss until lce;        //N5=4 ,将32位数分四次发送给SJA1000

 bit clr astat FLG0;
 bit set astat FLG1;
 
 r0=dm(i0,1);              //从接收缓冲区取得数据
 dm(addr)=r0;              //写地址
 
 bit set astat FLG0;
 bit clr astat FLG1;
 r15=r13;                  //每个循环都要把要发送的值放到r15里面去。因为在发送的时候只是将16到23位对齐
                           //但是,要注意,这样做只发了一个数据呢
 R15=LSHIFT R15 by r10;     //最开始传的是高位,把数据右移24位

 dm(addr)=R15;             //写数据
 r10=r10+r9;
 nop;                        //每传输一次数据之前必须将32位数移到相应的地方
 sss:nop;                   //以上为21060的发送程序

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -