标题: STC8H单片机代码问题 代码封装成函数再调用失败但是在main中成功运行 [打印本页]

作者: 18701931930    时间: 2020-12-15 22:19
标题: STC8H单片机代码问题 代码封装成函数再调用失败但是在main中成功运行
  1. for(i=0;i<4;i++)
  2. {
  3.     if((SCH_tasks_G[i].RunMe ==1)&&(SCH_tasks_G[i].Co_op==0))
  4.         {
  5.                 SCH_tasks_G[i].Ptask();
  6.                 SCH_tasks_G[i].RunMe=0;
  7.         }
  8.         if(SCH_tasks_G[i].Period == 0) //如果是单次任务,则删除
  9.         {
  10.                 SCH_tasks_G[i].Ptask =0;
  11.         }
  12. }
复制代码

以上代码封装成函数再调用,系统不执行。
放在main里就正常了,请问下大家有没有遇到这样的问题?        


作者: hhh402    时间: 2020-12-15 23:06
可能是变量的问题,i在函数中定义了吗?SCH_tasks_G[i].RunM是全局变量吗?
作者: 18701931930    时间: 2020-12-16 07:42
hhh402 发表于 2020-12-15 23:06
可能是变量的问题,i在函数中定义了吗?SCH_tasks_G.RunM是全局变量吗?

i定义了,要不然编译也不通过 啊,SCH_tasks_G.RunMe是全局变量
以前从来没遇到过的。
作者: 18701931930    时间: 2020-12-16 08:10
hhh402 发表于 2020-12-15 23:06
可能是变量的问题,i在函数中定义了吗?SCH_tasks_G.RunM是全局变量吗?

SCH_tasks_G[ i].RunMe函数调用标志位,因为我的函数是周期性调用,所以标志位在定时器中断服务函数内                                                       被置1的,函数是以函数指针的方式被调用。在main/while里循环检测各个函数的标志位,等于1就执行,否则就跳过。
作者: wwh2382    时间: 2020-12-16 10:07
也可能执行了你没察觉,不妨在函数里加一句点亮led的语句,是否执行就一目了然了。
作者: 18701931930    时间: 2020-12-16 11:01
wwh2382 发表于 2020-12-16 10:07
也可能执行了你没察觉,不妨在函数里加一句点亮led的语句,是否执行就一目了然了。

st=SCH_Task_Add(LED1,50,50,0,1);
st=SCH_Task_Add(Display_Update,30,30,0,1);
st=SCH_Task_Add(MAX31855_ReadTemper,25,25,0,1);
st=SCH_Task_Add(ADC_ReadVoltage2,30,30,0,1);
代码里有LED的,用示波器看了,就是没执行。
还有就是keil代码优化等级设置为0,它就正常 了。
keil优化等级默认为8.

作者: 18701931930    时间: 2020-12-16 11:08
这是工程文件
void main()
{
        u8 xdata st=0,i;
        P_SW2|=0x80; //可以访问扩展的RAM

        LED_Init();
        Timer1_Init();
        SPI_Init();
        TM1638_Init();
        PWM_Init();
        UART1_Init();
        ADC_Init();
        SCH_Task_Init();

        st=SCH_Task_Add(LED1,50,50,0,1);
        UART1_SendByte(st);
        st=SCH_Task_Add(Display_Update,30,30,0,1);
        UART1_SendByte(st);
        st=SCH_Task_Add(MAX31855_ReadTemper,25,25,0,1);
        UART1_SendByte(st);
        st=SCH_Task_Add(ADC_ReadVoltage2,30,30,0,1);
        UART1_SendByte(st);

        UART1_SendByte((u8)SCH_tasks_G[0].Ptask);
        UART1_SendByte((u8)SCH_tasks_G[1].Ptask);
        UART1_SendByte((u8)SCH_tasks_G[2].Ptask);
        UART1_SendByte((u8)SCH_tasks_G[3].Ptask);

        Timer1_Cmd(ENABLE);


        while(1)
        {
                //SCH_Task_Dispatch();
                for(i=0;i<4;i++)
                {
                        if((SCH_tasks_G[i].RunMe ==1)&&(SCH_tasks_G[i].Co_op==0))
                        {
                         SCH_tasks_G[i].Ptask();
                         SCH_tasks_G[i].RunMe=0;
                        }
                        if(SCH_tasks_G[i].Period == 0) //如果是单次任务,则删除
                        {
                                SCH_tasks_G[i].Ptask =0;
                        }
                }               
        }
}

封装成函数SCH_Task_Dispatch(),再调用运行失败,
直接写在main/while里面就能运行了!搞不懂

STC8H系列奶茶封口机.zip

168.77 KB, 下载次数: 10


作者: 小牢头    时间: 2020-12-16 12:13
将XDATA改为DATA试下吧,只要DATA没溢出,就尽量用DATA,溢出的部分才用XDATA
作者: cocolala    时间: 2020-12-16 12:42
是否存储空间在临界值所致?
作者: 18701931930    时间: 2020-12-16 13:03
小牢头 发表于 2020-12-16 12:13
将XDATA改为DATA试下吧,只要DATA没溢出,就尽量用DATA,溢出的部分才用XDATA

也不行
作者: 18701931930    时间: 2020-12-16 13:06
cocolala 发表于 2020-12-16 12:42
是否存储空间在临界值所致?

Program Size: data=34.0 xdata=112 const=17 code=3036

应该不会 ,昨天我打电话给STC的技术员,他让我把所有的变量设成xdata型,还是不行。
作者: 小牢头    时间: 2020-12-16 14:24
volatile u8 xdata SCH_tasks_Count=0;  //添加成功的任务个数

取消最前面的volatile试下
作者: 18701931930    时间: 2020-12-16 14:49
小牢头 发表于 2020-12-16 14:24
volatile u8 xdata SCH_tasks_Count=0;  //添加成功的任务个数

取消最前面的volatile试下

还是不行,晚上换个版本的keil软件试试,现在用的是keil4
作者: univers    时间: 2020-12-16 16:29
全局变量没有放在这个函数里造成的。
作者: 18701931930    时间: 2020-12-16 18:21
univers 发表于 2020-12-16 16:29
全局变量没有放在这个函数里造成的。

放了的

作者: 18701931930    时间: 2020-12-17 07:58
volatile u8 xdata n;                 
//任务调度(放在大循环里)
void SCH_Task_Dispatch()
{         
        for(n = 0;n <SCH_tasks_Count;n++)
        {
                //只调度合作式任务
                if((SCH_tasks_G[n].RunMe ==1)&&(SCH_tasks_G[n].Co_op==0))
                {
                        SCH_tasks_G[n].Ptask();//执行任务
                        SCH_tasks_G[n].RunMe = 0;//清除任务需要执行的标志
                        if(SCH_tasks_G[n].Period == 0) //如果是单次任务,则删除
                        {
                                SCH_tasks_G[n].Ptask =0;
                        }
                }
        }
}
我把函数里的n由局部变量改成全局变量,暂时正常了。
但是还是想不通,为什么?这里应该用局部变量啊。
我相信很多人也是这样用的。编程经验不足。搞不懂。




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1