常驻嘉宾
- 积分
- 5889
- 威望
- 2514
- 贡献
- 1289
- 兑换币
- 1650
- 注册时间
- 2013-2-20
- 在线时间
- 1043 小时
- 毕业学校
- 韶关学院
|
#include <hidef.h> /* common defines and macros */
#include "derivative.h" /* derivative-specific definitions */
#include <MC9S12XS128.h>
#define Gather_time 20
#define ACCE_UNIT -0.28
#define ACCE_Adjust_Time 3
#define GYROSCOPE_ANGLE_SIGMA_FREQUENCY 200 //陀螺仪角度周期频率 = (1000 / CONTROL_PERIOD)
// 5 Ms
#define GYRO_Ratio 0;
float OutData[4] = { 0 };
float g_fGYRO_Integral = 0;
int ACCE_Min = 136;
int ACCE_Max = 85;
long GYRO = 0;//陀螺仪采集20次的值
long ACCE = 0;//加速度计采集20次的值
int Aver_GYRO = 0;//平均滤波后的陀螺仪的值
int Aver_ACCE = 0;//平均滤波后的加速度计的值
int Off_GYRO = 0;//陀螺仪的零偏值
int Off_ACCE = 0;//加速度计的零偏值
float g_fCarAngle = 0;//车的角度
float g_fGyroSpeed = 0;//车的角速度
float g_fAcce = 0;//加速度计的角度
/*******************************************************************/
void SetBusCLK_40M(void)
{
CLKSEL=0X00; //不是能锁相环时钟
PLLCTL_PLLON=1; //锁相环电路允许
SYNR =0xc0|0x44; //fpllclock=2*osc*(1+SYNR)/(1+REFDV)=80MHz;
REFDV=0x80|0x01; //fbus=pllclock/2;
POSTDIV=0x00; //fpllclock=fvco/(2*POSTDIV)
_asm(nop);
_asm(nop);
while(!CRGFLG_LOCK); //when pll is steady ,then use it;
CLKSEL_PLLSEL =1; //engage PLL to system;
}
/********************************************************************/
void Init_AD() {
ATD0CTL0 = 0x01; //多通道转换时翻转回7通道
ATD0CTL1 = 0x01; //7:0-外部触发,65:00-8位精度,4:0-放电,3210:0001-AN1
ATD0CTL2 = 0x40; //6:1-快速清除标志位,43:00-下降沿触发,2:0禁止外部触发,01:中断禁止
ATD0CTL3 = 0x90; //7:1右对齐无符号,每次转换2个序列, No FIFO, Freeze模式下继续转 (4个通道吧)
ATD0CTL4 = 0xfe; //765:采样时间为4个AD时钟周期,ATDClock=[BusClock*0.5]/[PRS+1]
ATD0CTL5 = 0x31; //6:0特殊通道禁止,5:1连续转换 ,4:1多通道轮流采样通道1开始12
ATD0DIEN = 0x00; //禁止数字输?/禁止数字输入
}
/*********************************************************************/
void Init_SCI(){
SCI0BD = 260; //设置波特率为9600 260
SCI0CR1 = 0X00; //正常的8位数据传送,无奇偶校验
SCI0CR2 = 0X2C; //发送允许,中断发送允许
}
/*********************************************************************/
/*********************************************************************/
void Get_AD(void) {
int i;
while(!ATD0STAT0_SCF);
for(i=0;i<Gather_time;i++) {
ACCE += ATD0DR1;//加速度计
GYRO += ATD0DR2;//陀螺仪
}
}
void Get_Offset(void){
Off_GYRO = (int)(GYRO/Gather_time/1000)>>4;
Off_GYRO = Off_GYRO<<4;
Off_ACCE = (int)(ACCE/Gather_time/1000)>>4;
Off_ACCE = Off_ACCE<<4;
ACCE = 0;
GYRO = 0;
}
void Get_Aver_AD(void) {
Aver_ACCE = (int)(ACCE/Gather_time);
Aver_ACCE = Aver_ACCE>>4;
Aver_ACCE = Aver_ACCE<<4;
Aver_GYRO = (int)(GYRO/Gather_time);
Aver_GYRO = Aver_GYRO>>4;
Aver_GYRO = Aver_GYRO<<4;
ACCE = 0;
GYRO = 0;
}
void AngleCount(void){
float fDeltaValue ;
g_fAcce = ( Aver_ACCE - Off_ACCE) * ACCE_UNIT;
//加速度的偏置值 加速度的比例
g_fGyroSpeed = (Aver_GYRO - Off_GYRO) * GYRO_Ratio;
//陀螺仪的偏置值 陀螺仪的比例
g_fCarAngle = g_fGYRO_Integral;
fDeltaValue = (g_fAcce - g_fCarAngle) / ACCE_Adjust_Time;
//加速度调整时间常数
g_fGYRO_Integral += (g_fGyroSpeed + fDeltaValue) / GYROSCOPE_ANGLE_SIGMA_FREQUENCY;
// 陀螺仪角度周期频率
}
/*************************************************************************/
unsigned short CRC_CHECK(unsigned char *Buf, unsigned char CRC_CNT)
{
unsigned short CRC_Temp;
unsigned char i,j;
CRC_Temp = 0xffff;
for (i=0;i<CRC_CNT; i++){
CRC_Temp ^= Buf[i];
for (j=0;j<8;j++) {
if (CRC_Temp & 0x01)
CRC_Temp = (CRC_Temp >>1 ) ^ 0xa001;
else
CRC_Temp = CRC_Temp >> 1;
}
}
return(CRC_Temp);
}
void uart_putchar ( unsigned char c)
{
while(!(SCI0SR1&0x80)) ; //keep waiting when not empty
SCI0DRL=c;
}
void OutPut_Data(void)
{
int temp[4] = {0};
unsigned int temp1[4] = {0};
unsigned char databuf[10] = {0};
unsigned char i;
unsigned short CRC16 = 0;
for(i=0;i<4;i++)
{
temp[i] = (int)OutData[i];
temp1[i] = (unsigned int)temp[i];
}
for(i=0;i<4;i++)
{
databuf[i*2] = (unsigned char)(temp1[i]%256);
databuf[i*2+1] = (unsigned char)(temp1[i]/256);
}
CRC16 = CRC_CHECK(databuf,8);
databuf[8] = CRC16%256;
databuf[9] = CRC16/256;
for(i=0;i<10;i++)
uart_putchar(databuf[i]);
}
/*********************************************************************/
void main(void) {
/* put your own code here */
int i;
SetBusCLK_40M();
Init_AD();
Init_SCI();
for(i=0;i<1000;i++) {
Get_AD();
}
Get_Offset();
while(1){
Get_AD();
Get_Aver_AD();
AngleCount();
OutData[0] = g_fAcce;
OutData[1] = g_fGyroSpeed;
OutData[2] = g_fCarAngle;
OutData[3] = g_fGYRO_Integral;
OutPut_Data();
}
EnableInterrupts;
/* please make sure that you never leave main */
}
按我这样的程序,为什么显示不了像PDF里那样平滑的曲线,都是一些折线的??
|
|