#include "SIM7020C.h" #include "flash.h" #include "uart.h" #define STM32ID_ADDR 0x1FF80050 #define FLASH_STORE_START 0x8007000 #define FLASH_TOTAL_INF_ADDR FLASH_STORE_START #define FLASH_DATA_ADDR FLASH_STORE_START #define FLASH_STORE_END 0x8010000 #define FLASH_STORE_SIZE (FLASH_STORE_END - FLASH_STORE_START) // 64k - 28k = 36k #include "stm32l0xx_hal.h" //uint32_tidAddr[]={0x1FFFF7AC, /*STM32F0唯一ID起始地址*/ // 0x1FFFF7E8, /*STM32F1唯一ID起始地址*/ // 0x1FFF7A10, /*STM32F2唯一ID起始地址*/ // 0x1FFFF7AC, /*STM32F3唯一ID起始地址*/ // 0x1FFF7A10, /*STM32F4唯一ID起始地址*/ // 0x1FF0F420, /*STM32F7唯一ID起始地址*/ // 0x1FF80050, /*STM32L0唯一ID起始地址*/ // 0x1FF80050, /*STM32L1唯一ID起始地址*/ // 0x1FFF7590, /*STM32L4唯一ID起始地址*/ // 0x1FF0F420}; /*STM32H7唯一ID起始地址*/ #pragma pack (4) // 编译器将按照n个字节对齐; typedef struct { unsigned int year : 12 ; // 0 ~ 4095 unsigned int month : 4 ; // 0 ~ 15 unsigned int date : 5 ; // 0 ~ 31 unsigned int hour : 5 ; // 0 ~ 31 unsigned int min : 6 ; // 0 ~ 63 }time_t; typedef struct { signed short data_air_temp :16; // -32768 ~ 32768 = real data * 100 signed short data_soil_temp :16; // -32768 ~ 32768 = real data * 100 unsigned short data_light :16; // 0 ~ 65535 = real data unsigned short data_co2 :16; // 0 ~ 65536 = real data unsigned short data_air_Rh :12; // 0 ~ 4096 = real data * 40 unsigned short data_soil_Rh :12; // 0 ~ 4096 = real data * 40 unsigned char bat_value :8; // 0 ~ 256 = real data }data_t; typedef struct { time_t time ; // 4 bytes data_t data ; // 12 bytes }store_senser_t; // 16 bytes #pragma pack() #define DATA_LENGTH sizeof(store_senser_t) #define MAX_DATA_NUMS (FLASH_STORE_SIZE/DATA_LENGTH) unsigned char need_to_erase_flash = 0; //濡傛灉flash閲岄潰鏈夋暟鎹病鏈夊彂閫侊紝鍦ㄥ彂閫佸畬姣曞悗闇瑕佹竻绌篺lash store_senser_t store_senser; void change_senser_data_to_flash_type(void) { store_senser.time.year = 2020; store_senser.time.month = 4 ; store_senser.time.date = 25 ; store_senser.time.hour = 14 ; store_senser.time.min = 03 ; store_senser.data.data_air_temp = (sensee_data.temp_air * 100); store_senser.data.data_soil_temp = (sensee_data.temp_soil * 100); store_senser.data.data_air_Rh = (sensee_data.Rh_air * 40); store_senser.data.data_soil_Rh = (sensee_data.Rh_soil * 40); store_senser.data.data_light = (sensee_data.sun_shine) ; store_senser.data.data_co2 = (sensee_data.co2) ; store_senser.data.bat_value = (sensee_data.bat_val ) ; } void change_flash_type_to_senser_data(void) { sensee_data.temp_air = ((float)store_senser.data.data_air_temp / 100); sensee_data.temp_soil = ((float)store_senser.data.data_soil_temp / 100); sensee_data.Rh_air = ((float)store_senser.data.data_air_Rh / 40); sensee_data.Rh_soil = ((float)store_senser.data.data_soil_Rh / 40); sensee_data.sun_shine = ((float)store_senser.data.data_light ); sensee_data.co2 = ((float)store_senser.data.data_co2 ); sensee_data.bat_val = ((float)store_senser.data.bat_value ); } void write_data_to_flash(unsigned short nums) { union { store_senser_t store_senser_buffer; unsigned long uint_buffer_arriry[DATA_LENGTH/4]; }databuffer; unsigned char i = 0 ; unsigned long address = 0 ; if(nums == 0) return ; HAL_FLASH_Unlock(); HAL_FLASH_OB_Unlock(); HAL_Delay(10); address = FLASH_DATA_ADDR + (nums - 1 ) * DATA_LENGTH ; change_senser_data_to_flash_type(); databuffer.store_senser_buffer.time.year = store_senser.time.year ; databuffer.store_senser_buffer.time.month = store_senser.time.month ; databuffer.store_senser_buffer.time.date = store_senser.time.date ; databuffer.store_senser_buffer.time.hour = store_senser.time.hour ; databuffer.store_senser_buffer.time.min = store_senser.time.min ; databuffer.store_senser_buffer.data.bat_value = store_senser.data.bat_value ; databuffer.store_senser_buffer.data.data_air_Rh = store_senser.data.data_air_Rh ; databuffer.store_senser_buffer.data.data_air_temp = store_senser.data.data_air_temp ; databuffer.store_senser_buffer.data.data_co2 = store_senser.data.data_co2 ; databuffer.store_senser_buffer.data.data_light = store_senser.data.data_light ; databuffer.store_senser_buffer.data.data_soil_Rh = store_senser.data.data_soil_Rh ; databuffer.store_senser_buffer.data.data_soil_temp = store_senser.data.data_soil_temp ; for(i = 0 ; i < DATA_LENGTH/4 ; i++) HAL_FLASH_Program(TYPEPROGRAM_WORD, address + i*4, databuffer.uint_buffer_arriry[i]); HAL_FLASH_Lock(); HAL_FLASH_OB_Lock(); } void read_data_from_flash(unsigned short nums) { union { store_senser_t store_senser_buffer; unsigned long uint_buffer_arriry[DATA_LENGTH/4]; }databuffer; unsigned char i = 0 ; unsigned int address ; if(nums == 0) return ; address = FLASH_DATA_ADDR + (nums - 1 ) * DATA_LENGTH ; for(i = 0 ; i < DATA_LENGTH/4 ; i++) databuffer.uint_buffer_arriry[i] = *(unsigned char *)(address + i*4) ; store_senser.time.year = databuffer.store_senser_buffer.time.year ; store_senser.time.month = databuffer.store_senser_buffer.time.month ; store_senser.time.date = databuffer.store_senser_buffer.time.date ; store_senser.time.hour = databuffer.store_senser_buffer.time.hour ; store_senser.time.min = databuffer.store_senser_buffer.time.min ; store_senser.data.bat_value = databuffer.store_senser_buffer.data.bat_value ; store_senser.data.data_air_Rh = databuffer.store_senser_buffer.data.data_air_Rh ; store_senser.data.data_air_temp = databuffer.store_senser_buffer.data.data_air_temp ; store_senser.data.data_co2 = databuffer.store_senser_buffer.data.data_co2 ; store_senser.data.data_light = databuffer.store_senser_buffer.data.data_light ; store_senser.data.data_soil_Rh = databuffer.store_senser_buffer.data.data_soil_Rh ; store_senser.data.data_soil_temp = databuffer.store_senser_buffer.data.data_soil_temp ; change_flash_type_to_senser_data(); } unsigned char deviceid[26]; void get_device_id(void) { unsigned char i ; for(i = 0 ; i<26; i++) deviceid[i] = *(unsigned char *)(STM32ID_ADDR + i); } /* 清空flash数据 */ void flash_erase_page(void) { unsigned int FirstPage = 0, NbOfPages = 0, Address = 0; unsigned int PageError = 0; HAL_StatusTypeDef error_flag ; static FLASH_EraseInitTypeDef EraseInitStruct; NbOfPages = (FLASH_STORE_SIZE+ 1) >> 7; EraseInitStruct.TypeErase = TYPEERASE_PAGEERASE; EraseInitStruct.Page = FLASH_TOTAL_INF_ADDR; EraseInitStruct.NbPages = NbOfPages; HAL_FLASH_Unlock(); HAL_FLASH_OB_Unlock(); HAL_Delay(10); error_flag = HAL_FLASHEx_Erase(&EraseInitStruct, &PageError); if ( error_flag != HAL_OK) { /* Error occurred while page erase. User can add here some code to deal with this error. PageError will contain the faulty page. */ // Error_Handler(); } HAL_FLASH_Lock(); HAL_FLASH_OB_Lock(); if (PageError) logdata("error"); } /* 获取flash中已经存储的数据数量 (未被上传到服务器的数据总量) */ unsigned int get_data_store_length(void) { unsigned char i = 0 ; unsigned int data_num ; union { store_senser_t store_senser_buffer; unsigned long ucint_buffer_arriry[DATA_LENGTH/4]; }databuffer; for( data_num = 0; data_num < MAX_DATA_NUMS ; data_num ++) { if(data_num) need_to_erase_flash = 1; for(i = 0 ; i < DATA_LENGTH/4 ; i++) databuffer.ucint_buffer_arriry[i] = *(unsigned char *)(FLASH_STORE_START +data_num * DATA_LENGTH + i*4) ; if((databuffer.ucint_buffer_arriry[0] == 0x00) && (databuffer.ucint_buffer_arriry[1] == 0x00) && (databuffer.ucint_buffer_arriry[2] == 0x00) && (databuffer.ucint_buffer_arriry[3] == 0x00)) return data_num ; } } /* 测试flash存储 */ #include "uart.h" void flash_test(void) { unsigned char i = 0; // flash_erase_page(); for(i = 0; i < 5 ; i++ ) { // read_data_from_flash(i); sensee_data.temp_air = 0-i ; sensee_data.Rh_air = i ; sensee_data.temp_soil = i ; sensee_data.Rh_soil = i ; sensee_data.sun_shine = i ; sensee_data.co2 = i ; sensee_data.bat_val = i ; write_data_to_flash(i+senser_data_error_num+1); write_data_to_flash(MAX_DATA_NUMS-i-1-senser_data_error_num); sensee_data.temp_air = 0; sensee_data.Rh_air = 0; sensee_data.temp_soil = 0; sensee_data.Rh_soil = 0; sensee_data.sun_shine = 0; sensee_data.co2 = 0; sensee_data.bat_val = 0; // read_data_from_flash(i); //// flash_erase_page(); // read_data_from_flash(MAX_DATA_NUMS-i); i = i; } while(1); }