| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 545 人关注过本帖
标题:将汇编翻译成C了, 累死了。。。
只看楼主 加入收藏
wengege
Rank: 2
等 级:论坛游民
帖 子:148
专家分:93
注 册:2012-7-23
结帖率:89.47%
收藏
 问题点数:0 回复次数:1 
将汇编翻译成C了, 累死了。。。
应项目要求靠着一个汇编写的自定义协议源代码 硬是用C 实现。。。头大了。。
// 模块功能: 实现STM32与PIC16F57串行通信。


#include "PIC16F57_CM.h"
#include "Delay.h"

/*******************************************相关宏定义*****************************************/

#define SERIAL_TIME   530
#define SERIAL_TIME_BASE 10   // 0.5S
#define SWAP(A) ((A >> 4 | A << 4) & 0xff)  

/*******************************************相关函数定义***************************************/

u8 Serial_Read(u16 *);      
u8 Serial_Read_ASK(void);
u8 Serial_Write(u16 );
u8 Serial_Write_ASK (void);
void Serial_Free_IO(void);
void Serial_Func (void);
void Serial_Write_ACK(void);
u8 Serial_Read_ACK(void);
u8 Serial_Write_Task (u16 );
u8 Serial_Read_Task (u8 * , u8 * );
u8  Serial_UnlockCode (u16 , u8 *, u8 * );

/*******************************************相关全局变量定义***************************************/

u16 Serial_Write_Data;   /*  待写数据 */
u8  Serial_Read_Data;    /* 经解码后的有效数据 */
u8 Write_Enable;         /* 需要写操作 */
u8 Serial_Write_Time;
u8 Serial_Read_Data_Type;


/* *******************************************************************************************************
* 函数功能: STM32 与 PIC 通信入口
*
* 参数:     Has_Police_Flag == true: 需要写操作
*             Serial_Send_Time: 写操作间隔时间
*
* 备注:     读写数据操作的前提是需要判断SDA SCL管脚的电平状态:
*                1、当SDA管脚处于低电平状态时则可以执行读操作。
*               2、当SDA和SCL同时空闲(高电平)则可以执行写操作。
*         
*********************************************************************************************************/

void Serial_Func (void)
{   
   
         if (READ_SERIAL_SDA)
        {
                if ( READ_SERIAL_SCL && Write_Enable && Serial_Write_Time > SERIAL_TIME_BASE)
                {
                      static u8 Serial_Fault_Counter = 0;    /* 故障计数器 */

                      Serial_Write_Time = 0; /* 清除发送间隔时间 */
                      if (Serial_Write_Task (Serial_Write_Data))
                      {
                                Write_Enable = 0; /* 操作成功,失能写操作 */
                             Serial_Fault_Counter = 0; /* 执行成功清故障计数器 */
                      }
                      else
                      {
                              Serial_Fault_Counter++;  /* 发送失败则标记 */
                            if (Serial_Fault_Counter > 10)
                            {
                                    Serial_Fault_Counter = 0;
                                    Write_Enable = 0 ;
                                    Serial_Write_Data = 0;/* 超过指定次数则销毁待发数据 */
                            }        
                      }   
                      Serial_Free_IO(); /* 执行完读写操作则释放总线 */                  
                }            
        }
        else
        {
                u8  data = 0, Type = 0;

                if (Serial_Read_Task (&data, &Type))
                {
                     Serial_Read_Data = data;
                     Serial_Read_Data_Type = Type;

                }
                Serial_Free_IO(); /* 执行完读写操作则释放总线 */  
        }
        
   
}
 

