📄 acc_max197.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 + -