找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5247|回复: 35
收起左侧

C语言如何让两个步长不一样的FOR循环同时执行?

  [复制链接]
ID:653173 发表于 2020-7-14 08:46 | 显示全部楼层 |阅读模式
C如何让两个步长不一样的FOR循环同时执行?互不干扰,求大侠指点

void main()                                       
{            
        uchar i,j;

        while(1)
        {
//            for(i=0,j=0;i<8||j<15;i++,j++)  
              for(i=0;i<8;i++)
                {
               //循环体1
                }

                for(j=0;j<15;j++)
                {               
                //循环体2
                }
         }
        
}



回复

使用道具 举报

ID:331263 发表于 2020-7-14 09:47 | 显示全部楼层
void main()                                       
{            
        uchar i;

        while(1)
        {
                for(i=0;i<15;i++)
                {  
                    if((i*2)<15)   
                    {
                   //循环体1
                    }           
                   //循环体2
                }
         }      
}

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:653173 发表于 2020-7-14 10:20 | 显示全部楼层
dingpeng1980 发表于 2020-7-14 09:47
void main()                                       
{            
        uchar i;

if语句嵌套也不行啊,一个步长是8,一个是15,两个要随时都能运行。这样还是有一段时间循环体1没有继续执行,在等待循环体2执行完毕15个步长
回复

使用道具 举报

ID:142320 发表于 2020-7-14 12:12 | 显示全部楼层
你对C语言和编程的理解有误,我们为什么把两个不同for要同步,你要实现这个的目的是为了什么。否则都是无意义的问题。
回复

使用道具 举报

ID:653173 发表于 2020-7-14 12:41 | 显示全部楼层
gujp312365 发表于 2020-7-14 12:12
你对C语言和编程的理解有误,我们为什么把两个不同for要同步,你要实现这个的目的是为了什么。否则都是无意 ...

循环体1的输出与i有关,循环体2的输出与J有关。,比如P1口控制流水灯,P1口同时控制8段码
回复

使用道具 举报

ID:451718 发表于 2020-7-14 15:08 | 显示全部楼层
做时间定标,用定时器来实现。   基于硬件的编程,不要老想着用算法来搞。   程序写得再花,一编译就给你优化了。
回复

使用道具 举报

ID:451718 发表于 2020-7-14 15:09 | 显示全部楼层
做时间定标,然后在定时器里面去实现。   面向硬件的编程,不要老实想着算法, 程序再花,一编译就优化了

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:451718 发表于 2020-7-14 15:10 | 显示全部楼层
void tm0_isr() interrupt 1         //中断入口
{
        SysTick++;
回复

使用道具 举报

ID:451718 发表于 2020-7-14 15:14 | 显示全部楼层
void tm0_isr() interrupt 1         //中断入口
{
        SysTick++;
}

void main()
{
    switch(SysTick%8)
   {
        case 0:
            i= 0;
            j= 0;
            j= 1;
        break;
        case 1:
            i= 1;
            j= 2;
            j= 3;
        break;
        case 2:
            i= 2;
            j= 4;
            j= 5;
       break;
    ...........

   }
}
回复

使用道具 举报

ID:735148 发表于 2020-7-14 15:14 | 显示全部楼层
严格意义上的同时,只能执行一个;
你可以利用定时器定时,一个主要执行,另外一个隔一段时间执行一段,只要时间设置的足够短,就可以理解为同时执行。
回复

使用道具 举报

ID:636538 发表于 2020-7-14 15:28 | 显示全部楼层
soaic 发表于 2020-7-14 12:41
循环体1的输出与i有关,循环体2的输出与J有关。,比如P1口控制流水灯,P1口同时控制8段码

在我这看来,这个本身就不能同时,你的理解有误,虽然IO复用,但是是不同时间的使用,单片机执行的速度让你感觉在同时执行

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:553941 发表于 2020-7-14 15:28 | 显示全部楼层
这个问题问的,for循环本来就是要执行完内部的程序才能跳出,两个for肯定是两个单独的。优化你的逻辑吧,另外,单片机同一时刻只能做一件事
回复

使用道具 举报

ID:639106 发表于 2020-7-14 19:59 | 显示全部楼层
C不允许两条或两条以上的语句同时执行,你可以用定时器来切换这两个for循环
回复

使用道具 举报

ID:284454 发表于 2020-7-14 20:17 | 显示全部楼层
void main()                                       
{            
        uchar i,j,k=1;

        while(1)
        {
            if(k==1)

              for(i=0;i<8;i++)
                {
               //循环体1
                k=0
                }
           else
                for(j=0;j<15;j++)
                {               
                //循环体2
               k=1
                }
         }
        
}
c单个处理器永远没有同时同步的,只是无限接近同时同步,都是一步一步执行,切换快而已。
引入一个数,相当于正反转,每个循环执行一次就切换另一个循环。
中间忽略了几个指令周期,看看是不是和你的意思。
回复

使用道具 举报

ID:332444 发表于 2020-7-14 21:08 | 显示全部楼层
比如P1口控制流水灯,P1口同时控制8段码,没说明清楚是要怎样控制,数码管显示0-9?流水灯从左到右?
回复

使用道具 举报

ID:332444 发表于 2020-7-14 21:16 | 显示全部楼层
所谓同时也可以理解为多任务当然也是存在前后一个机器周期的,真正的同时也是可以的,就是用同一个计数达到不同值时的不同处理,比如i计数到8就执行再到15就执行可视为同时。
回复

使用道具 举报

ID:592807 发表于 2020-7-15 08:31 | 显示全部楼层
看了一圈不知道你要要什么东西。讲一下自己的了理解吧。i和j要相互独立而 i是8循环j是15循环的对吧
i = 0 j = 0
i = 1 j =1
.
.
.
i = 7 j = 7
i = 0 j = 8.
.
.

i = 6 j = 14
i = 7 j = 0

这样循环的对吧,你用取余数方法就可以得到你要的结果。
for(k = 0;k <120;k++)
i = k % 8;
j = k % 15;
i和j的值同时增大循环,取值相互独立。
回复

使用道具 举报

ID:331263 发表于 2020-7-15 08:51 | 显示全部楼层
重点看周期,如果小于循环周期就认为是同时运行,大于循环周期就提高时钟频率,在不够用就只有换cpu了
回复

使用道具 举报

ID:331263 发表于 2020-7-15 08:55 | 显示全部楼层
soaic 发表于 2020-7-14 12:41
循环体1的输出与i有关,循环体2的输出与J有关。,比如P1口控制流水灯,P1口同时控制8段码

你这不是总线通讯原理么?你还要一个时钟线,看看IIC通讯原理吧
回复

使用道具 举报

ID:331263 发表于 2020-7-15 09:02 | 显示全部楼层
dingpeng1980 发表于 2020-7-15 08:55
你这不是总线通讯原理么?你还要一个时钟线,看看IIC通讯原理吧

简单点的增加1个使能口,一个高使能一个低使能就能驱动2个了,这不是程序的问题你要搞懂原理
回复

使用道具 举报

ID:282850 发表于 2020-7-15 10:03 | 显示全部楼层
问题很是怪,程序是顺序执行的,这是基本思想,再加上中断。但永远不可能同时执行
回复

使用道具 举报

ID:311846 发表于 2020-7-15 11:43 | 显示全部楼层
非多核芯片做不到同时执行,无论多NB的单核芯片都是受时间轮执行的,单片机允许时间误差内一般当做同时执行处理,如UCOSII之类的多线程也是有时间差的,主要是看做什么,了解原理,才能编写相应的程序
回复

使用道具 举报

ID:653173 发表于 2020-7-16 10:10 | 显示全部楼层
xianfajushi 发表于 2020-7-14 21:08
比如P1口控制流水灯,P1口同时控制8段码,没说明清楚是要怎样控制,数码管显示0-9?流水灯从左到右?

是的。。。。
回复

使用道具 举报

ID:653173 发表于 2020-7-16 10:12 | 显示全部楼层
本帖最后由 soaic 于 2020-7-16 10:18 编辑
ko44 发表于 2020-7-14 20:17
void main()                                       
{            
        uchar i,j,k=1;

提供了一个很好的方法,谢谢!但是上述代码还是不能跳出循环,不能实现P0口跑马灯移位的同时,P1口数码管0-9显示
回复

使用道具 举报

ID:653173 发表于 2020-7-16 10:27 | 显示全部楼层
本帖最后由 soaic 于 2020-7-16 10:30 编辑
黄youhui 发表于 2020-7-15 08:31
看了一圈不知道你要要什么东西。讲一下自己的了理解吧。i和j要相互独立而 i是8循环j是15循环的对吧
i = 0  ...

谢谢大侠,利用公约数取余的方法解决了同步执行的问题,类似天干地支计年;代码也简单,牛!!!!
回复

使用道具 举报

ID:473925 发表于 2020-7-16 10:37 | 显示全部楼层
如果真正意义上的同时 ,要用FPGA 来做
回复

使用道具 举报

ID:804115 发表于 2020-7-16 12:01 | 显示全部楼层
兄弟,虽然你的表述不是很清晰,大家都不太好理解你要具体做什么,但我基本理解你要干什么了。
我想你是想问,当我们编程时,想让多个任务同时运行应该怎么编程,且在各个任务运行时尽可能互不影响,对吧?
首先,绝对的不影响是不可能的,因为mcu一般都是单核的,同一时间,一个指令周期只能执行一条命令。但我们还是可以做到通过肉眼看两个任务是同时运行的。比如流水灯和数码管显示,因为他们都是控制io翻转,耗时很小。
解决方法有两种:一种就是借助OS系统,可以简化代码,但需要熟悉OS系统;另外一种就是通过大循环里的标记判断; OS的就不说了,下面针对大循环举例说明一下:
基本思想:各个任务在写代码的形式上保持独立性,这样便于后期代码维护,同时要让各个任务之间的互相影响达到最小。
基本手段:拆分每个耗时的任务,每次大循环只执行拆分大任务后的一个个小部分。
       
       
unsigned char LedCnt=0,SmgCnt=0;

void led_handler(void)
{
  if(LedCnt < 8)
  {
    //循环体1   
  }else
  {
    LedCnt = 0;
  }
  LedCnt ++;
}

void shu_ma_guan_handler(void)
{
  if(SmgCnt < 8)
  {
    //循环体2
  }else
  {
    SmgCnt = 0;
  }
  SmgCnt ++;  
}

while(1)
{
  led_handler();
  shu_ma_guan_handler();
}


如果我理解错误,没有及时看到,可以给我qq发邮件,qq号如名。
回复

使用道具 举报

ID:653173 发表于 2020-7-16 14:14 | 显示全部楼层
本帖最后由 soaic 于 2020-7-16 14:51 编辑
黄youhui 发表于 2020-7-15 08:31
看了一圈不知道你要要什么东西。讲一下自己的了理解吧。i和j要相互独立而 i是8循环j是15循环的对吧
i = 0  ...

最大公约数取余,相当于天干地支纪年,这是最简单的实现办法。但是要满足步长8和15,公约数还得增加一下
for(k=0;k<144;k++)         //最大公约数取余同时执行
  {
      i=k%9;
      j=k%16;
     //原P0口循环体
     //原P1口循环体
    delay(500);
}
回复

使用道具 举报

ID:332444 发表于 2020-7-16 16:45 | 显示全部楼层

之前我回复过一个帖子,说明了一个P加一片锁存器就可以实现对8位数码管的控制,你的描述还是不够清楚,说要控制8段码是指只给数码管的段值而不控制数码管的位?
可以明确回复你的是可以实现的加1片锁存器即可解放P,若用2片锁存器可实现控制数码管的段和位,同时也能实现流水灯。
回复

使用道具 举报

ID:804329 发表于 2020-7-16 16:54 | 显示全部楼层
使用定时器中断就行,在main函数执行一个语句,在中断服务函数执行另一个。把中断服务函数进入间隔调小点就能看成同时进行。这就是前后台系统。
回复

使用道具 举报

ID:332444 发表于 2020-7-16 16:55 | 显示全部楼层
当然执行肯定是分时的,单核不可能实现并行,只能说使用手段可以实现一个P多重复用,且在时间安排允许的范围内。
回复

使用道具 举报

ID:332444 发表于 2020-7-16 17:02 | 显示全部楼层
我写的示例有用一个循环控制2种不同的延时,这很容易实现,但不是你要实现的目标,因此说你描述不够清楚,你要实现的功能不是用并行循环去实现的。
回复

使用道具 举报

ID:653173 发表于 2020-7-17 11:02 | 显示全部楼层
1692483014 发表于 2020-7-16 12:01
兄弟,虽然你的表述不是很清晰,大家都不太好理解你要具体做什么,但我基本理解你要干什么了。
我想你是想 ...

这也可以,但是要把两个LedCnt ++;、 SmgCnt ++;  放在循环体下一行
回复

使用道具 举报

ID:280512 发表于 2020-7-17 14:22 | 显示全部楼层
单片机硬件的工作就是由时钟同步,去一个周期一个周期的去执行指令。在一个cpu的条件下。不可能一个脉冲去执行两个指令
回复

使用道具 举报

ID:804733 发表于 2020-7-17 14:30 | 显示全部楼层
定时器或者使用操作系统(RTOS)
回复

使用道具 举报

ID:284454 发表于 2020-7-17 22:56 | 显示全部楼层
soaic 发表于 2020-7-16 10:12
提供了一个很好的方法,谢谢!但是上述代码还是不能跳出循环,不能实现P0口跑马灯移位的同时,P1口数码管 ...

代码只是弄了个接近同步的循环而已,每个循环需要执行什么任务,在单个循环里面再编辑功能。就跟单片机新手教程里讲的跑马灯以及数码管的实现一样就行了。
如果连一个单片机单独实现跑马灯都不会,还是再取复习下吧,遗忘那么多,再学新的没用的。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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