求助一个avr单片机短时间正常长时间运行会跑飞的问题

palleexu 2018-08-28 07:34:36
求助一个AVR单片机的问题,用的是atmega128a,开发平台avrstudio 4.17,编译用的是winavr2009。
项目的内容比较简单,当判断到外来的一个开关量指令时,通过IO口发指令驱动三位四通阀,启动液压系统驱动负载到规定的目标位置,具体的逻辑是:先下行到最低位置0,再上行到目标位置(1或2或3,等等),到达目标位置后停止。在上行和下行过程中通过霍尔传感器判断当前所处的位置,整个运行过程要求在4s内完成。
目前遇到的问题是:接到指令后下行正常,就是在上行过程中有时会出现停不住的情形,就是说应该到位置1的,结果超过了位置1,甚至到了位置2/3后仍然停不住,上行的指令仍然在发送,但这个过程中位置1、位置2、位置3等信号是能够正常读到并显示的,只不过没有进到if语句中,约莫20次会出现1次这样的故障。出现这种故障情形的时候,都是运行过程太长在3.5s以上(大概这个数),如果短时间之内能够完成该次运行的话,试过200次以上都没有问题,考虑运行时间太长和代码有什么关系?或者是编译的问题?
通过挂示波器发现软件是跑回到主程序中了,问题是为什么长时间运行会跑走?如果超过4s应该会报故障的,实际上没有到目标位置一直上行,肯定是超过4s的时间了。
请各位帮忙看一下代码有什么可能的隐患。
代码如下
while(t0 <= 2000)
{
DownBegin;//下行
if(IsPosRefresh == 1){PosRefresh();IsPosRefresh =0;wdt_reset();}//50ms调用1次位置刷新子程序并喂狗

if (PosFilter == 0x01)//0档有效
{
delay_ms(2);DownEnd;DownEnd;DownEnd;//停止调节
//这段是为了人工造成运行时间长故意加上的
t01 = t0;
while(t0 < (t01+1300))
{
if(IsPosRefresh == 1){PosRefresh();IsPosRefresh =0;wdt_reset();}
}
//实际的延时只有200ms,利用定时器0中断,2ms中断一次是2.6s
while(t0 <= 2000)//不论现在t0为多少,继续计时,看剩下的时间内能否上行到目标挡位
{
UpBegin;//上行
if(IsPosRefresh == 1){PosRefresh();IsPosRefresh =0;wdt_reset();}//50ms调用1次工位刷新子程序并喂狗
if(PosFilter == 0x02)//到目标挡位,信号的窗口期200ms,上面两行代码的实际影响的时间在10ms以下,应该不会错过
{
delay_ms(2);
UpEnd;UpEnd;UpEnd;//停止上行,连续发3次
//正常情况下,4s内能完成的话应该停止,下面还有若干代码,但实际故障的时候停不住
break;
}
else//如果上行还未到目标,继续上行的while循环
{

}
}
break;
}
else//下行未到0
{

}
}
if(t0 >= 2000)//如果超出4s就报故障,同时停止上行和下行。
{
UpEnd;DownEnd;
}
...全文
483 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
Y_T_CH 2018-11-07
  • 打赏
  • 举报
回复
请教一下,你这个问题解决了么?我现在也是一样的问题,一直复位。
void SPI_Flash_Read(uint8_t* pBuffer,uint32_t ReadAddr,uint16_t NumByteToRead)
{
uint16_t i;
SPI_FLASH_CS0;
TX1_String("*********************************\r\n");
SPI2_ReadWriteByte(W25X_ReadData);
SPI2_ReadWriteByte((uint8_t)((ReadAddr)>>16));
SPI2_ReadWriteByte((uint8_t)((ReadAddr)>>8));
SPI2_ReadWriteByte((uint8_t)ReadAddr);

for(i=0;i<NumByteToRead;i++)
{
pBuffer[i]=SPI2_ReadWriteByte(0XFF);
}
SPI_FLASH_CS1;
TX1_String("-----------------------------------\r\n");
}


