|
#include <iom16v.h>
#include <macros.h>
#include <math.h>
//#define checkbit(var,bit) (var&(0x01<<(bit))) /*定义查询位函数*/
//#define setbit(var,bit) (var|=(0x01<<(bit))) /*定义置位函数*/
//#define clrbit(var,bit) (var&=(~(0x01<<(bit)))) /*定义清零位函数*/
//-------------------------------------------------------
//输出端口初始化
void PORT_initial(void)
{
DDRA=0B00000000;//AD输入
PINA=0X00;
PORTA=0X00;
DDRB=0B00000000;
PINB=0X00;
PORTB=0X00;
DDRC=0B00011110;
PINC=0X00;
PORTC=0X00;
DDRD=0B00110010;
PIND=0X00;
PORTD=0B11111111;
}
//定时器1初始化
void T1_initial(void)
{
TCCR1A|=(1<<COM1A1)|(1<<WGM10)|(1<<COM1B1); //T1:8位快速PWM模式、匹配时清0,TOP时置位
TCCR1B|=(1<<WGM12)|(1<<CS11); //PWM:8分频:8M/8/256=4KHz;
}
//-------------------------------------------------------
//定时器2初始化
void T2_initial(void) //T2:计数至OCR2时产生中断
{
OCR2=0X4E; //T2:计数20ms(0X9C)10ms(0X4E)时产生中断;
TIMSK|=(1<<OCIE2);
TCCR2|=(1<<WGM21)|(1<<CS22)|(1<<CS21)|(1<<CS20); //CTC模式,1024分频
}
//-------------------------------------------------------
//外部中断初始化
void INT_initial(void)
{
MCUCR|=(1<<ISC01)|(1<<ISC00)|(1<<ISC11)|(1<<ISC10); //INT0、INT1上升沿有效
GICR|=(1<<INT0)|(1<<INT1); //外部中断使能
}
//串口初始化;
void USART_initial( void )
{
UBRRH = 0X00;
UBRRL = 51; //f=8MHz;设置波特率:9600:51;19200:25;
UCSRB = (1<<RXEN)|(1<<TXEN); //接收器与发送器使能;
UCSRC = (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1); //设置帧格式: 8 个数据位, 1 个停止位;
UCSRB|=(1<<RXCIE); //USART接收中断使能
}
//-------------------------------------------------------
//串口发送数据;
void USART_Transmit( unsigned char data )
{
while ( !( UCSRA & (1<<UDRE))); //等待发送缓冲器为空;
UDR = data; //将数据放入缓冲器,发送数据;
}
//-------------------------------------------------------
//串口接收数据中断,确定数据输出的状态;
#pragma interrupt_handler USART_Receive_Int:12
static char USART_State;
void USART_Receive_Int(void)
{
USART_State=UDR;//USART_Receive();
}
static int AD_data;
float adc_v;
//-------------------------------------------------------
int ADport(unsigned char port)
{
ADMUX=port;
ADCSRA|=(1<<ADEN)|(1<<ADSC)|(1<<ADPS1)|(1<<ADPS0); //采样频率为8分频;
while(!(ADCSRA&(BIT(ADIF))));
AD_data=ADCL;
AD_data+=ADCH*256;
// AD_data-=512;
return (AD_data);
}
//////////////////////这块要有比较大的改动!!//////////////////////////////////////
//用rad表示角度
//k这个加速度计:800mv/g。满量程:1.5g*0.8=1.2v。0g的情况下为1.65v。
//k陀螺仪的参数:0角速度时1.35v。-300deg/sec~300deg/sec。每deg/sec=0.67mv。即满量程是:这个什么情况!
//应该都仅仅用到一个方向,7361的X,陀螺仪的x。
static float gyro,acceler,Q,Z;
//-------------------------------------------------------
void AD_calculate(void)
{
acceler=ADport(0); //AD的加速度计原始数据 //角度校正
gyro=ADport(1); //AD得陀螺仪原始数据
Q=acceler;
Z=gyro;
acceler*=0.004062/4.16*4.88;//系数换算:4.16/1024);此处得到了芯片处输出电压
acceler-=1.47;
acceler=acceler/0.8;
acceler=acceler;
acceler=asin(acceler);//这个是以rad做单位的
///acceler=180/3.1415*asin(acceler); //asin得出来的是rad还是reg??应该是rad、这。。。
gyro*=0.004062/4.16*4.88;//4.16*2.5; //系数换算:4.16/1024);此处得到了芯片处输出电压
gyro-=1.36;
gyro=gyro/0.00067;//得到度每秒
Kalman_Filter(acceler,gyro);
/*
acceler*=0.0061035; //系数换算:2.5/(1.2*512);///%%%2.5/(0.8*512)************改了此
acceler=asin(acceler);
gyro*=0.00341; //角速度系数:(3.14/180)* 100/512=0.003407;?
*/
//complement_filter(acceler,gyro);
}
//定时器2中断处理
//-------------------------------------------------------
static unsigned char temp;
//-------------------------------------------------------
#pragma interrupt_handler T2INT_fun:4
void T2INT_fun(void)
{
AD_calculate();
}
int i,j;
//-------------------------------------------------------
void main(void)
{
PORT_initial();
INT_initial();
T2_initial();
AD_calculate();
USART_initial ();
SEI();
for (i=1;i<=500;i++) //延时启动PWM,等待卡尔曼滤波器稳定
{
for (j=1;j<=300;j++);;
}
// if(temp>=4) //10ms即中断;每秒计算:100/4=25次;
//{
[color=Red] //USART_Transmit(acceler+128);
//USART_Transmit(gyro+128);
//USART_Transmit(Q);
// USART_Transmit(Z);
//USART_Transmit(angle+128);
//USART_Transmit(angle_dot*57.3+128);
//USART_Transmit(128);
// temp=0;
//}
//temp+=1;
while(1)///这里是干嘛呢,死循环没有出去的时候啊
{
USART_Transmit(0);
}
}
高亮这一块不管怎么改,为什么都给我传回来80????????????????????? |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|