u8 Serial_Write_Task (u16 Data)
{

         if (Serial_Write_ASK ())
         {
                 /* 握手成功 */
                  SERIAL_SCL_OUT();
                if ( Serial_Write (Data) )
                    return 1;
         }
         return 0;         
}
/*
* 函数功能:读数据
*
* 参数:     data: 成功读操作后保存有效数据
*             Type: 读到的数据类型
*
* 备注:
*
*/
u8 Serial_Read_Task (u8 * pData, u8 * pType)
{
         u8 Type = 0;
         u8 Valid_Data = 0;
         u16 Pack_Data = 0;

         if ( Serial_Read_ASK () ) /* 读起始信号 */
         if ( Serial_Read (&Pack_Data) )  /* 读数据 */
         if ( Serial_UnlockCode (Pack_Data, &Valid_Data, &Type) )  /* 解码 */
         {
             *pData = Valid_Data;     /*  数据有效*/
             *pType = Type;
             Serial_Write_ACK(); /* 发送应答信号 */
             return 1; /*读操作成功 */
         }
         return 0; /* 读操作失败 */
}


/*
* 函数功能:初始化串行通信管脚
*
*
* 备注:
*
*/
void Serial_Init (void)
{
        RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOB, ENABLE);
        SERIAL_SCL_IN();  /* 输入上拉 */
        SERIAL_SCL_IN();  /* 输入上拉 */
}


/*
* 函数功能:释放通信管脚
*
*
* 备注:    管脚属性为输入上拉
*
*/
void Serial_Free_IO(void)
{
      SERIAL_SDA_IN();
      SERIAL_SCL_IN();
}

/*
* 函数功能:通信写握手操作
*
* 返回: 1:成功 0:失败
*
*
*/
u8 Serial_Write_ASK (void)
{
      SERIAL_SDA_OUT();
      SERIAL_SDA_L;
      delay_us(SERIAL_TIME);
      if (!READ_SERIAL_SCL)
      {
            SERIAL_SDA_H;
            delay_us(SERIAL_TIME);
            if (READ_SERIAL_SCL)
                  return 1;
      }
      return 0;
}


/*
* 函数功能:写数据操作
*
* 返回:     1:成功 0:失败
*
* 备注:
*/
u8 Serial_Write(u16 Data)
{
      u16 i;
      
      for (i = 0; i < 16; i++)
      {
            SERIAL_SCL_L;
            if ( Data & 0x8000)
                SERIAL_SDA_H;
            else
                SERIAL_SDA_L;
            Data <<= 1;
            delay_us(SERIAL_TIME);
            SERIAL_SCL_H;
            delay_us(SERIAL_TIME);           
      }
      Serial_Free_IO();

      return Serial_Read_ACK();
}


/*
* 函数功能:读ACK信号
*
* 返回:     1:应答成功 0:应答失败
*
* 备注:
*/
u8 Serial_Read_ACK(void)
{
      u16 i = 1800;

      while ( i-- )
      {
              delay_us (1);
            if (!READ_SERIAL_SCL)
                return 1; /* 收到对方应答发送成功 */                        
      }
      return 0;
}

/*
* 函数功能:通信读握手操作
*
* 返回: 1:成功 0:失败
*
*
*/
u8 Serial_Read_ASK(void)
{
    if ( !READ_SERIAL_SDA )
    {
        SERIAL_SCL_OUT();
        SERIAL_SCL_L;
        delay_us(SERIAL_TIME);
        if (READ_SERIAL_SDA) /* 等待释放总线命令 */
        {
            SERIAL_SCL_IN(); /* 释放总线 */
            delay_us(SERIAL_TIME); /* 间隔530us准备读取数据 */
            return 1;        
        }
                    
    }
    return 0;
}


 /*
* 函数功能:写ACK信号
*
* 返回:
*
*
*/
void Serial_Write_ACK(void)
{
        SERIAL_SCL_OUT();
        SERIAL_SCL_L;
        delay_us(SERIAL_TIME);        
}

/*
* 函数功能:读数据操作
*
* 返回:     1:完整数据 0:残缺数据
*
*
*/
u8 Serial_Read(u16 *pData)      
{
    u8 Out_Timer = 0;

    while (1)
    {
         /* 从释放总线到 接收第一个数据此时间隔530us */
         if ( !READ_SERIAL_SCL)
         {
HI:
                 delay_us(SERIAL_TIME);
                if (READ_SERIAL_SCL)
                {
                        Out_Timer = 0;
                        *pData <<= 1;
                        if (READ_SERIAL_SDA)
                            *pData |= 0x0001;
                        delay_us(SERIAL_TIME);   
                }
                else
                {
                        /* 低电平超时 */
                        Out_Timer++;
                        if (Out_Timer > 1)
                          return 0;
                        goto HI;
                }
         }
         else
         {
            Out_Timer++;
            if (Out_Timer > 1)
               return 1;      /*  高电平持续超过1ms,接收完成。*/
            delay_us(SERIAL_TIME);
         }
    }
}
 

