static void MemsConfigure2(void) { LIS302DL_FilterConfigTypeDef LIS302DL_FilterStruct; int8_t buffer[2]; LIS302DL_FilterStruct.HighPassFilter_Data_Selection = LIS302DL_FILTEREDDATASELECTION_OUTPUTREGISTER; LIS302DL_FilterStruct.HighPassFilter_Interrupt = LIS302DL_HIGHPASSFILTERINTERRUPT_1_2; LIS302DL_FilterStruct.HighPassFilter_CutOff_Frequency = LIS302DL_HIGHPASSFILTER_LEVEL_1; LIS302DL_FilterConfig(&LIS302DL_FilterStruct); LIS302DL_ReadXYZ(buffer, sizeof buffer); xOffset = buffer[0]; yOffset = buffer[1]; }
/** *@brief This method is the one provided by STMicroelectronic with the discoverycard demo. It is used to configure the LIS302DL accelerometer embedded on the discovery card. */ void init_LIS302DL(){ /* MEMS configuration */ LIS302DL_InitStruct.Power_Mode = LIS302DL_LOWPOWERMODE_ACTIVE; LIS302DL_InitStruct.Output_DataRate = LIS302DL_DATARATE_100; LIS302DL_InitStruct.Axes_Enable = LIS302DL_XYZ_ENABLE; LIS302DL_InitStruct.Full_Scale = LIS302DL_FULLSCALE_2_3; LIS302DL_InitStruct.Self_Test = LIS302DL_SELFTEST_NORMAL; LIS302DL_Init(&LIS302DL_InitStruct); /* Required delay for the MEMS Accelerometre: Turn-on time = 3/Output data Rate = 3/100 = 30ms */ Delay(30); /* MEMS High Pass Filter configuration */ LIS302DL_FilterStruct.HighPassFilter_Data_Selection = LIS302DL_FILTEREDDATASELECTION_OUTPUTREGISTER; LIS302DL_FilterStruct.HighPassFilter_CutOff_Frequency = LIS302DL_HIGHPASSFILTER_LEVEL_1; LIS302DL_FilterStruct.HighPassFilter_Interrupt = LIS302DL_HIGHPASSFILTERINTERRUPT_1_2; LIS302DL_FilterConfig(&LIS302DL_FilterStruct); }
/** * @brief Configure MEMS operation * @param None * @retval None */ void MEMS_Config(void) { LIS302DL_InitTypeDef LIS302DL_InitStruct; LIS302DL_FilterConfigTypeDef LIS302DL_FilterStruct; /* Set configuration of LIS302DL*/ LIS302DL_InitStruct.Power_Mode = LIS302DL_LOWPOWERMODE_ACTIVE; LIS302DL_InitStruct.Output_DataRate = LIS302DL_DATARATE_100; LIS302DL_InitStruct.Axes_Enable = LIS302DL_X_ENABLE | LIS302DL_Y_ENABLE; LIS302DL_InitStruct.Full_Scale = LIS302DL_FULLSCALE_2_3; LIS302DL_InitStruct.Self_Test = LIS302DL_SELFTEST_NORMAL; LIS302DL_Init(&LIS302DL_InitStruct); LIS302DL_FilterStruct.HighPassFilter_Data_Selection = LIS302DL_FILTEREDDATASELECTION_OUTPUTREGISTER; LIS302DL_FilterStruct.HighPassFilter_CutOff_Frequency = LIS302DL_HIGHPASSFILTER_LEVEL_1; LIS302DL_FilterStruct.HighPassFilter_Interrupt = LIS302DL_HIGHPASSFILTERINTERRUPT_OFF; LIS302DL_FilterConfig(&LIS302DL_FilterStruct); LIS302DL_Read(Buffer, LIS302DL_OUT_X_ADDR, 4); XOffset = Buffer[0]; YOffset = Buffer[2]; }
/** * @brief Execute the demo application. * @param None * @retval None */ static void Demo_Exec(void) { RCC_ClocksTypeDef RCC_Clocks; uint8_t togglecounter = 0x00; while(1) { DemoEnterCondition = 0x00; /* Reset UserButton_Pressed variable */ UserButtonPressed = 0x00; /* Initialize LEDs to be managed by GPIO */ STM_EVAL_LEDInit(LED4); STM_EVAL_LEDInit(LED3); STM_EVAL_LEDInit(LED5); STM_EVAL_LEDInit(LED6); /* SysTick end of count event each 10ms */ RCC_GetClocksFreq(&RCC_Clocks); SysTick_Config(RCC_Clocks.HCLK_Frequency / 100); /* Turn OFF all LEDs */ STM_EVAL_LEDOff(LED4); STM_EVAL_LEDOff(LED3); STM_EVAL_LEDOff(LED5); STM_EVAL_LEDOff(LED6); /* Waiting User Button is pressed */ while (UserButtonPressed == 0x00) { /* Toggle LED4 */ STM_EVAL_LEDToggle(LED4); Delay(10); /* Toggle LED4 */ STM_EVAL_LEDToggle(LED3); Delay(10); /* Toggle LED4 */ STM_EVAL_LEDToggle(LED5); Delay(10); /* Toggle LED4 */ STM_EVAL_LEDToggle(LED6); Delay(10); togglecounter ++; if (togglecounter == 0x10) { togglecounter = 0x00; while (togglecounter < 0x10) { STM_EVAL_LEDToggle(LED4); STM_EVAL_LEDToggle(LED3); STM_EVAL_LEDToggle(LED5); STM_EVAL_LEDToggle(LED6); Delay(10); togglecounter ++; } togglecounter = 0x00; } } /* Waiting User Button is Released */ while (STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET) {} UserButtonPressed = 0x00; /* TIM4 channels configuration */ TIM4_Config(); /* Disable all Timer4 channels */ TIM_CCxCmd(TIM4, TIM_Channel_1, DISABLE); TIM_CCxCmd(TIM4, TIM_Channel_2, DISABLE); TIM_CCxCmd(TIM4, TIM_Channel_3, DISABLE); TIM_CCxCmd(TIM4, TIM_Channel_4, DISABLE); /* MEMS configuration */ LIS302DL_InitStruct.Power_Mode = LIS302DL_LOWPOWERMODE_ACTIVE; LIS302DL_InitStruct.Output_DataRate = LIS302DL_DATARATE_100; LIS302DL_InitStruct.Axes_Enable = LIS302DL_XYZ_ENABLE; LIS302DL_InitStruct.Full_Scale = LIS302DL_FULLSCALE_2_3; LIS302DL_InitStruct.Self_Test = LIS302DL_SELFTEST_NORMAL; LIS302DL_Init(&LIS302DL_InitStruct); /* Required delay for the MEMS Accelerometre: Turn-on time = 3/Output data Rate = 3/100 = 30ms */ Delay(30); DemoEnterCondition = 0x01; /* MEMS High Pass Filter configuration */ LIS302DL_FilterStruct.HighPassFilter_Data_Selection = LIS302DL_FILTEREDDATASELECTION_OUTPUTREGISTER; LIS302DL_FilterStruct.HighPassFilter_CutOff_Frequency = LIS302DL_HIGHPASSFILTER_LEVEL_1; LIS302DL_FilterStruct.HighPassFilter_Interrupt = LIS302DL_HIGHPASSFILTERINTERRUPT_1_2; LIS302DL_FilterConfig(&LIS302DL_FilterStruct); LIS302DL_Read(Buffer, LIS302DL_OUT_X_ADDR, 6); X_Offset = Buffer[0]; Y_Offset = Buffer[2]; Z_Offset = Buffer[4]; /* USB configuration */ Demo_USBConfig(); /* Waiting User Button is pressed */ while (UserButtonPressed == 0x00) {} /* Waiting User Button is Released */ while (STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET) {} /* Disable SPI1 used to drive the MEMS accelerometre */ SPI_Cmd(LIS302DL_SPI, DISABLE); /* Disconnect the USB device */ DCD_DevDisconnect(&USB_OTG_dev); USB_OTG_StopDevice(&USB_OTG_dev); } }
/** * @brief Execute the demo application. * @param None * @retval None */ static void Demo_Exec(void) { RCC_ClocksTypeDef RCC_Clocks; /* 串口配置 */ USART1_Config(); NVIC_Config(); /* Initialize LEDs to be managed by GPIO */ STM_EVAL_LEDInit(LED4); STM_EVAL_LEDInit(LED3); STM_EVAL_LEDInit(LED5); STM_EVAL_LEDInit(LED6); //每次系统初始化后,都读取flash查看存储空间剩余情况 flash_readIndex(IndexList,uniIndexLength, &IndexCount); while(1) { DemoEnterCondition = 0x00; /* Reset UserButton_Pressed variable */ UserButtonPressed = 0x00; // SerialButtonPressed = 0x00; /* SysTick end of count event each 2.5ms */ RCC_GetClocksFreq(&RCC_Clocks); SysTick_Config(RCC_Clocks.HCLK_Frequency / TimeDev); /******************************************/ /***空闲状态,清空flash或者发送数据选项****/ /******************************************/ /* Waiting User Button is pressed */ while (UserButtonPressed == 0x00) { /********通过串口与上位机通信*******************/ /* if Send serial data Button(PB11) is pressed */ if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == Bit_SET)//不太灵敏 { while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == Bit_SET); /*串口通信状态指示灯*/ STM_EVAL_LEDOn(LED4); STM_EVAL_LEDOn(LED3); STM_EVAL_LEDOn(LED5); STM_EVAL_LEDOn(LED6); //读取flash中index区域 flash_readIndex(IndexList,uniIndexLength, &IndexCount); //与上位机握手操作 unsigned char* shakeHandSend = "ready? ";//最后一个字符必须是空格字符 while (*shakeHandSend != ' ') { SendChar(*shakeHandSend); shakeHandSend++; } Delay(100);//等待1s确认接收自上位机的握手信号"ok!" if (serialRecv[0] == 'o'&&serialRecv[1] == 'k'&&serialRecv[2] == '!') { //与上位机握手成功,可发送数据 serialFlag = 1; } else { //与上位机握手失败,无法发送数据 serialFlag = 0; /*串口握手失败指示灯*/ STM_EVAL_LEDOff(LED4); Delay(10); STM_EVAL_LEDOff(LED3); Delay(10); STM_EVAL_LEDOff(LED5); Delay(10); STM_EVAL_LEDOff(LED6); Delay(100); } if (1 == serialFlag) { //先发送IndexList数据给上位机,上位机选择需要的记录段(segment)反馈给下位机,下位机据此发送相应记录段给上位机 uint8_t i; unsigned char sendData[4]; SendString("index"); SendCounter = 0; while(SendCounter < IndexCount) { uint32_to_uint8(sendData,IndexList[SendCounter]); i = 0; while(i < 4) { SendChar((unsigned char)sendData[i]); i+= 1 ; } SendCounter += 1; } /*开始发送segment数据给上位机*/ while(serialRecv[0] == 'o');//等待确认接收自上位机的选择信号"0"——"6" Delay(2);//等待20ms后开始发送data,实现收发同步 if (serialRecv[0] == '0'||serialRecv[0] == '1'||serialRecv[0] == '2'||serialRecv[0] == '3'||serialRecv[0] == '4'||serialRecv[0] == '5'||serialRecv[0] == '6') { tempCount = IndexList[(serialRecv[0]-48)*uniIndexLength+2]; tempCount2 = 0; //读取flash user data area中对应数据 while (tempCount > lowerComputerBufferNum) { flash_readData(SendData,lowerComputerBufferNum, tempCount2*lowerComputerBufferNum, IndexList[(serialRecv[0]-48)*uniIndexLength]); SendCounter = 0; while(SendCounter < lowerComputerBufferNum) { SendChar((unsigned char)SendData[SendCounter]); SendCounter += 1 ; } tempCount -= lowerComputerBufferNum; tempCount2 += 1; Delay(9);//延时9ms以便上位机有时间处理缓冲区(上位机缓冲区大小同下位机) } if (tempCount != 0) { flash_readData(SendData,tempCount, tempCount2*lowerComputerBufferNum, IndexList[(serialRecv[0]-48)*uniIndexLength]); SendCounter = 0; while(SendCounter < tempCount) { SendChar((unsigned char)SendData[SendCounter]); SendCounter += 1 ; } } } /*选择是否擦除对应segment和index*/ //接收自上位机的删除信号 'Y' for 删除,'N' for 不删除 if(serialRecv[1] == 'Y') { //uint32_t tempIndexList[uniIndexLength*7]; flash_init_sector(IndexList[(serialRecv[0]-48)*uniIndexLength]);//擦除该index所对应flash user data area区域 flash_init_sector(((uint32_t)0x08010000));//先擦除Index区域(sector 4) i = 0; uint8_t k = 0; while(i < IndexCount) { if (i != (serialRecv[0]-48)*uniIndexLength) { IndexList[k] = IndexList[i]; IndexList[k+1] = IndexList[i+1]; IndexList[k+2] = IndexList[i+2]; k += uniIndexLength; } i += uniIndexLength; } flash_writeIndex(IndexList,IndexCount-uniIndexLength);//后重写该条index记录 IndexCount -= 3; } } } /********************清空flash********************************/ /* if Button(PB12) is pressed, flash user area will be erased*/ if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12) == Bit_SET) { /*waiting Button(PB12) being released*/ while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12) == Bit_SET); /* flash初始化 */ flash_init(); IndexCount = 0; /*灯全闪烁后全灭,指示flash中用户数据被擦除*/ STM_EVAL_LEDToggle(LED4); STM_EVAL_LEDToggle(LED3); STM_EVAL_LEDToggle(LED5); STM_EVAL_LEDToggle(LED6); Delay(10); STM_EVAL_LEDOff(LED4); STM_EVAL_LEDOff(LED3); STM_EVAL_LEDOff(LED5); STM_EVAL_LEDOff(LED6); Delay(100); } /* Toggle LED4 */ STM_EVAL_LEDToggle(LED6); Delay(50); //LED4 3 5用于二进制编码指示flash存储区占用个数 if((IndexCount/uniIndexLength)&(0x01))//最低位 { STM_EVAL_LEDOn(LED5); } else { STM_EVAL_LEDOff(LED5); } if((IndexCount/uniIndexLength)&(0x02)) { STM_EVAL_LEDOn(LED3); } else { STM_EVAL_LEDOff(LED3); } if((IndexCount/uniIndexLength)&(0x04))//最高位 { STM_EVAL_LEDOn(LED4); } else { STM_EVAL_LEDOff(LED4); } } /* Waiting User Button is Released */ while (STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET) {} /******************************************/ /***退出空闲状态,采样状态配置初始化*******/ /******************************************/ STM_EVAL_LEDOn(LED4); STM_EVAL_LEDOff(LED4); Delay(10); STM_EVAL_LEDOn(LED3); STM_EVAL_LEDOff(LED3); Delay(10); STM_EVAL_LEDOn(LED5); STM_EVAL_LEDOff(LED5); Delay(10); STM_EVAL_LEDOn(LED6); STM_EVAL_LEDOff(LED6); Delay(10); /*各段记录相互独立的标志位均清零*/ Counter = 0;//分组采用计数器复位 DataWriteErrorFlag = 0;//flash写入错误标志位复位 NoWrittenFlag = 0;//未写入标志位复位 WritingSectorFlag = 0;//正在写入sector标志位复位 totalDataNumber = 0;//各段记录数据个数计数器复位 UserButtonPressed = 0x00; /* MEMS configuration */ LIS302DL_InitStruct.Power_Mode = LIS302DL_LOWPOWERMODE_ACTIVE; LIS302DL_InitStruct.Output_DataRate = LIS302DL_DATARATE_400;//加速度传感器采用率400HZ LIS302DL_InitStruct.Axes_Enable = LIS302DL_XYZ_ENABLE; LIS302DL_InitStruct.Full_Scale = LIS302DL_FULLSCALE_2_3;//18 mg/digit LIS302DL_InitStruct.Self_Test = LIS302DL_SELFTEST_NORMAL; LIS302DL_Init(&LIS302DL_InitStruct); /* Required delay for the MEMS Accelerometre: Turn-on time = 3/Output data Rate = 3/400 = 7.5ms */ Delay(1); /* MEMS High Pass Filter configuration */ LIS302DL_FilterStruct.HighPassFilter_Data_Selection = LIS302DL_FILTEREDDATASELECTION_OUTPUTREGISTER; LIS302DL_FilterStruct.HighPassFilter_CutOff_Frequency = LIS302DL_HIGHPASSFILTER_LEVEL_1; LIS302DL_FilterStruct.HighPassFilter_Interrupt = LIS302DL_HIGHPASSFILTERINTERRUPT_1_2; LIS302DL_FilterConfig(&LIS302DL_FilterStruct); LIS302DL_Read(Buffer, LIS302DL_OUT_X_ADDR, 6); X_Offset = Buffer[0]; Y_Offset = Buffer[2]; Z_Offset = Buffer[4]; /******************************************/ /***********开始进入采样模式,写入flash****/ /******************************************/ DemoEnterCondition = 0x01; /* Waiting User Button is pressed */ while (UserButtonPressed == 0x00) //利用采样间隙写入缓冲器内数据,提高效率 { if((0 == Counter)&&(1 == NoWrittenFlag)&&(0 == DataWriteErrorFlag)) { if (WritingSectorFlag == 0) { writingDataAddr = getFreeDataStartAddr(); if (writingDataAddr == 0) { NoFreeSectors = 1;//无空闲sector块置位 NoWrittenFlag = 0; /* 指示灯全亮,指示存储空间已满 */ STM_EVAL_LEDOn(LED4); STM_EVAL_LEDOn(LED3); STM_EVAL_LEDOn(LED5); STM_EVAL_LEDOn(LED6); break;//退出采样模式 } else { //一次完整flash写入 flash_init_sector(writingDataAddr);//保险起见,先擦除该空闲sector块 DataWriteErrorFlag = flash_writeData(Total_Buffer, Total_Buffer_Number,writingDataAddr); NoWrittenFlag = 0;//表示已写入(flash) WritingSectorFlag = 1;//正在写入sector标志位置位,表示启用该块sector } } else { //flash写入 DataWriteErrorFlag = flash_writeData(Total_Buffer, Total_Buffer_Number,writingDataAddr); NoWrittenFlag = 0;//表示已写入(flash) } } if(DataWriteErrorFlag != 0) { flash_init_sector(writingDataAddr);//flash写入错误后,擦除相应存储空间,退出采样状态 WritingSectorFlag = 0;//归还对该块存储空间的使用权 /* 指示灯全亮后全灭,指示进入采样状态 */ STM_EVAL_LEDOn(LED4); STM_EVAL_LEDOn(LED3); STM_EVAL_LEDOn(LED5); STM_EVAL_LEDOn(LED6); Delay(100); STM_EVAL_LEDOff(LED4); STM_EVAL_LEDOff(LED3); STM_EVAL_LEDOff(LED5); STM_EVAL_LEDOff(LED6); Delay(100); break; } /* 指示灯全灭,指示进入采样状态 */ STM_EVAL_LEDOff(LED4); STM_EVAL_LEDOff(LED4); STM_EVAL_LEDOff(LED3); STM_EVAL_LEDOff(LED5); STM_EVAL_LEDOff(LED6); } /* Waiting User Button is Released */ while (STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET) {} /******************************************/ /***********退出采样模式,做善后处理*******/ /******************************************/ DemoEnterCondition = 0x00;//防止此时进入采样模式 /*如果退出采样模式时尚有数据未写入flash,在此一并写入flash*/ if(1 == NoWrittenFlag) flash_writeData(Total_Buffer, Counter,writingDataAddr); if ((0 == NoFreeSectors)&&(1 == WritingSectorFlag)) { /* 指示灯全灭后全亮,指示进入数据善后状态 */ STM_EVAL_LEDOff(LED4); STM_EVAL_LEDOff(LED3); STM_EVAL_LEDOff(LED5); STM_EVAL_LEDOff(LED6); Delay(10); STM_EVAL_LEDOn(LED4); STM_EVAL_LEDOn(LED3); STM_EVAL_LEDOn(LED5); STM_EVAL_LEDOn(LED6); Delay(10); /*至此,一条“完整”记录写入flash完毕,需要在flash中建立关于这条记录的索引index*/ flash_readIndex(IndexList,uniIndexLength, &IndexCount);//从flash中读取原IndexList IndexList[IndexCount] = writingDataAddr;//写入最新的数据地址块首地址 srand((int)time(0)); IndexList[IndexCount+1] = rand()%100;//写入最新的记录名 IndexList[IndexCount+2] = totalDataNumber;//写入最新的段记录总个数 flash_init_sector(((uint32_t)0x08010000));//先擦除Index区域(sector 4) flash_writeIndex(IndexList,IndexCount+3);//后写入 IndexCount += 3; } /* Disable SPI1 used to drive the MEMS accelerometre */ SPI_Cmd(LIS302DL_SPI, DISABLE); } }