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

女孩子学做网站有前途吗哪个公司需要做网站

女孩子学做网站有前途吗,哪个公司需要做网站,网站建设好做吗,网站关键词 公司目录 时钟源 控制器 时基单元 关于HAL库如何配置基本定时器 HAL是如何初始化我们的定时器句柄的 HAL_TIM_Base_Init 开始定时 如何处理句柄#xff1f; 在我们使用STM32解决一些问题的时候#xff0c;常常会遇到说#xff1a;我想要以一个周期做一些事情#xff1a;…目录 时钟源 控制器 时基单元 关于HAL库如何配置基本定时器 HAL是如何初始化我们的定时器句柄的 HAL_TIM_Base_Init 开始定时 如何处理句柄 在我们使用STM32解决一些问题的时候常常会遇到说我想要以一个周期做一些事情比如说周期性的向我的上位机发送当前的温度和湿度比如说周期性的点亮一个LED刷新一次LCD屏幕。这都离不开我们定时器的身影。STM32有2个基本定时器4个通用定时器2个高级定时器。我们慢慢来阐述不同种类的定时器的作用。现在让我们从最基础的最简单的基本定时器开始 学过数电的朋友一眼就能知道这个图怎么回事了我们对来自RCC时钟的信号进行分频当到打分频计数的时候向计数器发起一次脉冲计数器接受到脉冲后会自增1直到到达我们设定的阈值的时候发起一次中断通知定时器超时。这就是定时器的最基本的工作原理 这样来看定时器的核心就是计算器就是打点计数到点发起通知重置他有三个要素组成 时钟源 要实现计数功能首先要给它一个时钟源。打点计时还是需要水滴下来的基本定时器时钟挂载在 APB1 总线所以它的时钟来自于 APB1 总线但是基本定时器时钟不是直接由 APB1 总线直接提供而是先经过一个倍频器。当APB1 的预分频器系数为 1 时这个倍频器系数为 1即定时器的时钟频率等于 APB1 总线时钟频率当 APB1 的预分频器系数≥2 分频时这个倍频器系数就为 2 即定时器的时钟频率等于 APB1 总线时钟频率的两倍。 控制器 控制器除了控制定时器复位、使能、计数等功能之外还可以用于触发DAC 转换。这个是我们的定时器可以被控制的根本。 时基单元 时基单元包括计数器寄存器(TIMx_CNT)、预分频器寄存器(TIMx_PSC)、自动重载寄存器(TIMx_ARR) 。基本定时器的这三个寄存器都是 16 位有效数字即可设置值范围是 0~65535。时基单元中的预分频器PSC它有一个输入和一个输出。输入CK_PSC 来源于控制器部分实际上就是来自于内部时钟CK_INT即2 倍的APB1 总线时钟频率72MHz。输出 CK_CNT是分频后的时钟它是计数器实际的计数时钟通过设置预分频器寄存器(TIMx_PSC)的值可以得到不同频率 CK_CNT计算公式如下 fCK_CNT fCK_PSC / (PSC[15:0]1) 上式中PSC[15:0]是写入预分频器寄存器(TIMx_PSC)的值。 另外预分频器寄存器(TIMx_PSC)可以在运行过程中修改它的数值新的预分频数值将在下一个更新事件时起作用。因为更新事件发生时会把 TIMx_PSC 寄存器值更新到其影子寄存器中这才会起作用。 那什么是影子寄存器从框图上看可以看到图20.1.1.1中的预分频器PSC 后面有一个影子自动重载寄存器也有个影子这就表示这些寄存器有影子寄存器。影子寄存器是一个实际起作用的寄存器不可直接访问。举个例子我们可以把预分频系数写入预分频器寄存器(TIMx_PSC)但是预分频器寄存器只是起到缓存数据的作用只有等到更新事件发生时预分频器寄存器的值才会被自动写入其影子寄存器中这时才真正起作用。 也就是说我们不能直接暴力的打断当前的计数采用缓存的办法下一次更新这确保系统至少是稳定的工作的 自动重载寄存器及其影子寄存器的作用和上述同理。不同点在于自动重载寄存器是否具有缓冲作用还受到 ARPE 位的控制当该位置0 时ARR 寄存器不进行缓冲我们写入新的 ARR值时该值会马上被写入 ARR 影子寄存器中从而直接生效当该位置 1 时ARR 寄存器进行缓冲我们写入新的 ARR 值时该值不会马上被写入 ARR 影子寄存器中而是要等到更新事件发生才会被写入 ARR 影子寄存器这时才生效。预分频器寄存器则没有这样相关的控制位这就是它们不同点。 值得注意的是更新事件的产生有两种情况一是由软件产生将 TIMx_EGR 寄存器的位UG 置 1产生更新事件后硬件会自动将 UG 位清零。二是由硬件产生满足以下条件即可计数器的值等于自动重装载寄存器影子寄存器的值。 基本定时器的计数器CNT是一个递增的计数器当寄存器TIMx_CR1的CEN 位置1即使能定时器每来一个 CK_CNT 脉冲TIMx_CNT 的值就会递增加 1。当TIMx_CNT 值与 TIMx_ARR 的设定值相等时TIMx_CNT 的值就会被自动清零并且会生成更新事件如果开启相应的功能就会产生 DMA 请求、产生中断信号或者触发 DAC 同步电路然后下一个CK_CNT 脉冲到来TIMx_CNT 的值就会递增加 1如此循环。在此过程中TIMx_CNT 等于TIMx_ARR 时我们称之为定时器溢出因为是递增计数故而又称为定时器上溢。定时器溢出就伴随着更新事件的发生。 由上述可知我们只要设置预分频寄存器和自动重载寄存器的值就可以控制定时器更新事件发生的时间。自动重载寄存器(TIMx_ARR)是用于存放一个与计数器作比较的值当计数器的值等于自动重载寄存器的值时就会生成更新事件硬件自动置位相关更新事件的标志位如更新中断标志位。 下面举个例子来学习如何设置预分频寄存器和自动重载寄存器的值来得到我们想要的定时器上溢事件发生的时间周期。比如我们需要一个500ms 周期的定时器更新中断一般思路是先设置预分频寄存器然后才是自动重载寄存器。 考虑到我们设置的 CK_INT 为72MHz我们把预分频系数设置为 7200即写入预分频寄存器的值为 7199那么 fCK_CNT72MHz/720010KHz。这样就得到计数器的计数频率为10KHz即计数器 1 秒钟可以计 10000 个数。我们需要 500ms 的中断周期所以我们让计数器计数 5000 个数就能满足要求即需要设置自动重载寄存器的值为4999另外还要把定时器更新中断使能位 UIE 置 1CEN 位也要置 1。 关于HAL库如何配置基本定时器 下面给看官演示如何使用使用最基本的定时器完成定时触发任务 首先笔者现在用的STM32F103ZET6有两个基本的定时器TIM6和TIM7。笔者使用的是TIM6。现在勾选Activate使能我们的定时器后开始设置参数。 Prescaler是我们上面提到的预分频的意思这里笔者的RCC时钟是72MHz现在做分频笔者按照经典的方案分7200份也就是每一份实际上是10KHz CounterMode向上计数如果只是定时无所谓 Counter Period自动重装载值笔者打算1s触发一次事件那就是让1s计数1次即1HZ需要填入10000 - 1 9999Btw不太理解为什么非得要填一个很小的值然后在程序里自己维护一个计数我后来想了想可能是同步的其他周期的任务计时更加方便后补实际上就是更细粒度的维护 auto-reload preloadDisable的时候自动重装载寄存器写入新值后计数器立即产生计数溢出然后开始新的计数周期也就是说我们在Disable的时候马上修改我们在影子寄存器里的重载值而在Enable的时候则是完成当前周期之后再将值写入影子寄存器里多一个周期 下面我们就是使能一下我们的NVIC 完成其他配置之后我们就可以开始生成工程。值得注意的是初始化结束我们的寄存器之后记得开启定时器计时笑 /* USER CODE BEGIN 0 */ ​ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {if(htim htim6){HAL_GPIO_TogglePin(LED0_GPIO_Port, LED0_Pin);} } ​ /* USER CODE END 0 */ ​ /*** brief The application entry point.* retval int*/ int main(void) {/* USER CODE BEGIN 1 */ ​/* USER CODE END 1 */ ​/* MCU Configuration--------------------------------------------------------*/ ​/* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init(); ​/* USER CODE BEGIN Init */ ​/* USER CODE END Init */ ​/* Configure the system clock */SystemClock_Config(); ​/* USER CODE BEGIN SysInit *//* USER CODE END SysInit */ ​/* Initialize all configured peripherals */MX_GPIO_Init();MX_TIM6_Init();/* USER CODE BEGIN 2 */HAL_TIM_Base_Start_IT(htim6);/* USER CODE END 2 */ ​/* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE */ ​/* USER CODE BEGIN 3 */}/* USER CODE END 3 */ } 回调事件请在HAL_TIM_PeriodElapsedCallback内完成。下面我们依次介绍HAL库的函数配置。 HAL是如何初始化我们的定时器句柄的 HAL库这样抽象一个定时器 /*** brief 初始化 TIM6 定时器。* note   此函数初始化 TIM6 为基础计时器设置了预分频器和计数周期并配置了触发和同步模式。* retval None*/ static void MX_TIM6_Init(void) {/* USER CODE BEGIN TIM6_Init 0 */// 用户代码部分可以在此处添加初始化之前的代码/* USER CODE END TIM6_Init 0 */ ​TIM_MasterConfigTypeDef sMasterConfig {0}; // 定义主配置结构体用于配置 TIM6 的主从同步模式 ​/* USER CODE BEGIN TIM6_Init 1 */// 用户代码部分可以在此处添加初始化之后的代码/* USER CODE END TIM6_Init 1 */htim6.Instance TIM6; // 指定 TIM6 外设实例 ​// 配置定时器参数htim6.Init.Prescaler 7199; // 设置预分频器值为 7199。定时器计数频率为系统时钟频率 / (Prescaler 1)htim6.Init.CounterMode TIM_COUNTERMODE_UP; // 设置计数模式为向上计数模式htim6.Init.Period 9999; // 设置定时器周期为 9999。定时器将在计数到达此值时溢出htim6.Init.AutoReloadPreload TIM_AUTORELOAD_PRELOAD_DISABLE; // 禁用自动重载预加载功能 ​// 初始化定时器if (HAL_TIM_Base_Init(htim6) ! HAL_OK){Error_Handler(); // 如果定时器初始化失败调用错误处理函数} ​// 配置定时器主输出触发TRGO和主从同步模式sMasterConfig.MasterOutputTrigger TIM_TRGO_RESET; // 配置主输出触发为重置sMasterConfig.MasterSlaveMode TIM_MASTERSLAVEMODE_DISABLE; // 禁用主从同步模式if (HAL_TIMEx_MasterConfigSynchronization(htim6, sMasterConfig) ! HAL_OK){Error_Handler(); // 如果主从同步配置失败调用错误处理函数} ​/* USER CODE BEGIN TIM6_Init 2 */// 用户代码部分可以在此处添加初始化后的代码/* USER CODE END TIM6_Init 2 */ } 按照流程我们做了这一些事情 配置好我们在CubeMx中设置的一系列的参数值。 使用HAL_TIM_Base_Init(htim6) 函数用于初始化定时器的基本配置包括预分频器、计数模式、周期等参数。如果初始化失败程序将调用 Error_Handler() 进行错误处理。 主从同步配置 主输出触发Master Output Trigger, TRGOsMasterConfig.MasterOutputTrigger TIM_TRGO_RESET; 设置定时器的主输出触发事件为重置信号。重置信号通常用于同步其他外设或触发其他操作。 主从同步模式Master Slave ModesMasterConfig.MasterSlaveMode TIM_MASTERSLAVEMODE_DISABLE; 禁用主从同步模式这意味着 TIM6 不与其他定时器或外设同步工作。 HAL_TIM_Base_Init 这个是实际的IMPL函数HAL_TIM_Base_Init 函数用于初始化一个基本定时器的配置。它检查传入的定时器句柄和配置信息是否有效并根据用户的配置初始化相关硬件资源包括定时器计数器、时钟和中断。 /*** brief 初始化 TIM 基本定时器。* param htim 指向一个 TIM_HandleTypeDef 结构体该结构体包含了定时器的配置信息。* retval HAL 状态码HAL_OK 或 HAL_ERROR*/ HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim) {/* 检查 TIM 句柄是否有效 */if (htim NULL){return HAL_ERROR; // 如果 TIM 句柄无效返回错误} ​/* 检查定时器配置参数是否有效 */assert_param(IS_TIM_INSTANCE(htim-Instance)); // 确保传入的定时器实例有效assert_param(IS_TIM_COUNTER_MODE(htim-Init.CounterMode)); // 确保计数模式有效assert_param(IS_TIM_CLOCKDIVISION_DIV(htim-Init.ClockDivision)); // 确保时钟分频配置有效assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim-Init.AutoReloadPreload)); // 确保自动重载预加载配置有效 ​if (htim-State HAL_TIM_STATE_RESET){/* 如果定时器处于重置状态初始化定时器 */htim-Lock HAL_UNLOCKED; // 解锁定时器资源 ​ #if (USE_HAL_TIM_REGISTER_CALLBACKS 1)/* 如果启用回调函数注册功能重置中断回调为默认的弱回调 */TIM_ResetCallback(htim); ​if (htim-Base_MspInitCallback NULL){/* 如果没有用户提供的回调函数则使用默认的硬件初始化回调函数 */htim-Base_MspInitCallback HAL_TIM_Base_MspInit;}/* 初始化低级硬件配置GPIO、时钟、NVIC */htim-Base_MspInitCallback(htim); #else/* 如果没有启用回调函数注册直接调用默认的硬件初始化函数 */HAL_TIM_Base_MspInit(htim); #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */} ​/* 设置定时器状态为忙碌 */htim-State HAL_TIM_STATE_BUSY; ​/* 设置定时器时间基准配置 */TIM_Base_SetConfig(htim-Instance, htim-Init); ​/* 初始化 DMA burst 操作状态 */htim-DMABurstState HAL_DMA_BURST_STATE_READY; ​/* 初始化 TIM 通道的状态 */TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY); // 设置所有 TIM 通道为准备好状态TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY); // 设置所有通道的N状态为准备好 ​/* 设置定时器状态为就绪 */htim-State HAL_TIM_STATE_READY; ​return HAL_OK; // 返回初始化成功 } 函数的中间部分是参数验证 assert_param(IS_TIM_INSTANCE(htim-Instance))确保定时器实例如 TIM1, TIM2 等有效。 assert_param(IS_TIM_COUNTER_MODE(htim-Init.CounterMode))确保计数模式有效如向上计数、向下计数或其它模式。 assert_param(IS_TIM_CLOCKDIVISION_DIV(htim-Init.ClockDivision))检查时钟分频配置是否有效。 assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim-Init.AutoReloadPreload))检查自动重载预加载配置是否有效。 检查完毕如果定时器的状态为 HAL_TIM_STATE_RESET即未初始化或重置状态则执行硬件资源的分配和初始化。此时定时器的 Lock 锁定状态设置为解锁准备进一步的配置。 如果启用了回调函数注册功能通过宏 USE_HAL_TIM_REGISTER_CALLBACKS则重置回调函数为默认的弱回调。 如果没有提供用户自定义的回调函数则使用默认的初始化回调 HAL_TIM_Base_MspInit进行定时器的低级硬件初始化。硬件初始化通常包括时钟、GPIO 和 NVIC中断控制器的配置。 设置定时器配置 调用 TIM_Base_SetConfig(htim-Instance, htim-Init) 设置定时器的时间基准配置。这包括预分频器、计数模式、自动重载等设置。 DMA 状态初始化 设置定时器的 DMA burst 操作状态为 HAL_DMA_BURST_STATE_READY表示 DMA 操作准备就绪可以开始数据传输。 定时器通道状态设置 使用 TIM_CHANNEL_STATE_SET_ALL 和 TIM_CHANNEL_N_STATE_SET_ALL 宏将所有的定时器通道状态设置为 HAL_TIM_CHANNEL_STATE_READY表示通道准备好进行操作。 函数结尾 最后将定时器的状态设置为 HAL_TIM_STATE_READY表示定时器配置完成并准备好工作。函数返回 HAL_OK表示初始化成功。 开始定时 下面我们就要开始定时定时使用的函数就是HAL_TIM_Base_Start_IT HAL_TIM_Base_Start_IT 函数用于启动基本定时器的更新中断模式。当启用中断模式时定时器会定期触发更新事件并通过中断通知用户。此函数适用于需要周期性执行任务的应用比如定时器定时中断。这就是为什么我们要在上面开启他的中断 /*** brief 启动 TIM 基本定时器的中断模式。* param htim TIM 基本定时器句柄* retval HAL 状态码*/ HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim) {uint32_t tmpsmcr; ​/* 检查传入的 TIM 实例是否有效 */assert_param(IS_TIM_INSTANCE(htim-Instance)); ​/* 检查 TIM 的当前状态是否为就绪状态 */if (htim-State ! HAL_TIM_STATE_READY){return HAL_ERROR; // 如果定时器不是就绪状态返回错误} ​/* 设置定时器状态为忙碌 */htim-State HAL_TIM_STATE_BUSY; ​/* 启用 TIM 更新中断 */__HAL_TIM_ENABLE_IT(htim, TIM_IT_UPDATE); ​/* 启用定时器外设除非是触发模式trigger mode触发模式下定时器会自动启用 */if (IS_TIM_SLAVE_INSTANCE(htim-Instance)) // 检查是否为从模式定时器{tmpsmcr htim-Instance-SMCR TIM_SMCR_SMS; // 获取定时器从模式的状态if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) // 如果不是触发模式则启用定时器{__HAL_TIM_ENABLE(htim); // 启动定时器}}else{__HAL_TIM_ENABLE(htim); // 如果是主模式直接启用定时器} ​/* 返回操作状态 */return HAL_OK; // 返回成功 } 函数概述 参数检查 assert_param(IS_TIM_INSTANCE(htim-Instance))检查传入的定时器实例是否有效。通过宏 IS_TIM_INSTANCE确认 htim-Instance 属于有效的 TIM 实例例如 TIM1, TIM2 等。 定时器状态检查 if (htim-State ! HAL_TIM_STATE_READY)检查定时器的当前状态是否为就绪状态。如果定时器处于其他状态例如忙碌或未初始化状态则返回错误 HAL_ERROR表示不能启动定时器。 定时器状态更新 htim-State HAL_TIM_STATE_BUSY将定时器状态设置为 HAL_TIM_STATE_BUSY表示定时器正在被配置或启动防止其他操作与当前操作冲突。 启用 TIM 更新中断 __HAL_TIM_ENABLE_IT(htim, TIM_IT_UPDATE)启用定时器的更新中断。定时器会在计数溢出时产生更新事件触发相应的中断用户可以在中断处理函数中执行定时任务。 定时器启用 if (IS_TIM_SLAVE_INSTANCE(htim-Instance))检查定时器是否是从模式Slave mode。从模式的定时器通常需要与主定时器同步运行触发模式的定时器会自动启动无需手动启用。 tmpsmcr htim-Instance-SMCR TIM_SMCR_SMS获取定时器的从模式控制寄存器SMCR中的从模式选择字段SMS。 if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))如果定时器不是触发模式调用 __HAL_TIM_ENABLE(htim) 启动定时器。 如果是主模式定时器非从模式则直接启用定时器。 返回状态 如果一切顺利函数返回 HAL_OK表示定时器已成功启用并开始工作。 如何处理句柄 定时中断现在被打开了然后如何呢答案是我们要重载我们的CallBack函数 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) 这个函数需要我们自己先判定一下句柄然后接下来就是处理业务代码。
http://www.w-s-a.com/news/239413/

