打印
[其他ST产品]

通行闸机2(HAL库)

[复制链接]
楼主: 原来是wjc
手机看帖
扫描二维码
随时随地手机跟帖
21
原来是wjc|  楼主 | 2023-6-29 20:34 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
HCSR04.h

#ifndef __HCSR04_H
#define __HCSR04_H
#include "main.h"
#include "tim.h"
#include "stdio.h"



//高电平
#define TRIG1_H  HAL_GPIO_WritePin(HCSR04_TRIG1_GPIO_Port,HCSR04_TRIG1_Pin,GPIO_PIN_SET)
//低电平
#define TRIG1_L  HAL_GPIO_WritePin(HCSR04_TRIG1_GPIO_Port,HCSR04_TRIG1_Pin,GPIO_PIN_RESET)
//高电平
#define TRIG2_H  HAL_GPIO_WritePin(HCSR04_TRIG2_GPIO_Port,HCSR04_TRIG2_Pin,GPIO_PIN_SET)
//低电平
#define TRIG2_L  HAL_GPIO_WritePin(HCSR04_TRIG2_GPIO_Port,HCSR04_TRIG2_Pin,GPIO_PIN_RESET)

void delay_us(uint32_t us);
void SR04_GetData1(void);
void SR04_GetData2(void);

#endif

使用特权

评论回复
22
原来是wjc|  楼主 | 2023-6-29 20:34 | 只看该作者
es08a舵机旋转 模拟开门关门代码
控制舵机的代码,我写在了main.c里面,main.c的代码,在最下面会给代码

使用特权

评论回复
23
原来是wjc|  楼主 | 2023-6-29 20:34 | 只看该作者
红外遥控 代码
由于代码过于多,这里就直接给到大家,将下面的代码添加到HW_remote.c

(对于定时器输入捕获中断回调函数,我写到了main.c函数里面,最下面会给代码)

使用特权

评论回复
24
原来是wjc|  楼主 | 2023-6-29 20:34 | 只看该作者
HW_remote.c

#include "stm32f1xx_hal.h"
#include "HW_remote.h"
#include "main.h"
#include "tim.h"
//遥控器识别码为0
#define REMOTE_ID 0

//遥控器接收状态
//[7]:收到了引导码标志
//[6]:得到了一个按键的所有信息
//[5]:保留       
//[4]:标记上升沿是否已经被捕获                                                                  
//[3:0]:溢出计时器
uint8_t  RmtSta=0;                    
uint16_t Dval;                //下降沿时计数器的值
uint32_t RmtRec=0;        //红外接收到的数据                               
uint8_t  RmtCnt=0;        //按键按下的次数         
uint8_t  key;

//定时器更新(溢出)中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
//   printf("over\r\n");
if(htim->Instance==TIM1){
                if(RmtSta&0x80)//上次有数据被接收到了
                {       
                        RmtSta&=~0X10;                                                //取消上升沿已经被捕获标记
                        if((RmtSta&0X0F)==0X00)RmtSta|=1<<6;//标记已经完成一次按键的键值信息采集
                        if((RmtSta&0X0F)<14)RmtSta++;
                        else
                        {
                                RmtSta&=~(1<<7);//清空引导标识
                                RmtSta&=0XF0;        //清空计数器       
                        }                                                                   
                }       
}
}


//处理红外键盘
//返回值:
//         0,没有任何按键按下
//其他,按下的按键键值.
uint8_t Remote_Scan(void)
{        
        uint8_t sta=0;      
    uint8_t t1,t2;  
        if(RmtSta&(1<<6))//得到一个按键的所有信息了
        {
            t1=RmtRec>>24;                        //得到地址码
            t2=(RmtRec>>16)&0xff;        //得到地址反码
            if((t1==(uint8_t)~t2)&&t1==REMOTE_ID)//检验遥控识别码(ID)及地址
            {
                t1=RmtRec>>8;
                t2=RmtRec;        
                if(t1==(uint8_t)~t2)sta=t1;//键值正确         
                }   
                if((sta==0)||((RmtSta&0X80)==0))//按键数据错误/遥控已经没有按下了
                {
                         RmtSta&=~(1<<6);//清除接收到有效按键标识
                        RmtCnt=0;                //清除按键次数计数器
                }
        }  
    return sta;
}

