硬件上按经典的方案,MMA7361+ENC-03 目前正在测试 MMA7361 但用 visual scope 观察 波形一直不正确。望大侠帮忙。谢谢!
#include"STC12C5A60S2.H"
#include"intrins.h"
#include"math.h"
typedef unsigned char BYTE;
typedef unsigned int WORD;
#define ADC_POWER 0X80 //ADC power control bit
#define ADC_FLAG 0X10 //ADC complete flag
#define ADC_START 0X08 //ADC start control bit
#define ADC_SPEEDHH 0X60 //90 clocks
#define Timer1HighInitValue 0XFD //定时器初值 高位
#define Timer1LowInitValue 0xFD //定时器初值 低位
#define Timer0HighInitValue 0XDC //定时器0初值 高位
#define Timer0LowInitValue 0X00 //定时器0初值 低位;定时时长10 MS
#define NOP() _nop_()
sbit SleepMode = P2^0;
float OutData[4] = {0};
static float Accelerometer ; //加速度计测量并换算出的角度
static ADCAverageValue ;
void UARTInit();
//void Timer0Init();
void ADCInit();
void Delay();
BYTE GetADValue();
void AngularV_Angular_Calc();
int CRC_CHECK(unsigned char *Buf, unsigned char CRC_CNT);
void TransmitData(float OutData[]);
void main()
{
UARTInit();
//Timer0Init();
ADCInit();
SleepMode = 1;
while(1)
{
//BYTE i = 200;
AngularV_Angular_Calc();
OutData[0] = Accelerometer;
TransmitData(OutData);
//while(i--);
}
}
void UARTInit()
{
//Set Timer1 as 8-bit auto reload mode
//STC12C5A60S2 复位后是传统51的速度,12分频,但指令仍然是 1T
//通过 AUXR 可以对定时器不进行分频
TMOD = 0x20; //定时器 T1 工作于方式2,8位自动重装;0010
//Set auto-reload value
TH1 = Timer1HighInitValue;
TL1 = Timer1LowInitValue;
//Timer1 start run
TR1 = 1; //打开定时器1
SM0 = 0; //scon 方式一,8位 UART,波特率可变
SM1 = 1;
}
void ADCInit()
{
P1M1 = 0XFF;
P1M0 = 0X00;
P1ASF = 0XFF; // p1.0、P1.0作为模拟功能 A/D 使用
//打开 ADC 电源, 速度为90个时钟周期, //启动 ADC,选择 P1.x 为模拟输入通道
// 1000 0000|0110 0000 |0000 1000 //|0000 0000
ADC_CONTR = ADC_POWER|ADC_SPEEDHH|0;
Delay(); //首次打开ADC电源,延时 1ms 等待内部模拟电源稳定
}
void Delay()
{
unsigned char a,b;
for(b=21;b>0;b--)
for(a=130;a>0;a--);
NOP(); //if Keil,require use intrins.h
}
BYTE GetADValue()
{
BYTE i;
BYTE ADC_H,ADC_L;
WORD ADCValueSum=0;
WORD Temp=0;
for(i=0;i<5;i++)
{
ADC_RES =0;
ADC_RESL = 0;
ADC_CONTR |= ADC_START; //重启 AD
NOP();
NOP();
NOP();
NOP();
//经过 4 个时钟延时后,才能够正确读到 ADC_CONTR 控制寄存器的值
while(!(ADC_CONTR & 0X10)); //等待转换完成
ADC_CONTR &= 0XE7; //关闭AD 转换, 清ADC_FLAG
ADC_H=ADC_RES;
Temp=Temp|ADC_H;
ADC_L=ADC_RESL;
ADC_L=ADC_L&0x03;
Temp=Temp<<2;
Temp=Temp|ADC_L;
//Temp = ADC_RES << 2 | ADC_RESL;
ADCValueSum+=Temp;
}
ADCAverageValue = ADCValueSum/5;
return(ADCAverageValue);
}
//角速度、角度的计算
void AngularV_Angular_Calc()
{
Accelerometer = GetADValue();
//Accelerometer *= 0.006104; //AD 转换后返回值换算系数 5/(1024*0.8)=0.006104
//Accelerometer = 5729.6 * asin(Accelerometer); //asin 返回值为弧度值,需要乘以 180/pi =57.296
}
/*********************************
发送函数区
*********************************/
/*
以下是CRC校验码生成程序,Buf传入的是将要进行CRC校验的数组
*/
int CRC_CHECK(unsigned char *Buf, unsigned char CRC_CNT)
{
unsigned 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 TransmitData(float OutData[])
{
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++)
{
SBUF = databuf[i];
while(!TI) ; //keep waiting when not empty
TI = 0;
}
}
/*********************************
发送函数区
*********************************/ |