HC-SR04超声波传感器

1、产品特点:
HC-SR04超声波测距模块可提供2cm-400cm的非接触式距离感测功能,测距精度可达高到3mm;模块包括超声波发射器、接收器与控制电路。

基本工作原理:
(1)采用IO 口 TRIG触发测距,给最少10us的高电平信号。
(2)模块自动发送8个40khz的方波,自动检测是否有信号返回;(可以简单认为是高电平)
(3)有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2;

注:1、此模块不宜带电连接,若要带电连接,则先让模块的GND端先连接,否则会影响模块的正常工作。
2、测距时,被测物体的面积不少于0.5平方米且平面尽量要求平整,否则影响测量的结果
时序图如下
在这里插入图片描述

在这里插入图片描述
公式转换原理:
在这里插入图片描述
为什么最后是t3呢?
答:因为t/2后是单程的时间,路程=时间
速度=t*3mm/s=最终的数值(mm)

拓展:
pwm控制蜂鸣器占空比,下面是例子

#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_usart.h"
#include "sys.h"
#include "stdio.h"

static GPIO_InitTypeDef  	GPIO_InitStructure;
static USART_InitTypeDef 	USART_InitStructure;
static NVIC_InitTypeDef 	NVIC_InitStructure;		

static EXTI_InitTypeDef   EXTI_InitStructure;



static TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

static TIM_OCInitTypeDef  TIM_OCInitStructure;

static uint32_t g_freq=100,g_duty=50,g_cmp=0;

//重定义fputc函数 
int fputc(int ch, FILE *f)
{
    
     	
	USART_SendData(USART1,ch);
	while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);  
	
	return ch;
}   

void delay_us(uint32_t nus)
{
    
    		
	uint32_t temp;	    	 
	SysTick->LOAD =SystemCoreClock/8/1000000*nus; 	//时间加载	  		 
	SysTick->VAL  =0x00;        					//清空计数器
	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; 		//使能滴答定时器开始倒数 	 
	do
	{
    
    
		temp=SysTick->CTRL;
	}while((temp&0x01)&&!(temp&(1<<16)));			//等待时间到达   
	SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; 		//关闭计数器
	SysTick->VAL =0X00;       						//清空计数器 
}

void delay_ms(uint16_t nms)
{
    
    	 		  	  
	uint32_t temp;		   
	SysTick->LOAD=SystemCoreClock/8/1000*nms;		//时间加载(SysTick->LOAD为24bit)
	SysTick->VAL =0x00;           					//清空计数器
	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;    	//能滴答定时器开始倒数 
	do
	{
    
    
		temp=SysTick->CTRL;
	}while((temp&0x01)&&!(temp&(1<<16)));			//等待时间到达   
	SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;    	//关闭计数器
	SysTick->VAL =0X00;     		  				//清空计数器	  	    
} 

void LED_Init(void)
{
    
        	 
  
	//使能GPIOE,GPIOF时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOF, ENABLE);			

	//GPIOF9,F10初始化设置 
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9 | GPIO_Pin_10;		//LED0和LED1对应IO口
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;			    	//普通输出模式,
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;					//推挽输出,驱动LED需要电流驱动
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;		    	//100MHz
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;				    //上拉
	GPIO_Init(GPIOF, &GPIO_InitStructure);							//初始化GPIOF,把配置的数据写入寄存器						


	//GPIOE13,PE14初始化设置 
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_13 | GPIO_Pin_14;		//LED2和LED3对应IO口
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;					//普通输出模式
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;					//推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;				//100MHz
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;					//上拉
	GPIO_Init(GPIOE, &GPIO_InitStructure);							//初始化GPIOE,把配置的数据写入寄存器

	GPIO_SetBits(GPIOF,GPIO_Pin_9  | GPIO_Pin_10);			    	//GPIOF9,PF10设置高,灯灭
	GPIO_SetBits(GPIOE,GPIO_Pin_13 | GPIO_Pin_14);		
}

