51 开源 I2C-磁编码器-AS5600,12位磁编码器,通过串口发送 本程序实现AS5600读取各参数从串口发送的功能,注意AS5600有OTP存储器,通过IO口编程(GPO=0才能通过IO口编程,建议去掉R4避免误操作)只能执行1次,通过IO口或I2C编程只能执行3次,此操作不可逆,建议去掉R1使用5V模式,不去掉R1只能使用3.3V模式,5V模式最大增益255,3.3V模式最大增益128。
单片机 STC8G1K08A-8PIN,时钟频率11.0592MHz,UART1,115200bps,8N1, AS5600-12位磁编码器,使用成品模块。
AS5600-12位磁编码器 模块长这样:
模块原理图:
串口输出数据:
串口和printf的使用见此连接:
https://www.stcaimcu.com/forum.php?mod=viewthread&tid=4598
附带部分中文数据手册,重要部分已翻译。
/*----------------------------分割线----------------------------*/
#include <STC8G.H>
#include "define.h"
#include <intrins.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#define RXD P30
#define TXD P31
#define SCL P32
#define SDA P33
#define FOSC 11059200UL
#define BAUD 115200UL
#define BRT (0x10000-FOSC/BAUD/4)
#define T_Buffer_Len 64 //Uart1发送缓存长度
#define R_Buffer_Len 64 //Uart1接收缓存长度
#define AS5600_Write 0x6C
#define AS5600_Read 0x6D
unsigned char RP; //Uart1接收指针
unsigned char TP; //Uart1发送指针
unsigned char Uart_Send_Lenth; //Uart1发送长度
unsigned char xdata R_Buffer[R_Buffer_Len]; //Uart1接收缓存
unsigned char xdata T_Buffer[T_Buffer_Len]; //Uart1发送缓存
bit I2C_Busy;
/*----------------------------延时10us@STC-Y6@11.0592MHz----------------------------*/
void Delay_10us(void)
{
unsigned char i;
i=35;
while(--i);
}
/*----------------------------延时x10us----------------------------*/
void Delay_x10us(unsigned char x)
{
while(x--)
Delay_10us();
}
/*----------------------------延时10ms@STC-Y6@11.0592MHz----------------------------*/
void Delay_10ms(void)
{
unsigned char i,j;
_nop_();
_nop_();
i=144;
j=157;
do
{
while(--j);
}while(--i);
}
/*----------------------------延时x10ms----------------------------*/
void Delay_x10ms(unsigned char x)
{
while(x--)
Delay_10ms();
}
void UART_Send(unsigned int x)
{
TP=0;
Uart_Send_Lenth=x;
TI=1;
}
void Uart_Printf(unsigned char *v,...)
{
va_list ap;
va_start(ap,v);
while(Uart_Send_Lenth);
UART_Send(vsprintf(T_Buffer,v,ap));
va_end(ap);
}
void I2C_Start(void)
{
I2C_Busy=1;
I2CMSCR=0x81;
while(I2C_Busy);
}
void I2C_SendData(unsigned char dat)
{
I2CTXD=dat;
I2C_Busy=1;
I2CMSCR=0x82;
while(I2C_Busy);
}
void I2C_RecvACK(void)
{
I2C_Busy=1;
I2CMSCR=0x83;
while(I2C_Busy);
}
unsigned char I2C_RecvData(void)
{
I2C_Busy=1;
I2CMSCR=0x84;
while(I2C_Busy);
return I2CRXD;
}
void I2C_SendACK(void)
{
I2CMSST=0x00;
I2C_Busy=1;
I2CMSCR=0x85;
while(I2C_Busy);
}
void I2C_SendNAK(void)
{
I2CMSST=0x01;
I2C_Busy=1;
I2CMSCR=0x85;
while(I2C_Busy);
}
void I2C_Stop(void)
{
I2C_Busy=1;
I2CMSCR=0x86;
while(I2C_Busy);
}
void AS5600_Write_One_Byte(unsigned char addr,unsigned char dat)
{
I2C_Start();
I2C_SendData(AS5600_Write);
I2C_RecvACK();
I2C_SendData(addr);
I2C_RecvACK();
I2C_SendData(dat);
I2C_RecvACK();
I2C_Stop();
}
void AS5600_Write_Two_Byte(unsigned char addr,unsigned int dat)
{
I2C_Start();
I2C_SendData(AS5600_Write);
I2C_RecvACK();
I2C_SendData(addr);
I2C_RecvACK();
I2C_SendData((unsigned char)(dat>>8));
I2C_RecvACK();
I2C_SendData((unsigned char)(dat&0x00FF));
I2C_RecvACK();
I2C_Stop();
}
unsigned char AS5600_Read_One_Byte(unsigned char addr)
{
unsigned char dat;
I2C_Start();
I2C_SendData(AS5600_Write);
I2C_RecvACK();
I2C_SendData(addr);
I2C_RecvACK();
I2C_Start();
I2C_SendData(AS5600_Read);
I2C_RecvACK();
dat=I2C_RecvData();
I2C_SendNAK();
I2C_Stop();
return dat;
}
unsigned int AS5600_Read_Two_Byte(unsigned char addr)
{
unsigned char msb,lsb;
unsigned int dat;
I2C_Start();
I2C_SendData(AS5600_Write);
I2C_RecvACK();
I2C_SendData(addr);
I2C_RecvACK();
I2C_Start();
I2C_SendData(AS5600_Read);
I2C_RecvACK();
msb=I2C_RecvData();
I2C_SendACK();
lsb=I2C_RecvData();
I2C_SendNAK();
I2C_Stop();
dat=(unsigned int)msb<<8;
dat|=(unsigned int)lsb;
return dat;
}
void AS5600_Init(void)
{
AS5600_Write_Two_Byte(0x01,0x00);
Delay_x10us(100);
AS5600_Write_Two_Byte(0x03,0x00);
Delay_x10us(100);
AS5600_Write_One_Byte(0x07,0x00);
Delay_x10us(100);
AS5600_Write_One_Byte(0x08,0x00);
Delay_x10us(100);
// AS5600_Write_One_Byte(0xFF,0x80); //警告:此操作不可逆!
// Delay_x10us(100);
Uart_Printf("ZMCO=%BU\r\n",AS5600_Read_One_Byte(0x00));
Uart_Printf("ZPOS=%U\r\n",AS5600_Read_Two_Byte(0x01));
Uart_Printf("MPOS=%U\r\n",AS5600_Read_Two_Byte(0x03));
Uart_Printf("MANG=%U\r\n",AS5600_Read_Two_Byte(0x05));
Uart_Printf("CONF=0x%02BX%02BX\r\n",AS5600_Read_One_Byte(0x07),AS5600_Read_One_Byte(0x08));
}
void Init(void)
{
P_SW2|=EAXFR;
P3M0=0x00;
P3M1=0x00;
P5M0=0x00;
P5M1=0x00;
P3PU=0x0c;
AUXR=0x40; //设置定时器0时钟为12T模式,设置定时器1为1T模式,设置定时器1为波特率发生器
TMOD=0x01; //设置定时器0为16位不自动重装载模式,设置定时器1为16位自动重装载模式
TL0=0x00; //设置定时器0初始值(5ms)
TH0=0xEE; //设置定时器0初始值(5ms)
TF0=0; //清除TF0中断标志位
ET0=1; //启用定时器0中断
SCON=0x50; //设置UART1模式为8位数据可变波特率
TL1=BRT; //设置UART1波特率
TH1=BRT>>8; //设置UART1波特率
TR1=1; //打开定时器1
ES=1; //启用UART1中断
I2CCFG=0xC6; //345.6K@11.0592M
I2CMSCR=EMSI;
I2CMSST=0x00;
EA=1; //启用总中断
AS5600_Init();
}
void main(void)
{
Init();
while(1)
{
Uart_Printf("角度=%04U 结果=%04U 检测到磁铁=%BU 磁场太弱=%BU 磁场太强=%BU 增益=%03BU 幅度=%04U\r\n",AS5600_Read_Two_Byte(0x0C),AS5600_Read_Two_Byte(0x0E),(AS5600_Read_One_Byte(0x0B)&0x20)>>5,(AS5600_Read_One_Byte(0x0B)&0x10)>>4,(AS5600_Read_One_Byte(0x0B)&0x08)>>3,AS5600_Read_One_Byte(0x1A),AS5600_Read_Two_Byte(0x1B));
Delay_x10ms(2);
}
}
void Uart_Start(void)
{
TL0=0x00;
TH0=0xEE;
TR0=1;
}
void Uart_Stop(void)
{
TR0=0;
TL0=0x00;
TH0=0xEE;
RP=0;
memset(R_Buffer,0x00,sizeof R_Buffer);
}
void Timer0_Isr(void) interrupt 1
{
Uart_Stop();
}
void Uart_Isr(void) interrupt 4
{
if(RI)
{
RI=0;
Uart_Start();
R_Buffer[RP]=SBUF;
if(RP==0)
{
IAP_CONTR=0x60;
}
if(RP==R_Buffer_Len-1)
{
Uart_Stop();
}
else if(TR0)
{
RP++;
}
}
if(TI)
{
TI=0;
if(Uart_Send_Lenth!=0)
{
SBUF=(T_Buffer[TP]);
TP++;
}
if(TP==Uart_Send_Lenth)
{
TP=0;
Uart_Send_Lenth=0;
}
}
}
void I2C_Isr(void) interrupt 24
{
_push_(P_SW2);
P_SW2|=EAXFR;
if(I2CMSST&MSIF)
{
I2CMSST&=~MSIF;
I2C_Busy=0;
}
_pop_(P_SW2);
}
/*----------------------------分割线----------------------------*/
完整工程见附件:
AS5600.zip
(1.61 MB, 下载次数: 201)
|