我是这段函数执行完之后立刻复位,函数后面的一句程序也不执行。
palleexu 2018-10-12
  • 打赏
  • 举报
回复
不好意思结贴晚了,感谢各位回复。
yishumei 2018-09-21
  • 打赏
  • 举报
回复
引用 15 楼 PALLEE 的回复:
[quote=引用 13 楼 一树梅的回复:]UpEnd和DownEnd一起动作会不会使液压系统重新上行?
谢谢,这是给电磁阀断电,应该不会导致液压系统问题。[/quote] 楼主,代码的逻辑没有问题。我认为在超4s之后,程序没有有效关断控制液压系统上行的电磁阀。您可以在这方面查一下,供参考。 if(t0 >= 2000)//如果超出4s就报故障,同时停止上行和下行。 { UpEnd;DownEnd; } 改为 if(t0 >= 2000)//如果超出4s就报故障,同时停止上行和下行。 { UpEnd;UpEnd;UpEnd;DownEnd;DownEnd;DownEnd; }
依然冷暖 2018-09-20
  • 打赏
  • 举报
回复
纵观楼主的回复 大概意思就是 回答问题的人太菜了 你们想到的我都想到了 能不能来个厉害的
palleexu 2018-09-18
  • 打赏
  • 举报
回复
引用 12 楼 笨狗先飞的回复:
PosFilter == 0x02 是一种强表达形式,
分析一下PosFilter的取得方法,中断,通讯还是什么,会不会变量本身存在不稳定因素?
谢谢,这个变量是在一个定时中断中采集信号,连续采到四次才进行变量的赋值。通过在线调试观察,能够有效赋值,而且其他用到这个变量的地方工作正常,可能不是它的原因。
palleexu 2018-09-18
  • 打赏
  • 举报
回复
引用 14 楼 Haiguozhe的回复:
你把看门狗关了,我看着想看门狗复位
谢谢,关过看门狗,也还会出现。
palleexu 2018-09-18
  • 打赏
  • 举报
回复
引用 13 楼 一树梅的回复:
UpEnd和DownEnd一起动作会不会使液压系统重新上行?
谢谢,这是给电磁阀断电,应该不会导致液压系统问题。
Haiguozhe 2018-09-15
  • 打赏
  • 举报
回复
你把看门狗关了,我看着想看门狗复位
yishumei 2018-09-13
  • 打赏
  • 举报
回复
UpEnd和DownEnd一起动作会不会使液压系统重新上行?
笨狗先飞 2018-08-31
  • 打赏
  • 举报
回复
PosFilter == 0x02 是一种强表达形式,
分析一下PosFilter的取得方法,中断,通讯还是什么,会不会变量本身存在不稳定因素?
palleexu 2018-08-31
  • 打赏
  • 举报
回复
引用 10 楼 worldy的回复:
你的代码没有完整,无法看出你的思路,初看感觉似乎逻辑有点不是很清楚

比如
if(t0>=...)
{
。。。。。。。。//A
}
后面又
if(t0<=...)
{
。。。。。。。//B
}

=的情况,要么前面前面成立,要么后面成立,否则,真等于的时候,你的代码A和B都被执行,这是你想要的吗
感谢回复,后面的if是为了调节过程中如果液压出现故障等原因时可能导致调节超时,这个时候会提示故障用的
palleexu 2018-08-30
  • 打赏
  • 举报
回复
感谢楼上回复,①确实是 if(PosFilter == 0x02) 没有触发,如果触发的话就会停止,但搞不懂为什么没有触发,通过过程信号监测是能够判读到这个位置的信号的②t0定义是uint,最大到65536,不会到负数。
我觉得主要和这部分代码的运行时间有关,实际是4s(即t0=2000)的时间,但如果把2000改为3000,即使中间仍然模拟停顿2.6s也没有出现过错误,但是,一旦正常的调节时间和设定的时间(这里是4s)相近,就容易出现问题,没搞明白为什么。
worldy 2018-08-30
  • 打赏
  • 举报
回复
从楼主的描述看,应该不是代码跑飞,
可能原因:
检测的信号是否正常 或者
代码逻辑有问题
worldy 2018-08-30
  • 打赏
  • 举报
