找回密码
 立即注册

QQ登录

只需一步,快速开始

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

主芯片用的是stc15系列的单片机,有一个逻辑关系,不知道能不能实现。

[复制链接]
跳转到指定楼层
楼主
ID:721008 发表于 2020-4-15 13:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我有一个逻辑关系,不知道能不能实现,用的是AD7606的采样芯片,采样芯片在第一次采集电压值时启动定时,定时时间为10秒,在这个十秒内,采样芯片一直在采样。然后我想实现的是,从第一次采样到十秒结束,如果采样芯片采集的电压一直都是同样的电压,那么十秒结束后输出一个信息到外部设备;如果采样芯片在这十秒内采集到了另外一个电压,那么定时立马结束,跳出这个定时十秒的程序,输出信息给外部设备。我试了延时程序和定时器定时,都没有实现(不排除是程序的问题),本人单片机在入门中,还请大神指点,谢谢。
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:94031 发表于 2020-4-15 14:31 | 只看该作者
AD采样每次都不一样,是在一定范围波动的,这个情况你得注意。
回复

使用道具 举报

板凳
ID:94031 发表于 2020-4-15 14:35 | 只看该作者
不如你把最后想实现的过程说清楚,不一定要你现在的思路。
回复

使用道具 举报

地板
ID:584814 发表于 2020-4-15 14:46 | 只看该作者
立马结束跳出的,在编程中一般称作为中断,可自行百度。
回复

使用道具 举报

5#
ID:282850 发表于 2020-4-15 15:10 | 只看该作者
这个问题有点水平,说明楼主善于思考,试回答:
1、采样芯片采集的电压一直都是同样的电压,需保证相同,AD的值本来就有很小的变化的,要考虑取几位有效数来比对。
2、延时程序本身与执行是相冲突的,重写延时程序,在延时程序里加入AD采样及跳出程序,可能也可以实现
3、定时器定时,我一般采用中断方式,逻辑与你想要的不对。如果在主程序中反复读TA值,并if,估计能实现。
回复

使用道具 举报

6#
ID:452950 发表于 2020-4-15 15:54 | 只看该作者
假设采样频率为100MS一次,就可以设置循环条件,采样100次即为10s,若检测到与上次不一样则提前跳出。注意要考虑采样过程消耗的时间,若相对采样间隔时间较大,则需要计算,使延时时间和采样持续时间合计等于采样间隔时间。
uchar i=0,j=0,k=0;
while(i<100)
{
j=采样函数();if((k!=j)&&(i>0))break;
k=j;
i++;
delay(100);//延时100ms
}
输出j和k();//如果有变化,j为后者,k为前者;如果无变化,采样100次后两者一致

回复

使用道具 举报

7#
ID:213173 发表于 2020-4-15 18:33 | 只看该作者
实现楼主想要的功能没有问题。问题是楼主指的同样的电压与另外一个电压怎么定义,波动范围是多少?
回复

使用道具 举报

8#
ID:452950 发表于 2020-4-15 18:50 | 只看该作者
采样范围可以在采样函数里面处理,根据精度需求给采样得到的不同数值范围分级,将范围转化成级数,只输出级数就可以了。
回复

使用道具 举报

9#
ID:388197 发表于 2020-4-15 22:41 | 只看该作者
仅作逻辑参考,代码随便敲的,难免遗漏个括号分号什么的.

#define Range 5                 //采样值范围(因为每次采样都有细小的波动)小于这个值则认为值无变化
u8 FlagSample = 0;             //采样标志.
u8 FlagChange = 0;            //在采样时间内采样值是否有变化标志
u16 Timer = 0;                  //计时变量
u16 First_Adc_Value = 0;   //首次采样值
u16 Value = 0;                  //其他采样值

u16 Get_Adc_Value()        //ADC采样,返回值为采样值
{
    ..........
}
main()
{
    .....
    .....
   if(需要采样)
   {
       FlagSample = 1;
       First_Adc_Value = Get_Adc_Value();     //首次采样
       while(FlagSample == 1)
       {
            Value = Get_Adc_Value();
            FlagChagnge = 0;                          //清值变化标志
            if(Value == First_Adc_Value)          //如果相等则继续
           {
                continue;
           }else   if(First_Adc_Value > Value)   //如果首次采样大于期间采样
           {
                 if(First_Adc_Value - Value  < Range)  //如果两者相差小于设定范围
                 {
                       continue;                           //则认为二者相等,继续循环.
                 }else                                       //否则(两者相差大于5)则认为值有变化
                {
                       FlagSample = 0;                //关掉采样标志
                       Timer = 0;                        //定时清0,方便下次使用
                       FlagChange = 1;                //将有变化标志置1,表示有变化
                       break;
                }
           }else  if(First_Adc_Value < Value)    //如果首次采样小于期间采样
            {
                 ...我就不写了...照着上面依次类推就好了....
            }
       }
       if(FlagChange == 1)
       {
                输出值变了
       }else
      {
                输出值没变
      }
   }
}

void T0_ISR()      interrupt 1  定时器中断函数,假设是1ms中断
{
     ....
    .....
     if(FlagSample == 1)
     {
          Timer ++;
          if(Timer >= 10000)        // 10秒
          {
              Timer = 0;
              FlagSample = 0;
          }
     }else
     {
          Timer = 0;
     }
}
回复

使用道具 举报

10#
ID:721008 发表于 2020-4-16 10:26 | 只看该作者
wulin 发表于 2020-4-15 18:33
实现楼主想要的功能没有问题。问题是楼主指的同样的电压与另外一个电压怎么定义,波动范围是多少?

是这样的,我这个主要是为了测量电流传感器的,在采样电阻前端采集电压值,电压值只有两个状态,一个状态的电压范围是0.6~0.8V,另外一个状态的电压范围是1.3~.5V.
回复

使用道具 举报

11#
ID:213173 发表于 2020-4-16 13:55 | 只看该作者
ADMIN_ALLENY 发表于 2020-4-16 10:26
是这样的,我这个主要是为了测量电流传感器的,在采样电阻前端采集电压值,电压值只有两个状态,一个状态 ...

给你写一个编程思路,具体应用还要扩展完善。
以STC15系列为依据
void Timer0Init()        //50毫秒@12.000MHz
{
        AUXR &= 0x7F;        //定时器时钟12T模式 16位自动重装
        TMOD &= 0xF0;        //设置定时器模式
        TL0 = 0xB0;                //设置定时初值
        TH0 = 0x3C;                //设置定时初值
        TF0 = 0;                //清除TF0标志
        TR0 = 1;                //定时器0开始计时
        EA  = 1;                //开总中断
        ET0 = 1;                //开T0中断
}

void Timer0Interrupt() interrupt 1
{
        if(flag)                                        //启动检测
        {
                num++;                                        //计时
                Vin=GetADCResult(ch);        //读取ADC输入信号电压转换值
                                                                //电压范围0~VCC Vin=0~1023
                if(Vin<Vin_L||Vin>Vin_H)//判断电压范围
                {
                        sign_A=1;                        //输出信号1
                        flag=0;                                //清0启动标志
                        num=0;                                //清0计数变量
                }
                if(num>=200)                        //10秒到 结束
                {
                        sign_B=1;                        //输出信号2
                        flag=0;                                //清0启动标志
                        num=0;                                //清0计数变量
                }
        }
}
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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