查看: 8787|回复: 11

[其他] IAR全速运行和单步调试的结果不同怎么办?

[复制链接]

该用户从未签到

29

主题

104

帖子

0

中级会员

Rank: 3Rank: 3

积分
355
最后登录
2019-1-28
发表于 2016-6-17 16:11:39 | 显示全部楼层 |阅读模式
大家好,我现在在调试程序时发现如下现象,在使用IAR+j-link进行单步程序调试时,串口输出的数据正常,如下所示
单步调试结果.png
但是,我把程序全速运行后,输出的却是如下结果
全速运行结果.png
对比两个结果,在程序全速运行时,少输出了(31 01 31 01)四个字节,不知道可能是什么原因导致的,还请各位指点一下。
我知道答案 目前已有11人回答
回复

使用道具 举报

该用户从未签到

712

主题

6371

帖子

0

超级版主

Rank: 8Rank: 8

积分
24901
最后登录
2025-7-21
发表于 2016-6-17 16:19:17 | 显示全部楼层
发送这段数据的代码贴点出来看看。
你把每个字节发送之间加点延时,然后再全速测看看。
回复 支持 反对

使用道具 举报

  • TA的每日心情

    2016-10-20 09:45
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    80

    主题

    1038

    帖子

    5

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    2223
    最后登录
    2023-11-20
    发表于 2016-6-17 16:28:59 | 显示全部楼层
    判断发送完成后再发送下一帧
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    29

    主题

    104

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    355
    最后登录
    2019-1-28
     楼主| 发表于 2016-6-17 16:31:43 | 显示全部楼层
    小恩GG 发表于 2016-6-17 16:19
    发送这段数据的代码贴点出来看看。
    你把每个字节发送之间加点延时,然后再全速测看看。 ...

    这是代码,我写的有些乱,您多指点。//地址及命令打包函数
    uint8 *Instruction_Package(uint8 i)
    {
              uint8 Current_Sdmu_Num;
            Current_Sdmu_Num=i;
            Command_Pack[0]=0x30|bms;
            Command_Pack[1]=Current_Sdmu_Num;
            return Command_Pack;
    }
    //超时处理函数
    void Timer_Out_Handle()
    {
            Overtime_Flag=1;                     //超时处理标志位置位
            Overtime_Counter++;                  //串口超时计数器加一
            if(Overtime_Counter<TIME_OUT)       //判断超时处理次数是否达到上限
            {
                    index=0;
            }
            else
            {
                    Connection_Exception=1;     //连接异常标志位置位
            }       
    }

    //数据读取函数

    void Read_Sdmu(void)
    {
            uint8 i;
            uint8 j;
            uint8 k,l;
            uint8 *command=NULL;
            uint8 Overtime_2=0;        //表示第二种情况的超时
            uint8 Read_Bms_Success=0;  //一帧数据读取成功
           
            for(i=1;i<=Sdmu_Num;i++)
            {
                      Overtime_2=0;
                    for(bms=1;bms<5;bms++)
                    {
                            if(Overtime_2)
                            {
                                    break;
                            }
                              Read_Bms_Success=0;
                              RS485_SEND;                             //rs485切换为发送状态
                            DrvUART_SendNBytes(UART1, Start_Bit, 1);//发送一字节起始位
                            delay_1ms(1);                           //延时1ms,等待数据发送完成
                            while(!Send_Flag);                      //等待发送完成标志位置1
                            Send_Flag=0;                            //发送完成标志位清零
                            RS485_RECEIVE;                          //rs485切换为接收状态
                            Receive_State_Flag=1;                   //接收状态标志位,表示此时接收到的为响应码
                            Timer_Counter=10000;                                    
                              if(Overtime_Counter<TIME_OUT)
                            {
                                    while(1)
                                    {
                                            if(Read_Bms_Success)
                                            {
                                                    break;
                                            }
                                            else if(!Timer_Counter)                 //如果发生超时,则进行超时处理
                                            {
                                                    Timer_Out_Handle();            //调用超时处理函数
                                                    if(Overtime_Counter<TIME_OUT)
                                                    {
                                                            bms--;
                                                    }
                                                    break;//跳出超时循环,重发起始码
                                            }
                                            else if((index==1)|(index==Data_Num))
                                            {
                                            if((Receive_State_Flag==1)&(Data_Cache[0]==0x56))
                                            {
                                                    index=0;              //数据缓存数组元素个数计数器清零
                                                    Overtime_Flag=0;      //超时标志位清零
                                                    Data_Cache[0]=0x00;   //缓存数组清零
                                                    Receive_State_Flag=0; //数据接收状态标志清零
                                                   
                                                    RS485_SEND;                             //rs485切换为发送状态
                                                    command = Instruction_Package(i);       //调用命令和地址打包函数
                                                    DrvUART_SendNBytes(UART1,command, 2);   //发送命令码和地址码
                                                    delay_1ms(1);                           //延时1ms,等待数据发送完成
                                                    while(!Send_Flag);                      //等待发送完成标志位置1
                                                    Send_Flag=0;                            //发送完成标志位清零
                                                    RS485_RECEIVE;                          //rs485切换为接收状态
                                                    Receive_State_Flag=2;                   //接收状态标志位,表示此时接收到的为数据帧
                                                    Timer_Counter=10000;                    //给定时计数器赋值,设置超时时间
                                                    if(Overtime_Counter<2)
                                                    {
                                                            while(1)
                                                            {
                                                                    if(!Timer_Counter)                 //如果发生超时,则进行超时处理
                                                                    {
                                                                            Timer_Out_Handle();            //调用超时处理函数
                                                                            index=1;
                                                                            Data_Cache[0]=0x56;
                                                                            Receive_State_Flag=1;
                                                                            break;//此处应跳转到发送指令和地址的函数部分
                                                                    }
                                                                    else if((index==1)|(index==Data_Num))
                                                                    {
                                                                    if((Receive_State_Flag==2)&(index==Data_Num))
                                                                    {
                                                                            index=0;              //数据缓存数组元素个数计数器清零
                                                                            Overtime_Flag=0;      //超时标志位清零
                                                                            Overtime_Counter=0;   //超时计数器清零
                                                                            Receive_State_Flag=0; //数据接收状态标志清零
                                                                           
                                                                            RS485_SEND;                             //rs485切换为发送状态
                                                                            DrvUART_SendNBytes(UART1, End_Bit, 1);  //发送一字节结束码
                                                                            delay_1ms(1);                           //延时1ms,等待数据发送完成
                                                                            while(!Send_Flag);                      //等待发送标志位置1
                                                                            Send_Flag=0;                            //发送标志位清零
                                                                            Crc_Result=CRC_Cal_16(0xffff,Data_Cache,Data_Num);//调用CRC校验函数进行CRC硬件校验
                                                                            if(Crc_Error_Counter<CHECK_ERROR)
                                                                            {
                                                                                    if(Crc_Result==0)
                                                                                    {
                                                                                            k=bms;
                                                                                            l=i;
                                                                                            l=4*(l-1)+k-1;
                                                                                            Sdmu_Bms[l][0]=(i<<4)|bms;
                                                                                            for(j=0;j<Data_Num;j++)
                                                                                            {
                                                                                                    Sdmu_Bms[l][j]=Data_Cache[j];
                                                                                                    printf("%2x ",Sdmu_Bms[l][j]);
                                                                                            }
                                                                                            Read_Bms_Success=1;//bms数据读取成功标志位置一
                                                                                            break;//跳转到bms循环层,读取下一路bms的数据
                                                                                    }
                                                                                    else
                                                                                    {
                                                                                      Crc_Failed_Handle(); //调用CRC校验错误处理函数
                                                                                      index=1;             //缓存数组元素个数计数器变量置一
                                                                                      Data_Cache[0]=0x56;  //缓存数组第一个元素值设为0x56
                                                                                      Receive_State_Flag=1;//接收状态标志位置一
                                                                                      break;              //如果校验错误,应跳转到重发地址和指令的函数,重新进行该路bms数据的读取
                                                                                    }

                                                                            }
                                                                            else
                                                                            {
                                                                                    index=1;             //缓存数组元素个数计数器变量置一
                                                                                    Crc_Error_Flag=0;    //CRC校验错误标志位清零
                                                                                    Data_Cache[0]=0x56; //缓存数组第一个元素值设为0x56
                                                                                    Crc_Error_Counter=0; //CRC校验计数器清零
                                                                                    Receive_State_Flag=1;//接收状态标志位置一
                                                                                break;//如果校验失败次数超过三次,则跳转到bms循环层,读取下一路bms的数据
                                                                                   
                                                                            }
                                                                    }
                                                                    }
                                                            }
                                                    }
                                                    else
                                                    {
                                                              Overtime_2=1;
                                                            Overtime_Counter=0;  //超时计数器清零
                                                            Overtime_Flag=0;    //超时标志位置零
                                                            break;              //跳出超时判断的循环体,进入bms循环体                                               
                                                    }
                                            }
                                            }
                                    }
                            }
                            else
                            {
                                    Overtime_Counter=0;  //超时计数器清零
                                    Overtime_Flag=0;    //超时标志位置零
                                    break;              //跳出bms的循环体,进入SDMU循环体
                            }
                    }
            }
    }



    回复 支持 反对

    使用道具 举报

    该用户从未签到

    29

    主题

    104

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    355
    最后登录
    2019-1-28
     楼主| 发表于 2016-6-17 16:33:47 | 显示全部楼层
    花溪村长 发表于 2016-6-17 16:28
    判断发送完成后再发送下一帧

    恩,我是这样判断的,但还是不行,程序我已经贴出来了,您方便的话就帮忙看下吧,多谢!
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    29

    主题

    104

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    355
    最后登录
    2019-1-28
     楼主| 发表于 2016-6-17 16:44:47 | 显示全部楼层
    天天都有好心情 发表于 2016-6-17 16:31
    这是代码,我写的有些乱,您多指点。//地址及命令打包函数
    uint8 *Instruction_Package(uint8 i)
    {

    这是自定义的RS-485协议
    协议.png
    绿色部分为上位机向下位机传输的,灰色部分为下位机向上位机传输的
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    2

    主题

    57

    帖子

    0

    注册会员

    Rank: 2

    积分
    197
    最后登录
    2020-7-14
    发表于 2016-6-17 21:10:14 | 显示全部楼层
    DrvUART_SendNBytes这个函数的代码呢
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    29

    主题

    104

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    355
    最后登录
    2019-1-28
     楼主| 发表于 2016-6-18 08:46:30 | 显示全部楼层
    yu0405jie 发表于 2016-6-17 21:10
    DrvUART_SendNBytes这个函数的代码呢

    这是串口发送函数的代码:
    void DrvUART_SendNBytes(UART_MemMapPtr uartch, uint8 *buffer, uint32 N)
    {
        uint32 i;
           
        for(i = 0;i < N; i++)
        {
            DrvUART_SendOneByte(uartch, buffer);                 //发送一字节数据
                if(i==N-1)
                    {
                            Send_Flag=1;
                    }               
            }
    }
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    29

    主题

    104

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    355
    最后登录
    2019-1-28
     楼主| 发表于 2016-6-18 08:58:16 | 显示全部楼层
    天天都有好心情 发表于 2016-6-18 08:46
    这是串口发送函数的代码:
    void DrvUART_SendNBytes(UART_MemMapPtr uartch, uint8 *buffer, uint32 N)
    { ...

    这是单字节发送的代码
    void DrvUART_SendOneByte(UART_MemMapPtr uartch, uint8 buffer)
    {
        while(!(UART_S1_REG(uartch) & UART_S1_TDRE_MASK));            //等待发送缓冲区空
       
        UART_D_REG(uartch) = (uint8)buffer;                             //向数据寄存器中写入发送的数据
    }
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    712

    主题

    6371

    帖子

    0

    超级版主

    Rank: 8Rank: 8

    积分
    24901
    最后登录
    2025-7-21
    发表于 2016-6-20 09:34:47 | 显示全部楼层
    天天都有好心情 发表于 2016-6-17 16:44
    这是自定义的RS-485协议

    绿色部分为上位机向下位机传输的,灰色部分为下位机向上位机传输的

    楼主,那么你一楼贴出来的测试数据,分别是什么意思?
    是MCU到上位机机的吗?
    0X55, 0X31, 0X01
    你可以先单独测试下发送多个字节和单个字节,然后接受之后,再发送。保证这个流程没有问题。
    如果基本的发送多字节,单字节,接受多字节,单字节,互相切换都没问题。
    那么你现在的问题应该就是你帧结构规定代码的问题了。
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-22 12:08 , Processed in 0.113759 second(s), 31 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表