SPI 配置
作为参数参考,其详细配置请自行在CUBEMX 中配置生成代码
void MX_SPI2_Init(void)
{
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi2.Init.CLKPhase = SPI_PHASE_2EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 7;
hspi2.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi2.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
if (HAL_SPI_Init(&hspi2) != HAL_OK)
{
Error_Handler();
}
GPIO_InitStruct.Pin = CS1_ACCEL_Pin|CS1_GYRO_Pin|SPI2_NSS_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOB, CS1_ACCEL_Pin|CS1_GYRO_Pin|SPI2_NSS_Pin, GPIO_PIN_SET);
}
RM3100.C
#include "stdio.h"
#include "RM3100.h"
#include "spi.h"
#define RM3100_CS HAL_GPIO_WritePin(SPI2_NSS_GPIO_Port,SPI2_NSS_Pin,GPIO_PIN_RESET);
#define RM3100_DEL HAL_GPIO_WritePin(SPI2_NSS_GPIO_Port,SPI2_NSS_Pin,GPIO_PIN_SET);
uint8_t ccx0;
uint8_t ccx1;
uint8_t ccy0;
uint8_t ccy1;
uint8_t ccz0;
uint8_t ccz1;
void RM3100_init(void)
{
spi_read_onebyte(RM3100_CCX0_REG,&ccx0);
spi_read_onebyte(RM3100_CCX0_REG,&ccx0);
spi_read_onebyte(RM3100_CCX1_REG,&ccx1);
spi_read_onebyte(RM3100_CCY0_REG,&ccy0);
spi_read_onebyte(RM3100_CCY1_REG,&ccy1);
spi_read_onebyte(RM3100_CCZ0_REG,&ccz0);
spi_read_onebyte(RM3100_CCZ1_REG,&ccz1);
if((ccx0!=CCP0_DEFAULT)||(ccx1!=CCP1_DEFAULT)|| (ccy0!=CCP0_DEFAULT)||(ccy1!=CCP1_DEFAULT)||(ccz0!=CCP0_DEFAULT)||(ccz1!=CCP1_DEFAULT))
{
}
else
{
spi_write_onebyte(RM3100_TMRC_REG,TMRC);
spi_write_onebyte(RM3100_CMM_REG,CMM);
spi_write_onebyte(RM3100_CCX1_REG,CCP1);
spi_write_onebyte(RM3100_CCX0_REG,CCP0);
spi_write_onebyte(RM3100_CCY1_REG,CCP1);
spi_write_onebyte(RM3100_CCY0_REG,CCP0);
spi_write_onebyte(RM3100_CCZ1_REG,CCP1);
spi_write_onebyte(RM3100_CCZ0_REG,CCP0);
}
}
void spi_read_bytes(uint8_t reg,uint8_t len,uint8_t read_data[])
{
uint8_t temp;
RM3100_CS;
SPI1_ReadWriteByte(reg | 0x80);
for(temp=0;temp<len;temp++)
{
read_data[temp] = SPI1_ReadWriteByte(0xff);
}
RM3100_DEL;
}
void spi_read_onebyte(uint8_t reg,uint8_t *data)
{
RM3100_CS;
SPI1_ReadWriteByte(reg | 0x80);
*data = SPI1_ReadWriteByte(0xff);
RM3100_DEL;
}
void spi_write_onebyte(uint8_t reg,uint8_t data)
{
RM3100_CS;
SPI1_ReadWriteByte(reg);
SPI1_ReadWriteByte(data);
RM3100_DEL;
}
void spi_write_bytes(uint8_t reg,uint8_t len,uint8_t write_data[])
{
uint8_t temp;
RM3100_CS;
SPI1_ReadWriteByte(reg);
for(temp=0;temp<len;temp++)
{
SPI1_ReadWriteByte(write_data[temp]);
}
RM3100_DEL;
}
bool RM3100_data_ok(void)
{
uint8_t temp;
spi_read_onebyte(RM3100_STATUS_REG,&temp);
if(temp&0x80) return true;
else return false;
}
uint8_t SPI1_ReadWriteByte(uint8_t TxData)
{
uint8_t retry=0;
HAL_SPI_TransmitReceive(&hspi2,&TxData,&retry,1,0xffff);
return retry;
}
bool get_RM3100_data(int32_t* mx,int32_t* my,int32_t* mz)
{
uint8_t temp_data[9];
uint8_t status=0;
int32_t mag_data[3];
while(!(status&0x80))
spi_read_onebyte(RM3100_STATUS_REG,&status);
if(!(status&0x80)) return false;
spi_read_bytes(RM3100_MX2_REG,9,temp_data);
mag_data[0]= (uint32_t)temp_data[0]<<24 | (uint32_t)temp_data[1]<<16 | (uint32_t)temp_data[2]<<8;
mag_data[1]= (uint32_t)temp_data[3]<<24 | (uint32_t)temp_data[4]<<16 | (uint32_t)temp_data[5]<<8;
mag_data[2]= (uint32_t)temp_data[6]<<24 | (uint32_t)temp_data[7]<<16 | (uint32_t)temp_data[8]<<8;
*mx=mag_data[0]>>8;
*my=mag_data[1]>>8;
*mz=mag_data[2]>>8;
return true;
}
uint8_t get_RM3100_devid(void)
{
uint8_t dev_id;
spi_read_onebyte(RM3100_REVID_REG,&dev_id);
return dev_id;
}
RM3100.H
#ifndef __RM3100_H
#define __RM3100_H
#include <stdbool.h>
#include "main.h"
#define RM3100_POLL_REG 0x00
#define RM3100_CMM_REG 0x01
#define RM3100_CCX1_REG 0x04
#define RM3100_CCX0_REG 0x05
#define RM3100_CCY1_REG 0x06
#define RM3100_CCY0_REG 0x07
#define RM3100_CCZ1_REG 0x08
#define RM3100_CCZ0_REG 0x09
#define RM3100_TMRC_REG 0x0B
#define RM3100_MX2_REG 0x24
#define RM3100_MX1_REG 0x25
#define RM3100_MX0_REG 0x26
#define RM3100_MY2_REG 0x27
#define RM3100_MY1_REG 0x28
#define RM3100_MY0_REG 0x29
#define RM3100_MZ2_REG 0x2A
#define RM3100_MZ1_REG 0x2B
#define RM3100_MZ0_REG 0x2C
#define RM3100_BIST_REG 0x33
#define RM3100_STATUS_REG 0x34
#define RM3100_HSHAKE_REG 0x34
#define RM3100_REVID_REG 0x36
#define CCP0 0xC8
#define CCP1 0x00
#define CCP0_DEFAULT 0xC8
#define CCP1_DEFAULT 0x00
#define GAIN_CC50 20.0f
#define GAIN_CC100 38.0f
#define GAIN_CC200 75.0f
#define UTESLA_TO_MGAUSS 10.0f
#define TMRC 0x93
#define CMM 0x71
typedef struct
{
uint16_t raw_mag_x;
uint16_t raw_mag_y;
uint16_t raw_mag_z;
float mag_ut_x;
float mag_ut_y;
float mag_ut_z;
}RM3100_DATA;
void spi_read_bytes(uint8_t reg,uint8_t len,uint8_t read_data[]);
void spi_read_onebyte(uint8_t reg,uint8_t *data);
void spi_write_onebyte(uint8_t reg,uint8_t data);
void spi_write_bytes(uint8_t reg,uint8_t len,uint8_t write_data[]);
void RM3100_init(void);
bool get_RM3100_data(int32_t *mx,int32_t *my,int32_t *mz);
uint8_t get_RM3100_devid(void);
bool RM3100_data_ok(void);
uint8_t SPI1_ReadWriteByte(uint8_t TxData);
#endif
MAIN.C
int32_t mx,my,mz;
get_RM3100_data(&mx,&my,&mz);
|