/************************************************************
* °æÈ¨£º2025CIMC Copyright¡£
* Îļþ£ºFunction.c
* ×÷Õß: Lingyu Meng
* ƽ̨: 2025CIMC IHD-V04
* °æ±¾: Lingyu Meng 2025/2/16 V0.01 original
************************************************************/
/************************* Í·Îļþ *************************/
#include "Function.h"
#include "LED.h"
#include "RTC.h"
#include "USART0.h"
#include "SPI_FLASH.h"
#include "ff.h"
#include "diskio.h"
#include "sdcard.h"
#include "sys_check.h"
#include "oled.h"
#include "conf_read.h"
#include "ratio_set.h"
#include "limit_set.h"
#include "key.h"
#include "adc.h"
#include "RTC.h"
/************************* ºê¶¨Òå *************************/
#define BUFFER_SIZE 256
#define TX_BUFFER_SIZE BUFFER_SIZE
#define RX_BUFFER_SIZE BUFFER_SIZE
#define FLASH_WRITE_ADDRESS 0x000000
#define FLASH_READ_ADDRESS FLASH_WRITE_ADDRESS
// ²ÉÑùÖÜÆÚ³£Á¿¶¨Òå
#define CYCLE_5S 1
#define CYCLE_10S 10
#define CYCLE_15S 15
// Flash´æ´¢µØÖ·¶¨Òå
#define SAMPLE_CYCLE_ADDR 0x000100
/************************ ±äÁ¿¶¨Òå ************************/
uint8_t tx_buffer[TX_BUFFER_SIZE];
uint8_t rx_buffer[TX_BUFFER_SIZE];
uint16_t i = 0, count, result = 0;
uint8_t is_successful = 0;
//FIL fdst;
UINT br, bw;
BYTE buffer[128];
BYTE filebuffer[128];
typedef struct {
int count; // µ±Ç°ÎļþÊý¾Ý¼ÆÊý
// unsigned long datetime; // µ±Ç°ÎļþµÄʱ¼ä´Á
FIL file; // µ±Ç°Îļþ¶ÔÏó
} DataFileInfo;
static DataFileInfo data_file_info = {0, {0}};
// È«¾Ö±äÁ¿
uint32_t sample_cycle = CYCLE_5S; // µ±Ç°²ÉÑùÖÜÆÚ£¬µ¥Î»Ãë
/************************ º¯Êý¶¨Òå ************************/
ErrStatus memory_compare(uint8_t* src,uint8_t* dst,uint16_t length);
void nvic_config(void);
void write_file(void);
/************************************************************
* Function : System_Init
* Comment : ÓÃÓÚ³õʼ»¯MCU
* Parameter: null
* Return : null
* Author : Lingyu Meng
* Date : 2025-02-30 V0.1 original
************************************************************/
void System_Init(void)
{
systick_config(); // ʱÖÓÅäÖÃ
nvic_config(); // ÅäÖÃÖжϿØÖÆÆ÷
KEY_Init(); // KEY³õʼ»¯
LED_Init();
USART0_Config(); // ´®¿Ú³õʼ»¯
nvic_irq_enable(USART0_IRQn, 0, 0); // ʹÄÜUSART0ÖжÏ
usart_interrupt_enable(USART0, USART_INT_RBNE); // ½ÓÊÕÖжϴò¿ª
ADC_port_init(); // ADC³õʼ»¯
OLED_Init();
TF_Init();
spi_flash_init(); // ³õʼ»¯SPI Flash
RTC_Init();
// ´ÓFlash¶ÁÈ¡±£´æµÄ²ÉÑùÖÜÆÚ
uint32_t saved_cycle;
spi_flash_buffer_read((uint8_t*)&saved_cycle, SAMPLE_CYCLE_ADDR, sizeof(uint32_t));
// ÑéÖ¤¶ÁÈ¡µÄÖµÊÇ·ñÓÐЧ
if (saved_cycle == CYCLE_5S || saved_cycle == CYCLE_10S || saved_cycle == CYCLE_15S) {
sample_cycle = saved_cycle;
printf("Loaded saved sample cycle: %d s\r\n", sample_cycle);
} else {
// ÎÞЧֵ£¬Ê¹ÓÃĬÈÏ5Ãë
sample_cycle = CYCLE_5S;
printf("Using default sample cycle: %d s\r\n", sample_cycle);
// ±£´æÄ¬ÈÏÖµµ½Flash
spi_flash_sector_erase(SAMPLE_CYCLE_ADDR);
spi_flash_buffer_write((uint8_t*)&sample_cycle, SAMPLE_CYCLE_ADDR, sizeof(uint32_t));
}
// ¶ÁÈ¡¶ÓÎé±àºÅ
Team_num();
delay_1ms(10);
}
/************************************************************
* Function : UsrFunction
* Comment : Óû§³ÌÐò¹¦ÄÜ
* Parameter: null
* Return : null
* Author : Liu Tao @ GigaDevice
* Date : 2025-05-10 V0.1 original
************************************************************/
void UsrFunction(void)
{
uint8_t sampling_enabled = 0; // ²ÉÑùʹÄܱêÖ¾
uint32_t last_sample_time = 0; // ÉϴβÉÑùʱ¼ä
uint32_t last_led_toggle_time = 0; // LEDÇл»Ê±¼ä
uint8_t led_state = 0; // LEDµ±Ç°×´Ì¬
// ¾²Ì¬±äÁ¿¼Ç¼°´¼üÉÏ´Î״̬£¨ÓÃÓÚ±ßÔµ¼ì²â£©
static uint8_t last_key2 = 1, last_key3 = 1, last_key4 = 1;
printf("====system init====\r\n");
Read_Team_num(); // ¶ÁÈ¡¶ÓÎé±àºÅ
printf("\n\r====system ready====\r\n");
OLED_ShowString(0, 0, "system idle", 16);
OLED_Refresh();
while (1) {
uint32_t current_tick = systick_get_tick();
// ================ °´¼ü´¦Àí ================
// ¼ì²âKEY1°´ÏÂʼþ
if (KEY_Stat(KEY_PORT, KEY1_PIN)) {
// °´¼ü״̬·×ª
sampling_enabled = !sampling_enabled;
if (sampling_enabled) {
// Æô¶¯²ÉÑù
printf("Output==> Periodic Sampling (Key Start)\r\n");
printf("Output==> sample cycle: %ds\r\n", sample_cycle);
last_sample_time = current_tick;
last_led_toggle_time = current_tick;
led_state = 0;
OLED_Clear();
OLED_ShowString(0, 0, "Sampling...", 16);
OLED_Refresh();
} else {
// Í£Ö¹²ÉÑù
printf("Output==> Periodic Sampling STOP (Key Stop)\r\n");
gpio_bit_reset(GPIOA, GPIO_PIN_5); // ¹Ø±ÕLED1
OLED_Clear();
OLED_ShowString(0, 0, "system idle", 16);
OLED_Refresh();
}
// Ìí¼ÓÈ¥¶¶ÑÓʱ
delay_1ms(50);
}
// ¼ì²âKEY2°´ÏÂʼþ£¨ÖÜÆÚÉèΪ5s£©
uint8_t current_key2 = KEY_Stat(KEY_PORT, KEY2_PIN);
if (current_key2 && !last_key2) {
sample_cycle = CYCLE_5S;
printf("Output==> sample cycle adjust: %ds\r\n", sample_cycle);
// ±£´æµ½Flash
spi_flash_sector_erase(SAMPLE_CYCLE_ADDR);
spi_flash_buffer_write((uint8_t*)&sample_cycle, SAMPLE_CYCLE_ADDR, sizeof(uint32_t));
// Èç¹ûÕýÔÚ²ÉÑù£¬¸üвÉÑùʱ¼ä
if (sampling_enabled) {
last_sample_time = current_tick;
}
}
last_key2 = current_key2;
// ¼ì²âKEY3°´ÏÂʼþ£¨ÖÜÆÚÉèΪ10s£©
uint8_t current_key3 = KEY_Stat(KEY_PORT, KEY3_PIN);
if (current_key3 && !last_key3) {
sample_cycle = CYCLE_10S;
printf("Output==> sample cycle adjust: %ds\r\n", sample_cycle);
// ±£´æµ½Flash
spi_flash_sector_erase(SAMPLE_CYCLE_ADDR);
spi_flash_buffer_write((uint8_t*)&sample_cycle, SAMPLE_CYCLE_ADDR, sizeof(uint32_t));
// Èç¹ûÕýÔÚ²ÉÑù£¬¸üвÉÑùʱ¼ä
if (sampling_enabled) {
last_sample_time = current_tick;
}
}
last_key3 = current_key3;
// ¼ì²âKEY4°´ÏÂʼþ£¨ÖÜÆÚÉèΪ15s£©
uint8_t current_key4 = KEY_Stat(KEY_PORT, KEY4_PIN);
if (current_key4 && !last_key4) {
sample_cycle = CYCLE_15S;
printf("Output==> sample cycle adjust: %ds\r\n", sample_cycle);
// ±£´æµ½Flash
spi_flash_sector_erase(SAMPLE_CYCLE_ADDR);
spi_flash_buffer_write((uint8_t*)&sample_cycle, SAMPLE_CYCLE_ADDR, sizeof(uint32_t));
// Èç¹ûÕýÔÚ²ÉÑù£¬¸üвÉÑùʱ¼ä
if (sampling_enabled) {
last_sample_time = current_tick;
}
}
last_key4 = current_key4;
// ================ ´®¿ÚÃüÁî´¦Àí ================
if (cmd_ready) {
cmd_ready = 0;
int len = cmd_index;
// ÇåÀíÃüÁîĩβµÄ¿Õ°××Ö·û
while (len > 0 && (cmd_buffer[len - 1] == '\r' || cmd_buffer[len - 1] == '\n' || cmd_buffer[len - 1] == ' ')) {
cmd_buffer[len - 1] = '\0';
len--;
}
// ²âÊÔÃüÁî
if (strcmp((const char*)cmd_buffer, "test") == 0) {
sys_check(); // ϵͳ×Ô¼ì
}
// RTCÅäÖÃÃüÁî
else if (strcmp((const char*)cmd_buffer, "RTC Config") == 0) {
printf("\r\nInput Datetime\r\n");
while (cmd_ready == 0) delay_1ms(10);
char datetime_str[64];
strcpy(datetime_str, (const char*)cmd_buffer);
cmd_ready = 0;
rtc_settime(datetime_str);
}
// ÏÔʾµ±Ç°Ê±¼ä
else if (strcmp((const char*)cmd_buffer, "RTC now") == 0) {
rtc_show_time();
}
// conf¼ì²â
else if (strcmp((const char*)cmd_buffer, "conf") == 0) {
conf();
}
// ratio¼ì²â
else if (strcmp((const char*)cmd_buffer, "ratio") == 0) {
ratio_set();
}
// limit¼ì²â
else if (strcmp((const char*)cmd_buffer, "limit") == 0) {
limit_set();
}
// conf_read¼ì²â
else if (strcmp((const char*)cmd_buffer, "conf_read") == 0) {
printf("\r\nread parameters from flash\r\n");
conf_read();
}
// conf_save¼ì²â
else if (strcmp((const char*)cmd_buffer, "conf_save") == 0) {
conf_save();
}
// Æô¶¯²ÉÑùÃüÁî
else if (strcmp((const char*)cmd_buffer, "start") == 0) {
sampling_enabled = 1;
printf("Output==> Periodic Sampling\r\n");
printf("Output==> sample cycle: %ds\r\n", sample_cycle);
last_sample_time = current_tick;
last_led_toggle_time = current_tick;
led_state = 0;
OLED_Clear();
OLED_ShowString(0, 0, "Sampling...", 16);
OLED_Refresh();
}
// Í£Ö¹²ÉÑùÃüÁî
else if (strcmp((const char*)cmd_buffer, "stop") == 0) {
if (sampling_enabled) {
sampling_enabled = 0;
printf("Output==> Periodic Sampling STOP\r\n");
gpio_bit_reset(GPIOA, GPIO_PIN_5); // ¹Ø±ÕLED1
OLED_Clear();
OLED_ShowString(0, 0, "system idle", 16);
OLED_Refresh();
}
}
}
// ================ ²ÉÑùÈÎÎñ ) ================
if (sampling_enabled) {
// LEDÉÁ˸¿ØÖÆ£¨·Ç×èÈû·½Ê½£©
if (current_tick - last_led_toggle_time >= 500) {
last_led_toggle_time = current_tick;
led_state = !led_state;
if (led_state) {
gpio_bit_set(GPIOA, GPIO_PIN_5); // LEDÁÁ
} else {
gpio_bit_reset(GPIOA, GPIO_PIN_5); // LEDÃð
}
}
// ²ÉÑù¶¨Ê±£¨Ê¹Óõ±Ç°ÖÜÆÚ£©
if (current_tick - last_sample_time >= sample_cycle * 1000) {
// ¶ÁÈ¡RTCʱ¼ä
// ¶ÁÈ¡ADCÖµ
adc_flag_clear(ADC0, ADC_FLAG_EOC);
while (SET != adc_flag_get(ADC0, ADC_FLAG_EOC)) {} // µÈ´ýת»»Íê³É
uint16_t adc_value = ADC_RDATA(ADC0);
float vol_value = adc_value * 3.3f / 4095.0f;
rtc_current_time_get(&rtc_initpara);
// ת»»Îª10½øÖÆ
uint8_t hour = bcd_to_dec(rtc_initpara.hour);
uint8_t minute = bcd_to_dec(rtc_initpara.minute);
uint8_t second = bcd_to_dec(rtc_initpara.second);
uint8_t year = bcd_to_dec(rtc_initpara.year);
uint8_t month = bcd_to_dec(rtc_initpara.month);
uint8_t day = bcd_to_dec(rtc_initpara.date);
/**************** OLED?? ****************/
char time_str[16];
char volt_str[16];
sprintf(time_str, "%02u:%02u:%02u", hour, minute, second);
sprintf(volt_str, "%.2f V", vol_value);
OLED_Clear();
OLED_ShowString(0, 0, time_str, 16);
OLED_ShowString(0, 16, volt_str, 16);
OLED_Refresh();
/***************´®¿ÚÊä³ö****************/
printf("20%02u-%02u-%02u %02u:%02u:%02u %.2fV\r\n",
year, month, day, hour, minute, second, vol_value);
/*************** ´æ´¢Êý¾Ý ***************
int count; // µ±Ç°ÎļþÊý¾Ý¼ÆÊý
unsigned long datetime; // µ±Ç°ÎļþµÄʱ¼ä´Á
FIL file; // µ±Ç°Îļþ¶ÔÏóDataFileInfo data_file_info = {0, 0, {0}};*/
FRESULT res;
FATFS fs;
char dir_path[] = "0:/sample"; // Ä¿±êĿ¼
char filename[64];
if (data_file_info.count == 0) {
//³õʼ»¯´æ´¢É豸
DSTATUS status = disk_initialize(0);
if (status != 0) {
printf("Disk initialize failed. Status: 0x%02X\n", status);
return;
}
//¹ÒÔØÎļþϵͳ
res = f_mount(0, &fs);
if (res != FR_OK) {
printf("Mount failed=%d\n", res);
return;
}
// ¹Ø±Õ֮ǰ´ò¿ªµÄÎļþ
if (data_file_info.file.fs) {
f_close(&data_file_info.file);
}
//È·±£Ä¿±êĿ¼´æÔÚ
FILINFO fno;
res = f_stat(dir_path, &fno);
if (res == FR_NO_FILE) { // Ŀ¼²»´æÔÚ
res = f_mkdir(dir_path); // ´´½¨Ä¿Â¼
if (res != FR_OK) {
printf("Ŀ¼´´½¨Ê§°Ü %s: %d\n", dir_path, res);
return;
}
} else if (res != FR_OK) {
printf("Ŀ¼·ÃÎÊ´íÎó: %d\n", res);
return;
}
// Éú³É´øÂ·¾¶µÄÎļþÃû
snprintf(filename, sizeof(filename),
"%s/sampleDeta20%02d%02d%02d%02d%02d%02d.txt",
dir_path,
year, month, day, hour, minute, second);
// ´´½¨ÐÂÎļþ
res = f_open(&data_file_info.file, filename, FA_CREATE_ALWAYS | FA_WRITE);
if (res != FR_OK) {
printf("Îļþ´´½¨Ê§°Ü %s: %d\n", filename, res);
// return;
}else{
printf("Îļþ´´½¨³É¹¦");
f_open(&data_file_info.file, filename, FA_CREATE_ALWAYS | FA_WRITE);
}
}
// дÈëÊý¾Ý
char data_line[50];
snprintf(data_line, sizeof(data_line), "20%02d-%02d-%02d %02d:%02d:%02d %.2f V\r\n",
year, month, day, hour, minute, second, vol_value);
UINT bw;
// f_open(&data_file_info.file, filename, FA_CREATE_ALWAYS | FA_WRITE);
res = f_write(&data_file_info.file, data_line, strlen(data_line), &bw);
// f_close(&data_file_info.file);
// f_mount(0, NULL);//Ð¶ÔØÎļþϵͳ
if (res != FR_OK || bw != strlen(data_line)) {
printf("Êý¾ÝдÈëʧ°Ü: %d\n", res);
} else {
f_sync(&data_file_info.file);
data_file_info.count++;
// ´ïµ½10ÌõÊý¾ÝºóÖØÖÃ
if (data_file_info.count >= 10) {
data_file_info.count = 0;
f_mount(0, NULL);//Ð¶ÔØÎļþϵͳ
}
}
last_sample_time = current_tick;
}
} else {
// ¿ÕÏÐ״̬ÏÂÌí¼ÓСÑÓʱ
delay_1ms(10);
}
}
}
void nvic_config(void)
{
nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3); // ÉèÖÃÖжÏÓÅÏȼ¶·Ö×é
nvic_irq_enable(SDIO_IRQn, 0, 0); // ʹÄÜSDIOÖжϣ¬ÓÅÏȼ¶Îª0
}
/* ͨ¹ý´®¿ÚÊäÈëдÈëÎļþ */
void write_file(void)
{
printf("Input data (press Enter to save):\r\n");
uint16_t index = 0;
while(1){
if(usart_flag_get(USART0, USART_FLAG_RBNE) != RESET){
char ch = usart_data_receive(USART0); // Èç¹û½ÓÊÕ»º³åÇø·Ç¿Õ£¬´ÓUSART0½ÓÊÕÒ»¸ö×Ö·û
if(ch == '\r'){ // ¼ì²é½ÓÊÕµ½µÄ×Ö·ûÊÇ·ñΪ»Ø³µ¼ü£¨'\r'£©
filebuffer[index] = '\0'; // Èç¹ûÊǻسµ¼ü£¬ÔÚµ±Ç°Î»ÖÃÌí¼Ó×Ö·û´®½áÊø·û '\0'
break; // Ìø³öÑ»·£¬½áÊøÊý¾Ý½ÓÊÕ
}
filebuffer[index++] = ch; // ´æ´¢½ÓÊÕµ½µÄ×Ö·û
if(index >= sizeof(filebuffer)-1) break; // Èç¹û»º³åÇøÂúÔò½áÊø½ÓÊÕ
}
}
}
/*!
\brief memory compare function
\param[in] src: source data pointer
\param[in] dst: destination data pointer
\param[in] length: the compare data length
\param[out] none
\retval ErrStatus: ERROR or SUCCESS
*/
ErrStatus memory_compare(uint8_t* src, uint8_t* dst, uint16_t length)
{
while(length --){
if(*src++ != *dst++)
return ERROR;
}
return SUCCESS;
}
把 int count; // µ±Ç°ÎļþÊý¾Ý¼ÆÊý
unsigned long datetime; // µ±Ç°ÎļþµÄʱ¼ä´Á
FIL file; // µ±Ç°Îļþ¶ÔÏóDataFileInfo data_file_info = {0, 0, {0}};*/
FRESULT res;
FATFS fs;
char dir_path[] = "0:/sample"; // Ä¿±êĿ¼
char filename[64];
if (data_file_info.count == 0) {
//³õʼ»¯´æ´¢É豸
DSTATUS status = disk_initialize(0);
if (status != 0) {
printf("Disk initialize failed. Status: 0x%02X\n", status);
return;
}
//¹ÒÔØÎļþϵͳ
res = f_mount(0, &fs);
if (res != FR_OK) {
printf("Mount failed=%d\n", res);
return;
}
// ¹Ø±Õ֮ǰ´ò¿ªµÄÎļþ
if (data_file_info.file.fs) {
f_close(&data_file_info.file);
}
//È·±£Ä¿±êĿ¼´æÔÚ
FILINFO fno;
res = f_stat(dir_path, &fno);
if (res == FR_NO_FILE) { // Ŀ¼²»´æÔÚ
res = f_mkdir(dir_path); // ´´½¨Ä¿Â¼
if (res != FR_OK) {
printf("Ŀ¼´´½¨Ê§°Ü %s: %d\n", dir_path, res);
return;
}
} else if (res != FR_OK) {
printf("Ŀ¼·ÃÎÊ´íÎó: %d\n", res);
return;
}
// Éú³É´øÂ·¾¶µÄÎļþÃû
snprintf(filename, sizeof(filename),
"%s/sampleDeta20%02d%02d%02d%02d%02d%02d.txt",
dir_path,
year, month, day, hour, minute, second);
// ´´½¨ÐÂÎļþ
res = f_open(&data_file_info.file, filename, FA_CREATE_ALWAYS | FA_WRITE);
if (res != FR_OK) {
printf("Îļþ´´½¨Ê§°Ü %s: %d\n", filename, res);
// return;
}else{
printf("Îļþ´´½¨³É¹¦");
f_open(&data_file_info.file, filename, FA_CREATE_ALWAYS | FA_WRITE);
}
}
// дÈëÊý¾Ý
char data_line[50];
snprintf(data_line, sizeof(data_line), "20%02d-%02d-%02d %02d:%02d:%02d %.2f V\r\n",
year, month, day, hour, minute, second, vol_value);
UINT bw;
// f_open(&data_file_info.file, filename, FA_CREATE_ALWAYS | FA_WRITE);
res = f_write(&data_file_info.file, data_line, strlen(data_line), &bw);
// f_close(&data_file_info.file);
// f_mount(0, NULL);//Ð¶ÔØÎļþϵͳ
if (res != FR_OK || bw != strlen(data_line)) {
printf("Êý¾ÝдÈëʧ°Ü: %d\n", res);
} else {
f_sync(&data_file_info.file);
data_file_info.count++;
// ´ïµ½10ÌõÊý¾ÝºóÖØÖÃ
if (data_file_info.count >= 10) {
data_file_info.count = 0;
f_mount(0, NULL);//Ð¶ÔØÎļþϵͳ
}
}封装起来,void write_data_to_file(const char* dir_path,
int year, int month, int day,
int hour, int minute, int second,
float vol_value)
最新发布