角度传感器程序总结

角度传感器程序总结
角度传感器程序总结

角度传感器程序总结

——电信101 吴超琼

角度传感器AS5045这种绝对角度测量方式可即时指出磁铁的角度位置,其分辨率达到0.0879°=每圈360°共4096个位置,能够以串行比特流及PWM信号输出的形式给出数字化数据。

2种数字式12位绝对值输出:

-串行接口输出

-脉冲调制(PWM)输出

该程序采用了串行接口输出12位绝对值输出。

角度传感器程序流程图如下:

AS5045采集得的数据是角度位置数据,要得到物体真正转过的角度就要进行计算,一圈360°,共4096个位置(5045芯片就是这样分配的),每个位置就有0.00879°,用读取AS5045得到的数据a乘以0.00879就得到我们所要求的角度。为了精确我们小数点后要有相应的有效数字,若有n位有效数字,就需要再乘以10n。例如:

jiaodu=a*0.00879*10n。

程序如下:

/*********通过AD转换和数字信号处理(DSP)算法**********/

/*********AS5045可提供精确的高分辨率*******************/

/*********绝对角度位置信息*****************************/

/*********AS5045能够检测磁场的方向并计算出12位的二进制编码********

*********此编码通过同步串行接口(SSI)进行访问*****/

/**********屏蔽掉的程序是另一种算法差不多************************/

#include

#include

#include

#define uchar unsigned char

#define uint unsigned int

/******液晶引脚定义******/

sbit RST=P0^0;

sbit PSB=P0^1;

sbit E=P0^5;

sbit RW=P0^6;

sbit RS=P0^7;

//用了并行PSB=1,数据口用P2

/*****AS5045引脚定义**************/

sbit D0=P3^2; //同步串行接口的数据输出

sbit CLK=P3^3; //同步串行接口的时钟输入

sbit CSn=P3^4; //片选,低电平有效,施密特触发器输入,内部上拉电阻

uint dd; //算得的最终角度

//float cc;

uint out,bb;

//out为获取得的角度信息(绝对角度位置数据)D[11:0] 串行字包括18位数据,前12位是角度信息

uint dis0[7]; //用来存放角度数据

uchar code tab[]={"角度传感器实验"};

uchar code dis1[]={"当前角度: "};

uchar code dis2[]={"."};

void delay(uint z)

{

uint x,y;

for(y=110;y>0;y--)

for(x=z;x>0;x--);

}

/*******读取忙状态****/

bit lcd_busy()

{

bit result;

RS=0;

RW=1;

E=1;

delay(5);

result=(bit)(P2&0X80);

E=0;

return(result);

}

/******写指令*******/

void write_com(uchar com)

{

while(lcd_busy());

RS=0;

RW=0;

P2=com;

delay(5);

E=1;

delay(5);

E=0;

delay(5); }

/******写数据*******/

void write_data(uchar dat)

{

while(lcd_busy());

RS = 1;

RW = 0;

E = 0;

P2 = dat;

delay(5);

E = 1;

delay(5);

E = 0;

}

//****液晶初始化******//

void lcd_init()

{

PSB = 1; //并行口

RST = 0; //复位

delay(5);

RST = 1;

delay(5);

write_com(0x30); //基本指令操作delay(5);

write_com(0x0c);//开显示

delay(5);

write_com(0x01); //清屏

delay(5);

}

/*****显示坐标********/

void lcd_pos(uchar x,uchar y)

{

uchar pos;

if(x==1)

{x=0x80;}

else if(x==2)

{x=0x90;}

else if(x==3)

{x=0x88;}

else if(x==4)

{x=0x98;}

pos=x+y;

write_com(pos); //显示地址

}

/*********获取角度信息(绝对角度位置数据)*****************************/

uint ad_change()

{

uchar i;

out=0; //初始化为0

CSn=1; //CSn片选先保持高电平

CLK=1; //时钟保持高电平

CSn=0; //CSn变为低电平,数据输出(D0)将从高阻状态变为高电平并启动读取操作

delay(2);

CLK=0; //数据在CLK的第一个下降沿锁存至输出移位寄存器内

delay(2);

for(i=0;i<12;i++) //有12位角度信息

{

out=out<<1; //一位一位的移出来

CLK=1;

//每个后续的CLK上升沿将移出一位数据

delay(2);

out|=D0;

delay(2);

CLK=0;

delay(2);

}

delay(2);

CSn=1; //通过一个CSn(持续一段时间)高脉冲来启动后续测量

//CSn=1用于启动下一个角度位置的读取操作

CLK=1;

delay(1);

return(out); //输出角度信息

}

/********计算角度并拆分*********************/

void jiaodu1()

{

bb=ad_change(); //角度位置数据

dd=(uint)(bb*8.79); //可以这样写,也可以像下面这样写

// cc=(float)(bb*0.0002442); // 360°/4096=0.0879°(一圈有4096个位置,每个位置占0.0879°)0.0879°/360°=0.0002442 (比率)

//

// dd=(long int)(cc*100*360); //100

是根据下面角度的小数点后面有几位有效数字,比如有2位就乘以100.3位就乘以1000

dis0[0]=dd/10000+0x30; //拆分角度,小数点后两位有效数字

dis0[1]=dd%10000/1000+0x30;

dis0[2]=dd%1000/100+0x30;

dis0[3]=dd%100/10+0x30;

dis0[4]=dd%10+0x30;

//dis0[0]=dd/1000000+0x30; //拆分角度,四位有效数字

//dis0[1]=dd%1000000/100000+0x30;

//dis0[2]=dd%100000/10000+0x30;

//dis0[3]=dd%10000/1000+0x30;

//dis0[4]=dd%1000/100+0x30;

//dis0[5]=dd%100/10+0x30;

//dis0[6]=dd%10+0x30;

}

void main()

{

uchar s;

delay(5);

lcd_init();//初始化

delay(5);

lcd_pos(1,0); //液晶显示初始化

s=0;

while (tab[s]!='\0')

{

write_data(tab[s]);

s++;

delay(2);

}

lcd_pos(2,0);//液晶显示初始化

s=0;

while (dis1[s]!='\0')

{

write_data(dis1[s]);

s++;

delay(2);

}

lcd_pos(3,2);

s=0;

while (dis2[s]!='\0')

{

write_data(dis2[s]);

s++;

delay(2);

}

while (1)

{

lcd_pos (3,0); //角度显示,小数点前有三位数字,小数点后有2位有效数字jiaodu1();

write_data(dis0[0]);

write_data(dis0[1]);

write_data(dis0[2]);

lcd_pos (3,3);

jiaodu1();

write_data(dis0[3]);

write_data(dis0[4]);

// write_data(dis0[5]);

// write_data(dis0[6]);

}

}

相关主题
相关文档
最新文档