void key_exti_init(void)
{
    
    
	
	/* GPIOA GPIOE 硬件时钟使能 */
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOE, ENABLE);

	/* 使能 SYSCFG 时钟 */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);	
	
	/* 配置PA0引脚为输入模式  */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;						//第0根引脚	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;				//输入模式,能够检测外部电平状态
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//GPIO最大的速度为100MHz
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;	//不需要上下拉电阻
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	/* 配置PE2引脚为输入模式  */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;			//第2 根引脚	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;							//输入模式,能够检测外部电平状态
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;						//GPIO最大的速度为100MHz
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;							//使能内部上拉电阻(可选)
	GPIO_Init(GPIOE, &GPIO_InitStructure);


	/* Connect EXTI Line0 to PA0 pin */
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
	/* Connect EXTI Line2 to PE2 pin */
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource2);


	/* Configure EXTI Line0 */
	EXTI_InitStructure.EXTI_Line = EXTI_Line0;				//使用外部中断控制线0
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;		//中断事件
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;	//上升沿触发,按键松开的时候就触发中断  
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;				//中断控制线使能
	EXTI_Init(&EXTI_InitStructure);


	/* Configure EXTI Line2  */
	EXTI_InitStructure.EXTI_Line = EXTI_Line2;				//使用外部中断控制线2
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;		//中断事件
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;	//上升沿触发,按键松开的时候就触发中断  
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;				//中断控制线使能
	EXTI_Init(&EXTI_InitStructure);

	//支持4个抢占优先级,支持4个响应优先级
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

	/* Enable and set EXTI Line0 Interrupt to the lowest priority */
	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;			//外部中断控制线0中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;//抢占优先级0x3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;		//响应优先级0x3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//外部中断控制线0中断通道使能
	NVIC_Init(&NVIC_InitStructure);


	/* Enable and set EXTI Line2 Interrupt to the lowest priority */
	NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;			//外部中断控制线2中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x3;//抢占优先级0x3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x3;		//响应优先级0x3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//外部中断控制线2中断通道使能
	NVIC_Init(&NVIC_InitStructure);
}

void tim13_init(uint32_t freq)
{
    
    
	/* TIM13 clock enable,使能定时器13硬件时钟 */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM13, ENABLE);
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);		

	/* 配置PF8引脚为复用功能模式  */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;			//第8根引脚	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;		//复用功能模式,使用引脚的第二功能
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;		//推挽输出模式
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//GPIO最大的速度为100MHz
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;		//使能内部上拉电阻,增大输出电流的能力
	GPIO_Init(GPIOF, &GPIO_InitStructure);
	
	/* Connect TIM13 pins to PF8 */  
	GPIO_PinAFConfig(GPIOF, GPIO_PinSource8, GPIO_AF_TIM13);
	
	
	/* Time base configuration,定时器参数的基本配置:定时时间、分频值、计数方法*/
	TIM_TimeBaseStructure.TIM_Period =(10000/freq)-1;														//设置频率
	TIM_TimeBaseStructure.TIM_Prescaler = 8400-1;												//预分频值8400
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;						//二次分频,也就是说再进行一次分频,当前是1分频
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;			//向上计数的方法

	TIM_TimeBaseInit(TIM13, &TIM_TimeBaseStructure);
	
	/* PWM1 Mode configuration: Channel1 */
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;					//PWM模式1,在递增计数模式下,只要 TIMx_CNT<TIMx_CCR1,通道 1 便为有效状态,否则为无效状态。
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;		//允许输出
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;			//有效的时候,输出高电平
	TIM_OC1Init(TIM13, &TIM_OCInitStructure);

	TIM_OC1PreloadConfig(TIM13, TIM_OCPreload_Enable);					//自动重载初值,不断输出PWM脉冲
	TIM_ARRPreloadConfig(TIM13, ENABLE);								//自动重载使能

	/* TIM13 enable counter,使能定时器13工作 */
	TIM_Cmd(TIM13, ENABLE);

}

void tim13_deinit(void)
{
    
    
	
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;			//禁止输出
	TIM_OC1Init(TIM13, &TIM_OCInitStructure);

	/* TIM13 disable counter,禁止定时器13工作 */
	TIM_Cmd(TIM13, DISABLE);
}