使用特权

评论回复
25
原来是wjc|  楼主 | 2023-6-29 20:35 | 只看该作者
由于代码过于多,这里就直接给到大家,将下面的代码添加到HW_remote.h

使用特权

评论回复
26
原来是wjc|  楼主 | 2023-6-29 20:35 | 只看该作者
HW_remote.h
#ifndef __HW_REMOTE_H
#define __HW_REMOTE_H
#include "stm32f1xx_hal.h"



uint8_t Remote_Scan(void);     //定义功能函数

#endif

使用特权

评论回复
27
原来是wjc|  楼主 | 2023-6-29 20:35 | 只看该作者
串口一,在usart.c文件中添加下面函数
(注意:一定要在USER CODE BEGIN-----USER CODE END 之间添加自己的代码,或者是预编译文件,只有写在该注释之间的代码,在使用STM32CubeMX生成代码时,才不会被清空。)


使用特权

评论回复
28
原来是wjc|  楼主 | 2023-6-29 20:36 | 只看该作者
/*********************************************************
*
*重定义 fputc 函数,就可以使用printf函数打印输出了
*
*********************************************************/
int fputc(int ch,FILE *f)
{
        HAL_UART_Transmit (&huart1 ,(uint8_t *)&ch,1,HAL_MAX_DELAY );
        return ch;
}

使用特权

评论回复
29
原来是wjc|  楼主 | 2023-6-29 20:36 | 只看该作者
最后,在给大家main.c的代码
(注意:一定要在USER CODE BEGIN-----USER CODE END 之间添加自己的代码,或者是预编译文件,只有写在该注释之间的代码,在使用STM32CubeMX生成代码时,才不会被清空。)

使用特权

评论回复
30
原来是wjc|  楼主 | 2023-6-29 20:36 | 只看该作者
main.c
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * [url=home.php?mod=space&uid=288409]@file[/url]           : main.c
  * [url=home.php?mod=space&uid=247401]@brief[/url]          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "OLED.h"
#include "hw.h"
#include "HCSR04.h"
#include "HW_remote.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
extern float distant1;//超声波1测量距离
extern float distant2;//超声波2测量距离
extern uint8_t measure_Cnt1;//超声波1状态标志位
extern uint32_t measure_Buf1[];//存放定时器计数值的数组
extern uint8_t measure_Cnt2;//超声波2状态标志位
extern uint32_t measure_Buf2[];//存放定时器计数值的数组
extern uint16_t Dval;                //下降沿时计数器的值
extern uint8_t RmtSta;       
extern uint32_t RmtRec;        //红外接收到的数据                               
extern uint8_t  RmtCnt;        //按键按下的次数



uint8_t  key_num;
//定时器输入捕获中断回调函数
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//捕获中断发生时执行
{
       
        if(TIM2 == htim->Instance)// 判断触发的中断的定时器为TIM2
        {
                switch(measure_Cnt1){
                        case 1:
                                measure_Buf1[0] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);//获取当前的捕获值.
                                __HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);  //设置为下降沿捕获
                                measure_Cnt1++;                                            
                                break;              
                        case 2:
                                measure_Buf1[1] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);//获取当前的捕获值.
                                HAL_TIM_IC_Stop_IT(&htim2,TIM_CHANNEL_1); //停止捕获   或者: __HAL_TIM_DISABLE(&htim5);
                                measure_Cnt1++;  
                        
                }
       
        }
        if(TIM3 == htim->Instance)// 判断触发的中断的定时器为TIM3
        {
                switch(measure_Cnt2){
                        case 1:
                                measure_Buf2[0] = HAL_TIM_ReadCapturedValue(&htim3,TIM_CHANNEL_1);//获取当前的捕获值.
                                __HAL_TIM_SET_CAPTUREPOLARITY(&htim3,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);  //设置为下降沿捕获
                                measure_Cnt2++;                                            
                                break;              
                        case 2:
                                measure_Buf2[1] = HAL_TIM_ReadCapturedValue(&htim3,TIM_CHANNEL_1);//获取当前的捕获值.
                                HAL_TIM_IC_Stop_IT(&htim3,TIM_CHANNEL_1); //停止捕获   或者: __HAL_TIM_DISABLE(&htim5);
                                measure_Cnt2++;  
                        
                }
       
        }
       
        //红外遥控