回复
你的代码没有完整,无法看出你的思路,初看感觉似乎逻辑有点不是很清楚

比如
if(t0>=...)
{
。。。。。。。。//A
}
后面又
if(t0<=...)
{
。。。。。。。//B
}

=的情况,要么前面前面成立,要么后面成立,否则,真等于的时候,你的代码A和B都被执行,这是你想要的吗
palleexu 2018-08-30
  • 打赏
  • 举报
回复
引用 5 楼 worldy 的回复:
从楼主的描述看,应该不是代码跑飞,
可能原因:
检测的信号是否正常 或者
代码逻辑有问题

谢谢,检测的信号应该是正常的,位置信号持续时间较长,每个位置信号能够记录到80+次,现在想着就是代码逻辑肯定有问题,不知道在执行过程中就跑走了,但感觉逻辑应该很简单,不存在问题,主要是一旦正常的过程调节时间和限定时间(这里是4s)相近,就容易出现问题,没搞明白为什么。
实际调节过程只有不到2s,反复试了上千次都没问题,一旦故意在调节过程中延时,使总的调节时间和限定时间相近,如3.7s,3.8s的样子,接近4s,就很容易出问题。
palleexu 2018-08-30
  • 打赏
  • 举报
回复
引用 7 楼 cjn0916 的回复:
PosFilter 和 t0 是不是要增加volalite试试?

前面定义的时候已经加了,谢谢
cjn_xaut 2018-08-30
  • 打赏
  • 举报
回复
PosFilter 和 t0 是不是要增加volalite试试?
palleexu 2018-08-29
  • 打赏
  • 举报
回复
感谢楼上回复。 这个是笔误,前面的while里面是小于,没有等于。 但即使如此,和故障现象是不是也没什么关系?
D_dx1 2018-08-29
  • 打赏
  • 举报
回复
while(t0 <= 2000),if(t0 >= 2000)?那t0 == 2000的时候2个都执行一遍?
笨狗先飞 2018-08-29
  • 打赏
  • 举报
