当前位置: 首页 > news >正文

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);  // 函数声明,初始化USART1int __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();  // 初始化GPIOMX_RTC_Init();  // 初始化RTCMX_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();  // 初始化GPIOMX_ADC1_Init();  // 初始化ADC1MX_USART1_UART_Init();  // 初始化UART1HAL_ADC_Start(&hadc1);  // 启动ADC1while (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;  // 选择外部高速振荡器HSERCC_OscInitStruct.HSEState = RCC_HSE_ON;  // 启动HSE振荡器RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;  // HSE预分频值设置为1RCC_OscInitStruct.HSIState = RCC_HSI_ON;  // 启动内部高速振荡器HSIRCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;  // 启动PLLRCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;  // PLL时钟源选择HSERCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL8;  // PLL倍频因子设置为8if (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;  // 系统时钟源选择PLLRCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;  // AHB时钟分频设置为1RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;  // APB1时钟分频设置为2RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;  // APB2时钟分频设置为1if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)  // 配置时钟{Error_Handler();  // 如果配置失败,进入错误处理}PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;  // 外设时钟选择为ADCPeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV8;  // ADC时钟分频设置为8if (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;  // 设置转换通道数为1if (HAL_ADC_Init(&hadc1) != HAL_OK)  // 初始化ADC1{Error_Handler();  // 如果初始化失败,进入错误处理}sConfig.Channel = ADC_CHANNEL_8;  // 选择ADC通道8sConfig.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;  // 配置波特率为115200huart1.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

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 深入理解Python函数参数传递:可变与不可变对象的实战解析20240914
  • Web安全与网络安全:SQL漏洞注入
  • setup函数子传父普通写法
  • centos8构建nginx1.27.1+BoringSSL+http3+lua+openresty
  • STM32——看门狗通俗解析
  • Django日志
  • WebRTC服务器搭建
  • SpringBoot + Vue + ElementUI 实现 el-table 分页功能详解
  • 【信号】SIGCHLD信号--了解
  • error: subprocess-exited-with-error
  • 【数据库】MySQL聚合统计
  • 【vuetify】v-select 无法正常显示,踩坑记录!
  • Vue3生命周期钩子函数(Vue3生命周期)
  • vue3 一次二次封装element-plus组件引发的思考
  • 解决ubuntu 24.04 ibus出现卡死、高延迟问题
  • 《剑指offer》分解让复杂问题更简单
  • Angular数据绑定机制
  • Apache Pulsar 2.1 重磅发布
  • Codepen 每日精选(2018-3-25)
  • iOS | NSProxy
  • js操作时间(持续更新)
  • JS数组方法汇总
  • leetcode378. Kth Smallest Element in a Sorted Matrix
  • quasar-framework cnodejs社区
  • Rancher-k8s加速安装文档
  • React-flux杂记
  • React的组件模式
  • Vue--数据传输
  • Vue小说阅读器(仿追书神器)
  • 关于 Cirru Editor 存储格式
  • 前端之React实战:创建跨平台的项目架构
  • 使用Gradle第一次构建Java程序
  • Semaphore
  • 回归生活:清理微信公众号
  • 说说我为什么看好Spring Cloud Alibaba
  • ​sqlite3 --- SQLite 数据库 DB-API 2.0 接口模块​
  • !$boo在php中什么意思,php前戏
  • # Python csv、xlsx、json、二进制(MP3) 文件读写基本使用
  • #Datawhale X 李宏毅苹果书 AI夏令营#3.13.2局部极小值与鞍点批量和动量
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • (day 2)JavaScript学习笔记(基础之变量、常量和注释)
  • (libusb) usb口自动刷新
  • (超详细)语音信号处理之特征提取
  • (附源码)c#+winform实现远程开机(广域网可用)
  • (七)Flink Watermark
  • (七)Java对象在Hibernate持久化层的状态
  • (深入.Net平台的软件系统分层开发).第一章.上机练习.20170424
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (一)十分简易快速 自己训练样本 opencv级联haar分类器 车牌识别
  • (幽默漫画)有个程序员老公,是怎样的体验?
  • (转)Windows2003安全设置/维护
  • .[backups@airmail.cc].faust勒索病毒的最新威胁:如何恢复您的数据?
  • .[hudsonL@cock.li].mkp勒索加密数据库完美恢复---惜分飞
  • .net dataexcel winform控件 更新 日志
  • .net mvc 获取url中controller和action