if(TIM1 == htim->Instance)
{
//         printf("ic\r\n");
        if(HAL_GPIO_ReadPin(IRpa8_GPIO_Port,IRpa8_Pin))//上升沿捕获
        {
                TIM_RESET_CAPTUREPOLARITY(&htim1,TIM_CHANNEL_1);   //一定要先清除原来的设置!!
        TIM_SET_CAPTUREPOLARITY(&htim1,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);//CC1P=1 设置为下降沿捕获
        __HAL_TIM_SET_COUNTER(&htim1,0);  //清空定时器值             
                          RmtSta|=0X10;                                        //标记上升沿已经被捕获
        }else //下降沿捕获
        {
        Dval=HAL_TIM_ReadCapturedValue(&htim1,TIM_CHANNEL_1);//读取CCR1也可以清CC1IF标志位
        TIM_RESET_CAPTUREPOLARITY(&htim1,TIM_CHANNEL_1);   //一定要先清除原来的设置!!
        TIM_SET_CAPTUREPOLARITY(&htim1,TIM_CHANNEL_1,TIM_ICPOLARITY_RISING);//配置TIM5通道1上升沿捕获
                if(RmtSta&0X10)                                        //完成一次高电平捕获
                {
                        if(RmtSta&0X80)//接收到了引导码
                        {
                                               
                                if(Dval>300&&Dval<800)                        //560为标准值,560us
                                {
                                        RmtRec<<=1;        //左移一位.
                                        RmtRec|=0;        //接收到0          
                                }else if(Dval>1400&&Dval<1800)        //1680为标准值,1680us
                                {
                                        RmtRec<<=1;        //左移一位.
                                        RmtRec|=1;        //接收到1
                                }else if(Dval>2200&&Dval<2600)        //得到按键键值增加的信息 2500为标准值2.5ms
                                {
                                        RmtCnt++;                 //按键次数增加1次
                                        RmtSta&=0XF0;        //清空计时器               
                                }
                        }else if(Dval>4200&&Dval<4700)                //4500为标准值4.5ms
                                {
                                        RmtSta|=1<<7;        //标记成功接收到了引导码
                                        RmtCnt=0;                //清除按键次数计数器
                                }                                                 
                        }
                RmtSta&=~(1<<4);
                }                                                                  
        }
       
       
}


//PWM控制舵机
// angle:角度值,500-1000-1500-2000-2500
//角度
uint16_t angle;
void Servo_Control(angle)
{
        //设置默认的占空比值
//   __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1, (uint16_t )angle / 180 * 2000 + 500);
        __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1, angle);
}
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
  //超声波设置距离
  float jl;
  /* 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_TIM2_Init();
  MX_USART1_UART_Init();
  MX_TIM3_Init();
  MX_TIM1_Init();
  MX_TIM4_Init();
  /* USER CODE BEGIN 2 */
        HAL_TIM_Base_Start_IT(&htim1);
  HAL_TIM_IC_Start_IT(&htim1,TIM_CHANNEL_1);
        HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_1);

        __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1, 500);
  printf("test\r\n");
       
       
  OLED_Init();
       
       
        OLED_ShowCHinese(0, 0, 3);                                                        //人
        OLED_ShowCHinese(0, 16, 4);                                                 //数
  OLED_ShowCHinese(0, 32, 8);                                                        //:

  OLED_ShowCHinese(2, 0, 0);                                                        //超
        OLED_ShowCHinese(2, 16, 1);                                                 //声
        OLED_ShowCHinese(2, 32, 2);                                                 //波
        OLED_ShowCHinese(2, 48, 9);                                                 //1
        OLED_ShowCHinese(2, 64, 8);                                                        //:
        OLED_ShowCHinese(4, 0, 0);                                                        //超
        OLED_ShowCHinese(4, 16, 1);                                                 //声
        OLED_ShowCHinese(4, 32, 2);                                                 //波
        OLED_ShowCHinese(4, 48, 10);                                                 //2
        OLED_ShowCHinese(4, 64, 8);                                                        //:
       
        OLED_ShowCHinese(6, 0, 15);                                                 //键
        OLED_ShowCHinese(6, 16, 16);                                                 //值
        OLED_ShowCHinese(6, 32, 8);                                                        //:
        OLED_ShowCHinese(6, 90, 13);                                                 //关
        OLED_ShowCHinese(6, 106, 14);                                                 //闭
       
