找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 724|回复: 17
打印 上一主题 下一主题
收起左侧

C语言程序怎样知道另一变量加1并跟随加1

  [复制链接]
跳转到指定楼层
楼主
ID:965189 发表于 2025-5-8 12:33 来自手机 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
51单片机C程序,怎样知道另一个变量a在加一。如果a加1,b也加1。如果a停止加1,b也停止并退出。怎样写?
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:332444 发表于 2025-5-8 13:33 | 只看该作者
用状态,+1同时赋值状态,跟随后状态取消.
回复

使用道具 举报

板凳
ID:1121801 发表于 2025-5-8 13:43 | 只看该作者
定义变量x,x=a,然后在后面需要b+1的程序之前用a-x==1作为条件,再在b+1语句后加一条x=a,纳入a-x==1条件中.
回复

使用道具 举报

地板
ID:68189 发表于 2025-5-8 13:43 | 只看该作者
常规思维: 定时器中断函数中添加:   if(b!=a)  b=a;  这样变量b的值永远追随a  
回复

使用道具 举报

5#
ID:1109793 发表于 2025-5-8 14:36 | 只看该作者
在加一,说的是多久?
比如1秒,那么先TMP=A,每秒钟IF(A==TMP+1){B++;TMP = A;}ELSE IF(A==TMP)RETURN;
如果一秒内没变化或者加了大于1,就退出,退出就是啥也不做,意思就是B没有变化。
周期很重要,可以0.1秒,也能1天。
回复

使用道具 举报

6#
ID:583948 发表于 2025-5-8 15:04 | 只看该作者
volatile unsigned char a = 0; // 使用volatile防止优化
unsigned char b = 0;
unsigned char last_a = 0;

void main() {
    while(1) {
        if (a != last_a) { // 检测a是否变化
            b++; // 同步增加b
            last_a = a; // 更新旧值
        }
    }
}
回复

使用道具 举报

7#
ID:69038 发表于 2025-5-8 15:46 | 只看该作者
char A,B;
char OA;

  //外部引入
回复

使用道具 举报

8#
ID:69038 发表于 2025-5-8 15:49 | 只看该作者
if (OA !=A)
  {
    if (OA=A+1){OA=A;B++;}
    if(OA!=A+1){OA=A;}
}
回复

使用道具 举报

9#
ID:1130698 发表于 2025-5-8 21:06 | 只看该作者
你这个需求是怎么来的?不可以直接使用变量a吗?
回复

使用道具 举报

10#
ID:1149928 发表于 2025-5-8 21:25 | 只看该作者
C语言不太好做,要么利用中断检测,检测到a的值变化就触发一次中断然后b+1;要么使用轮询的方法,一直循环查询a是否加一。如果你是用FPGA就好办很多,将a作为always的边沿触发条件,里面b+1。
回复

使用道具 举报

