GPIO

寄存器版本stm32的目录,在keil根目录添加startup_stm32f40_41xxx.s即可,

stm32f4有7组io口,分别GOIOA-GPIOG,每一组io有16个io端口,每个io为一个引脚,在我们用io口必须使能(控制信号的输入输出)对应io口时钟寄存器来控制io口,

每组io有10个32位寄存器控制,

寄存器

avatar

寄存器版本

main.c

#include "sys.h"
#include "led.h"
#include "delay.h"
	
int main() {
		delay_init(168);
		ledInit();
		while(1) {
			GPIOF_ODR &= ~(1<<9);
			GPIOF_ODR &= ~(1<<10);
			delay_ms(300);
			GPIOF_ODR |= ~(1<<9);
			GPIOF_ODR |= ~(1<<10);
			delay_ms(300);
		}
}

led.h

#ifndef __LED_H_
#define __LED_H_

	#define GPIOF_MODER (*(volatile unsigned *) 0x40021400)
	
   #define GPIOF_OTYPER (*(volatile unsigned *) 0x40021404)
	
   #define GPIOF_OSPEEDR (*(volatile unsigned *) 0x40021408)
	
   #define GPIOF_PUPDR (*(volatile unsigned *) 0x4002140C)
	
   #define GPIOF_ODR (*(volatile unsigned *) 0x40021414)
	
   #define RCC_AHB1ENR (*(volatile unsigned *) 0x40023830)	
		 
	void ledInit(void);
#endif

led.c

#include "led.h"

void ledInit(void) {
         RCC_AHB1ENR |= 1<<5;   //使能时钟
		 GPIOF_MODER &= ~(3<<2*9);   //输入,输出模式 00 输入 01 输出 10 复用 11模拟
		 GPIOF_MODER |= 1<<(2*9);  
		 GPIOF_OSPEEDR &= ~(3<<2*9);   //输出速度 00 2MHz, 01 25MHz, 10 50MHz,11 100MHz
		 GPIOF_OSPEEDR |= 2<<(2*9);    
		 GPIOF_PUPDR  &= ~(3<<2*9);   //上拉,下拉 00 为无上下拉 01 上拉 10 下拉 11保留
		 GPIOF_PUPDR |= 1<<(2*9);
		 GPIOF_OTYPER &= ~(1<<9);    //输出类型 =0 推挽输出 = 1 开漏
		 GPIOF_OTYPER |= 0<<9;
		 GPIOF_ODR |= 1<<9;          //控制输出电平
		 GPIOF_MODER &= ~(3<<2*10);
		 GPIOF_MODER |= 1<<(2*10);
		 GPIOF_OSPEEDR &= ~(3<<2*10);
		 GPIOF_OSPEEDR |= 2<<(2*10);
		 GPIOF_PUPDR  &= ~(3<<2*10);
		 GPIOF_PUPDR |= 1<<(2*10);
		 GPIOF_OTYPER &= ~(1<<10);
		 GPIOF_OTYPER |= 0<<10;
		 GPIOF_ODR |= 1<<10;
}

库函数版本

使用前必须设置使能时钟

RCC_AHB1PeriphClockCmd();

库函数几个有关操作io口函数

void GPIO_Init() 设置上面图片的前4个寄存器

读取输入电平

uint8_t GPIO_ReadInputDataBit();

uint16_t GPIO_ReadInputData();

读取输出电平

uint8 GPIO_ReadOutputDataBit();

uint16 GPIO_ReadOutputData();

4个设置输出电平的函数

void GPIO_setBits(); //设置低电平 = 0

void GPIO_ReseBits(); //设置高电平 = 1

void GPIO_writeBit();

void GPIO_write();

GPIO_setBits,GPIO_ReseBits这两个函数使用的是BSRR寄存器不是使用的ODR寄存器,BSRR寄存器高16bit写1对应管脚为低电平,对寄存器低16bit写1对应管脚为高电平。写 0 无动作。

main.c

#include "stm32f4xx.h"
#include "delay.h"
#include "led.h"

int main(void) { 
	delay_init(168);
	ledInit();
	
	while(1) {
		GPIO_SetBits(GPIOF,GPIO_Pin_9);
		GPIO_SetBits(GPIOF,GPIO_Pin_10);
		delay_ms(500);
		
		GPIO_ResetBits(GPIOF,GPIO_Pin_9);
		GPIO_ResetBits(GPIOF,GPIO_Pin_10);
		delay_ms(500);
	
	}
}

led.c

#include "led.h"
#include "sys.h"

void ledInit(void) {
	 GPIO_InitTypeDef GPIO_InitStruct;
	
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);  //时钟使能
	
	 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
	 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
	 GPIO_InitStruct.GPIO_OType =  GPIO_OType_PP;
	 GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
	 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	 GPIO_Init(GPIOF,&GPIO_InitStruct);
	 GPIO_SetBits(GPIOF,GPIO_Pin_9);
	
	 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
	 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
	 GPIO_InitStruct.GPIO_OType =  GPIO_OType_PP;
	 GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
	 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	 GPIO_Init(GPIOF,&GPIO_InitStruct);
	 GPIO_SetBits(GPIOF,GPIO_Pin_10);
	
}

led.h

#ifndef __LED_H
#define __LED_H


void ledInit(void);

#endif