//        Servo_Control(0);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
                //显示人数
                hw_git();//获取电平
                OLED_ShowNum(1,7,number,3);//显示无符号数
                //超声波1检测距离
                SR04_GetData1();
                OLED_ShowNum(2,10,distant1,2);
                OLED_ShowChar(2,12,'.');
                OLED_ShowNum(2,13,(uint16_t)(distant1*100)%100,2);
                if(distant1<=15)
                {
                        angle= 2200;
                        Servo_Control(angle);
                        OLED_ShowCHinese(6, 90, 11);                                                 //打
                        OLED_ShowCHinese(6, 106, 12);                                                 //开
                        angle=500;
                }
                //超声波2检测距离
                SR04_GetData2();
                OLED_ShowNum(3,10,distant2,2);
                OLED_ShowChar(3,12,'.');
                OLED_ShowNum(3,13,(uint16_t)(distant2*100)%100,2);
                if(distant2<=10)
                {
                        angle= 500;
                        Servo_Control(angle);
                        OLED_ShowCHinese(6, 90, 13);                                                 //关
                        OLED_ShowCHinese(6, 106, 14);                                                 //闭
                }
                //提示
                key_num=Remote_Scan();
                if(key_num)
                {
                        printf("键值:%d\r\n",key_num);
                        OLED_ShowNum(4,6,key_num,3);
                        switch (key_num)
                        {
                                case 104:
                                        angle= 2200;
                                        OLED_ShowCHinese(6, 90, 11);                                                 //打
                                        OLED_ShowCHinese(6, 106, 12);                                                 //开
                                  break;
                                case 176:
                                        angle= 500;
                                        OLED_ShowCHinese(6, 90, 13);                                                 //关
                                        OLED_ShowCHinese(6, 106, 14);                                                 //闭
                                  break;
                                default:
          break;
                        }
                        key_num=0;
                        Servo_Control(angle);
                }
               
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
       
       
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  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;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */


使用特权

评论回复
31
原来是wjc|  楼主 | 2023-6-29 20:36 | 只看该作者
完整效果

使用特权

评论回复
32
Undshing| | 2023-7-1 23:17 | 只看该作者
遥控是怎么实现的啊?

使用特权

评论回复
33
万图| | 2023-12-30 07:12 | 只看该作者

把这干扰信号再次辐射出去

使用特权

评论回复
34
Uriah| | 2023-12-30 08:15 | 只看该作者

对变换器效率测量

使用特权

评论回复
35
帛灿灿| | 2023-12-30 10:11 | 只看该作者

印制电路板(PCB)的线路设计

使用特权

评论回复
36
Bblythe| | 2023-12-30 11:14 | 只看该作者

含有延展到远高于基本开关频率的谐波

使用特权

评论回复
37
Bblythe| | 2023-12-30 11:14 | 只看该作者

含有延展到远高于基本开关频率的谐波

使用特权

评论回复
38
周半梅| | 2023-12-30 13:10 | 只看该作者

需要设定一个阈值来对像素点进行设置

使用特权

评论回复
39
Pulitzer| | 2023-12-30 14:13 | 只看该作者

输入电容主要是起到高频能量存储器的作用

使用特权

评论回复
40
童雨竹| | 2023-12-30 16:09 | 只看该作者

二值化就是让图像的像素点矩阵中的每个像素点的灰度值为0(黑色)或者255(白色

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则