⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 acc_max197.c

📁 max197车载加速度检测代码,用stc58实现其功能
💻 C
字号:
//采用移动窗算法对加速度信号进行处理,一旦超过阀值则驱动继电器,红色警报灯亮
#include<reg52.h>
#include<stdio.h>
#include <intrins.h>
#include<math.h>
#include<absacc.h>

#define uint unsigned int
#define uchar unsigned char

#define ad_ch0 XBYTE[0xfeff]   //MAX197通道0的地址
uchar test=0x0000;
//sbit test_1=P1^2;
//sbit test_2=P1^3;
//sbit test_3=P1^4;
//sbit test_4=P1^5;
sbit P1_6=P1^6;        //转换结束信号
sbit P1_7=P1^7;        //AD读取高低位选择
sbit ad_rd=P3^7;       
sbit ad_wr=P3^6;
sbit ad_cs=P2^0;
sbit action=P1^0;//继电器控制位


int i=0;  //时间窗移位计数器;
int t_counter;//定时计数器
uchar ad_l,ad_h;//AD转换数据高、低位
uchar ad_value[35]={0,0,0,0,0,0,0,0,0,0,
				    0,0,0,0,0,0,0,0,0,0,
                    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};    //ad转换结果数据存储区
uchar ad_array[35]={0,0,0,0,0,0,0,0,0,0,
				    0,0,0,0,0,0,0,0,0,0,
                    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};  //该数组存放小梯形的面积


void t_int();  //子函数声明区 
uchar ad_get();
uchar filter();
int flag();  
void motion();
void initial();
int moving_window();
uchar integral(uchar array[35]);
void delay(uint t);
 

//主程序开始
void main()		
{
  initial();
    while(1)
  {
    if(flag()==1)
      moving_window();
	  if(moving_window()==1)
        motion();    //根据积分子程序的返回值做出相应的动作
      else 
      i++;     //窗每移动一次,移位计数器加1
        if(i==35)
        i=0;   //若窗移动了35次,则移位计数器清零  
   };
}

//初始化程序,系统上电后,在700毫秒内给ad_array[]赋初值。
void initial()
{
	int n,m=0;
    P1=0xff;
    P2=0xff;
    P3=0xff;
    action=1;  //
	TMOD =0x01;       //T0工作方式
	TL0 = 0x18;     
	TH0 = 0xfc;     //初值设置	
    EA = 1;         //CPU开中断
    ET0 = 1;        //定时器0允许
    TR0 = 1;        //T0工作开始
	ad_value[0]=0;   //先读入一个AD转换值
	for(n=1;n<35;n++)
	{ 
	  while(flag()==1)  //定时20毫秒时间到,则读入AD数据
		{
          
		  ad_value[n]=filter();
          ad_array[n-1]=(ad_value[n]+ad_value[n-1])*0.5;   //计算小梯形的面积
         };
	};
}

//ad_get:
uchar ad_get()
{
    uchar ad;//AD转换结果变量
//	ad_ch0=0x48;//正常工作,内部时钟模式,输入电压范围+/-5V
ad_ch0=0x48;
    while(P1_6!=0)
    {
      P1_7=0;//数据转换完,先置HBEN=0,即先读低位
     };
    ad_l=ad_ch0;
    P1_7=1;
    ad_h=ad_ch0;
    P1_7=0;
    ad=ad_l*256+ad_h;
//ad_cs=1;采样完毕后,重新置零
//ad_ch0=0x10;
    return(ad);
}
//moving_window:
int moving_window()
{
    //移动窗算法
	int moving_flag;
    uchar integral_value,fazhi=-0.23;      //阀值变量;
	  ad_value[i]=filter();       //1ms时间到,则读入一次滤波后的AD数据
      if(i==0)
		ad_array[i]=(ad_value[i]+ad_value[34])*0.5; 
      else
	    ad_array[i]=(ad_value[i]+ad_value[i-1])*0.5;   //计算小梯形的面积
      integral_value=integral(ad_array);
	  if(integral_value>fazhi)
		moving_flag=1;
	  else 
		moving_flag=0;
    return(moving_flag);    
}

//对加速度信号进行积分
uchar integral(uchar ad_array[35])
{
	int t,sum;
	for(t=0;t<35;t++)
		sum+=ad_array[t];
	return(sum);
}


//定时1毫秒中断服务子程序
void t_int()  interrupt 1 using 1
{
    TL0 = 0x18;     
	TH0 = 0xfc;     //重设初值
    t_counter++;
    if(t_counter==20)
    flag();   	
}
//定时返回标志子程序
int flag()
{
    int flag11;
    flag11=1;
    t_counter=0;
    return(flag11);
}
// 滤波子程序
uchar filter()
{
	int m,n;
    uchar filter[4],max,sum,ad_filter;
	for(n=0;n<3;n++)   //由于加速度信号可能变化极快,因此先采4个样本,再进行滤波
    {
      filter[n]=ad_get();
      sum+=filter[n];
	};
    for(m=0;m<3;m++)   //采样完成后,对采样值排序
    {
	  if(filter[m+1]<filter[m])
        {max=filter[m];
		 filter[m]=filter[m+1];
         filter[m+1]=max;
		};     
	};
    sum=sum-filter[0]-filter[3];  //累加和减去最小值和最大值
    ad_filter=sum/2;  //求滤波值
	return(ad_filter);	
}


//输出控制指令子程序
void motion()
{
	  action=0;
      _nop_();
      _nop_();
}

//延时程序
void delay(uint t)  
{
  uint i;
  for(;t>0;t--)
    for(i=110;i>0;i--);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -