STM32 HAL库之Tiny Program 1 - 数据监测存储系统

发布于:2024-12-18 ⋅ 阅读:(41) ⋅ 点赞:(0)

项目需求

        每间隔一段时间对STM32 MCU内部工作电压和温度进行采集监测,并存储到MicroSD卡内。   

实现机制

        使用定时器定时触发ADC转换,对温度和内部电压Vref两个规则通道数据进行采集,采集的数据保存在MicroSD卡内,MicroSD卡使用FatFs文件系统管理。该项目使用STM32CubeMX进行配置开发。

ADC配置

TIMER配置

SDIO配置

  FatFs配置

应用代码

1、SDIO初始代码需要重新映射

uint8_t BSP_SD_Init(void)
{
  uint8_t sd_state = MSD_OK;
	
	SD_InitTypeDef Init;
	Init.ClockEdge           = SDIO_CLOCK_EDGE_RISING;
	Init.ClockBypass         = SDIO_CLOCK_BYPASS_DISABLE;
	Init.ClockPowerSave      = SDIO_CLOCK_POWER_SAVE_DISABLE;
	Init.BusWide             = SDIO_BUS_WIDE_1B;
	Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
	Init.ClockDiv            = SDIO_INIT_CLK_DIV;
	
  /* Check if the SD card is plugged in the slot */
  if (BSP_SD_IsDetected() != SD_PRESENT)
  {
    return MSD_ERROR;
  }
  /* HAL SD initialization */
  sd_state = HAL_SD_Init(&hsd);      // added by user config 4bit must in low frequency
	
	SDIO_Init(hsd.Instance, Init);
  /* Configure SD Bus width (4 bits mode selected) */
  if (sd_state == MSD_OK)
  {
    /* Enable wide operation */
    if (HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK)
    {
      sd_state = MSD_ERROR;
    }
  }

  return sd_state;
}

2、ADC校正、DMA启动以及TIMER启动

  /* USER CODE BEGIN 2 */
	HAL_ADCEx_Calibration_Start(&hadc1);
//	HAL_ADC_Start(&hadc1);
//	HAL_ADC_PollForConversion(&hadc1, 0xffff);
	HAL_ADC_Start_DMA(&hadc1,(uint32_t *)uAdcValue, 2);
	HAL_TIM_Base_Start(&htim8);
  /* USER CODE END 2 */

使用ADC时,需HAL_ADCEx_Calibration_Start对ADC进行校正,保证采集数据的精准度。

float ConvertTemperature(uint32_t temp)
{
	float convertValue = 0.0, returnValue = 0.0;
	
	convertValue = 3.3*temp/4095;
	returnValue = ((1.43 - convertValue)/4.3)*1000 + 25;
	return returnValue;	
}

float ConvertVDD(uint32_t vddValue)
{
	float  returnValue = 0.0;
	
//	returnValue = vddValue*3.3/4095;
	returnValue = 1.2 * 4095/vddValue;	
	return returnValue;
}

3、文件操作

	res = f_mount(&DataFs, SDPath, 1);
	if(FR_OK != res)
	{
		Error_Handler();
	}
	
	res = f_open(&DataFile,"0:MonitorLog.txt", FA_WRITE | FA_CREATE_ALWAYS);
	if(FR_OK != res)
	{
		Error_Handler();
	}
	  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

		if (gFlag_AdcUpadte == 1)
		{
				Ta = ConvertTemperature(uAdcValue[0]);
				Vdd = ConvertVDD(uAdcValue[1]);
				sprintf((char *)demotxt,"Time= %d :Ta=%f VDD=%f\n", uwTick/1000, Ta, Vdd);
			
				res = f_write(&DataFile, demotxt, strlen((const char*)demotxt), (UINT *)&temp);
				pos_DataFile += strlen((const char*)demotxt);
				f_lseek(&DataFile, pos_DataFile);
				
				if(FR_OK != res)
				{
					Error_Handler();
				}
				
				gCnt_DataSync ++;
				
				if (gCnt_DataSync == 15)
				{
					f_sync(&DataFile);
					gCnt_DataSync = 0;
					if(FR_OK != res)
					{
						Error_Handler();
					}
				}
				gFlag_AdcUpadte = 0;
		}

		
//		HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
//		HAL_Delay(100);
  }
  /* USER CODE END 3 */

        SCAN模式下使用DMA中断传输,每次转换完毕后触发DMA中断,在中断中更新写SD标志gFlag_AdcUpadte。

        写入采集数据到文件系统中,需要使用f_sync更新缓存,这一点很是奇怪。f_write写数据到SD卡的最小单位为一个sector,在RAM中写入数据达到一个sector的数据量512Byte,才真正进行写入SD卡操作。

实验结果


网站公告

今日签到

点亮在社区的每一天
去签到