void USART1_Init(uint32_t baud)
{
    
    
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); 							//使能GPIOA时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);							//使能USART1时钟
 
	//串口1对应引脚复用映射
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); 						//GPIOA9复用为USART1
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); 						//GPIOA10复用为USART1
	
	//USART1端口配置
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; 						//GPIOA9与GPIOA10
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;									//复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;								//速度50MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 									//推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; 									//上拉
	GPIO_Init(GPIOA,&GPIO_InitStructure); 											//初始化PA9,PA10

	//USART1 初始化设置
	USART_InitStructure.USART_BaudRate = baud;										//波特率设置
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;						//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;							//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;								//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;	//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;					//收发模式
	USART_Init(USART1, &USART_InitStructure); 										//初始化串口1
	
	USART_Cmd(USART1, ENABLE);  													//使能串口1 
	
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);									//开启相关中断

	//Usart1 NVIC 配置
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;								//串口1中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;							//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;								//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;									//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);													//根据指定的参数初始化VIC寄存器
}


void sr04_init(void)
{
    
    
	//使能GPIOB,GPIOE时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOE, ENABLE);			

	//PB6初始化设置 
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_6;						//PB6引脚
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;			    	//普通输出模式,
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;					//推挽输出,驱动LED需要电流驱动
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;		    	//100MHz
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;				    //上拉
	GPIO_Init(GPIOB, &GPIO_InitStructure);							//初始化GPIOB,把配置的数据写入寄存器						

	//PE6初始化设置 
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_6;						//PB6引脚
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN;			    	//普通输入模式,
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;		    	//100MHz
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;				    //上拉
	GPIO_Init(GPIOE, &GPIO_InitStructure);							//初始化GPIOE,把配置的数据写入寄存器		


}

//获取距离,单位为mm
uint32_t sr04_get_distance(void)
{
    
    
	uint32_t t=0;
	
	//发送触发信号
	PBout(6)=1;
	delay_us(20);
	PBout(6)=0;
	
	//等待输出回响信号
	while(PEin(6)==0);
	
	
	//测量回响信号时间
	
	while(PEin(6))
	{
    
    
		delay_us(8);
		
		t++;
	
	}
	
	t = t/2;

	
	return (3*t);

}

int main(void)
{
    
     
	uint32_t distance;
	
	LED_Init();		

	//系统定时器初始化,时钟源来自HCLK,且进行8分频,
	//系统定时器时钟频率=168MHz/8=21MHz
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); 
		
	//设置中断优先级分组2
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	//串口1,波特率115200bps,开启接收中断
	USART1_Init(115200);
	
	//初始化超声波模块
	sr04_init();
	

	
	//初始化定时器13
	tim13_init(g_freq);
	
	//按键中断初始化
	key_exti_init();
	
	while(1)
	{
    
    
		//获取距离
		distance = sr04_get_distance();
		
		if(distance>4000)
			continue;
		
		//串口显示距离
		printf("distance=%dmm\r\n",distance);
		
		delay_ms(500);
		
		//为了方便测试,当前测试距离缩小为原来的一半。
		if(distance < 600/2)	
		{
    
    
			PFout(9)=0;
			PFout(10)=0;
			PEout(13)=0;
			PEout(14)=0;
			
			//设置频率
			g_freq = 600;
			tim13_init(g_freq);
			
			//设置占空比
			g_cmp = g_freq * g_duty/100;
			TIM_SetCompare1(TIM13,g_cmp);
		}
		else if(distance < 1000/2)
		{
    
    
			PFout(9)=0;
			PFout(10)=0;
			PEout(13)=0;
			PEout(14)=1;		
			
			//设置频率
			g_freq = 400;
			tim13_init(g_freq);	

			//设置占空比
			g_cmp = g_freq * g_duty/100;
			TIM_SetCompare1(TIM13,g_cmp);			
		}
		else if(distance < 1400/2)
		{
    
    
			PFout(9)=0;
			PFout(10)=0;
			PEout(13)=1;
			PEout(14)=1;	
			
			//设置频率
			g_freq = 200;
			tim13_init(g_freq);	

			//设置占空比
			g_cmp = g_freq * g_duty/100;
			TIM_SetCompare1(TIM13,g_cmp);			
		}	
		else if(distance < 1800/2)
		{
    
    
			PFout(9)=0;
			PFout(10)=1;
			PEout(13)=1;
			PEout(14)=1;	

			//设置频率
			g_freq = 100;
			tim13_init(g_freq);		

			//设置占空比
			g_cmp = g_freq * g_duty/100;
			TIM_SetCompare1(TIM13,g_cmp);			
		}	
		else
		{
    
    
			PFout(9)=1;
			PFout(10)=1;
			PEout(13)=1;
			PEout(14)=1;	

			//蜂鸣器停止工作
			tim13_deinit();
		}
	}
}


