공부방/ARM_STM32 노진호교수님_필기

240425_dirver_UltraSonic

맘스터치보단파파이스 2024. 4. 25. 11:28

/*
 * apMain.h
 *
 *  Created on: Apr 23, 2024
 *      Author: kccistc
 */

#ifndef AP_APMAIN_H_
#define AP_APMAIN_H_

#include "stm32f4xx_hal.h"
#include "../driver/button/button.h"
#include "../driver/led/led.h"
#include "../driver/LCD/LCD.h"
#include "../driver/UltraSonic/UltraSonic.h"

typedef enum{POWER_ON, STATE1, STATE2, STATE3} ledState_t;

void sys_init();
int apMain();

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);

#endif /* AP_APMAIN_H_ */
/*
 * apMain.c
 *
 *  Created on: Apr 23, 2024
 *      Author: kccistc
 */

#include "apMain.h"
#include <stdio.h>

ledState_t ledstate = POWER_ON;
button_t button1, button2, button3;
led_t led1, led2, led3;

ultraSonic_t ultraSonic1, ultraSonic2, ultraSonic3;

extern TIM_HandleTypeDef htim1;
extern TIM_HandleTypeDef htim2;
extern TIM_HandleTypeDef htim3;

#define FRONT_GPIO_TRIG			GPIOC
#define FRONT_GPIO_TRIG_PIN		GPIOC_PIN_0
#define FRONT_GPIO_ECHO			GPIOC
#define FRONT_GPIO_ECHO_PIN		GPIOC_PIN_1

#define MIDDLE_GPIO_TRIG		GPIOB
#define MIDDLE_GPIO_TROG_PIN	GPIOB_PIN_0
#define MIDDLE_GPIO_TROG		GPIOA
#define MIDDLE_GPIO_ECHO_PIN	GPIOA_PIN_4



void sys_init() {
	button_init(&button1, GPIOC, GPIO_PIN_10);
	button_init(&button2, GPIOC, GPIO_PIN_11);
	button_init(&button3, GPIOC, GPIO_PIN_12);

	led_init(&led1, GPIOC, GPIO_PIN_8);
	led_init(&led2, GPIOC, GPIO_PIN_6);
	led_init(&led3, GPIOC, GPIO_PIN_5);

	LCD_init();
	DelayInit();
}


int apMain()
{
	sys_init();

	char buff1[50];
	char buff2[50];
	char buff3[50];
	int distance1, distance2, distance3;
	LCD_writeStringXY(0, 0, "ULTRASONIC!!!");



	UltraSonic_init(&ultraSonic1,&htim1,GPIOC,GPIO_PIN_0,GPIOC,GPIO_PIN_1);
	UltraSonic_init(&ultraSonic2,&htim2,GPIOB,GPIO_PIN_0,GPIOA,GPIO_PIN_4);
	UltraSonic_init(&ultraSonic3,&htim3,GPIOC,GPIO_PIN_3,GPIOC,GPIO_PIN_2);

	while(1)
	{
		if(button_getState(&button1)==ACT_RELEASED){
		distance1 = UltraSonic_getDistance(&ultraSonic1);
		sprintf(buff1, "dist1: %dcm      ",distance1 );
		LCD_writeStringXY(1, 0, buff1);
		}
		else if(button_getState(&button2)==ACT_RELEASED){
		distance2 = UltraSonic_getDistance(&ultraSonic2);
		sprintf(buff2, "dist2: %dcm      ",distance2 );
		LCD_writeStringXY(1, 0, buff2);
		}
		else if(button_getState(&button3)==ACT_RELEASED){
		distance3 = UltraSonic_getDistance(&ultraSonic3);
		sprintf(buff3, "dist3: %dcm      ",distance3 );
		LCD_writeStringXY(1, 0, buff3);
		}

	}
	return 0;
}



void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	UltraSonic_ISR_Process(&ultraSonic1, GPIO_Pin);
	UltraSonic_ISR_Process(&ultraSonic2, GPIO_Pin);
	UltraSonic_ISR_Process(&ultraSonic3, GPIO_Pin);


}
#include "UltraSonic.h"
#include "../common/delayus/delayus.h"



void UltraSonic_init(ultraSonic_t *ultraSonic,
		TIM_HandleTypeDef *hTim,
		GPIO_TypeDef* GPIO_Trig,
		uint16_t GPIO_TrigPin,
		GPIO_TypeDef* GPIO_Echo,
		uint16_t GPIO_EchoPin)
{
	ultraSonic->hTim = hTim;
	ultraSonic->GPIO_Trig = GPIO_Trig;
	ultraSonic->GPIO_TrigPin = GPIO_TrigPin;
	ultraSonic->GPIO_Echo = GPIO_Echo;
	ultraSonic->GPIO_EchoPin = GPIO_EchoPin;
	ultraSonic->timCounter = 0;
	ultraSonic->echoFlag = 0;
}

int UltraSonic_getEchopinState(ultraSonic_t *ultraSonic)
{
	return (HAL_GPIO_ReadPin(ultraSonic->GPIO_Echo, ultraSonic->GPIO_EchoPin)); //rising edge(상승)
}