/*
* 函数功能:对待发数据编码
*
* 参数         Type: 数据类型, 为0表示正常数据 为其他值表示保留数据。
*            Data: 待编码数据。
*
* 返回:    编码后的待发数据
*
*/
u16 Serial_Coding(u8 Type, u8 Data)
{
        u8 Data_Tmp;
        static u8 Serial_Number = 0; //流水号

    /*组装类别状态字,各位属性如下:
         bit<7,6> = 00 - 正常         
         bit.1 - 隐蔽报警
         bit.0 - 流水号(每次发送变化一次)
    */
           Type <<= 6;  
        Type |= !Serial_Number;        
   
   /*组装信号/校验和字节:信号/校验和字的字宽为一个字节,它其实是将待发数据编码,保证接收方能验证数据的完整性。假设TYPE是类别状态字、DATA是有效数据(低四位有效)、WORK是信号/校验和字节,则分以下步骤完成编码:
         1、Data_Tmp =  Data。            
         2、取Type 高低位交换值     
         3、DATA  =  DATA  +  TYPE  + (TYPE高低位交换的值)。     
         4、将WORK舍弃高四位,低四位移到高四位。将DATA 的低四位按照降序存入到 WORK的低四位。比如 原先 DATA的BIT3 最后位于WORK的BIT0。
   */
         Data_Tmp = Data;
   
         Data += Type + SWAP(Type);
         
         Data_Tmp <<= 4;
         Data_Tmp |= (Data & 0x01) << 3 | (Data & 0x02) << 1 | (Data & 0x04) >> 1 | (Data & 0x08) >> 3;

          return 256 * Type + Data_Tmp;
}

 
/*
* 函数功能:解码读到的数据
*
* 参数         Input_Data: 读到的数据
*            pData:解码后的数据
*            pType: 解码后的数据类型(警情或者拨码盘编码)
*
* 备注:
*/
u8  Serial_UnlockCode (u16 Input_Data, u8 *pData, u8 * pType)
{
      
           u8 Data_H = 0;
        u8 Data_L = 0;
        u8 Data_L_Tmp = 0;

        /* 分离高低字节 */
        Data_L = Input_Data & 0x00ff;
        Data_H = Input_Data >> 8;
        /* 备份低字节数据 */
        Data_L_Tmp = Data_L;
        /*
           Data_L = Data_L高低位交换值 + Data_H高低位交换值 + ata_H
        */
         Data_L =  SWAP(Data_L) + SWAP(Data_H) + Data_H;
        /*
        *  Data_L_Tmp 低四位升序移入 Data_L的低四位 比如Data_L_Tmp的bit0 移到Data_L的bit3
        */
        Data_L <<= 4;
         Data_L |= (Data_L_Tmp & 0x01) << 3 | (Data_L_Tmp & 0x02) \
                << 1 | (Data_L_Tmp & 0x04) >> 1 | (Data_L_Tmp & 0x08) >> 3;

        /* 校验数据 */
        if ( SWAP(Data_L) == Data_L )
        {
                *pData = Data_L_Tmp >> 4;
                *pType = Data_H & 0xc0;    /*[类别]:00 - 正常,01 - 保留,10 - 拨号手柄,11 - 车载手柄 */
                  return 1;
        }
        return 0;
}




搜索更多相关主题的帖子: include 翻译 源代码 
2013-01-19 16:39
w527705090
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:11
帖 子:441
专家分:1882
注 册:2011-6-28
收藏
得分:0 
你大功告成啊

有心者,千方百计;无心者,千难万难。
2013-01-19 18:08
快速回复:将汇编翻译成C了, 累死了。。。
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.012596 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved