RTC、ADC

RTC

  • RTC(Real-Time Clock)是实时时钟模块,用于跟踪实际时间(年、月、日、时、分、秒),即使在系统断电或处于低功耗模式下也能保持时间的准确性。
特点
  • 时间和日期跟踪
  • 低功耗模式支持
  • 可编程闹钟和定时器
  • 备份寄存器
使用方法
  1. 开启RCC的High SPeed Clock的Crystal/Ceramic模式
  2. 配置时钟电路。
  3. RTC所用时钟
    在这里插入图片描述
  4. 配置RTC
    - active clock source
    - active Calendar
  5. 使用USART1将其改为异步通信
  6. 具体代码
#include "main.h"  // 包含主头文件,定义了所需的外设和函数

RTC_HandleTypeDef hrtc;  // 声明RTC句柄,用于RTC外设的配置和操作
UART_HandleTypeDef huart1;  // 声明UART句柄,用于串口1的配置和操作

void SystemClock_Config(void);  // 函数声明,配置系统时钟
static void MX_GPIO_Init(void);  // 函数声明,初始化GPIO
static void MX_RTC_Init(void);  // 函数声明,初始化RTC
static void MX_USART1_UART_Init(void);  // 函数声明,初始化USART1

int __io_putchar(int ch)  // 重定向`printf`函数的输出,将其通过串口发送
{
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);  // 使用UART1发送字符
    return ch;  // 返回发送的字符
}

int main(void)  // 主函数,程序从此处开始执行
{
    HAL_Init();  // 初始化HAL库,设置时钟、外设以及NVIC中断优先级
    SystemClock_Config();  // 调用系统时钟配置函数
    MX_GPIO_Init();  // 初始化GPIO
    MX_RTC_Init();  // 初始化RTC
    MX_USART1_UART_Init();  // 初始化USART1,用于串口通信
        RTC_DateTypeDef date;  // 定义RTC日期结构体
    date.Year = 24;  // 设置年份为2024年
    date.Month = 9;  // 设置月份为9月
    date.Date = 13;  // 设置日期为13日
    date.WeekDay = RTC_WEEKDAY_FRIDAY;  // 设置星期为星期五
    HAL_RTC_SetDate(&hrtc, &date, RTC_FORMAT_BIN);  // 设置RTC的日期为二进制格式
    
    RTC_TimeTypeDef time;  // 定义RTC时间结构体
    time.Hours = 16;  // 设置小时为16点
    time.Minutes = 10;  // 设置分钟为10分
    time.Seconds = 50;  // 设置秒为50秒
    HAL_RTC_SetTime(&hrtc, &time, RTC_FORMAT_BIN);  // 设置RTC的时间为二进制格式
    while (1)  // 主循环,程序将一直执行
    {
        HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BIN);  // 获取当前RTC日期
        HAL_RTC_GetTime(&hrtc, &time, RTC_FORMAT_BIN);  // 获取当前RTC时间
        printf("TIME:20%02d-%02d-%02d %02d:%02d:%02d \r\n",
         date.Year, date.Month, date.Date, time.Hours, time.Minutes, time.Seconds);  // 格式化输出当前时间,发送到串口
       HAL_Delay(1000);  // 延时1000毫秒(1秒),用于控制时间输出的刷新间隔
    }
}

ADC (Analog-to-Digital Converter)

  • 模式转换器,负责将模拟信号转换成数字信号。
  • 允许微控制器读取来自传感器或其它模拟输入的电压变化,并将其转换为可以处理的数字值。
  • 使用方法
    1. 查找电路图选择要进行模数转换的接口,我的是ADC的通道8
    2. 设置ADC1的通道8的continuous为Enabled。
    3. 开启USART1串口为异步通信,用于调试。
    4. 设置RCC为Crystal
    5. 配置时钟,设置ADC1为8MHZ。
    6. 获取对应的值,并进行*3300/4095(其中3300是参考电压,4095是最大值ADC值)
    在这里插入图片描述
    7. 通过这种方式,你可以准确地将ADC读取的数字值转换为对应的电压值,从而实现对模拟信号的有效监测。
    8. 代码示例
#include "main.h"  // 包含主头文件

ADC_HandleTypeDef hadc1;  // 声明ADC句柄
UART_HandleTypeDef huart1;  // 声明UART句柄

void SystemClock_Config(void);  // 系统时钟配置函数声明
static void MX_GPIO_Init(void);  // GPIO初始化函数声明
static void MX_ADC1_Init(void);  // ADC1初始化函数声明
static void MX_USART1_UART_Init(void);  // UART1初始化函数声明

int __io_putchar(int ch)  // 重定向printf函数,将其通过串口发送
{
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);  // 使用UART1发送字符
    return ch;  // 返回发送的字符
}

int main(void)  // 主函数
{
  HAL_Init();  // 初始化HAL库
  SystemClock_Config();  // 配置系统时钟
  MX_GPIO_Init();  // 初始化GPIO
  MX_ADC1_Init();  // 初始化ADC1
  MX_USART1_UART_Init();  // 初始化UART1
  HAL_ADC_Start(&hadc1);  // 启动ADC1

  while (1)  // 无限循环
  {
	  uint32_t regVal = HAL_ADC_GetValue(&hadc1);  // 获取ADC转换后的值
	  uint32_t mv = regVal * 3300 / 4095;  // 将ADC值转换为电压值,单位为毫伏
	  printf("voltage = %d mv\r\n", mv);  // 通过UART输出电压值
	  HAL_Delay(500);  // 延时500毫秒
  }
}

void SystemClock_Config(void)  // 系统时钟配置
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};  // 配置结构体初始化
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};  // 配置结构体初始化
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};  // 外设时钟配置结构体初始化

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;  // 选择外部高速振荡器HSE
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;  // 启动HSE振荡器
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;  // HSE预分频值设置为1
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;  // 启动内部高速振荡器HSI
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;  // 启动PLL
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;  // PLL时钟源选择HSE
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL8;  // PLL倍频因子设置为8
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)  // 配置振荡器
  {
    Error_Handler();  // 如果配置失败,进入错误处理
  }
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;  // 配置HCLK, SYSCLK, PCLK1和PCLK2时钟
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;  // 系统时钟源选择PLL
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;  // AHB时钟分频设置为1
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;  // APB1时钟分频设置为2
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;  // APB2时钟分频设置为1

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)  // 配置时钟
  {
    Error_Handler();  // 如果配置失败,进入错误处理
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;  // 外设时钟选择为ADC
  PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV8;  // ADC时钟分频设置为8
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)  // 配置外设时钟
  {
    Error_Handler();  // 如果配置失败,进入错误处理
  }
}

static void MX_ADC1_Init(void)  // ADC1初始化
{
  ADC_ChannelConfTypeDef sConfig = {0};  // ADC通道配置结构体初始化

  hadc1.Instance = ADC1;  // 设置ADC实例
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;  // 禁用扫描模式
  hadc1.Init.ContinuousConvMode = ENABLE;  // 启用连续转换模式
  hadc1.Init.DiscontinuousConvMode = DISABLE;  // 禁用不连续转换模式
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;  // 软件触发ADC转换
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;  // 数据右对齐
  hadc1.Init.NbrOfConversion = 1;  // 设置转换通道数为1
  if (HAL_ADC_Init(&hadc1) != HAL_OK)  // 初始化ADC1
  {
    Error_Handler();  // 如果初始化失败,进入错误处理
  }

  sConfig.Channel = ADC_CHANNEL_8;  // 选择ADC通道8
  sConfig.Rank = ADC_REGULAR_RANK_1;  // 设置通道为第1转换顺序
  sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;  // 设置采样时间为1.5个周期
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)  // 配置ADC通道
  {
    Error_Handler();  // 如果配置失败,进入错误处理
  }
}

static void MX_USART1_UART_Init(void)  // UART1初始化
{
  huart1.Instance = USART1;  // 设置UART实例
  huart1.Init.BaudRate = 115200;  // 配置波特率为115200
  huart1.Init.WordLength = UART_WORDLENGTH_8B;  // 设置数据位长度为8位
  huart1.Init.StopBits = UART_STOPBITS_1;  // 设置停止位为1位
  huart1.Init.Parity = UART_PARITY_NONE;  // 禁用校验位
  huart1.Init.Mode = UART_MODE_TX_RX;  // 设置为收发模式
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;  // 禁用硬件流控制
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;  // 设置16倍过采样
  if (HAL_UART_Init(&huart1) != HAL_OK)  // 初始化UART1
  {
    Error_Handler();  // 如果初始化失败,进入错误处理
  }
}

static void MX_GPIO_Init(void)  // GPIO初始化
{
  __HAL_RCC_GPIOD_CLK_ENABLE();  // 启用GPIOD时钟
  __HAL_RCC_GPIOB_CLK_ENABLE();  // 启用GPIOB时钟
  __HAL_RCC_GPIOA_CLK_ENABLE();  // 启用GPIOA时钟
}

void Error_Handler(void)  // 错误处理函数
{
  __disable_irq();  // 禁用中断
  while (1)  // 进入死循环
  {
  }
}

#ifdef  USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)  // 断言失败处理函数
{
}
#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值