回复
如果说上行已经开始,但是没有停下来,
那很有可能是 if(PosFilter == 0x02) 这个条件没有触发,
检查 PosFilter 变量的情况,
其次,确认 t0会不会因为过大,变成负数了?
加载更多回复(1)
第一章:AVR单片机C语言程序设计概述 1.1 AVR单片机简介 1.2 AVR Studio+WinAVR开发环境安装及应用 1.3 AVR-GCC程序设计基础 1.4 程序与数据内存访问 1.5 I/O端口编程 1.6 外设相关寄存器及应用 1.7 中断服务程序 1.8 GCC在AVR单片机应用系统开发中的优势 第二章:PROTEUS操作基础 2.1 PROTEUS操作界面简介 2.2 仿真电路原理图设计 2.3 元件选择 2.4 仿真运行 2.5 PROTEUS与AVR Studio的联合调试 2.6 PROTEUS在AVR单片机应用系统开发中的优势 第三章:基础程序设计 3.1 闪烁的LED 3.2 左右来回的流水灯 3.3 花样流水灯 3.4 LED模拟交通灯 3.5 单只数码管循环显示0~9 3.6 8只数码管滚动显示单个数字 3.7 8只数码管显示多个不同字符 3.8 K1~K4控制LED移位 3.9 数码管显示4×4键盘矩阵按键 3.10 数码管显示拨码开关编码 3.11 继电器控制照明设备 3.12 开关控制报警器 3.13 按键发音 3.14 INT0中断计数 3.15 INT0及INT1中断计数 3.16 TIMER0控制单只LED闪烁 3.17 TIMER0控制的流水灯 3.18 TIMER0控制数码管扫描显示 3.19 TIMER1控制交通指示灯 3.20 TIMER1与TIMER2控制十字路口秒计时显示屏 3.21 用工作于计数方式的T/C0实现100以内的按键计数 3.22 用定时器设计的门铃 3.23 报警器与旋转灯 3.24 100000秒以内的计时程序 3.25 用TIMER1输入捕获功能设计的频率计 3.26 用工作于异步模式的T/C2控制的可调式数码管电子钟 3.27 TIMER1定时器比较匹配中断控制音阶播放 3.28 用TIMER1输出比较功能调节频率输出 3.29 TIMER1控制的PWM脉宽调制器 3.30 数码管显示两路A/D转换结果 3.31 模拟比较器测试 3.32 EEPROM读写与数码管显示 3.33 Flash程序空间中的数据访问 3.34 单片机与PC机双向串口通讯仿真 3.35 看门狗应用 第四章:硬件应用 4.1 74HC138与74HC154译码器应用 4.2 74HC595串入并出芯片应用 4.3 用74LS148与74LS21扩展中断 4.4 62256扩展内存 4.5 用8255实现接口扩展 4.6 可编程接口芯片8155应用 4.7 可编程外围定时计数器8253应用 4.8 数码管BCD解码驱动器7447与4511应用 4.9 8×8LED点阵屏显示数字 4.10 8位数码管段位复用串行驱动芯片MAX6951应用 4.11串行共阴显示驱动器MAX7219与7221应用 4.12 16段数码管演示 4.13 16键解码芯片74C922应用 4.14 1602字符液晶测试程序 4.15 1602液晶显示DS1302实时时钟 4.16 1602液晶工作于四位模式实时显示当前时间 4.17 2×20串行字符液晶演示 4.18 LGM12864液晶显示程序 4.19 PG160128A液晶图文演示 4.21 TG126410液晶串行模式演示 4.21 用带SPI接口的MCP23S17扩展16位通用IO端口 4.22 用TWI接口控制MAX6953驱动4片5×7点阵显示器 4.23 用TWI接口控制MAX6955驱动16段数码管显示 4.24 用DAC0832生成多种波形 4.25 用带SPI接口的数模转换芯片MAX515调节LED亮度 4.26 正反转可控的直流电机 4.27正反转可控的步进电机 4.28 DS18B20温度传感器测试 4.29 SPI接口温度传感器TC72应用测试 4.30 SHT75温湿度传感器应用 4.31 用SPI接口读写AT25F1024 4.32 用TWI接口读写24C04 4.33 MPX4250压力传感器测试 4.34 MMC存储卡测试 4.35 红外遥控发射与解码仿真 第五章:综合设计 5.1 多首电子音乐的选播 5.2 电子琴仿真 5.3 普通电话机拨号键盘应用 5.4 手机键盘仿真 5.5 数码管模拟显示乘法口诀 5.6 用DS1302与数码管设计的可调电子钟 5.7 用DS1302与LGM12864设计的可调式中文电子日历 5.8 用PG12864LCD设计的指针式电子钟 5.9 高仿真数码管电子钟 5.10 1602LCD显示的秒表 5.11 用DS18B20与MAX6951驱动数码管设计的温度报警器 5.12 用1602LCD与DS18B20设计的温度报警器 5.13 温控电机在L298驱动下改变速度与方向运行 5.14 PG160128中文显示日期时间及带刻度显示当前温度 5.15 液晶屏曲线显示两路模数转换结果 5.16 用74LS595与74LS154设计的16×16点阵屏 5.17 用8255与74LS154设计的16×16点阵屏 5.18 8×8LED点阵屏仿电梯数字滚动显示 5.19 用内置EEPROM与1602液晶设计的MD5加密电子密码锁 5.20 12864LCD显示24C08保存的开机画面 5.21 12864LCD显示EPROM27C256保存的开机画面 5.22 IIC-AT24C1024×2硬字库应用 5.23 SPI-AT25F2048硬件字库应用 5.24 带液晶显示的红外遥控调速仿真 5.25 能接收串口信息的带中英文硬字库的80×16点阵显示屏 5.26 用AVR与1601LCD设计的计算器 5.27 电子秤仿真设计 5.28 模拟射击训练游戏 5.29 PC机通过485远程控制单片机 5.30 用IE访问AVR+RTL8019设计的以太网应用系统

27,373

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