相关文章:

  • 网站关键词seo推广公司哪家好无锡市无锡市住房和城乡建设局网站
  • 开远市新农村数字建设网站网站如何做QQ登录
  • 自己做个网站教程高端网站开发哪家强
  • 网站模板免费下载中文版大连网站建设哪家专业
  • 网站建设的基本代理公司注册公司坑人
  • 企业网站被黑后如何处理wordpress邮件发送类
  • 北京网站的网站建设公司建设工程竣工验收消防备案网站
  • 淄博市 网站建设报价wordpress里的发消息给我
  • 网站下拉菜单怎么做游戏网站模板免费下载
  • 阿里云上做网站套模板怎么做一个网站开发小组
  • 营销型网站源码下载青岛做网站建设的公司哪家好
  • 迁西网站定制怎么制作网址内容
  • 深圳装饰公司网站宁波网站建设哪里有
  • 建站网站破解版怎么看自己的网站是用什么做的
  • 做微商那个网站好织梦模板更新网站
  • 网站注册表单怎么做手机做网站需要多少天
  • 书店商城网站html模板下载企业网站建设方案书范文
  • 建设网站是普通办公吗快速排名seo软件
  • 大型外贸网站建设网站建设图片尺寸要求
  • 网站建设可信赖北京网站开发月薪
  • 专门做lolh的网站wordpress 模版 cho's
  • 网上做设计兼职哪个网站好点网站开发毕业周记
  • 自学商城网站建设无为网页定制
  • wordpress全站cdn手机网站调用分享
  • 淄博做网站58同城wordpress微信号订阅
  • 不同的网站 做301公共资源交易中心是干嘛的
  • 36 氪 网站如何优化怎么优化自己的网站
  • 网站兼容问题湖北网站建设优化
  • 2018新网站做外链app制作的网站
  • 外贸网站建设怎么建设pc网站做移动端适配