欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

stm32学习 GPIO

程序员文章站 2022-07-02 11:03:52
...
每个GPI/O端口有两个32位配置寄存器(GPIOx_CRLGPIOx_CRH),两个32位数据寄存器
(GPIOx_IDRGPIOx_ODR),一个32位置位/复位寄存器(GPIOx_BSRR),一个16位复位寄存
(GPIOx_BRR)和一个32位锁定寄存器(GPIOx_LCKR)
根据数据手册中列出的每个
I/O端口的特定硬件特征,GPIO端口的每个位可以由软件分别配置
成多种模式。
输入浮空
输入上拉
输入下拉
模拟输入
开漏输出
推挽式输出
推挽式复用功能
开漏复用功能
每个
I/O端口位可以*编程,然而I/0端口寄存器必须按32位字被访问(不允许半字或字节访
)GPIOx_BSRRGPIOx_BRR寄存器允许对任何GPIO寄存器的读/更改的独立访问;这
样,在读和更改访问之间产生
IRQ时不会发生危险。


当作为输出配置时,写到输出数据寄存器上的值(GPIOx_ODR)输出到相应的I/O引脚。可以以推
挽模式或开漏模式
(当输出0时,只有N-MOS被打开)使用输出驱动器。
输入数据寄存器
(GPIOx_IDR)在每个APB2时钟周期捕捉I/O引脚上的数据 。


当对GPIOx_ODR的个别位编程时,软件不需要禁止中断:在单次APB2写操作里,可以只更改
一个或多个位。
这是通过对“置位
/复位寄存器” (GPIOx_BSRR,复位是 GPIOx_BRR)中想要更改的位写’1’
实现的。没被选择的位将不被更改。


例程

//led.h
#include<stm32f10x.h>

void led_init(void);
//led.c
#include<stm32f10x.h>
#include<led.h>
int main(void)
{		
   delay_init();
	 led_init();
  	while(1)
	{
		GPIOA->ODR|=1<<8;
		GPIOD->ODR|=1<<2;
		delay_ms(500);
		GPIOA->ODR&=~(1<<8);
		GPIOD->ODR&=~(1<<2);
		delay_ms(500);
	}	 
} 

//main.c
#include "sys.h"
#include "usart.h"		
#include "delay.h"	 
#include "led.h"


int main(void)
{		
   delay_init();
	 led_init();
  	while(1)
	{
		GPIOA->ODR|=1<<8;
		GPIOD->ODR|=1<<2;
		delay_ms(500);
		GPIOA->ODR&=~(1<<8);
		GPIOD->ODR&=~(1<<2);
		delay_ms(500);
	}	 
} 

warnings:函数声明时无参的话加void;

errors:main.c中还有个错误未解决

          main.c(11): error:  #165: too few arguments in function call

                                     delay_init();

找到该函数定义:

//初始化延迟函数
//当使用OS的时候,此函数会初始化OS的时钟节拍
//SYSTICK的时钟固定为HCLK时钟的1/8
//SYSCLK:系统时钟
void delay_init(u8 SYSCLK)
{
#if SYSTEM_SUPPORT_OS 						//如果需要支持OS.
	u32 reload;
#endif
 	SysTick->CTRL&=~(1<<2);					//SYSTICK使用外部时钟源	 
	fac_us=SYSCLK/8;						//不论是否使用OS,fac_us都需要使用
#if SYSTEM_SUPPORT_OS 						//如果需要支持OS.
	reload=SYSCLK/8;						//每秒钟的计数次数 单位为K	   
	reload*=1000000/delay_ostickspersec;	//根据delay_ostickspersec设定溢出时间
											//reload为24位寄存器,最大值:16777216,在72M下,约合1.86s左右	
	fac_ms=1000/delay_ostickspersec;		//代表OS可以延时的最少单位	   
	SysTick->CTRL|=1<<1;   					//开启SYSTICK中断
	SysTick->LOAD=reload; 					//每1/delay_ostickspersec秒中断一次	
	SysTick->CTRL|=1<<0;   					//开启SYSTICK    
#else
	fac_ms=(u16)fac_us*1000;				//非OS下,代表每个ms需要的systick时钟数   
#endif
}					
那参数该填什么呢




注:GPIO和PORT不是同一个模块Port是用来把引脚复用到其他模块上,其中一个功能就是复用到GPIO模块上,当然也可以复用到其他专用的接口,如UART,IIC等。而GPIO只用于普通IO,即微控制器主动控制输出电平高低,或者读取电平