找回密码
 立即注册
查看: 2601|回复: 9

51 开源 I2C-磁编码器-AS5600,12位磁编码器,通过串口发送

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-01 07:10:25
已绑定手机

76

主题

4833

回帖

8343

积分

超级版主

DebugLab

积分
8343
发表于 2023-10-19 22:39:37 | 显示全部楼层 |阅读模式
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位磁编码器 模块长这样:
O1CN017CJ0Yl2KZ76jMbfEn_!!2876359570.avif.jpg

O1CN01LnSQX02KZ76dN9fNT_!!2876359570.avif.jpg

模块原理图:

原理图.JPG

串口输出数据:

截图202310192217481756.jpg


串口和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)




DebugLab
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-01 07:10:25
已绑定手机

76

主题

4833

回帖

8343

积分

超级版主

DebugLab

积分
8343
发表于 2023-10-20 08:03:14 | 显示全部楼层
串口输出角度为实时角度,结果在极限值处有10bit回滞,如果配置了开始角度和结束角度,结果为对应的范围,本程序开始角度和结束角度初始化为0,所以结果和角度相等
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-01 07:10:25
已绑定手机

76

主题

4833

回帖

8343

积分

超级版主

DebugLab

积分
8343
发表于 2023-10-20 08:03:15 | 显示全部楼层
本帖最后由 DebugLab 于 2023-10-20 08:04 编辑

磁铁使用径向充磁的磁铁
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2024-01-15 09:24:33

1

主题

12

回帖

82

积分

注册会员

积分
82
发表于 2023-12-20 09:31:43 | 显示全部楼层
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:338
  • 最近打卡:2025-05-01 00:00:50

4

主题

242

回帖

1287

积分

金牌会员

积分
1287
发表于 2024-1-9 16:38:18 | 显示全部楼层
这模块板子做的挺好看的,自己打样的?

点评

买的成品模块  发表于 2024-1-10 08:06
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:204
  • 最近打卡:2025-04-30 11:23:45

2

主题

65

回帖

168

积分

注册会员

积分
168
发表于 2024-8-7 08:37:23 | 显示全部楼层
求助,AS5600磁编码器怎么模拟出多圈角度呢

点评

不支持的  详情 回复 发表于 2024-8-7 09:26
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-01 07:10:25
已绑定手机

76

主题

4833

回帖

8343

积分

超级版主

DebugLab

积分
8343
发表于 2024-8-7 09:26:23 | 显示全部楼层
ofe*** 发表于 2024-8-7 08:37
求助,AS5600磁编码器怎么模拟出多圈角度呢

不支持的
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:347
  • 最近打卡:2025-05-01 10:36:23

7

主题

281

回帖

1051

积分

金牌会员

积分
1051
发表于 2024-12-12 10:00:42 | 显示全部楼层
学习了
回复

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:87
  • 最近打卡:2025-04-30 09:11:54
已绑定手机

12

主题

56

回帖

367

积分

中级会员

积分
367
发表于 2025-2-20 17:18:27 | 显示全部楼层
感谢大神分享
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-1 19:43 , Processed in 0.463879 second(s), 112 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表