ADXL345传感器分辨率13位,测量范围±16g(可选±2、±4、±8g),输出数据格式为16位补码,可通过SPI(三线或者四线)或者IIC接口读取。同时还支持32级的FIFO数据存储,满足快速读取数据的要求。
SpiWriteCmd(0x2E,0x00); // 中断寄存器清零
SpiWriteCmd(0x31,0x0B); // 4线SPI 全分辨率 g加速度范围
SpiWriteCmd(0x2D,0x08); // 传感器测量模式
SpiWriteCmd(0x2C,0x0E); // 传感器传输数据速率1600HZ
SpiWriteCmd(0x2F,0x03); // 中断映射
SpiWriteCmd(0x38,0x94); // FIFO模式设置
SpiWriteCmd(0x1E,0x00); // X轴偏移量
SpiWriteCmd(0x1F,0x00); // Y轴偏移量
SpiWriteCmd(0x20,0x00); // Z轴偏移量
SpiWriteCmd(0x2E,0x83); //中断寄存器使能
话不多说,直接上代码,本文采用STMF407读取数据,SPI数据位8位,全双工,软件控制片选,高位在前(MB First),
SPI.h
#define ADS_SPI_PORT GPIOB
#define ADS_SPI_CS_PIN GPIO_Pin_12
#define ADS_SPI_SCK_PIN GPIO_Pin_13
#define ADS_SPI_MISO_PIN GPIO_Pin_14
#define ADS_SPI_MOSI_PIN GPIO_Pin_15
#define ADS_SPI_CS_HIGH() GPIO_SetBits(ADS_SPI_PORT, ADS_SPI_CS_PIN)
#define ADS_SPI_CS_LOW() GPIO_ResetBits(ADS_SPI_PORT, ADS_SPI_CS_PIN)
SPI.c
unsigned char ADXL345RXBuff[250]; //DMA 接收缓存
unsigned char ADXL345TXBuff[10]; //DMA 发送缓存
// SPI IO口初始化
void Spi2IOInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// Enable GPIOC clocks
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
// Connect SPI2 pins to AF5
GPIO_PinAFConfig(ADS_SPI_PORT, GPIO_PinSource13, GPIO_AF_SPI2); // SCK
GPIO_PinAFConfig(ADS_SPI_PORT, GPIO_PinSource14, GPIO_AF_SPI2); // MISO
GPIO_PinAFConfig(ADS_SPI_PORT, GPIO_PinSource15, GPIO_AF_SPI2); // MOSI
// SPI SCK¡¢MOSI pin configuration
GPIO_InitStructure.GPIO_Pin = ADS_SPI_SCK_PIN|ADS_SPI_MOSI_PIN|ADS_SPI_MISO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//GPIO_PuPd_DOWN;//GPIO_PuPd_UP;//GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(ADS_SPI_PORT, &GPIO_InitStructure);
//SPI2 NSS pin in output pushpull mode
GPIO_InitStructure.GPIO_Pin = ADS_SPI_CS_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //GPIO_PuPd_NOPULL;
GPIO_Init(ADS_SPI_PORT, &GPIO_InitStructure);
ADS_SPI_CS_HIGH(); // cs default state is high
ADS_SPI_CS_LOW();
ADS_SPI_CS_HIGH();
}
// SPI模式初始化
void SPI2Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
SPI_I2S_DeInit(SPI2);
//Enable the SPI periph
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
Spi2IOInit();
// SPI configuration
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; // SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI2, &SPI_InitStructure);
// Enable the SPI2
SPI_Cmd(SPI2, ENABLE);
}
// SPI写指令
void SpiWriteCmd(u8 cmd,u8 data)
{
ADS_SPI_CS_LOW();
while((SPI2->SR &0x0002)==0);
SPI2->DR = (cmd);
while((SPI2->SR &0x0001)==0);
SPI_I2S_ReceiveData(SPI2);
while((SPI2->SR &0x0002)==0);
SPI2->DR = (data);
while((SPI2->SR &0x0001)==0);
SPI_I2S_ReceiveData(SPI2);
ADS_SPI_CS_HIGH();
}
// SPI读指令
u8 SpiReadCmd(u8 cmd)
{
ADS_SPI_CS_LOW();
unsigned char returnvalue;
while((SPI2->SR &0x0002)==0);
SPI2->DR = (cmd|0x80);
while((SPI2->SR &0x0001)==0);
returnvalue = (unsigned char)(SPI_I2S_ReceiveData(SPI2)); // Return the Byte read from the SPI bus
while((SPI2->SR &0x0002)==0);
SPI2->DR = (0x00);
while((SPI2->SR &0x0001)==0);
returnvalue =(unsigned char)(SPI_I2S_ReceiveData(SPI2)); // Return the Byte read from the SPI bus
ADS_SPI_CS_HIGH();
return(returnvalue);
}
void ADXL345Init()
{
u8 TempData;
SPI2Init();
TempData = SpiReadCmd(0x00);
while(TempData!=0xE5) //判断是否器件ID正确 验证SPI通信是否正常
{
SendData(&TempData,1);
}
SpiWriteCmd(0x2E,0x00);
SpiWriteCmd(0x31,0x0B);
SpiWriteCmd(0x2D,0x08);
SpiWriteCmd(0x2C,0x0E);
SpiWriteCmd(0x2E,0x00);
SpiWriteCmd(0x38,0x00);
SpiWriteCmd(0x2F,0x00);
SpiWriteCmd(0x1E,0x00);
SpiWriteCmd(0x1F,0x00);
SpiWriteCmd(0x20,0x00);
}
void ReadADXL345Data()
{
unsigned char StrBuff[50];
short int Acc_X=0,Acc_Y=0,Acc_Z=0;
unsigned char Buf[6];
Buf[0]=SpiReadCmd(0x32);
Buf[1]=SpiReadCmd(0x33);
Buf[2]=SpiReadCmd(0x34);
Buf[3]=SpiReadCmd(0x35);
Buf[4]=SpiReadCmd(0x36);
Buf[5]=SpiReadCmd(0x37);
Acc_X = ((Buf[1]<<8|Buf[0]));
Acc_Y = ((Buf[3]<<8|Buf[2]));
Acc_Z = ((Buf[5]<<8|Buf[4]));
sprintf(StrBuff,"X=%4.3f m/s2 Y=%4.3f m/s2 Z=%4.3f m/s2 \r\n",Acc_X*3.9/1000*9.8,Acc_Y*3.9/1000*9.8,Acc_Z*3.9/1000*9.8);
SendData(StrBuff,strlen(StrBuff));
多字节读取的方式和常规不同的就是:
无需自己手动修改读取数据的地址,
外部传感器自动修改地址并传输,
多字节读取时序图如下:
从上面可以看出,在发送0xF2之后,无论发送什么数据,都自动传回六个数据。
有的好奇宝宝可能会问,为什么是0xF2呢?
因为读指令最高位为1,次高位为多字节位,要置1,而寄存器的数据地址为0x32,这样或则可以得到0xF2。
void ContinuousReadADXL345Data()
{
unsigned char StrBuff[50];
short int Acc_X=0,Acc_Y=0,Acc_Z=0;
unsigned char Buf[6];
ADS_SPI_CS_LOW();
unsigned char returnvalue;
while((SPI2->SR &0x0002)==0);
SPI2->DR = 0x32|0xC0;
while((SPI2->SR &0x0001)==0);
Buf[0] = (unsigned char)(SPI_I2S_ReceiveData(SPI2)); // Return the Byte read from the SPI bus
while((SPI2->SR &0x0002)==0);
SPI2->DR = 0x00;
while((SPI2->SR &0x0001)==0);
Buf[0] = (unsigned char)(SPI_I2S_ReceiveData(SPI2)); // Return the Byte read from the SPI bus// Buf[1] = (unsigned char)(SPI_I2S_ReceiveData(SPI2));
while((SPI2->SR &0x0002)==0);
SPI2->DR = 0x00;
while((SPI2->SR &0x0001)==0);
Buf[1] = (unsigned char)(SPI_I2S_ReceiveData(SPI2)); // Return the Byte read from the SPI bus
while((SPI2->SR &0x0002)==0);
SPI2->DR = 0x00;
while((SPI2->SR &0x0001)==0);
Buf[2] = (unsigned char)(SPI_I2S_ReceiveData(SPI2)); // Return the Byte read from the SPI bus
while((SPI2->SR &0x0002)==0);
SPI2->DR = 0x00;
while((SPI2->SR &0x0001)==0);
Buf[3] = (unsigned char)(SPI_I2S_ReceiveData(SPI2)); // Return the Byte read from the SPI bus
while((SPI2->SR &0x0002)==0);
SPI2->DR = 0x00;
while((SPI2->SR &0x0001)==0);
Buf[4] = (unsigned char)(SPI_I2S_ReceiveData(SPI2)); // Return the Byte read from the SPI bus
while((SPI2->SR &0x0002)==0);
SPI2->DR = 0x00;
while((SPI2->SR &0x0001)==0);
Buf[5] = (unsigned char)(SPI_I2S_ReceiveData(SPI2)); // Return the Byte read from the SPI bus
ADS_SPI_CS_HIGH();
Acc_X = ((Buf[1]<<8|Buf[0]));
Acc_Y = ((Buf[3]<<8|Buf[2]));
Acc_Z = ((Buf[5]<<8|Buf[4]));
sprintf(StrBuff,"X=%4.1f***Y=%4.1f***Z=%4.1f\r\n",Acc_X*3.9/1000*9.8,Acc_Y*3.9/1000*9.8,Acc_Z*3.9/1000*9.8);
SendData(StrBuff,strlen(StrBuff));
}
从上面可以看出,只需填写第一个寄存器的地址之后,后面的数据可以直接读取,无需再修改寄存器。
使用DMA进行数据读取,在这里我使用数据更新中断去读取数据。
设置INT1数据更新中断使能,触发外中断去开始DMA数据数据传输。
void SPI2Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
SPI_I2S_DeInit(SPI2);
//Enable the SPI periph
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
Spi2IOInit();
// SPI configuration
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; // SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI2, &SPI_InitStructure);
// Enable the SPI2
SPI_Cmd(SPI2, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream4_IRQn;
NVIC_Init(&NVIC_InitStructure);
MyDMAInit();
EXTIX_Init();
}
void MyDMAInit()
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);//DMA时钟
DMA_DeInit(DMA1_Stream3); //SPI_RX
/* DMA Stream 3 */
DMA_InitStructure.DMA_Channel = DMA_Channel_0; //
DMA_InitStructure.DMA_PeripheralBaseAddr =(u32)(&(SPI2->DR));·
DMA_InitStructure.DMA_Memory0BaseAddr = (u32)(&ADXL345RXBuff[0]);//
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;//
DMA_InitStructure.DMA_BufferSize = FIFO_COUNT*7;//
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//
DMA_Init(DMA1_Stream3, &DMA_InitStructure);//³õʼ»¯DMA Stream
SPI_I2S_DMACmd(SPI2,SPI_I2S_DMAReq_Rx,ENABLE);
DMA_ITConfig(DMA1_Stream3, DMA_IT_TC, ENABLE);
DMA_Cmd(DMA1_Stream3, DISABLE);
DMA_DeInit(DMA1_Stream4); //SPI_TX
/* DMA Stream 4*/
DMA_InitStructure.DMA_Channel = DMA_Channel_0; //
DMA_InitStructure.DMA_PeripheralBaseAddr =(u32)(&(SPI2->DR));//
DMA_InitStructure.DMA_Memory0BaseAddr = (u32)(&ADXL345TXBuff[0]);//DMA
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;//
DMA_InitStructure.DMA_BufferSize = 7;//
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//
DMA_Init(DMA1_Stream4, &DMA_InitStructure);//
SPI_I2S_DMACmd(SPI2,SPI_I2S_DMAReq_Tx,ENABLE);
// DMA_ITConfig(DMA1_Stream4, DMA_IT_TC, ENABLE);
}
void EXTIX_Init()
{
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//GPIO_PuPd_DOWN;//GPIO_PuPd_UP;//GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOD, EXTI_PinSource8);//
EXTI_InitStructure.EXTI_Line = EXTI_Line8;//LINE8
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//
EXTI_Init(&EXTI_InitStructure);//
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;//
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;//
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//
NVIC_Init(&NVIC_InitStructure);
}
u8 ExtiFlag=0; // 数据更新中断标志位
void EXTI9_5_IRQHandler()
{
if(EXTI_GetITStatus(EXTI_Line8))
{
DMA_Cmd(DMA1_Stream3, DISABLE);
DMA_Cmd(DMA1_Stream4, DISABLE);
u8 TempData = SpiReadCmd(0x30);
if((TempData&0x80))
ExtiFlag=1;
EXTI_ClearITPendingBit(EXTI_Line8);
}
}
void SPIDMAReadADXL345Data()
{
int pro=0;
ADS_SPI_CS_LOW();
DMA_Cmd(DMA1_Stream3, ENABLE);
ADXL345TXBuff[0]=0xF2;
ADXL345TXBuff[1]=0x00;
ADXL345TXBuff[2]=0x00;
ADXL345TXBuff[3]=0x00;
ADXL345TXBuff[4]=0x00;
ADXL345TXBuff[5]=0x00;
ADXL345TXBuff[6]=0x00;
DMA_Cmd(DMA1_Stream4, DISABLE);
DMA_SetCurrDataCounter(DMA1_Stream4,7);
DMA_Cmd(DMA1_Stream4, ENABLE);
while(DMA_GetFlagStatus(DMA1_Stream4, DMA_FLAG_TCIF4) == RESET)
{
pro=DMA_GetCurrDataCounter(DMA1_Stream4);
}
DMA_ClearFlag(DMA1_Stream4, DMA_FLAG_TCIF4);
while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_BSY)==SET); //需要等待SPI总线传输完成最后一个字节,否则Z轴数据存在问题。
ADS_SPI_CS_HIGH();
ExtiFlag=0;
}
u8 DMAReadFlag = 0; // DMA接收数据完成中断标志位
void DMA1_Stream3_IRQHandler()
{
if (DMA_GetITStatus(DMA1_Stream3, DMA_IT_TCIF3) != RESET)
{
DMA_ClearFlag(DMA1_Stream3, DMA_IT_TCIF3);
DMAReadFlag=1;
DMA_Cmd(DMA1_Stream3, DISABLE);
}
}
void ReadDMAData()
{
short int Acc_X=0,Acc_Y=0,Acc_Z=0;
unsigned char StrBuff[50];
if(ExtiFlag==1) //数据更新中断,则开始DMA读取数据
{
SPIDMAReadADXL345Data();
}
if(DMAReadFlag) //读取数据完成之后,则开始计算三轴并显示
{
Acc_X = ((ADXL345RXBuff[2]<<8|ADXL345RXBuff[1]));
Acc_Y = ((ADXL345RXBuff[4]<<8|ADXL345RXBuff[3]));
Acc_Z = ((ADXL345RXBuff[6]<<8|ADXL345RXBuff[5]));
sprintf(StrBuff,"X=%4.3f Y=%4.3f Z=%4.3f\r\n",Acc_X*3.9/1000*9.8,Acc_Y*3.9/1000*9.8,Acc_Z*3.9/1000*9.8);
SendData(StrBuff,strlen(StrBuff));
DMAReadFlag=0;
}
}
FIFO模式共分为三种,FIFO模式,流模式和触发模式,一般使用前两种,FIFO模式存满缓存区之后则不再继续填充数据,而流模式则继续回覆盖之前已存在的数据。
FIFO最大缓存32级数据,即32个三轴数据,总共32*6=192个数据。FIFO可设置存满一定字节后触发中断,中断为水印中断(Watermark 奇怪的名字)。存满之后继续填充缓存器,直到存满32级缓存。所以不需要完全存满再去读取数据,那样时效性不高,可设置16级之后就读取数据,这样类似于半中断,效率更高。
这个FIFO唯一一点不好的地方我觉得是,FIFO数据不是一次性读出,而是多次通过寄存器去读取,意思就是FIFO数据的读取地址就是0x32-0x37,读完之后,FIFO缓存就往寄存器里填充缓存的数据,然后再去读,直到填充完。
使用水印中断来触发外中断去读取FIFO数据。
void ADXL345Init()
{
u8 TempData;
SPI2Init();
TempData = SpiReadCmd(0x00);
while(TempData!=0xE5)
{
SendData(&TempData,1);
}
SpiWriteCmd(0x2E,0x00);
SpiWriteCmd(0x31,0x0B);
SpiWriteCmd(0x2D,0x08);
SpiWriteCmd(0x2C,0x0E);
SpiWriteCmd(0x2F,0x03);
SpiWriteCmd(0x38,0x9F); // 设置FIFO模式 10011111 32条目 流模式 只保存最新数据
SpiWriteCmd(0x1E,0x00);
SpiWriteCmd(0x1F,0x00);
SpiWriteCmd(0x20,0x00);
SpiWriteCmd(0x2E,0x83); //设置INT2 为水印中断
ADXL345TXBuff[0]=0xF2; //DMA 发送缓存
ADXL345TXBuff[1]=0x00;
ADXL345TXBuff[2]=0x00;
ADXL345TXBuff[3]=0x00;
ADXL345TXBuff[4]=0x00;
ADXL345TXBuff[5]=0x00;
ADXL345TXBuff[6]=0x00;
}
u8 ExtiFlag=0;
void EXTI9_5_IRQHandler()
{
if(EXTI_GetITStatus(EXTI_Line8))
{
DMA_Cmd(DMA1_Stream3, DISABLE);
DMA_Cmd(DMA1_Stream4, DISABLE);
u8 TempData = SpiReadCmd(0x30); //读取中断标志位 确定中断产生
if((TempData&0x02))
ExtiFlag=1;
EXTI_ClearITPendingBit(EXTI_Line8);
}
}
void SPIDMAReadADXL345Data()
{
u8 i=0;
DMA_Cmd(DMA1_Stream3, ENABLE);
for(i=0;i<FIFO_COUNT;i++) //FIFO_COUNT 代表触发FIFO缓存个数
{
ADS_SPI_CS_LOW();
DMA_Cmd(DMA1_Stream4, DISABLE);
DMA_SetCurrDataCounter(DMA1_Stream4,7); /
DMA_Cmd(DMA1_Stream4, ENABLE);
while(DMA_GetFlagStatus(DMA1_Stream4, DMA_FLAG_TCIF4) == RESET)
{
DMA_GetCurrDataCounter(DMA1_Stream4);//
}
DMA_ClearFlag(DMA1_Stream4, DMA_FLAG_TCIF4);
while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_BSY)==SET);
ADS_SPI_CS_HIGH();
}
ExtiFlag=0;
}
u8 DMAReadFlag = 0;
void DMA1_Stream3_IRQHandler()
{
if (DMA_GetITStatus(DMA1_Stream3, DMA_IT_TCIF3) != RESET)
{
DMA_ClearFlag(DMA1_Stream3, DMA_IT_TCIF3);
DMAReadFlag=1;
DMA_Cmd(DMA1_Stream3, DISABLE);
}
}
void ReadDMAData()
{
short int Acc_X=0,Acc_Y=0,Acc_Z=0;
unsigned char StrBuff[50];
unsigned char C=10;
if(ExtiFlag==1)
{
SPIDMAReadADXL345Data();
}
if(DMAReadFlag)
{
Acc_X = ((ADXL345RXBuff[7*C+2]<<8|ADXL345RXBuff[7*C+1]));
Acc_Y = ((ADXL345RXBuff[7*C+4]<<8|ADXL345RXBuff[7*C+3]));
Acc_Z = ((ADXL345RXBuff[7*C+6]<<8|ADXL345RXBuff[7*C+5]));
sprintf((char *)StrBuff,"X=%4.3f Y=%4.3f Z=%4.3f\r\n",Acc_X*3.9/1000*9.8,Acc_Y*3.9/1000*9.8,Acc_Z*3.9/1000*9.8);
SendData(StrBuff,strlen((char *)StrBuff));
DMAReadFlag=0;
}
}
最后楼主分享一个完整的代码,使用STM32F407读取ADXL345三轴加速度传感器数据,keil工程。
下载链接:
工程文件 SPI协议版本
工程文件 SPI+DMA协议版本
如有雷同,纯属我抄你,有问题可以直接联系邮箱,在个人资料里面。