PROFIBUS DP从站开发 VPC3源程序分析---vpc3_get_dinbufptr (void)函数

本文详细解析了如何通过UBYTEPTR_ATTRvpc3_get_dinbufptr函数获取SPC3的数据输入缓冲区指针,涉及状态机状态判断和物理地址计算。了解缓冲区分配与读取过程对于设备编程至关重要。
摘要由CSDN通过智能技术生成

UBYTE PTR_ATTR vpc3_get_dinbufptr (void)

//
/// 以下程序注释由成都地质学院霸王猫添加,引用时请尊重作者劳动成果,标明引用者来自成都地质学院霸王猫。
//

UBYTE PTR_ATTR vpc3_get_dinbufptr (void)

    入口参数:

 		无

    出口参数:
		无

    返回值:
        	输入缓冲区的指针

    调用格式:

		UBYTE PTR_ATTR* input_buf_ptr;
		if (input_buf_ptr = vpc3_get_dinbufptr ()) // get pointer to DIN data

    函数功能:
		获取输入缓冲区的指针
	

    原理:
  		(1)、SPC3从D缓存器中发送输入数据。
   		(2)、在发送之前,SPC3从N缓存器得到Din缓冲器数据,然后放到D缓冲器中。如果当前N状态下无新的输入数据,将没有变化。
   		(3)、用户使U缓冲器中新的数据可用,通过 New_Din_buffer_Cmd ,缓冲器从U转变到N。
   		(4)、用户可以读取状态机单元的状态,有4种状态:NIL、Din_Buf_Ptr1、Din_Buf_Ptr2、Din_Buf_Ptr3,当前数据指针在N状态下。
   		(5)、当读取New_Din_Buffer_Cmd时,用户可得知交换后哪一个缓存属于用户	


    源程序:

/*---------------------------------------------------------------------------*/
/*  D e s c r i p t i o n : vpc3_get_dinbufptr                               */
/*                                                                           */
/* This function fetches the pointer to the actual input buffer.             */
/*---------------------------------------------------------------------------*/
UBYTE PTR_ATTR* vpc3_get_dinbufptr (void)
{
	UBYTE PTR_ATTR* p_dinbuf; // pointer to output buffer ( VPC3 -> DP-Master )

    switch (vpc3->ctrl_reg.rd.din_buffer_sm & 0x30)         // locate user Din Buffer
    {
	case 0x10:
            p_dinbuf = (UBYTE PTR_ATTR *)((VPC3_ADR)(vpc3->din_buf_ptr[0] << SEG_MULDIV)+(VPC3_ADR)VPC3_ASIC_ADDRESS);
            break;
            
        case 0x20:
            p_dinbuf = (UBYTE PTR_ATTR *)((VPC3_ADR)(vpc3->din_buf_ptr[1] << SEG_MULDIV)+(VPC3_ADR)VPC3_ASIC_ADDRESS);            		
            break;
            
        case 0x30:
            p_dinbuf = (UBYTE PTR_ATTR *)((VPC3_ADR)(vpc3->din_buf_ptr[2] << SEG_MULDIV)+(VPC3_ADR)VPC3_ASIC_ADDRESS);            
            break;

        default:
            p_dinbuf = NULL_PTR;
            break;
    }
    return (p_dinbuf);
}
	




//-------------------------------------------------------------------------------------
1. 执行下面语句 
//-------------------------------------------------------------------------------------
	switch (vpc3->ctrl_reg.rd.din_buffer_sm & 0x30)


已知:
	(1)、ctrl_reg.rd.din_buffer_sm = 寄存器地址(08H)= 数据输入状态机的缓冲器
						 	bit5   bit4 			--->  U:  用户缓冲器的分配
							 0       0				NULL
							 0       1				Din_Buf_Ptr1
							 1       0				Din_Buf_Ptr2
							 1       1				Din_Buf_Ptr3
目的:
	通过状态机得到数据输入缓冲区的指针。

结果:
	随机得到如下3个值。
	(1)、0x10(16)
	(2)、0x20(32)
	(3)、0x30(48)

     


