1553B通信项目开发笔记(三)bu61580程序编写,实现回环之BC端

博主用的是一款内嵌BU61580芯片的ARM9芯片,限于某些原因就不说芯片型号了。

该控制芯片将BU61580的寄存器和存储器区域映射到了这四个地址

#define BM1553b0MEM             0x81100000
#define BM1553b0REG             0x81104000


#define BM1553b1MEM             0x81000000
#define BM1553b1REG             0x81004000

该控制芯片包含两个1553控制器,下面将通过一个BC一个RT来实现回环通信。

1、BC端设置

  *(volatile INT32U *)(BM1553b1REG + (3 << 2))  = 0x0001;              //reset	
	*(volatile INT32U *)(BM1553b1REG + (7 << 2))  = 0x8000;              //配置寄存器3#, bit15-设置增强模式
	*(volatile INT32U *)(BM1553b1REG + (7 << 2))  = 0x8000;              //配置寄存器3#,设置其他位	
	*(volatile INT32U *)(BM1553b1REG + (0 << 2))  = 0x0000;              //EOM interupt
	*(volatile INT32U *)(BM1553b1REG + (1 << 2))  = 0x0170;              //配置寄存器1#,bit8-Frame Auto Repeat,bit6-Internal Trigger Enabled,bit5-Internal Message Gap Timer Enabled
	                                                                       //bit5-Internal Message Gap Timer Enabled,bit4-Retry Enabled
	*(volatile INT32U *)(BM1553b1REG + (2 << 2))  = 0x1410;              //配置寄存器2#
	*(volatile INT32U *)(BM1553b1REG + (8 << 2))  = 0x11E0;              //配置寄存器4#bit12-Expanded BC Control WORD,bit8-First Retry/Second Retry Alt,
  	*(volatile INT32U *)(BM1553b1REG + (9 << 2))  = 0x0800;              //配置寄存器5#bit11-扩展过零点检测 
	*(volatile INT32U *)(BM1553b1REG + (13 << 2)) = 0x2710;              //BC帧时间1s,分辨率100us 

        首先是设置BC端的寄存器,将上述1553B1作为BC端。这部分寄存器设置具体说明可以参考61580手册,这里不再赘述。

  int i; 
  for(i=0;i<4096;i++)
	{
		*(volatile INT32U *)(BM1553b1MEM + (i << 2)) = 0x0;        					//初始化存储器
	}

        然后初始化1553B1的存储器区域

  	int i,j;
/消息块总配置——数量,指针
	  *(volatile INT32U *)(BM1553b1MEM + (0x100 << 2)) = 0x0;           //set send stack pointer
		*(volatile INT32U *)(BM1553b1MEM + (0x101 << 2)) = 0xfffb;        //set messages in a frame (0xffff - value) 这里是四个消息块 0-3 如果只有一个消息 就设置0XFFFE
		*(volatile INT32U *)(BM1553b1MEM + (0x102 << 2)) = 0x0;           //set send stack pointer
		*(volatile INT32U *)(BM1553b1MEM + (0x103 << 2)) = 0xfffb;        //set messages in a frame (0xffff - value)
		
/消息块0
		*(volatile INT32U *)(BM1553b1MEM + (0 << 2)) = 0x0;                 
		*(volatile INT32U *)(BM1553b1MEM + (1 << 2)) = 0x0;
		*(volatile INT32U *)(BM1553b1MEM + (2 << 2)) = 0x0;
		*(volatile INT32U *)(BM1553b1MEM + (3 << 2)) = 0x0108;//0x0108 信息块0的起始地址
        //消息块存储区域范围:108-12D 总长度37 前面俩地址(108 109)放控制字和命令字 第三个地址(10A)开始放数据
	    *(volatile INT32U *)(BM1553b1MEM + (0x0108 << 2)) = 0x0100;  
	     //0X0100->0001 0000 0000  0x0180->0001 1000 0000 
		 //BC控制字 BIT8=1出错时允许重发,BIT7=1选择A通道/BIT7=0选择B通道,BIT=1本消息结束后产生中断
	     //BC控制字  0x0180 BIT8=1 使能重发       BIT7=1 选择A通道   
		 //BC控制字  0x0100 BIT8=1 使能重发       BIT7=0 选择B通道  
		 //BIT2-BIT0:000-BC-RT(T/_R和命令字第9位关联,1=RT-BC,0=BC-RT),010-BROADCAST,100-MODECODE, 
	    *(volatile INT32U *)(BM1553b1MEM + (0x0109 << 2)) = 0x083E;        
		//命令字BIT0-4:RT ADD,BIT5:T/_R,BIT6-10:子地址;BIT11-15;数据个数,00000代表32/00001代表1         
		//PS:这个位置好像说反了,字节排序,RT地址按正常排序应该是11-15BIT
	    //BC命令字 0x083E  0000 1000 0011 1110   00001:RT1   0:接收    00001:子地址1 11110	:长度30bytes
		//这个数据块是RT<-BC的方向,第10bit为0,代表BC要求RT接收数据。	 

	    for(i=0;i<30;i++)
	     {
			*(volatile INT32U *)(BM1553b1MEM + ((0x010a + i) << 2)) = i; //放数据
	     }