void EXTI0_IRQHandler(void)
{
    
    
	//检查外部中断控制线0是否真的触发中断
	if(EXTI_GetITStatus(EXTI_Line0)== SET)
	{
    
    
		if(g_duty>=10)
		{
    
    
			g_duty-=10;
			
			printf("duty=%d\r\n",g_duty);
		}

		/* Clear the EXTI line 0 pending bit */
		EXTI_ClearITPendingBit(EXTI_Line0);		

	}
}


void EXTI2_IRQHandler(void)
{
    
    
	//检查外部中断控制线2是否真的触发中断
	if(EXTI_GetITStatus(EXTI_Line2)== SET)
	{
    
    
		if(g_duty<100)
		{
    
    
			g_duty+=10;
			
			printf("duty=%d\r\n",g_duty);
		}
		/* Clear the EXTI line 2 pending bit */
		EXTI_ClearITPendingBit(EXTI_Line2);		

	}
}

void USART1_IRQHandler(void)                				//串口1中断服务程序
{
    
    
	uint8_t d;

	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  	//接收中断
	{
    
    
		//接收数据
		d = USART_ReceiveData(USART1);						
		
		//发送数据
		USART_SendData(USART1,d);
		
		while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
			 
	} 

} 


sys.h

#ifndef __SYS_H__
#define __SYS_H__

//位带操作,实现51类似的GPIO控制功能
//IO口操作宏定义
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr)) 
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum)) 

//IO口地址映射
#define GPIOA_ODR_Addr    (GPIOA_BASE+20) //0x40020014
#define GPIOB_ODR_Addr    (GPIOB_BASE+20) //0x40020414 
#define GPIOC_ODR_Addr    (GPIOC_BASE+20) //0x40020814 
#define GPIOD_ODR_Addr    (GPIOD_BASE+20) //0x40020C14 
#define GPIOE_ODR_Addr    (GPIOE_BASE+20) //0x40021014 
#define GPIOF_ODR_Addr    (GPIOF_BASE+20) //0x40021414    
#define GPIOG_ODR_Addr    (GPIOG_BASE+20) //0x40021814   
#define GPIOH_ODR_Addr    (GPIOH_BASE+20) //0x40021C14    
#define GPIOI_ODR_Addr    (GPIOI_BASE+20) //0x40022014     

#define GPIOA_IDR_Addr    (GPIOA_BASE+16) //0x40020010 
#define GPIOB_IDR_Addr    (GPIOB_BASE+16) //0x40020410 
#define GPIOC_IDR_Addr    (GPIOC_BASE+16) //0x40020810 
#define GPIOD_IDR_Addr    (GPIOD_BASE+16) //0x40020C10 
#define GPIOE_IDR_Addr    (GPIOE_BASE+16) //0x40021010 
#define GPIOF_IDR_Addr    (GPIOF_BASE+16) //0x40021410 
#define GPIOG_IDR_Addr    (GPIOG_BASE+16) //0x40021810 
#define GPIOH_IDR_Addr    (GPIOH_BASE+16) //0x40021C10 
#define GPIOI_IDR_Addr    (GPIOI_BASE+16) //0x40022010 
 
//IO口操作,只对单一的IO口!
//确保n的值小于16!
#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出 
#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //输入 

#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //输出 
#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //输入 

#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //输出 
#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //输入 

#define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //输出 
#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //输入 

#define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //输出 
#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //输入

#define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //输出 
#define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //输入

#define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //输出 
#define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //输入

#define PHout(n)   BIT_ADDR(GPIOH_ODR_Addr,n)  //输出 
#define PHin(n)    BIT_ADDR(GPIOH_IDR_Addr,n)  //输入

#define PIout(n)   BIT_ADDR(GPIOI_ODR_Addr,n)  //输出 
#define PIin(n)    BIT_ADDR(GPIOI_IDR_Addr,n)  //输入

#endif

猜你喜欢

转载自blog.csdn.net/ABCisCOOL/article/details/115035145