STM32 Driver and Hardware Design for ADXL345 (ZT) by ADIForum
The netizen "Hunting Stars" was posted on Sina Weibo's blog post - "ADTM345 STM32 Driver and Hardware Design" (original link http://blog.sina.com.cn/s/blog_6754612e0101ag39.html ), with the author's consent Forward this forum
First, the hardware circuit interface picture
1. The ADXL345 hardware interface picture uses the SPI port for communication, so that the data is read faster and can be converted into the IIC communication interface.
I found some IIC interfaces on the Internet, so I will do SPI communication on DIY.
2.STM32F103T series MCU is rich in MCU resources, I am familiar with development speed.
The hardware circuit is first to achieve the function, so the design is relatively simple. Subsequent Xiaobian wants to do wireless Bluetooth data transmission, so the hardware interface of Bluetooth serial communication and 3.3V power management are also left on the hardware.
For the time being, the hardware is designed in such a way that it is designed as a double-layer PCB, thus reducing the space. Capacitance and resistance are 0805 easy to solder. The device is selected as a patch.
Second, the microcontroller driver code
1.ADXL345 port configuration function
#define ADXL345_FLAG_TIMEOUT ((uint32_t)0x1000)
#define ADXL345_SPI SPI1
#define ADXL345_SPI_CLK RCC_APB2Periph_SPI1
#define ADXL345_SPI_SCK_PIN GPIO_Pin_5
#define ADXL345_SPI_SCK_GPIO_PORT GPIOA
#define ADXL345_SPI_SCK_GPIO_CLK RCC_APB2Periph_GPIOA
#define ADXL345_SPI_SCK_SOURCE GPIO_PinSource5
#define ADXL345_SPI_SCK_AF GPIO_AF_5
#define ADXL345_SPI_MISO_PIN GPIO_Pin_6
#define ADXL345_SPI_MISO_GPIO_PORT GPIOA
#define ADXL345_SPI_MISO_GPIO_CLK RCC_APB2Periph_GPIOA
#define ADXL345_SPI_MISO_SOURCE GPIO_PinSource6
#define ADXL345_SPI_MISO_AF GPIO_AF_5
#define ADXL345_SPI_MOSI_PIN GPIO_Pin_7
#define ADXL345_SPI_MOSI_GPIO_PORT GPIOA
#define ADXL345_SPI_MOSI_GPIO_CLK RCC_APB2Periph_GPIOA
#define ADXL345_SPI_MOSI_SOURCE GPIO_PinSource7
#define ADXL345_SPI_MOSI_AF GPIO_AF_5
#define ADXL345_SPI_CS_PIN GPIO_Pin_2
#define ADXL345_SPI_CS_GPIO_PORT GPIOB
#define ADXL345_SPI_CS_GPIO_CLK RCC_APB2Periph_GPIOB
#define ADXL345_SPI_INT1_PIN GPIO_Pin_0
#define ADXL345_SPI_INT1_GPIO_PORT GPIOB
#define ADXL345_SPI_INT1_GPIO_CLK RCC_APB2Periph_GPIOB
#define ADXL345_SPI_INT1_EXTI_LINE EXTI_Line0
#define ADXL345_SPI_INT1_EXTI_PORT_SOURCE EXTI_PortSourceGPIOB
#define ADXL345_SPI_INT1_EXTI_PIN_SOURCE EXTI_PinSource0
#define ADXL345_SPI_INT1_EXTI_IRQn EXTI0_IRQn
#define ADXL345_SPI_INT2_PIN GPIO_Pin_1
#define ADXL345_SPI_INT2_GPIO_PORT GPIOB
#define ADXL345_SPI_INT2_GPIO_CLK RCC_APB2Periph_GPIOB
#define ADXL345_SPI_INT2_EXTI_LINE EXTI_Line1
#define ADXL345_SPI_INT2_EXTI_PORT_SOURCE EXTI_PortSourceGPIOB
#define ADXL345_SPI_INT2_EXTI_PIN_SOURCE EXTI_PinSource1
#define ADXL345_SPI_INT2_EXTI_IRQn EXTI1_IRQn
#define ADXL345_WHO_AM_I_ADDR 0x0F
#define ADXL345_CTRL_REG1_ADDR 0x20
#define ADXL345_CTRL_REG2_ADDR 0x21
#define ADXL345_CTRL_REG3_ADDR 0x22
#define ADXL345_CTRL_REG4_ADDR 0x23
#define ADXL345_CTRL_REG5_ADDR 0x24
#define ADXL345_REFERENCE_REG_ADDR 0x25
#define ADXL345_OUT_TEMP_ADDR 0x26
#define ADXL345_STATUS_REG_ADDR 0x27
#define ADXL345_OUT_X_L_ADDR 0x28
#define ADXL345_OUT_X_H_ADDR 0x29
#define ADXL345_OUT_Y_L_ADDR 0x2A
#define ADXL345_OUT_Y_H_ADDR 0x2B
#define ADXL345_OUT_Z_L_ADDR 0x2C
#define ADXL345_OUT_Z_H_ADDR 0x2D
#define ADXL345_FIFO_CTRL_REG_ADDR 0x2E
#define ADXL345_FIFO_SRC_REG_ADDR 0x2F
#define ADXL345_INT1_CFG_ADDR 0x30
#define ADXL345_INT1_SRC_ADDR 0x31
#define ADXL345_INT1_TSH_XH_ADDR 0x32
#define ADXL345_INT1_TSH_XL_ADDR 0x33
#define ADXL345_INT1_TSH_YH_ADDR 0x34
#define ADXL345_INT1_TSH_YL_ADDR 0x35
#define ADXL345_INT1_TSH_ZH_ADDR 0x36
#define ADXL345_INT1_TSH_ZL_ADDR 0x37
#define ADXL345_INT1_DURATION_ADDR 0x38
#define I_AM_ADXL345 ((uint8_t)0xD4)
#define ADXL345_MODE_POWERDOWN ((uint8_t)0x00)
#define ADXL345_MODE_ACTIVE ((uint8_t)0x08)
#define ADXL345_OUTPUT_DATARATE_1 ((uint8_t)0x00)
#define ADXL345_OUTPUT_DATARATE_2 ((uint8_t)0x40)
#define ADXL345_OUTPUT_DATARATE_3 ((uint8_t)0x80)
#define ADXL345_OUTPUT_DATARATE_4 ((uint8_t)0xC0)
#define ADXL345_X_ENABLE ((uint8_t)0x02)
#define ADXL345_Y_ENABLE ((uint8_t)0x01)
#define ADXL345_Z_ENABLE ((uint8_t)0x04)
#define ADXL345_AXES_ENABLE ((uint8_t)0x07)
#define ADXL345_AXES_DISABLE ((uint8_t)0x00)
#define ADXL345_BANDWIDTH_1 ((uint8_t)0x00)
#define ADXL345_BANDWIDTH_2 ((uint8_t)0x10)
#define ADXL345_BANDWIDTH_3 ((uint8_t)0x20)
#define ADXL345_BANDWIDTH_4 ((uint8_t)0x30)
#define ADXL345_FULLSCALE_250 ((uint8_t)0x00)
#define ADXL345_FULLSCALE_500 ((uint8_t)0x10)
#define ADXL345_FULLSCALE_2000 ((uint8_t)0x20)
#define ADXL345_BlockDataUpdate_Continous ((uint8_t)0x00)
#define ADXL345_BlockDataUpdate_Single ((uint8_t)0x80)
#define ADXL345_BLE_LSB ((uint8_t)0x00)
#define ADXL345_BLE_MSB ((uint8_t)0x40)
#define ADXL345_HIGHPASSFILTER_DISABLE ((uint8_t)0x00)
#define ADXL345_HIGHPASSFILTER_ENABLE ((uint8_t)0x10)
#define ADXL345_INT1INTERRUPT_DISABLE ((uint8_t)0x00)
#define ADXL345_INT1INTERRUPT_ENABLE ((uint8_t)0x80)
#define ADXL345_INT2INTERRUPT_DISABLE ((uint8_t)0x00)
#define ADXL345_INT2INTERRUPT_ENABLE ((uint8_t)0x08)
#define ADXL345_INT1INTERRUPT_LOW_EDGE ((uint8_t)0x20)
#define ADXL345_INT1INTERRUPT_HIGH_EDGE ((uint8_t)0x00)
#define ADXL345_BOOT_NORMALMODE ((uint8_t)0x00)
#define ADXL345_BOOT_REBOOTMEMORY ((uint8_t)0x80)
#define ADXL345_HPM_NORMAL_MODE_RES ((uint8_t)0x00)
#define ADXL345_HPM_REF_SIGNAL ((uint8_t)0x10)
#define ADXL345_HPM_NORMAL_MODE ((uint8_t)0x20)
#define ADXL345_HPM_AUTORESET_INT ((uint8_t)0x30)
#define ADXL345_HPFCF_0 0x00
#define ADXL345_HPFCF_1 0x01
#define ADXL345_HPFCF_2 0x02
#define ADXL345_HPFCF_3 0x03
#define ADXL345_HPFCF_4 0x04
#define ADXL345_HPFCF_5 0x05
#define ADXL345_HPFCF_6 0x06
#define ADXL345_HPFCF_7 0x07
#define ADXL345_HPFCF_8 0x08
#define ADXL345_HPFCF_9 0x09
#define ADXL345_CS_LOW() GPIO_ResetBits(ADXL345_SPI_CS_GPIO_PORT, ADXL345_SPI_CS_PIN)
#define ADXL345_CS_HIGH() GPIO_SetBits(ADXL345_SPI_CS_GPIO_PORT, ADXL345_SPI_CS_PIN)
void ADXL345_Init(ADXL345_InitTypeDef *ADXL345_InitStruct);
void ADXL345_RebootCmd(void);
void ADXL345_INT1InterruptCmd(uint8_t InterruptState);
void ADXL345_INT2InterruptCmd(uint8_t InterruptState);
void ADXL345_INT1InterruptConfig(ADXL345_InterruptConfigTypeDef *ADXL345_IntConfigStruct);
uint8_t ADXL345_GetDataStatus(void);
void ADXL345_FilterConfig(ADXL345_FilterConfigTypeDef *ADXL345_FilterStruct);
void ADXL345_FilterCmd(uint8_t HighPassFilterState);
void ADXL345_Write(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite);
void ADXL345_Read(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead);
2.ADXL345的SPI配置函数
void SPI_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA |
RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(ADXL345_SPI_CLK ,ENABLE);
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin =ADXL345_SPI_CS_PIN ;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(ADXL345_SPI_CS_GPIO_PORT, &GPIO_InitStructure);
GPIO_SetBits(ADXL345_SPI_CS_GPIO_PORT,ADXL345_SPI_CS_PIN);
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin =ADXL345_SPI_SCK_PIN|ADXL345_SPI_MISO_PIN|ADXL345_SPI_MOSI_PIN;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(ADXL345_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);
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_High;
SPI_InitStructure.SPI_CPHA=SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_256;
SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial=7;
SPI_Init(ADXL345_SPI, &SPI_InitStructure);
SPI_Cmd(ADXL345_SPI,ENABLE);
}
3.ADXL345初始化配置函数
void ADXL345_init(void)
{
SPI_init(); //ADXL345¶Ë¿Ú³õʼ»¯ÅäÖÃSPIͨÐÅ
ADXL345_write_byte(0x1E,0x00); //X Æ«ÒÆÁ¿ ¸ù¾Ý²âÊÔ´«¸ÐÆ÷µÄ״̬дÈëpdf29Ò³ 0X00 (15.6mg/LSB)
ADXL345_write_byte(0x1F,0x00); //Y Æ«ÒÆÁ¿ ¸ù¾Ý²âÊÔ´«¸ÐÆ÷µÄ״̬дÈëpdf29Ò³ 0X00 (15.6mg/LSB)
ADXL345_write_byte(0x20,0x00); //Z Æ«ÒÆÁ¿ ¸ù¾Ý²âÊÔ´«¸ÐÆ÷µÄ״̬дÈëpdf29Ò³ 0X00 (15.6mg/LSB)
ADXL345_write_byte(0x21,0x00); //Çû÷ÑÓʱ0:½ûÓÃ; (1.25ms/LSB)
ADXL345_write_byte(0x22,0x00); //¼ì²âµÚÒ»´ÎÇû÷ºóµÄÑÓʱ0:½ûÓÃ; (1.25ms/LSB)
ADXL345_write_byte(0x23,0x00); //Çû÷´°¿Ú0:½ûÓÃ; (1.25ms/LSB)
ADXL345_write_byte(0x24,0x01); //±£´æ¼ì²â»î¶¯·§Öµ; (62.5mg/LSB)
ADXL345_write_byte(0x25,0x01); //±£´æ¼ì²â¾²Ö¹·§Öµ; (62.5mg/LSB)
ADXL345_write_byte(0x26,0x2B); //¼ì²â»î¶¯Ê±¼ä·§Öµ; (1s/LSB)
ADXL345_write_byte(0x27,0x00); //
ADXL345_write_byte(0x28,0x09); //×ÔÓÉÂäÌå¼ì²âÍƼö·§Öµ; (62.5mg/LSB)
ADXL345_write_byte(0x29,0xFF); //×ÔÓÉÂäÌå¼ì²âʱ¼ä·§Öµ,ÉèÖÃΪ×î´óʱ¼ä; (5ms/LSB)
ADXL345_write_byte(0x2A,0x80); //
//ADXL345_read_byte(0x2B); //Ö»¶Á¼Ä´æÆ÷,״̬¶ÁÈ¡
ADXL345_write_byte(0x2C,0x0F); //ËÙÂÊÉ趨Ϊ3200HZ²Î¿¼pdf13Ò³ 0X0A 1OO,0X0E 1600HZ
ADXL345_write_byte(0x2D,0x08); //Ñ¡ÔñµçԴģʽ¹Ø±Õ×Ô¶¯ÐÝÃß,ÐÝÃß,»½Ðѹ¦Äܲο¼pdf24Ò³
ADXL345_write_byte(0x2E,0x80); //ʹÄÜ DATA_READY ÖжÏ
ADXL345_write_byte(0x2F,0x00);
//ADXL345_read_byte(0x30); //Ö»¶Á¼Ä´æÆ÷,״̬¶ÁÈ¡
ADXL345_write_byte(0x31,0X0B); //Êý¾ÝͨПñʽ;ÉèÖÃΪ×Լ칦ÄܽûÓÃ,4ÏßÖÆSPI½Ó¿Ú,µÍµçƽÖжÏÊä³ö,13λȫ·Ö±æÂÊ,Êä³öÊý¾ÝÓÒ¶ÔÆë,16gÁ¿³Ì
ADXL345_write_byte(0x38,0x00); //FIFOģʽÉ趨,Streamģʽ£¬´¥·¢Á¬½ÓINT1,31¼¶Ñù±¾»º³å
//ADXL345_read_byte(0x39); //Ö»¶Á¼Ä´æÆ÷,״̬¶ÁÈ¡
}
4.ADXL345的读写函数
u8 ADXL345_read_byte(u8 add)
{
GPIO_ResetBits(ADXL345_SPI_CS_GPIO_PORT ,ADXL345_SPI_CS_PIN);
SPI_I2S_SendData(ADXL345_SPI,(add|0x80)<<8|0x00);
while(SPI_I2S_GetFlagStatus(ADXL345_SPI,SPI_I2S_FLAG_TXE)==RESET);
while(SPI_I2S_GetFlagStatus(ADXL345_SPI, SPI_I2S_FLAG_RXNE)==RESET);
GPIO_SetBits(ADXL345_SPI_CS_GPIO_PORT ,ADXL345_SPI_CS_PIN);
return SPI_I2S_ReceiveData(ADXL345_SPI)&0xff;
}
void ADXL345_write_byte(u8 add,u8 val)
{
GPIO_ResetBits(ADXL345_SPI_CS_GPIO_PORT ,ADXL345_SPI_CS_PIN);
SPI_I2S_SendData(ADXL345_SPI,add<<8|val);
while(SPI_I2S_GetFlagStatus(ADXL345_SPI,SPI_I2S_FLAG_TXE)==RESET);
while(SPI_I2S_GetFlagStatus(ADXL345_SPI, SPI_I2S_FLAG_RXNE)==RESET);
GPIO_SetBits(ADXL345_SPI_CS_GPIO_PORT ,ADXL345_SPI_CS_PIN);
SPI_I2S_ReceiveData(ADXL345_SPI)&0xff;
}
void ADXL345_ReadXYZ(float *g)
{
uint8_t BUF[6]; // ´æ·ÅX,Y,ZÖáµÄÊý¾Ý
int16_t temp;
BUF[0] = ADXL345_read_byte(0x32);
BUF[1] = ADXL345_read_byte(0x33);
delay_ms(1);
BUF[2] = ADXL345_read_byte(0x34);
BUF[3] = ADXL345_read_byte(0x35);
delay_ms(1);
BUF[4] = ADXL345_read_byte(0x36);
BUF[5] = ADXL345_read_byte(0x37);
delay_ms(1);
temp = (BUF[1] << 8) + BUF[0];
if(temp < 0)
Temp = -temp;
g[0] = (float)(temp * 3.9); //1⁄4ÆËãÊý3⁄4ÝoÍÏÔÊ3⁄4,2é¿ 1⁄4ADXL345¿ ËÙÈëËÙÈëÅÅμÚ4Ò3
Temp = (BUF[3] << 8) + BUF[2];
If(temp < 0)
Temp = -temp;
g[1] = (float)(temp * 3.9); //1⁄4ÆËãÊý3⁄4ÝoÍÏÔÊ3⁄4,2é¿ 1⁄4ADXL345¿ ËÙÈëËÙÈëÅÅμÚ4Ò3
Temp = (BUF[5] << 8) + BUF[4];
If(temp < 0)
Temp = -temp;
g[2] = (float)(temp * 3.9); //1⁄4ÆËãÊý3⁄4ÝoÍÏÔÊ3⁄4,2é¿ 1⁄4ADXL345¿ ËÙÈëËÙÈëÅÅμÚ4Ò3
}