找回密码
 立即注册
查看: 2617|回复: 42

发现一个bug不知道是单片机还是Keil的问题 | 是细节问题,大家必须看下,原子操作

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:395
  • 最近打卡:2025-05-02 05:31:55

16

主题

702

回帖

2474

积分

金牌会员

积分
2474
发表于 2024-11-20 11:28:25 | 显示全部楼层 |阅读模式
发现一个bug,不知道是单片机的问题还是Keil的问题,程序中只有1个定时器中断程序 截图202411201124364738.jpg 截图202411201105437248.jpg
截图202411201126344592.jpg
截图202411201128147516.jpg

本帖被以下淘专辑推荐:

回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:123
  • 最近打卡:2025-04-19 16:12:35
已绑定手机

60

主题

777

回帖

4001

积分

论坛元老

自定义头衔

积分
4001
发表于 2024-11-20 13:30:16 来自手机 | 显示全部楼层
bkeuqoaq 发表于 2024-11-20 13:11
void main(void)
{
        P_SW2 |= 0x80;

我虽然没点开楼主的程序,但是结合他的截图,和你的修改,我就知道问题出在哪里了

{:5_278:}

51单片机是8位机,
因此对16位和32位C语言变量的读写并不是原子操作,需要逐个字节提取。

如果在16位数据的读取过程(包含若干条指令),进了中断导致数据变化,
那么将会错误地读到来自不同时刻的高低字节。

比如举个例子,当变量值为511时

高字节为1,低字节为255

此时main函数打算调取这个数据

先调取了低字节 255

突然进了中断,中断对这个变量进行了自增,变为512,也就是
高字节为2,低字节为0

回到main函数

main函数继续调取高字节,读到2

main函数中拼凑得到的高低字节分别为2和255,拼凑也就是767。

已经既不等于511,也不等于512!!!

大相径庭。所以进行16位,32位的volatile变量访问时,一定要关闭中断!确保访问操作的原子性

{:5_361:}

联系我请点击左下角的【回复】按钮,否则我收不到消息提
回复 支持 1 反对 0

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:395
  • 最近打卡:2025-05-02 05:31:55

16

主题

702

回帖

2474

积分

金牌会员

积分
2474
发表于 2024-11-20 11:29:37 | 显示全部楼层
单片机用的是STC8H4K64TL,STC8H1K28我也试了,也是这种情况
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:395
  • 最近打卡:2025-05-02 05:31:55

16

主题

702

回帖

2474

积分

金牌会员

积分
2474
发表于 2024-11-20 11:30:40 | 显示全部楼层
Keil版本我也试了,9.60,  9.06, 9.53这些版本也是同样的问题
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:395
  • 最近打卡:2025-05-02 05:31:55

16

主题

702

回帖

2474

积分

金牌会员

积分
2474
发表于 2024-11-20 11:31:36 | 显示全部楼层
硬件仿真和直接烧录程序,结果都是一样的,直接烧录程序,是通过P3.4的波形看的
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:395
  • 最近打卡:2025-05-02 05:31:55

16

主题

702

回帖

2474

积分

金牌会员

积分
2474
发表于 2024-11-20 11:33:29 | 显示全部楼层
这是项目文件,官方可以测试一下

STC8H4K32TL.rar

54.09 KB, 下载次数: 47

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:395
  • 最近打卡:2025-05-02 05:31:55

16

主题

702

回帖

2474

积分

金牌会员

积分
2474
发表于 2024-11-20 11:38:00 | 显示全部楼层
STC8H8K64U也是同样的问题
截图202411201137254883.jpg
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:156
  • 最近打卡:2025-04-29 00:51:09

24

主题

229

回帖

1281

积分

金牌会员

积分
1281
发表于 2024-11-20 11:54:30 | 显示全部楼层
编译器问题
不要声明时就赋值
初始化时赋值
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:395
  • 最近打卡:2025-05-02 05:31:55

16

主题

702

回帖

2474

积分

金牌会员

积分
2474
发表于 2024-11-20 12:21:02 | 显示全部楼层
CyberH*** 发表于 2024-11-20 11:54
编译器问题
不要声明时就赋值
初始化时赋值

多谢指点,我试一下看看
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-02 07:55:56
已绑定手机

19

主题

3190

回帖

4870

积分

论坛元老

积分
4870
发表于 2024-11-20 12:25:16 来自手机 | 显示全部楼层
CyberHamster 发表于 2024-11-20 11:54
编译器问题
不要声明时就赋值
初始化时赋值

keil还有这种问题啊。声明时不能赋值!
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:395
  • 最近打卡:2025-05-02 05:31:55

16

主题

702

回帖

2474

积分

金牌会员

积分
2474
发表于 2024-11-20 12:25:24 | 显示全部楼层
变量定义时不赋初值,在主程序中赋值,结果就正常了,再请问一下,局部变量也是这样吗?

点评

请问是中断的问题,那这里在变量定义时赋值又是什么问题?  详情 回复 发表于 2024-11-25 10:11
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 08:59 , Processed in 0.136408 second(s), 118 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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