基于光敏电阻的stm32光线检测计数器(stm32project_2)

本文探讨了如何通过STM32的编程实现光敏传感器的计数功能,初次尝试中遇到计数问题,经过优化引入了中间变量。最后提出使用EXTI外部中断以简化计数逻辑,降低代码复杂性。
摘要由CSDN通过智能技术生成

 需求分析

在上一篇博客中,实现了能识别周围光线强度变化(主要判别标准是光敏电阻前有无遮挡物)并利用传感器do口输出值,通过oled显示屏给出当前光线情况。

那么很自然的想法是,对于光敏传感器来说,如果能计下其do口电平变化次数,岂非可以读出光敏电阻被遮挡次数,进而实现“计数”功能?

为了实现该需求,我们做如下尝试

编写代码

第一次尝试

int main(){
lit_init();
	OLED_Init();
	int a=0;
	int b=0;
	while(1){
	if(get_lit()==0){
	OLED_ShowString(1,1,"enoughlit");
	OLED_ShowNum(2,1,a,6);
	}
	if(get_lit()==1){
	OLED_ShowString(1,1,"nolit");
a++;
		OLED_ShowNum(2,1,a,6);
		
	}}}

这里引入一个变量a对当get_lit返回数值为1时,a=a+1,即实现当光敏电阻被遮挡时,计数加一功能,那么实际运行代码,烧录进stm32中却发现,当光线充足时,计数值为0,当光敏电阻被遮挡时,计数值从000000一直增长000001,000002...,重新分析代码,在while循环中,执行if判别,当get_lit()=1时,执行一遍对应代码,后重新进入循环,执行if判别,故可知当光敏传感器被遮挡时,始终执行循环体内第二个if判别式中内容,故出现计数值一直增长情况

第二次尝试

int main(){
lit_init();
	OLED_Init();
	int a=0;
	int b=0;
	while(1){
	if(get_lit()==0){
	OLED_ShowString(1,1,"enoughlit");
	OLED_ShowNum(2,1,b,6);
	b=a+1;}
	if(get_lit()==1){
	OLED_ShowString(1,1,"nolit");
a++;
		OLED_ShowNum(2,1,a,6);
		a=b;
	}}}

第二次尝试中,吸取第一次的教训,为了不使得计数变量在被遮挡时一直增长,引入另一个中间变量b,b的功能是在每一次第二个if判别式执行末尾时,对a进行复位,这样即使遮挡,如果第一次循环中a=2,b=2,那么第二次循环,执行到a++语句时,a=3,再到后面a=b,使得a复位为b,那么b值应该为一次循环后a的值,很容易想到在另一个if判别中对b进行赋值,赋值为b=a+1,如此可实现相应功能

总结

在两次尝试中,第一次想到要使用变量进行计数,第二次对计数过程进行优化改进,使得计数更贴合使用实际。但总而言之,为了实现计数,我们引入了两个多余的变量,增加了程序额外的负担,并且嵌套在if判别式中的重复调用,在代码理解上也是人为增加了一些难度,下一篇博客尝试引入stm32的中断概念,利用EXTI外部中断,更为简洁地实现对端口电平变化的检测与计数

 

 

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32F103R系列微控制器可以使用其内部的定时器/计数器模块来实现计数器的功能。以下是使用STM32CubeMX和HAL库实现计数器的步骤: 1. 打开STM32CubeMX并创建一个新的工程。 2. 在“Pinout & Configuration”选项卡中配置所需的引脚。 3. 在“Clock Configuration”选项卡中配置所需的时钟源和时钟分频器。 4. 在“Project Manager”选项卡中选择生成代码的IDE并生成代码。 5. 在生成的代码中,打开“main.c”文件并添加以下代码: ```c #include "stm32f1xx_hal.h" TIM_HandleTypeDef htim2; // 定义定时器句柄 void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_TIM2_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_TIM2_Init(); HAL_TIM_Base_Start(&htim2); // 启动定时器 while(1) { uint16_t count = __HAL_TIM_GET_COUNTER(&htim2); // 获取计数器值 // 处理计数器值 } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = 16; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; 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; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { Error_Handler(); } } void MX_TIM2_Init(void) { TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; htim2.Instance = TIM2; htim2.Init.Prescaler = 1; htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 65535; htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; if (HAL_TIM_Base_Init(&htim2) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) { Error_Handler(); } } static void MX_GPIO_Init(void) { __HAL_RCC_GPIOC_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); } ``` 在此示例中,使用TIM2模块作为计数器,并在while循环中获取计数器的值。计数器的最大值为65535,当计数器达到该值时会自动清零并重新开始计数。 在上述代码中,需要注意以下几点: - 代码中使用了HAL库提供的函数来初始化和启动定时器。 - 需要通过__HAL_TIM_GET_COUNTER函数获取计数器的值。 - 需要根据实际情况配置引脚、时钟等参数。 希望这些信息能对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值