12 学习阶段总结

来源:互联网 发布:济宁网络问政平台登录 编辑:程序博客网 时间:2024/04/26 00:09

目前的项目主要是新版的主动上传程序,功能主要是有:主动上传+温度测试+二次寿命判断等等。现在楼主主要分享一下在项目进行过程中的一些经验总结:

(1)随机函数的使用

这个主要注意的点还是一开始的随机种子以及真假随机数的辨别等,但是在一个没有time.h的工程中,如果使用像博主一样的ADC小数点采集作为随机种子的输入的时候,必须要注意一点,虽然我们的ADC采集小数点可能是随机采集的,但是在使用过程中,仅仅是调用当前的ADC口进行随机种子输入就可以了吗?答案是否定的,原因很简单,一般作为一个ADC的输入口,可能会做一些外围电路的元器件搭配处理,例如端口的上拉或者下拉,而在博主的目前的工作项目中,要产生一个真的随机数。必须使用引脚浮空的端口,可以理解为“原生态”的端口,这种端口的电平是真的随机变化的,这样方便取值。如果有一个上拉电阻作为外围电路,那么是否可以理解为我们采集的ADC的值永远都是3.xx伏特,这样对于取值是不太好的,博主做过实验,在一个上拉端口的ADC采集口中,往往在20次以后产生的随机数都是固定的变化序列了。

(2)拥塞算法的想法与判别

拥塞算法一个最容易进入的误区在于我们会把一个板子的事情想象成两个事情,例如博主以前写的判断方法。想的很好,就是当数据一直传输的时候标志位置位,当数据传输结束的时候标志位回到0,然后发送之前进行判断,是否有数据一直在485总线一直传输。看上去逻辑仿佛没有错误,但是博主犯了一个错误就是,数据传输的也是本身的板子。所以这样看来逻辑就是混乱的。自己检测自己,这是什么东东。。博主手中能用的代码的思想就是使用定时器来判断总线是否忙,具体实现可以参见博主前面的博文。

(4)中断内部的思想简化

在博主前面的一个项目中,需要实现这样一个功能,平时进行主动上传的频率是10min一帧,当出现警报的时候变为5s一帧。一开始博主的代码是这样的:

interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
    // Place your code here
    TCNT0=0x3C;   
    #asm("wdr")  
    t0cnt++;
    t0cnt1++;
    if(t0cnt>40)
    {   
        t0cnt=0;            
        readvalueflag=1; 

    }
//    if(sendnow==0)
//    {
//        ontime=(4800-10*sum-savetime);           //一次雷击的时候
//        bigtime=1;
//    }
//    if(sendnow==1)      //一旦外部中断开启马上进入 一直持续
//    {   savetime=savet0cnt; //将经过的时间保存
//        sum++;
//        ontime=200;     //5s
//        //sendnow=0;
//        t01cnt=0;  
//    }
//   if(t01cnt>ontime)//(random(txbuf[49])+time))  //2min
//    {   
//        sendnow=0;
//        t01cnt=0;
//        sendbasicflag=1;  
//        if(savet0cnt>=4800 )                 //到达了2min的界限
//        {
//            savet0cnt=0;
//            savetime=0;
//            sum=0;
//        }
//        if(bigtime==1)                     //到达一个大时间间隔
//        {
//            sum=0;
//            bigtime=0;
//        }            
//    }
//    else
//    {sendnow=2;}
}

具体的代码思想是使用标志位,表示是否是一个大的时间,例如10min,然后在10min内进行数据的加减更改,虽然最后的目的达到了。但是真的十分繁琐,而且一个致命的错误是,这是在一个中断中写的代码。中断的代码我们必须力保简洁明了。

接下来是一个很简单的简化版本:

interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
    // Place your code here
    TCNT0=0x3C;   
    #asm("wdr")  
    t0cnt++;
    t0cnt1++;
    if(t0cnt>40)
    {   
        t0cnt=0;            
        readvalueflag=1;
    }
    if(t0cnt1>(random(txbuf[15])+timelevel))
    {  
        t0cnt1=0;
        sendbasicflag=1;   
    }
}

使用timelevel来表示大头时间。前面的随机数是进行随机微调的时间。而timelevel的界定是在异常判断中进行

  if(((big0rsmall(liehuavalue,wdvalue))<spdlhmenxian)||(sta2==1)||(sta1==1)) //门限低于设定阈值或者开关量异常
            {   
                timelevel=400;//报警5s间隔发送

                。。。
            }
            else
            {   
                timelevel=2400; //平时就10min的间隔进行
               。。。
            }           
这样不就很简单的实现了中断的简洁和功能的实现了,而且在代码量大的时候也为单片机节约了flash的空间。
0 0
原创粉丝点击