void UltraSonic_clearTimer(ultraSonic_t *ultraSonic)
{
	__HAL_TIM_SET_COUNTER(ultraSonic->hTim,0); //처음에 0으로 세팅
}
void UltraSonic_startTimer(ultraSonic_t *ultraSonic)
{
	HAL_TIM_Base_Start(ultraSonic->hTim);
}
void UltraSonic_stopTimer(ultraSonic_t *ultraSonic)
{
	HAL_TIM_Base_Stop(ultraSonic->hTim);
}

uint16_t UltraSonic_getTimerCounter(ultraSonic_t *ultraSonic)
{
	return __HAL_TIM_GET_COUNTER(ultraSonic->hTim);
}


void UltraSonic_ISR_Process(ultraSonic_t *ultraSonic, uint16_t GPIO_Pin)
{
	if (GPIO_Pin == ultraSonic->GPIO_EchoPin) {//인터럽트 루틴
		//echo pin high 유지시간 측정

		if(UltraSonic_getEchopinState(ultraSonic)){
			UltraSonic_clearTimer(ultraSonic);
			UltraSonic_startTimer(ultraSonic);
			UltraSonic_clearEchoFlag(ultraSonic);
		}
		else { //falling edge (하강)
			UltraSonic_stopTimer(ultraSonic);
			ultraSonic->timCounter = UltraSonic_getTimerCounter(ultraSonic);
			UltraSonic_setEchoFlag(ultraSonic);
		}
	}
}

void UltraSonic_startTrig(ultraSonic_t *ultraSonic)
{
	HAL_GPIO_WritePin(ultraSonic->GPIO_Trig, ultraSonic->GPIO_TrigPin, SET);
	DelayUS(15);
	HAL_GPIO_WritePin(ultraSonic->GPIO_Trig, ultraSonic->GPIO_TrigPin, RESET);
}

void UltraSonic_clearEchoFlag(ultraSonic_t *ultraSonic)
{
	ultraSonic->echoFlag = 0;
}

void UltraSonic_setEchoFlag(ultraSonic_t *ultraSonic)
{
	ultraSonic->echoFlag = 1;
}


int UltraSonic_isCmpltRecvEcho(ultraSonic_t *ultraSonic)//flag return
{
	return ultraSonic->echoFlag;
}

int UltraSonic_getDistance(ultraSonic_t *ultraSonic)
{
	int timeout = 0;
	UltraSonic_startTrig(ultraSonic);
	while(!UltraSonic_isCmpltRecvEcho(ultraSonic)){//1이 되는것을 기다리기
		timeout++;
		if(timeout > 20)return 0;
		HAL_Delay(1);
	}
	UltraSonic_clearEchoFlag(ultraSonic);
	return ultraSonic->timCounter * 0.017; //cm distance (0.034/2)갔다오는거 나누기
}
#ifndef DRIVER_ULTRASONIC_ULTRASONIC_H_
#define DRIVER_ULTRASONIC_ULTRASONIC_H_

#include "stm32f4xx_hal.h"

//trig port, trig pin, echo port, echo pin, timer, flag : 센서 1번과 2번의 차이점
typedef struct{
	TIM_HandleTypeDef *hTim;
	GPIO_TypeDef* GPIO_Trig;
	uint16_t GPIO_TrigPin;
	GPIO_TypeDef* GPIO_Echo;
	uint16_t GPIO_EchoPin;
	uint16_t timCounter;
	int echoFlag;
}ultraSonic_t;

void UltraSonic_init(ultraSonic_t *ultraSonic,
		TIM_HandleTypeDef *hTim,
		GPIO_TypeDef* GPIO_Trig,
		uint16_t GPIO_TrigPin,
		GPIO_TypeDef* GPIO_Echo,
		uint16_t GPIO_EchoPin);

void DelayInit(void);
void DelayUS(uint32_t us);

int UltraSonic_getEchopinState(ultraSonic_t *ultraSonic);
void UltraSonic_clearTimer(ultraSonic_t *ultraSonic);
void UltraSonic_startTimer(ultraSonic_t *ultraSonic);
void UltraSonic_stopTimer(ultraSonic_t *ultraSonic);
uint16_t UltraSonic_getTimerCounter(ultraSonic_t *ultraSonic);
void UltraSonic_ISR_Process(ultraSonic_t *ultraSonic, uint16_t GPIO_Pin);
void UltraSonic_startTrig(ultraSonic_t *ultraSonic);
void UltraSonic_clearEchoFlag(ultraSonic_t *ultraSonic);
void UltraSonic_setEchoFlag(ultraSonic_t *ultraSonic);
int UltraSonic_isCmpltRecvEcho(ultraSonic_t *ultraSonic);
int UltraSonic_getDistance(ultraSonic_t *ultraSonic);

#endif /* DRIVER_ULTRASONIC_ULTRASONIC_H_ */

'공부방 > ARM_STM32 노진호교수님_필기' 카테고리의 다른 글

240426 Serial Communication(UART, I2C, SPI ) & BUFF  (0) 2024.04.26
240425_PWM, MOTOR  (0) 2024.04.26
240424 LCD & ULTRASONIC & INTERRUPTS  (0) 2024.04.24
240424 과제  (0) 2024.04.24
240423 UART2_LCD  (1) 2024.04.23