AS5048的硬件SPI操作源码

发布者:落寞梦惊最新更新时间:2019-04-27 来源: eefocus关键字:AS5048  硬件SPI  操作源码 手机看文章 扫描二维码
随时随地手机看文章

调了半天终于调通了,贴出来给有需要的朋友参考下,给stm32写的,硬件SPI


c文件:


/**

  ******************************************************************************

  * @file    AS5048A.c

  * @author  Lei Liu

  * @version V1.0

  * @date    2018.03.16

  * @brief   

  ******************************************************************************

  * @attention

  * SCK  -- PB13

  * MISO -- PB14

  * MOSI -- PB15

  * CS   -- PB12

  ******************************************************************************

  */

#include "AS5048.h"

#include "stm32f10x.h"



uint8_t error_flag;



//SPI2

void AS5048A_Init(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

SPI_InitTypeDef  SPI_InitStructure;


RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2,  ENABLE );

RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA| RCC_APB2Periph_GPIOB, ENABLE);



GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOB, &GPIO_InitStructure);


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOB, &GPIO_InitStructure);


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //Set CS pin high to disable device

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOB, &GPIO_InitStructure);

GPIO_SetBits(GPIOB, GPIO_Pin_12);



SPI_Cmd(SPI2, DISABLE);

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;;

SPI_InitStructure.SPI_Mode              = SPI_Mode_Master;

SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;

SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;

SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;

SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;

SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;

SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

SPI_InitStructure.SPI_CRCPolynomial = 7;

SPI_Init(SPI2, &SPI_InitStructure);


SPI_Cmd(SPI2, ENABLE);



DelayUs(500);

}







uint16_t SPI_WriteByte(uint16_t TxData)

{

GPIO_ResetBits(GPIOB, GPIO_Pin_12);


DelayUs(1);


SPI_I2S_SendData(SPI2, TxData); 



while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);



DelayUs(1);


GPIO_SetBits(GPIOB, GPIO_Pin_12);


DelayUs(1);

return SPI_I2S_ReceiveData(SPI2);  

}



// Calculates even parity of 16it value, returns 1 (odd) or 0 (even)

uint8_t parity_even(uint16_t v) 

{

    if(v == 0) return 0;



    v ^= v >> 8;

    v ^= v >> 4;

    v ^= v >> 2;

    v ^= v >> 1;

    

    return v & 1;

}



uint16_t Read_As5048A_Reg(uint16_t cmd)

{

uint16_t data = 0;

uint16_t res;

uint16_t command = 0x4000;// PAR=0 R/W=R

command = command | cmd;

command |= ((uint16_t)parity_even(command)<<15);//Add a parity bit on the the MSB

    SPI_WriteByte(command);


command = 0x4000;// PAR=0 R/W=R

command = command | CMD_NOP;

command |= ((uint16_t)parity_even(command)<<15);//Add a parity bit on the the MSB

    res = SPI_WriteByte(command);

error_flag = 1;



    if ((res & (1 << 14)) == 0)//判断第14位是否为0,0为正确值

{

        data = (res & 0x3FFF);

        error_flag = (parity_even(data) ^ (res >> 15));

    } 

else//读数据错误,发送清错误命令 

{

command = 0x4000;

command = command | CMD_CLEAR_ERROR;

command |= ((uint16_t)parity_even(command)<<15);//Add a parity bit on the the MSB

SPI_WriteByte(command);

    }

    return data;

}



//写寄存器

void Write_As5048A_Reg(uint16_t cmd,uint16_t value)

{

uint16_t data = 0;

uint16_t res;

uint16_t command = 0x0000; // PAR=0 R/W=W


command = command | cmd;

command |= ((uint16_t)parity_even(command)<<15);//Add a parity bit on the the MSB

    SPI_WriteByte(command);



command = 0x0000; // PAR=0 R/W=W

command = command | value;

command |= ((uint16_t)parity_even(command)<<15);//Add a parity bit on the the MSB

    SPI_WriteByte(command);



    command = 0x4000;// PAR=0 R/W=R

command = command | CMD_NOP;

command |= ((uint16_t)parity_even(command)<<15);//Add a parity bit on the the MSB

    res = SPI_WriteByte(command);

error_flag = 1;


    if ((res & (1 << 14)) == 0)//判断第14位是否为0,0为正确值

{

        data = (res & 0x3FFF);

        error_flag = (parity_even(data) ^ (res >> 15));

    } 

else//读数据错误,发送清错误命令 

{

        command = 0x4000;

command = command | CMD_CLEAR_ERROR;

command |= ((uint16_t)parity_even(command)<<15);//Add a parity bit on the the MSB

SPI_WriteByte(command);

    }

}





uint16_t Read_As5048A_Value(uint16_t cmd)

{

uint16_t val;

val = Read_As5048A_Reg(cmd);

if(error_flag)//奇偶校验错误

{

val = 0;

}

return val;

}









