STM32F407VG IO位操作

/************************************
     标题:操作GPIO的练习
     软件平台:MDK-keil uvision v4.23
     硬件平台:stm32f4-discovery
     主频:168M    
     author:大舟
     data:2012-09-04
 *************************************/
 /*sys时钟为HSE频率/PLL_M*PLL_N/PLL_P,定义HSE为8M,则sys时钟频率为168M */
 #include <stm32f4xx.h> 
 
 
 #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))
 
 //F4XXIO 口地址映射
 #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 (GPIOF_BASE+16) //0x40021C10
 #define GPIOI_IDR_Addr (GPIOG_BASE+16) //0x40022010
 
 //F4XXIO 口操作 , 只对单一的 IO 口 ,n 的值范围 [0-15]
 #define GPIOAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) 	//GPIOA 某一位输出
 #define GPIOAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) 	//GPIOA 某一位输入
 #define GPIOBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) 	//GPIOB 某一位输出
 #define GPIOBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) 	//GPIOB 某一位输入
 #define GPIOCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) 	//GPIOC 某一位输出
 #define GPIOCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) 	//GPIOC 某一位输入
 #define GPIODout(n) BIT_ADDR(GPIOD_ODR_Addr,n) 	//GPIOD 某一位输出
 #define GPIODin(n) BIT_ADDR(GPIOD_IDR_Addr,n) 	//GPIOD 某一位输入
 #define GPIOEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) 	//GPIOE 某一位输出
 #define GPIOEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) 	//GPIOE 某一位输入
 #define GPIOFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) 	//GPIOF 某一位输出
 #define GPIOFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) 	//GPIOF 某一位输入
 #define GPIOGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) 	//GPIOG 某一位输出
 #define GPIOGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) 	//GPIOG 某一位输入
 #define GPIOHout(n) BIT_ADDR(GPIOH_ODR_Addr,n) 	//GPIOH 某一位输出
 #define GPIOHin(n) BIT_ADDR(GPIOH_IDR_Addr,n) 	//GPIOH 某一位输入
 #define GPIOIout(n) BIT_ADDR(GPIOI_ODR_Addr,n) 	//GPIOI 某一位输出
 #define GPIOIin(n) BIT_ADDR(GPIOI_IDR_Addr,n) 	//GPIOI 某一位输入
 /*************************************************************************/
 
 #define LED1 GPIODout(12) 	// 定义 LED1 为 GPIOD_Pin_12
 #define LED2 GPIODout(13) 	// 定义 LED1 为 GPIOD_Pin_13
 #define LED3 GPIODout(14) 	// 定义 LED1 为 GPIOD_Pin_14
 #define LED4 GPIODout(15) 	// 定义 LED1 为 GPIOD_Pin_15
 #define KEY1 GPIOAin(0) 	// 定义 KEY1 为 GPIOC_Pin_0
 
 
 uint32_t Gb_TimingDelay;
 
 void Delay(uint32_t nTime);
 void LED_init(void);
 void key_init(void);
 void key_scan(void);
 
 int main (void)
 {   
 	SysTick_Config(SystemCoreClock / 1000); //设置systemtick一毫秒中断  
 	RCC->APB2ENR |= (1<<14);  //使能syscfg时钟
 	
 	LED_init();
 	key_init();
 //  LED1=1;		//LED灯亮
 	while(1)
 	{
 		//流水灯
 		LED1=!LED1;
 		LED2=!LED2;
 		LED3=!LED3;
 		LED4=!LED4;
 		Delay(1000);
 		
 		//按键扫描
 		key_scan();	
 	}
 }
 
 void LED_init(void)
 {
 	RCC->AHB1ENR |= 0x00000008; //使能GPIOD时钟
 	
 	GPIOD->MODER &= 0x00FFFFFF; //设置PD12,13,14,15输出
 	GPIOD->MODER |= 0x55000000; 
 	
 	GPIOD->OTYPER &= 0xFFFF0FFF; //设置PD12,13,14,15推挽输出
 	
 	GPIOD->OSPEEDR &= 0x00FFFFFF; //PD12,13,14,15 速度100m
 	GPIOD->OSPEEDR |= 0xff000000;
 	
 	SYSCFG->CMPCR = 0x00000001; //使用IO补偿单元,当GPIO速度超过50M的时候要考虑使用此设置
 	
 	GPIOD->PUPDR &= 0x00FFFFFF;  //PD12,13,14,15 无上拉无下拉
 }
 
 void key_init(void)
 {
 	RCC->AHB1ENR |= 0x00000001; //使能GPIOA时钟
 	
 	GPIOA->MODER &= 0xFFFFFFFC; //设置PA0输入
 	
 	GPIOA->PUPDR &= 0xFFFFFFFC; //设置PA0为下拉,因为PA0的输入状态为1
 	GPIOA->PUPDR |= 0x00000002;	
 }
 
 void key_scan(void)
 {
 	if(KEY1==1) 	// 如果按键按下
 	{
 		Delay(10);	//去抖
 		if(KEY1==1)	// 如果按键按下
 		{
 			LED1=!LED1;	//LED灯亮
 			while(KEY1==1);//松手检测
 		}
 	}
 }
 
 void Delay(uint32_t nTime)
 { 
   Gb_TimingDelay = nTime;
 
   while(Gb_TimingDelay != 0);
 }
 
 void SysTick_Handler(void)
 {
   if (Gb_TimingDelay != 0x00)
   { 
     Gb_TimingDelay--;
   }
 }
 


说明:以上程序是在以下两个资料下修改而成的。

(1)“STM32F407VG用位带别名区实现IO位操作例程”(杨年荣) http://wenku.baidu.com/view/4057a658804d2b160b4ec083.html

(2)“stm32f407学习之四————GPIO(操作寄存器)”  http://blog.csdn.net/w471176877/article/details/7957171

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值