11#
ID:1149962 发表于 2025-5-9 10:03 | 只看该作者
int a = 0; int a_pre = 0; int b;  void test() {     while(1)     {         if(a_pre != a)         {             break;         }         else             b++;         a_pre++;      // 定义一个变量和a同时自加         a++;          // 模拟a自加的操作,如果这里a不自加了,a_pre和a就不相等了。     }     return ; }
回复

使用道具 举报

12#
ID:965189 发表于 2025-5-12 22:09 | 只看该作者
多谢上面各位的回复和指导。还是用了原来:if(b!=a)b=a;之前使用达不到要求,是因为后续配套部分不合理,修改后达到了要求的效果。
回复

使用道具 举报

13#
ID:1109793 发表于 2025-5-13 08:40 | 只看该作者
君工创 发表于 2025-5-12 22:09
多谢上面各位的回复和指导。还是用了原来:if(b!=a)b=a;之前使用达不到要求,是因为后续配套部分不合理,修 ...

B==A,不用动
否则B=A,那不就是直接B=A就行了?
回复

使用道具 举报

14#
ID:1150350 发表于 2025-5-13 15:26 | 只看该作者
下面是一个 51 单片机 C 程序,它可以检测变量a是否在加 1,并相应地控制变量b的变化。程序通过定时器定期采样a的值,比较两次采样的结果来判断a是否在持续加 1。
#include <reg51.h>

// 定义全局变量
unsigned int a = 0;        // 被监测的变量
unsigned int b = 0;        // 跟随变化的变量
unsigned int a_prev = 0;   // 存储a的上一次采样值
bit a_increasing
= 0;      // 标记a是否在增加

// 定时器0初始化函数
void Timer0_Init() {
    TMOD
|= 0x01;          // 设置定时器0为模式1(16位定时器)
    TH0
= 0xFC;           // 定时初值设置,定时约1ms
    TL0
= 0x66;
    ET0
= 1;              // 使能定时器0中断
    EA
= 1;               // 开总中断
    TR0
= 1;              // 启动定时器0
}

// 定时器0中断服务函数
void Timer0_ISR() interrupt 1 {
    TH0
= 0xFC;           // 重新加载定时初值
    TL0
= 0x66;
   
    // 检测a是否增加
    if (a > a_prev) {
        if (a == a_prev + 1) {
            // a增加了1
            a_increasing
= 1;
            b
++;          // b跟随a加1
        } else {
            // a增加了超过1,可能是重置或其他操作
            a_increasing
= 0;
        }
    } else {
        // a没有增加
        a_increasing
= 0;
    }
   
    a_prev
= a;           // 更新a的上一次采样值
}

// 主函数
void main() {
    Timer0_Init();        // 初始化定时器0
   
    while(1) {
        // 主循环可以执行其他任务
        // 当a_increasing变为0时,b将停止增加
        // 可以在这里添加退出条件的处理
        if (!a_increasing && b > 0) {
            // b已经停止增加,可以执行退出操作
            // 例如关闭外设、保存数据等
            // 这里只是简单示例,实际应用中可能需要更复杂的处理
            break;        // 退出主循环
        }
    }
   
    // 程序结束后的处理
    while(1);             // 进入死循环,保持程序在此处
}

这个程序的工作原理如下:
1. 使用定时器 0 每 1ms 产生一次中断,在中断服务函数中检测变量a的变化。
2. 每次中断时,将当前的a值与上一次保存的值比较:
◦ 如果a增加了 1,则b也加 1,并设置a_increasing标志为 1。
◦ 如果a没有增加或增加超过 1,则设置a_increasing标志为 0。
3. 主循环中检查a_increasing标志,当标志变为 0 且b已经开始增加时,程序可以执行退出操作。
回复

使用道具 举报

15#
ID:1138534 发表于 2025-5-13 18:16 | 只看该作者
在 51 单片机 C 语言编程中,如果你想让变量 b 跟随变量 a 的自增(即只有在 a 增加时,b 才增加),并且当 a 停止增加时 b 停止并退出循环,关键在于检测变量 a 是否发生变化。  说明了如何实现这个逻辑: #include <reg51.h>  void main() {     unsigned int a = 0;     unsigned int b = 0;     unsigned int last_a = 0;      while (1) {         if (a != last_a) {  // 说明a发生了变化             b++;            // b 跟着加 1             last_a = a;     // 更新上一次的 a 值         } else {             break;          // a 没有变化,退出循环         }          // 在这里模拟 a 的自增,比如:         // a++;  // 如果不模拟自增,可以用外部中断或串口输入来控制     }      // 循环结束,程序可以继续做其他事情     while (1);  // 停在这里 }
回复

使用道具 举报

16#
ID:965189 发表于 2025-5-13 21:02 | 只看该作者
xiaobendan001 发表于 2025-5-13 08:40
B==A,不用动
否则B=A,那不就是直接B=A就行了?

我不是要它相等,我要知道它是加1了。
回复

使用道具 举报

17#
ID:1109793 发表于 2025-5-14 07:27 | 只看该作者
君工创 发表于 2025-5-13 21:02
我不是要它相等,我要知道它是加1了。

那万一加了2呢
回复

使用道具 举报

18#
ID:879809 发表于 2025-5-14 22:40 | 只看该作者
李晓楠 发表于 2025-5-13 15:26
下面是一个 51 单片机 C 程序,它可以检测变量a是否在加 1,并相应地控制变量b的变化。程序通过定时器定期 ...

你的代码有很大的隐患,8位单片机int是16位的,所以a++不是原子操作,举例来说a=255,a++分两步,1)低位++产生carry,2)高位+carry。如果在两步中间发生中断,你读到的a的值是0,会引发程序行为异常。
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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