/消息块1
		*(volatile INT32U *)(BM1553b1MEM + (4 << 2)) = 0x0;                 
		*(volatile INT32U *)(BM1553b1MEM + (5 << 2)) = 0x0;
		*(volatile INT32U *)(BM1553b1MEM + (6 << 2)) = 0x0;
		*(volatile INT32U *)(BM1553b1MEM + (7 << 2)) = 0x012e;//0x012e 信息块1的起始地址

	    *(volatile INT32U *)(BM1553b1MEM + (0x012e << 2)) = 0x0180;     //消息块的第一个地址放控制字,第二个放命令字   
		//控制字 BIT8=1出错时允许重发,BIT7=1选择A通道/BIT7=0选择B通道,BIT=1本消息结束后产生中断 
	    //BC控制字  0x0100 BIT8=1 使能重发       BIT7=0 选择B通道                                                                  //BIT2-BIT0:000-BC-RT(T/_R和命令字第9位关联,1=RT-BC,0=BC-RT),010-BROADCAST,100-MODECODE, 
	    *(volatile INT32U *)(BM1553b1MEM + (0x012f << 2)) = 0x083E;        
		//命令字BIT0-4:RT ADD,BIT5:T/_R,BIT6-10:子地址;BIT11-15;数据个数,00000代表32/00001代表1
		//PS:这个位置好像说反了,字节排序,RT地址按正常排序应该是11-15BIT
		//BC命令字 0x083E  
		//0000 1000 0011 1110   
		//00001:RT1  
		//0:接收     
		//00001:子地址1      
		//11110:长度30bytes
		//这个数据块是RT<-BC的方向,第10bit为0,代表BC要求RT接收数据。	 

		
		for(i=0;i<30;i++)
		{
			*(volatile INT32U *)(BM1553b1MEM + ((0x130 + i) << 2)) = i; //数据
		}
		
/消息块2
		*(volatile INT32U *)(BM1553b1MEM + (8 << 2)) = 0x0;                 
		*(volatile INT32U *)(BM1553b1MEM + (9 << 2)) = 0x0;
		*(volatile INT32U *)(BM1553b1MEM + (10 << 2)) = 0x0;//消息间隔4.096ms
		*(volatile INT32U *)(BM1553b1MEM + (11 << 2)) = 0x0154;//0x0154 信息块2的起始地址

	    *(volatile INT32U *)(BM1553b1MEM + (0x0154 << 2)) = 0x0104;       //控制字 BIT8=1出错时允许重发,BIT7=1选择A通道/BIT7=0选择B通道,BIT=1本消息结束后产生中断
	      //BC控制字  0x0184 BIT8=1 使能重发       BIT7=1 选择A通道  BIT2=1 模式码  
         //BIT2-BIT0:000-BC-RT(T/_R和命令字第9位关联,1=RT-BC,0=BC-RT),010-BROADCAST,100-MODECODE, 		
	    *(volatile INT32U *)(BM1553b1MEM + (0x0155 << 2)) = 0x0C10;       
		//命令字BIT0-4:RT ADD,BIT5:T/_R,BIT6-10:子地址;BIT11-15;数据个数,00000代表32/00001代表1
		//命令字0x0c10:0000 1100 0001 0000 
		//00001 :RT1   
		//1:T  
		//00000:方式码 
		//10000:发送矢量字
		//PS:这个位置好像说反了,字节排序,RT地址按正常排序应该是11-15BIT
		//这个数据块是RT->BC的方向,第10bit为1,代表BC要求RT发送数据。
		//读取数据就不需要往存储区域里写数据

