269 lines
10 KiB
C
269 lines
10 KiB
C
#include "stm32f4xx.h" // Device header
|
||
#include "stm32f4xx_conf.h"
|
||
#include "MyI2C.h"
|
||
#include "Warming.h"
|
||
#include "Delay.h"
|
||
|
||
#define IST8310_Address 0x0E//IST8310的地址
|
||
|
||
#define IST8310_Who_Am_I 0x00//Who Am I寄存器
|
||
#define IST8310_CNTL1 0x0A//控制设置1寄存器
|
||
#define IST8310_CNTL2 0x0B//控制设置2寄存器
|
||
#define IST8310_AVGCNTL 0x41//采样平均寄存器
|
||
#define IST8310_PDCNTL 0x42//脉冲持续时间寄存器
|
||
#define IST8310_DataStart 0x03//数据寄存器首地址
|
||
#define IST8310_TEMPL 0x1C//温度寄存器-温度低八位
|
||
#define IST8310_TEMPH 0x1D//温度寄存器-温度高八位
|
||
|
||
MyI2C_InitTypedef MyI2C_InitStruction;//I2C配置结构体
|
||
uint8_t IST8310_DataStartFlag;//IST8310开始接收数据标志位
|
||
int16_t IST8310_RawData[4];//IST8310原始数据,1~3为xyz轴磁场原始数据,4为温度原始数据
|
||
float IST8310_MagneticField[3];//IST8310磁场数据,分别为xyz轴磁场数据(单位uT)
|
||
float IST8310_Temperature;//IST8310温度数据(单位℃)
|
||
|
||
/*
|
||
*函数简介:IST8310的RSTN延时
|
||
*参数说明:无
|
||
*返回类型:无
|
||
*备注:默认配置RSTN延时500us,重启一次延时1ms
|
||
*/
|
||
void IST8310_Delay_us(void)
|
||
{
|
||
uint32_t temp;
|
||
SysTick->LOAD=500*21; //时间加载,我们要延时500倍的us, 1us是一个fac_ua周期,所以总共要延时的周期值为二者相乘最后送到Load中。
|
||
SysTick->VAL=0x00; //清空计数器
|
||
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; //开启使能位 开始倒数
|
||
do temp=SysTick->CTRL;
|
||
while((temp&0x01) && !(temp&(1<<16))); //用来判断 systick 定时器是否还处于开启状态,然后在等待时间到达,也就是数到0的时候,此时第十六位设置为1
|
||
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器使能位
|
||
SysTick->VAL=0x00; //清空计数器
|
||
}
|
||
|
||
/*
|
||
*函数简介:IST8310配置RSTN电平
|
||
*参数说明:高低电平,0-低电平 1-高电平
|
||
*返回类型:无
|
||
*备注:规定RSTN为PG6
|
||
*备注:RSTN为低电平时重启IST8310
|
||
*备注:每次修改RSTN,需要等待一段时间产生作用(测试得到0.5ms足矣)
|
||
*/
|
||
void IST8310_RSTN(uint8_t x)
|
||
{
|
||
GPIO_WriteBit(GPIOG,GPIO_Pin_6,(BitAction)(x));
|
||
IST8310_Delay_us();//延时0.5ms
|
||
}
|
||
|
||
/*
|
||
*函数简介:IST8310重启
|
||
*参数说明:无
|
||
*返回类型:无
|
||
*备注:重启大概耗时1ms
|
||
*/
|
||
void IST8310_Reset(void)
|
||
{
|
||
IST8310_RSTN(0);
|
||
IST8310_RSTN(1);
|
||
}
|
||
|
||
/*
|
||
*函数简介:IST8310初始化
|
||
*参数说明:无
|
||
*返回类型:无
|
||
*备注:规定SCL为PA8,SDA为PC9,DRDY为PG3(下降沿)
|
||
*备注:初始化中配置了寄存器并进行了重启,大概耗时1ms
|
||
*备注:在初始化中对寄存器进行了配置
|
||
*备注:初始化时会检查IST8310的ID,ID错误会进行报警,并且程序会卡死不断的进行检测,具体报警现象见Warming.h
|
||
*/
|
||
void IST8310_Init(void)
|
||
{
|
||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);
|
||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG,ENABLE);//开启时钟
|
||
|
||
MyI2C_InitStruction.MyI2C_SCL_RCC=RCC_AHB1Periph_GPIOA;//配置SCL为PA8
|
||
MyI2C_InitStruction.MyI2C_SCL_GPIOx=GPIOA;
|
||
MyI2C_InitStruction.MyI2C_SCL_Pin=GPIO_Pin_8;
|
||
MyI2C_InitStruction.MyI2C_SDA_RCC=RCC_AHB1Periph_GPIOC;//配置SDA为PC9
|
||
MyI2C_InitStruction.MyI2C_SDA_GPIOx=GPIOC;
|
||
MyI2C_InitStruction.MyI2C_SDA_Pin=GPIO_Pin_9;
|
||
MyI2C_Init(&MyI2C_InitStruction);
|
||
|
||
GPIO_InitTypeDef GPIO_InitStructure;
|
||
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN;
|
||
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上拉输入
|
||
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;//配置DRDY(PG3)
|
||
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
|
||
GPIO_Init(GPIOG,&GPIO_InitStructure);
|
||
|
||
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOG,EXTI_PinSource3);//配置PG3与中断线的映射关系
|
||
|
||
EXTI_InitTypeDef EXTI_InitStructure;
|
||
EXTI_InitStructure.EXTI_Line=EXTI_Line3;//配置中断线3
|
||
EXTI_InitStructure.EXTI_LineCmd=ENABLE;//使能中断线
|
||
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;//配置为外部中断模式
|
||
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;//选择下降沿触发
|
||
EXTI_Init(&EXTI_InitStructure);//初始化EXTI
|
||
|
||
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//选择NVIC分组为2
|
||
|
||
NVIC_InitTypeDef NVIC_InitStructure;
|
||
NVIC_InitStructure.NVIC_IRQChannel=EXTI3_IRQn;//配置NVIC通道3
|
||
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//使能NVIC通道
|
||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级
|
||
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;//响应优先级
|
||
NVIC_Init(&NVIC_InitStructure);//初始化NVIC
|
||
|
||
while(1)
|
||
{
|
||
if(MyI2C_CheckDevice(&MyI2C_InitStruction,IST8310_Address)==1 && MyI2C_CheckWhoAmI(&MyI2C_InitStruction,IST8310_Address,IST8310_Who_Am_I)==0x10)//设备连接正常,Who Am I正确
|
||
{
|
||
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//开启NVIC通道
|
||
NVIC_Init(&NVIC_InitStructure);//初始化NVIC
|
||
|
||
MyI2C_WriteRegister(&MyI2C_InitStruction,IST8310_Address,IST8310_CNTL1,0x03);//配置为连续输出模式,输出频率200Hz
|
||
MyI2C_WriteRegister(&MyI2C_InitStruction,IST8310_Address,IST8310_CNTL2,0x08);//配置为DRDY下降沿中断,不重启
|
||
MyI2C_WriteRegister(&MyI2C_InitStruction,IST8310_Address,IST8310_AVGCNTL,0x12);//配置为四次采样平均
|
||
MyI2C_WriteRegister(&MyI2C_InitStruction,IST8310_Address,IST8310_PDCNTL,0xC0);//配置为正常脉冲持续时间
|
||
IST8310_Reset();//IST8310重启
|
||
break;
|
||
}
|
||
else//设备异常
|
||
{
|
||
NVIC_InitStructure.NVIC_IRQChannelCmd=DISABLE;//关闭NVIC通道
|
||
NVIC_Init(&NVIC_InitStructure);//初始化NVIC
|
||
Warming_IST8310LinkError();//IST8310连接异常报警
|
||
Delay_ms(25);
|
||
}
|
||
}
|
||
|
||
while(IST8310_DataStartFlag==0);//等待数据开始接收
|
||
}
|
||
|
||
/*
|
||
*函数简介:IST8310数据读取
|
||
*参数说明:无
|
||
*返回类型:无
|
||
*备注:读取三轴磁场(单位uT)和温度(单位℃)
|
||
*备注:温度转换比例没找到,暂且以0.001为比例转换
|
||
*/
|
||
void IST8310_GetData(void)
|
||
{
|
||
uint8_t IST8310_MagneticFieldReceive[6],TempL,TempH;//三轴磁场返回数据,温度返回数据(低八位),温度返回数据(高八位)
|
||
|
||
MyI2C_ContinuousReadRegister(&MyI2C_InitStruction,IST8310_Address,IST8310_DataStart,IST8310_MagneticFieldReceive,6);//读取三轴磁场返回数据
|
||
TempL=MyI2C_ReadRegister(&MyI2C_InitStruction,IST8310_Address,IST8310_TEMPL);//读取温度返回数据(低八位)
|
||
TempH=MyI2C_ReadRegister(&MyI2C_InitStruction,IST8310_Address,IST8310_TEMPH);//读取温度返回数据(高八位)
|
||
|
||
IST8310_RawData[0]=(int16_t)(((uint16_t)(IST8310_MagneticFieldReceive[1])<<8)|IST8310_MagneticFieldReceive[0]);
|
||
IST8310_RawData[1]=(int16_t)(((uint16_t)(IST8310_MagneticFieldReceive[3])<<8)|IST8310_MagneticFieldReceive[2]);
|
||
IST8310_RawData[2]=(int16_t)(((uint16_t)(IST8310_MagneticFieldReceive[5])<<8)|IST8310_MagneticFieldReceive[4]);//获取三轴磁场原始数据
|
||
IST8310_RawData[3]=(int16_t)(((uint16_t)(TempH)<<8)|TempL);//获取温度原始数据
|
||
|
||
IST8310_MagneticField[0]=IST8310_RawData[0]*0.3f;
|
||
IST8310_MagneticField[1]=IST8310_RawData[1]*0.3f;
|
||
IST8310_MagneticField[2]=IST8310_RawData[2]*0.3f;//获取三轴磁场数据
|
||
IST8310_Temperature=IST8310_RawData[3]*0.001f;//获取温度
|
||
}
|
||
|
||
/*
|
||
*函数简介:IST8310外部中断中断函数
|
||
*参数说明:无
|
||
*返回类型:无
|
||
*备注:在中断函数中读取数据
|
||
*/
|
||
void EXTI3_IRQHandler(void)
|
||
{
|
||
if(EXTI_GetITStatus(EXTI_Line3)==SET)//检测IST8310外部中断触发(即检测EXTI通道3中断触发)
|
||
{
|
||
EXTI_ClearITPendingBit(EXTI_Line3);//清除标志位
|
||
IST8310_GetData();//读取数据
|
||
IST8310_DataStartFlag=1;//数据开始接收
|
||
}
|
||
}
|
||
|
||
/*硬件I2C的遗骸*/
|
||
////void IST8310_I2CInit(void)
|
||
////{
|
||
////
|
||
////
|
||
//// GPIO_InitTypeDef GPIO_InitStructure;
|
||
//// GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
|
||
//// GPIO_InitStructure.GPIO_OType=GPIO_OType_OD;
|
||
//// GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
|
||
//// GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;
|
||
//// GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
|
||
//// GPIO_Init(GPIOA,&GPIO_InitStructure);
|
||
//// GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
|
||
//// GPIO_Init(GPIOC,&GPIO_InitStructure);
|
||
//// GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
|
||
//// GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
|
||
//// GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
|
||
//// GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
|
||
//// GPIO_Init(GPIOG,&GPIO_InitStructure);
|
||
////
|
||
//// GPIO_PinAFConfig(GPIOA,GPIO_PinSource8,GPIO_AF_I2C3);
|
||
//// GPIO_PinAFConfig(GPIOC,GPIO_PinSource9,GPIO_AF_I2C3);
|
||
////
|
||
//// I2C_InitTypeDef I2C_InitStructure;
|
||
//// I2C_InitStructure.I2C_Mode=I2C_Mode_I2C;
|
||
//// I2C_InitStructure.I2C_ClockSpeed=10000;
|
||
//// I2C_InitStructure.I2C_DutyCycle=I2C_DutyCycle_2;
|
||
//// I2C_InitStructure.I2C_Ack=I2C_Ack_Disable;
|
||
//// I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;
|
||
//// I2C_InitStructure.I2C_OwnAddress1=0x01;
|
||
//// I2C_Init(I2C3,&I2C_InitStructure);
|
||
////
|
||
//// I2C3->CR1 |= I2C_CR1_SWRST;
|
||
//// while(I2C_GetFlagStatus(I2C3,I2C_FLAG_BUSY)==SET);
|
||
//// I2C3->CR1 &= ~I2C_CR1_SWRST;
|
||
////
|
||
//// I2C_Cmd(I2C3,ENABLE);
|
||
////
|
||
//// GPIO_ResetBits(GPIOG,GPIO_Pin_6);
|
||
//// Delay_ms(50);
|
||
//// GPIO_SetBits(GPIOG,GPIO_Pin_6);
|
||
//// Delay_ms(50);
|
||
//// LED_BInit();
|
||
////}
|
||
|
||
////void IST8310_I2CWriteData(uint8_t Address,uint8_t Data)
|
||
////{
|
||
//// uint8_t B=0;
|
||
//// while(I2C_GetFlagStatus(I2C3,I2C_FLAG_BUSY)==SET);
|
||
////
|
||
//// I2C_GenerateSTART(I2C3,ENABLE);
|
||
//// while(I2C_CheckEvent(I2C3,I2C_EVENT_MASTER_MODE_SELECT)!=SUCCESS);
|
||
////
|
||
//// while(I2C_GetFlagStatus(I2C3,I2C_FLAG_BUSY)!=SET);
|
||
//// while(I2C_GetFlagStatus(I2C3,I2C_FLAG_MSL)!=SET);
|
||
//// //I2C_SendData(I2C3,0x0E<<1);
|
||
//// int i=0;
|
||
//// do
|
||
//// {
|
||
//// I2C_Send7bitAddress(I2C3,i<<1,I2C_Direction_Receiver);
|
||
//// i++;
|
||
//// if(i==0x8F)break;
|
||
//// }
|
||
//// while(I2C_GetFlagStatus(I2C3,I2C_FLAG_ADDR)!=SET);
|
||
//// if(i<0x8F)LED_BON();
|
||
//// //while(I2C_CheckEvent(I2C3,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)!=SUCCESS);
|
||
|
||
//// I2C_SendData(I2C3,0x00);
|
||
//// //while(I2C_CheckEvent(I2C3,I2C_EVENT_MASTER_BYTE_TRANSMITTING)!=SUCCESS);
|
||
////
|
||
////// I2C_SendData(I2C3,Data);
|
||
//// //while(I2C_CheckEvent(I2C3,I2C_EVENT_MASTER_BYTE_TRANSMITTED)!=SUCCESS);
|
||
//// I2C_GenerateSTART(I2C3,ENABLE);
|
||
//// //while(I2C_CheckEvent(I2C3,I2C_EVENT_MASTER_MODE_SELECT)!=SUCCESS);
|
||
////
|
||
//// //I2C_SendData(I2C3,(0x0E<<1)|0x01);
|
||
//// I2C_Send7bitAddress(I2C3,0x0E,I2C_Direction_Receiver);
|
||
//// //while(I2C_GetFlagStatus(I2C3,I2C_FLAG_AF)==SET);
|
||
//// //while(I2C_GetFlagStatus(I2C3,I2C_FLAG_ADDR)!=SET);
|
||
//// //while(I2C_CheckEvent(I2C3,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)!=SUCCESS);
|
||
|
||
//// B=I2C_ReceiveData(I2C3);
|
||
//// //while(I2C_CheckEvent(I2C3,I2C_EVENT_MASTER_BYTE_TRANSMITTING)!=SUCCESS);
|
||
////
|
||
//// I2C_GenerateSTOP(I2C3,ENABLE);
|
||
////}
|