//-------------------------------------------------------------------------------------
2. 执行下面语句 
//-------------------------------------------------------------------------------------
	case 0x10:
            p_dinbuf = (UBYTE PTR_ATTR *)((VPC3_ADR)(vpc3->din_buf_ptr[0] << SEG_MULDIV)+(VPC3_ADR)VPC3_ASIC_ADDRESS);
            break;  

已知:
	(1)、ctrl_reg.rd.din_buffer_sm  & 0x30 = 0x10
	(2)、vpc3->din_buf_ptr[0] = 103
	(3)、SEG_MULDIV = 0x03
	(4)、VPC3_ASIC_ADDRESS = 0x2000

目的:
	获取Din_Buf_Ptr1的物理地址
	vpc3->ctrl_reg.rd.din_buffer_sm & 0x30 = 0x10 ,表示用户缓冲器的分配使用Din_Buf_Ptr1。

结果:
	p_dinbuf = (UBYTE PTR_ATTR *)((VPC3_ADR)(vpc3->din_buf_ptr[0] << SEG_MULDIV)+(VPC3_ADR)VPC3_ASIC_ADDRESS);
		 = (103) << 0x03 + 0x2000 =  824 + 8192 = 9016 = 0x2338



//-------------------------------------------------------------------------------------
3. 执行下面语句 
//-------------------------------------------------------------------------------------
        case 0x20:
            p_dinbuf = (UBYTE PTR_ATTR *)((VPC3_ADR)(vpc3->din_buf_ptr[1] << SEG_MULDIV)+(VPC3_ADR)VPC3_ASIC_ADDRESS);            		
            break;


已知:
	(1)、ctrl_reg.rd.din_buffer_sm  & 0x30 = 0x20
	(2)、vpc3->din_buf_ptr[0] = 134
	(3)、SEG_MULDIV = 0x03
	(4)、VPC3_ASIC_ADDRESS = 0x2000

目的:
	获取Din_Buf_Ptr2的物理地址
	vpc3->ctrl_reg.rd.din_buffer_sm & 0x30 = 0x20 ,表示用户缓冲器的分配使用Din_Buf_Ptr2。

结果:
	p_dinbuf = (UBYTE PTR_ATTR *)((VPC3_ADR)(vpc3->din_buf_ptr[1] << SEG_MULDIV)+(VPC3_ADR)VPC3_ASIC_ADDRESS);
		 = 134 << 3  + 0x2000  = 1072 + 8192 = 9264 = 0x2430




//-------------------------------------------------------------------------------------
4. 执行下面语句 
//-------------------------------------------------------------------------------------
        case 0x30:
            p_dinbuf = (UBYTE PTR_ATTR *)((VPC3_ADR)(vpc3->din_buf_ptr[2] << SEG_MULDIV)+(VPC3_ADR)VPC3_ASIC_ADDRESS);            
            break;


已知:
	(1)、ctrl_reg.rd.din_buffer_sm  & 0x30 = 0x30
	(2)、vpc3->din_buf_ptr[0] = 165
	(3)、SEG_MULDIV = 0x03
	(4)、VPC3_ASIC_ADDRESS = 0x2000

目的:
	获取Din_Buf_Ptr3的物理地址
	vpc3->ctrl_reg.rd.din_buffer_sm & 0x30 = 0x30 ,表示用户缓冲器的分配使用Din_Buf_Ptr3。

结果:
	p_dinbuf = (UBYTE PTR_ATTR *)((VPC3_ADR)(vpc3->din_buf_ptr[2] << SEG_MULDIV)+(VPC3_ADR)VPC3_ASIC_ADDRESS); 
		 = 165 << 3  + 0x2000  = 1320 + 8192 = 9512 = 0x2528




//-------------------------------------------------------------------------------------
5. 执行下面语句 
//-------------------------------------------------------------------------------------
        default:
            p_dinbuf = NULL_PTR;
            break;


目的:
	判断数据输入状态机是否进入不可用的状态

结果:
	上述语句不执行。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值