/消息块3
		
		*(volatile INT32U *)(BM1553b1MEM + (12 << 2)) = 0x0;                 
		*(volatile INT32U *)(BM1553b1MEM + (13 << 2)) = 0x0;
		*(volatile INT32U *)(BM1553b1MEM + (14 << 2)) = 0x0;
		*(volatile INT32U *)(BM1553b1MEM + (15 << 2)) = 0x0180;//信息块3的起始地址

	    *(volatile INT32U *)(BM1553b1MEM + (0x0180 << 2)) = 0x0184;       //控制字 BIT8=1出错时允许重发,BIT7=1选择A通道/BIT7=0选择B通道,BIT=1本消息结束后产生中断
	    //BC控制字  0x0104 BIT8=1 使能重发       BIT7=0 选择B通道  BIT2=1 模式码                                                                //BIT2-BIT0:000-BC-RT(T/_R和命令字第9位关联,1=RT-BC,0=BC-RT),010-BROADCAST,100-MODECODE, 
	    *(volatile INT32U *)(BM1553b1MEM + (0x0181 << 2)) = 0x0C10;       
		//命令字BIT0-4:RT ADD,BIT5:T/_R,BIT6-10:子地址;BIT11-15;数据个数,00000代表32/00001代表1
		//PS:这个位置好像说反了,字节排序,RT地址按正常排序应该是11-15BIT
		//命令字0x0c10:0000 1100 0001 0000 表示00001 :RT1   1:发送  00000:方式码 10000:发送矢量字
		//这个数据块是RT->BC的方向,第10bit为1,代表BC要求RT发送数据。
		//读取数据就不需要往存储区域里写数据

        然后是关键的一个部分,在1553B1的存储器区域设置BC端需要实现的消息,这里写入了四条消息,分别实现两条BC=>RT,两条RT=>BC。细节均在代码里进行备注。

       *(volatile INT32U *)(BM1553b1REG + (0x0 << 2)) = 0x0008;              //EOM interupt     这个似乎是消息结束后中断 
       *(volatile INT32U *)(BM1553b1REG + (0x3 << 2)) = 0x0002;              //Start Send	

        最后是打开EOM中断和开启BC,这里的EOM中断是BC消息帧结束中断。

2、BC中断服务

		  Nowpos = *(volatile INT32U *)(BM1553b0MEM + (0x100 << 2)) ;   //堆栈指针
		  Nowpos =  Nowpos & 0xfc;
				
		  for( ; Nowpos != Lastpos; Lastpos = ( Lastpos + 4) & 0xff )    //判定堆栈指针是否有移动
		  {	 
				
			   State_word =  *(volatile INT32U *)(BM1553b0MEM + ((Lastpos ) << 2));             //读出状态字
			   Adr_data   =  *(volatile INT32U *)(BM1553b0MEM + ((Lastpos + 2) << 2));          //读出地址字
			   Com_word   =  *(volatile INT32U *)(BM1553b0MEM + ((Lastpos + 3) << 2));          //读出命令字
			
			   Sub_adr    =  Com_word & 0x07e0;                //解析出子地址
		  	 Channel_A_B = State_word & 0x2000;                //解析出通道来源
			  //printf("A_B %x\r\n",State_word);
				 printf("A_B %d\r\n",(Channel_A_B>>13));           //状态字第十三位是AB通道标志
			
				 if(Sub_adr == 0x20)//接收消息                     //判定接收消息的子地址来源
				 {
					for(i=0;i<30;i++)
					{
						R1553B_DATA[i] = *(volatile INT32U *)(BM1553b0MEM + ((0x420+i)<< 2));//接收到的数据
					}
						
					for(i=0;i<30;i++)
					{
						*(volatile INT32U *)(BM1553b0MEM + ((0x820+i)<< 2))=T1553B_DATA[i];//需要发送的数据 写到RT0里  实际上是完成一个回环测试?
					}	
						
						*(volatile INT32U *)(BM1553b0MEM + (0x120 << 2)) = 0x0001; //置矢量字   这个是RT0的东西  在手册里暂时没找到说明
				 }	
				 else if(Sub_adr == 0x420)//发送消息    子地址有这么多吗?不是就0-32么
				 {
				  *(volatile INT32U *)(BM1553b0MEM + (0x120 << 2)) = 0x0000;   //清矢量字,矢量字存储在地址0x120
				 }
			  }

        这里需要说明的是,本控制芯片将61580芯片内嵌,所以使用专门的中断标志位即可实现中断,如果是外部的61580则需要使用外部输入中断来识别芯片提供的中断信号。

        这部分中断服务程序,是从别的地方搞到的,所以有些地方还没有理解清楚。

        暂时更新到这里,后面会着重去理解终端服务程序里标注问号的位置。

  • 9
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值