尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

秋招项目总结三

秋招项目总结三 1.ADC配置在ADC当中会加一个模拟看门狗MX_ADC_AnalogWatchdog_Config()模拟看门狗的主要作用就是检测ADC转换之后电压阈值是否超出系统设定然后模拟看门狗触发中断执行中断当中的操作。前ADC后模拟看门狗// 1. 首先初始化ADC基本参数 void MX_ADC1_Init(void) { hadc1.Instance ADC1; hadc1.Init.Resolution ADC_RESOLUTION_12B; hadc1.Init.ScanConvMode DISABLE; // ... 其他基本配置 HAL_ADC_Init(hadc1); // 先完成ADC基础初始化 // 2. 配置ADC通道 sConfig.Channel ADC_CHANNEL_1; sConfig.Rank 1; HAL_ADC_ConfigChannel(hadc1, sConfig); /* USER CODE BEGIN ADC1_Init 2 */ // 3. 在这里配置模拟看门狗ADC初始化完成后 MX_ADC_AnalogWatchdog_Config(); // 用户自定义函数 /* USER CODE END ADC1_Init 2 */ }关于ADC包含18个输入通道16个外部引脚的输入以及2个内部信号源其中2个内部信号源主要是内部温度传感器用于检测stm32自身的温度内部参考电压检测电源电压ADC内部执行触发控制控制ADC转换器的开始硬件触发以及软件触发硬件触发可以来源于定时器也可以选择外部中断得引脚。软件触发完全由CPU控制// 在代码中明确调用函数来启动转换 HAL_ADC_Start(hadc1); // 启动ADC HAL_ADC_PollForConversion(hadc1, 1000); // 等待转换完成 uint16_t value HAL_ADC_GetValue(hadc1);// 读取结果硬件触发取决于外部信号如定时器、GPIO等自动启动ADC转换无需CPU干预// 想象成安防监控摄像头 void surveillance_camera(void) { setup_camera_auto_mode(); // 初始设置一次 while(1) { // 不需要任何操作摄像头会自动 // - 定时拍照定时器触发 // - 检测到运动时拍照外部事件触发 process_other_tasks(); // CPU可以处理其他任务 } }ADC逐次比较的过程是由RCC去提供时钟CLOCK。AD转换器转换完成之后会将EOC进行置位为1之后可以进行读取ADC数据寄存器模拟看门狗也会检测ADC转换完成的数据一同送入到中断输出控制当中进行中断处理。开关控制进行ADC的使能关于ADC的转换模式主要分为四种1.单次转换非扫描模式2.连续转换非扫描模式3.单次转换扫描模式4.连续转换扫描模式其中关于非扫描模式是只有位置1是有效的而扫描模式是多个位置均有效单次转换是执行完一次不会跳转执行下一次关于数据对齐ADC是12位数据12位分辨率转换结果范围为0-4095但是内部的数据寄存器是16位的故需要涉及到数据对齐。按照读数的规则会一般选择数据右对齐这种方式。总结一下关于ADC所需要的配置1、选择合适的ADC资源2、配置ADC的时钟3、设置ADC的分辨率4、选择ADC的转换模式共4种5、选择ADC的触发方式6、设置数据对齐配置7、是否允许DMA请求8、EOC模数转换完成之后标志位是否置12.模拟看门狗在ADC当中的配置在ADC当中有模拟看门狗的配置MX_ADC_AnalogWatchdog_Config()// 设置模拟看门狗的“栅栏”范围 ADC_AnalogWDGConfTypeDef wdgConfig; wdgConfig.WatchdogNumber ADC_ANALOGWATCHDOG_1; wdgConfig.HighThreshold 3000; // 高阈值对应约2.44V (假设3.3V参考电压12位ADC) wdgConfig.LowThreshold 500; // 低阈值对应约0.41V wdgConfig.ITMode ENABLE; // 启用中断模式 HAL_ADC_AnalogWDGConfig(hadc1, wdgConfig);例如当检测一个外界传感器的数值当在阈值范围当中则属于是正常测量一旦回传的信息在阈值范围之外则会进行看门狗发出中断触发3.电池ADC检测在项目当中主要进行电池充电的检测然后进行ADC的转换进行8次采样求均值利用电池计算公式BatVoltage dat *2 *3.3 /4096uint8_t PowerCalculate() { uint8_t power; float voltage; voltage BatCheck_8times(); if(ChargeCheck()) {voltage - INTERNAL_RES * CHARGING_CUR;} if((voltage 4.2)) {power 100;} else if(voltage 4.06 voltage 4.2) {power 90;} else if(voltage 3.98 voltage 4.06) {power 80;} else if(voltage 3.92 voltage 3.98) {power 70;} else if(voltage 3.87 voltage 3.92) {power 60;} else if(voltage 3.82 voltage 3.87) {power 50;} else if(voltage 3.79 voltage 3.82) {power 40;} else if(voltage 3.77 voltage 3.79) {power 30;} else if(voltage 3.74 voltage 3.77) {power 20;} else if(voltage 3.68 voltage 3.74) {power 10;} else if(voltage 3.45 voltage 3.68) {power 5;} return power; }4.系统时钟的配置void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct {0}; /** Configure the main internal regulator output voltage电源配置 */ __HAL_RCC_PWR_CLK_ENABLE(); // 使能电源控制时钟 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);// 配置电源调节器为电压等级1最高性能模式 /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure.振荡器初始化 */ RCC_OscInitStruct.OscillatorType RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSE;// 配置要使用的振荡器类型HSI高速内部振荡器和LSE低速外部振荡器 RCC_OscInitStruct.LSEState RCC_LSE_ON; // 使能外部低速晶振通常32.768kHz用于RTC实时时钟 RCC_OscInitStruct.HSIState RCC_HSI_ON; // 使能内部高速振荡器通常16MHz作为系统时钟源 RCC_OscInitStruct.HSICalibrationValue RCC_HSICALIBRATION_DEFAULT;// HSI默认校准值 // 配置PLL锁相环用于倍频产生高频时钟 RCC_OscInitStruct.PLL.PLLState RCC_PLL_ON;// 使能PLL RCC_OscInitStruct.PLL.PLLSource RCC_PLLSOURCE_HSI;// PLL时钟源为HSI RCC_OscInitStruct.PLL.PLLM 8; // PLL输入分频16MHz / 8 2MHz RCC_OscInitStruct.PLL.PLLN 100; // PLL倍频2MHz * 100 200MHz RCC_OscInitStruct.PLL.PLLP RCC_PLLP_DIV2; // PLL输出分频系统时钟用200MHz / 2 100MHz RCC_OscInitStruct.PLL.PLLQ 4;// PLL另一路输出分频外设用200MHz / 4 50MHz if (HAL_RCC_OscConfig(RCC_OscInitStruct) ! HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks总线时钟配置 */ RCC_ClkInitStruct.ClockType RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;// 配置所有时钟类型HCLKAHB总线、SYSCLK系统时钟、PCLK1APB1总线、PCLK2APB2总线 RCC_ClkInitStruct.SYSCLKSource RCC_SYSCLKSOURCE_PLLCLK;// 系统时钟源为PLL输出100MHz RCC_ClkInitStruct.AHBCLKDivider RCC_SYSCLK_DIV1; // AHB总线时钟 系统时钟 / 1 100MHz RCC_ClkInitStruct.APB1CLKDivider RCC_HCLK_DIV2; // APB1总线时钟 AHB时钟 / 2 50MHzAPB1最大支持50MHz RCC_ClkInitStruct.APB2CLKDivider RCC_HCLK_DIV1; // APB2总线时钟 AHB时钟 / 1 100MHzAPB2支持更高频率 if (HAL_RCC_ClockConfig(RCC_ClkInitStruct, FLASH_LATENCY_3) ! HAL_OK) { Error_Handler(); } }关于系统时钟需要进行两个时钟配置阶段HAL_RCC_OscConfig()时钟源配置和HAL_RCC_ClockConfig()时钟分配和切换时钟源配置使能HSI、HSE、LSE等物理振荡器一般情况下是高性能的产品需要用到外部时钟源的配置与内部时钟源的配置配置PLL参数分频系数M、倍频系数N、输出分频P/Q等待时钟源稳定PLL锁定时间验证时钟源配置的正确性时钟分配和切换选择系统时钟源HSI/HSE/PLL配置AHB、APB1、APB2总线分频器实际执行系统时钟源的切换配置Flash访问延迟以适应更高频率5.关于消息队列Key_MessageQueue osMessageQueueNew(1, 1, NULL); //按键消息队列 Idle_MessageQueue osMessageQueueNew(1, 1, NULL); //空闲状态消息队列 Stop_MessageQueue osMessageQueueNew(1, 1, NULL); //休眠状态消息队列 IdleBreak_MessageQueue osMessageQueueNew(1, 1, NULL); //退出空闲状态消息队列 HomeUpdata_MessageQueue osMessageQueueNew(1, 1, NULL); //主页更新消息队列 DataSave_MessageQueue osMessageQueueNew(2, 1, NULL); //数据保存消息队列本项目的消息队列主要是传递状态标志位用于不同人物之间的传递本项目主要是定义了六个消息队列按键消息队列、空闲状态消息队列、休眠状态消息队列、退出空闲状态消息队列、主页更新消息队列、数据保存消息队列对于其他信息传递机制内存开销性能适用场景任务通知最小(0额外内存)最快一对一通知轻量级同步信号量较小快资源管理任务同步事件组较小快多事件等待复杂状态机消息队列中等中等数据传输带数据的通知
返回列表