/************************************

OTP Write Zero Position: 0 for No error

1. Read angle information

2. Set the Programming Enable bit in the OTP control register

3. Write previous read angle position into OTP zero position register

4. Read back for verification the zero position register data

5. Set the Burn bit to start the automatic programming procedure

6. Read angle information (equals to 0)

7. Set the Verify bit to load the OTP data again into the internal registers with modified threshold comparator levels

8. Read angle information (equals to 0)

******************************************/

uint8_t Write_As5048A_ZeroPosition()

{

uint16_t Angle_val;

uint8_t Angle_High,Angle_Low;

uint16_t cmd;

Angle_val = Read_As5048A_Value(CMD_ANGLE);

cmd=Read_As5048A_Value(CMD_ProgramControl);


Write_As5048A_Reg(CMD_ProgramControl,0x01);

DelayUs(10);

cmd=Read_As5048A_Value(CMD_ProgramControl);

DelayUs(10);

Write_As5048A_Reg(CMD_OTPHigh,Angle_val>>8);

DelayUs(10);

Write_As5048A_Reg(CMD_OTPLow,Angle_val&0xFF);

DelayUs(10);

Angle_High=Read_As5048A_Value(CMD_OTPHigh);

DelayUs(10);

Angle_Low=Read_As5048A_Value(CMD_OTPLow);

DelayUs(10);

if(Angle_High != (uint8_t)(Angle_val>>8))

return 1;

if(Angle_Low != (uint8_t)(Angle_val&0xFF))

return 2;


Write_As5048A_Reg(CMD_ProgramControl,0x09);

DelayUs(10);

cmd=Read_As5048A_Value(CMD_ProgramControl);

DelayUs(10);

Angle_val = Read_As5048A_Value(CMD_ANGLE);

DelayUs(10);

if(Angle_val != 0 )

return 3;


Write_As5048A_Reg(CMD_ProgramControl,0x49);

DelayUs(10);

cmd=Read_As5048A_Value(CMD_ProgramControl);

DelayUs(10);

Angle_val = Read_As5048A_Value(CMD_ANGLE);

DelayUs(10);

if(Angle_val != 0 )

return 4;


return 0;

}





#ifndef __AS5048A_H

#define __AS5048A_H



#include "sys.h"





 


h文件:


 


//寄存器地址

#define CMD_ANGLE    0x3FFF //((1<<15) | (1<<14) | 0x3FFF)//角度信息

#define CMD_READ_MAG    0x3FFE//磁信息

#define CMD_READ_DIAG    0x3FFD //诊断信息

#define CMD_NOP            0x0000 //No operation dummy information

#define CMD_CLEAR_ERROR    0x0001 //错误状态寄存器

#define CMD_ProgramControl 0x0003

#define CMD_OTPHigh 0x0016

#define CMD_OTPLow 0x0017







void AS5048A_Init(void);

uint16_t SPI_WriteByte(uint16_t TxData);

void Write_As5048A_Reg(uint16_t cmd,uint16_t value);

uint8_t parity_even(uint16_t v);

uint16_t Read_As5048A_Reg(uint16_t cmd);

uint16_t Read_As5048A_Value(uint16_t cmd);

uint8_t Write_As5048A_ZeroPosition();//OTP Abandoned

#endif


关键字:AS5048  硬件SPI  操作源码 引用地址:AS5048的硬件SPI操作源码

上一篇:SCA100T STM32代码
下一篇:STM32F0系列Hal库SPI库BUG

推荐阅读最新更新时间:2024-11-17 00:21

STM32硬件SPI驱动0.96寸的OLED
1.OLED相关 参见—- 51 软件模拟SPI驱动OLED 2.硬件SPI 参见—- SPI专题(二)——STM32驱动FLASH(W25Q64) 3.驱动程序 驱动程序参照51单片机进行移植,只不过模拟的SPI换成STM32硬件SPI,不用再写时序部分的代码。对于STM32的硬件SPI,我们在驱动FLASH中已有介绍,这里就不再做介绍。 OLED引脚部分定义: #ifndef __OLED_H #define __OLED_H #include spi.h #include stm32f10x.h #include stm32f10x_conf.h #define Max_Column
[单片机]
基于PIC16F73单片机和ADS8341的SPI通信软硬件实现方法
PIC单片机为美国微芯公司(Ml-CROChip)公司生产研发,品种极其丰富,各系列片内功能资源各不相同,可以满足用户不同层次的开发要求。它采用哈佛总线结构和精简指令集(RISC)技术,其寻址方式简单、运行速度快、功耗低、驱动能力强等。在MICROCHIP公司PIC系列产品里,有低档、中挡、高挡单片机,且大部分都带有USART、SPI、IIC等总线接口,有的甚至还带有USB和CAN模块。这些特点给开发者带来了很大的方便。 1.ADS8341的特性 ADS8341是一种比较新的逐次逼近式的16位的A/D转换器件,其需要2.7~5V单电压供电,具有4通道单独输入或2通道差动输入,可以通过一个8位的控制字来选择其输入通道,
[单片机]
基于PIC16F73单片机和ADS8341的<font color='red'>SPI</font>通信软<font color='red'>硬件</font>实现方法
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
更多每日新闻

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved