|
加速度传感器MMA7260
单片机mega48 内部8位AD 外部8M晶振
编译器cvavr
液晶 PD口(编译器lcd库)
x轴 ADC0
只测试x轴,用的均值加中值滤波,静止时波动范围 100mv。 俺的天啊,电路连接图参考datasheet。
MMA7260 g1,g2悬空,sl接高 x接adc0 用的杜邦线(不会是线的问题吧)
诚心请教加速度传感器的滤波方案。。。。。。。。。。。。
代码如下:
/*----------------------------MMA7620.c-------------------------------*/
/*****************************************************
This program was produced by the
CodeWizardAVR V2.03.9 Standard
Automatic Program Generator
?Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
Project :
Version :
Date : 2011-5-20
Author : uoow
Company : moon
Comments:
Chip type : ATmega48V
AVR Core Clock frequency: 8.000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 128
*****************************************************/
#include <mega48.h>
#include <delay.h>
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x0B ;PORTD
#endasm
#include <lcd.h>
#define uchar unsigned char
#define uint unsigned int
#define ADEN 7
#define ADIF 4
#define N 8
#define A 200
uchar disp[]=" ";//5个空格
uint t;
void c_ascii(uint data)
{
disp[0]=data/1000+0x30;
disp[1]=(data%1000)/100+0x30;
disp[2]=(data%100)/10+0x30;
disp[3]=data%10+0x30;
disp[4]=0x20;
}
interrupt [TIM0_COMPA] void timer0_comp_isr(void)
{
t++;
}
uint read_ad(uchar ch) {
uchar i;
uint adc_v;
ADMUX = 0x60|ch; //基准AVCC、左对齐、通道ch
ADCSRA = 0xC2; //使能、开启、4分频
while(!(ADCSRA & (1 << ADIF))); //等待
i = ADCH;
ADCSRA &= ~(1 << ADIF); //清标志
ADCSRA &= ~(1 << ADEN); //关闭转换
adc_v=(unsigned long)i*5000/256; //vref=5v
return adc_v;
}
/*-----------------------
* 均值加中值滤波
* 分为七大段分别均值(N=8)处理
* 然后将均值作中值滤波处理
* 波动范围100mv
*-----------------------*/
uint filter(uchar ch) //均值+中值滤波 N=8
{
unsigned long sum=0;
uchar count,cnt;
uint value_buf[N-1],temp;
uchar i,j;
for(cnt=0;cnt<N-1;cnt++)
{
for(count=0;count<N;count++)
{
sum+=read_ad(ch);
delay_ms(2);
}
sum=sum/N;
value_buf[cnt]=sum;
sum=0;
delay_ms(4);
}
for(j=0;j<N-1;j++)
{
for(i=0;i<N-1-j;i++)
{
if(value_buf>value_buf[i+1])
{
temp=value_buf;
value_buf=value_buf[i+1];
value_buf[i+1]=temp;
}
}
}
return value_buf[(N-2)/2];
// ADCSRA &= ~(1 << ADEN); // 关闭转换
// return (uint)(sum8/N);
}
/************************************************
一群趋炎附势之徒,伸手党,sb,忙人,专家,高手,笨蛋
*************************************************/
//限幅滤波 A=
/*uint filter(uchar ch)
{
uint data;
uint datanew;
data=read_ad(ch);
datanew = read_ad(ch);
if((datanew -data >A)||(data-datanew>A))
return data;
return datanew;
}
*/
/*uint filter(uint axis) //中值滤波 + N=15
{
uint value_buf[N],temp;
uchar count,i,j;
for (count=0;count<N;count++)
{
value_buf[count]=axis;
delay_ms(10);
}
for(j=0;j<N-1;j++)
{
for(i=0;i<N-j;i++)
{
if(value_buf>value_buf[i+1])
{
temp=value_buf;
value_buf=value_buf[i+1];
value_buf[i+1]=temp;
}
}
}
return value_buf[(N-1)/2];
}
*/
/*uint filter(uint axis) //加权平均滤波 - N=12
{
unsigned long sum=0;
uchar count;
uint value_buf[N];
for(count=0;count<N;count++)
{
value_buf[count]=axis;
delay_ms(10);
}
for(count=0;count<N;count++)
{
sum+=value_buf[count]*jq[count];
}
return (uint)(sum/sum_jq);
}
*/
void display(uint data)
{
uchar *i=disp;
c_ascii(data);
lcd_gotoxy(0,1); // go on the second LCD line
while(*i!=0x20) //*i!=0x20
lcd_putchar(*i++);
}
void main(void)
{
DDRC=0x08;
PORTC=0x08;
// PORTC=0x08; //sl =1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
lcd_init(16); // initialize the LCD for 2 lines & 16 columns
lcd_clear(); // clere the LCD
lcd_putsf("MMA7260 test:"); // display the message
//----T/C0 init--------
TCCR0A=0x02; //CTC模式
TCCR0B=0x03; //64分频 8M/64=125khz
TCNT0=0;
OCR0A=0xf9; //2ms
TIMSK0=0x02; //匹配A中断使能
//-----AD init---------
ADMUX=0x60; //avcc 参考源 左对齐 通道0
ADCSRA=0xc5; //adc 允许,adcclk=250khz。
// ADCSRB=0x03; //选择t/c0比较匹配中断作为adc触发源
#asm("sei")
while(1)
{
if(t==100) //200ms
{
display(filter(0));
t=0;
}
}
}
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|