从上文可以看到,在系统启动过程中会对系统时钟进行一次配置,有了时钟源以后,我们来看简单的GPIO配置:对于GPIO,使用寄存器进行配置时:我们先来看一个例子:
#include <stm32f4xx.h>
uint32_t Gb_TimingDelay;
void Delay(uint32_t nTime);
void main()
{
SysTick_Config(SystemCoreClock/1000);//1ms based time
RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN; //ENABLE GPIOD
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; //ENABLE SYSCFG
GPIOD->MODER &= 0x00FFFFFF; //set direction
GPIOD->MODER |= 0x55000000;
GPIOD->OTYPER &= 0xFFFF0FFF; //set the way of output:31-16:observed 15-0: 1: output push-pull 0: output open-drain
GPIOD->OSPEEDR &= 0X00FFFFFF; //speed
GPIOD->OSPEEDR |= 0XFF000000;
SYSCFG->CMPCR =0X00000001; //speed CMR
GPIOD->PUPDR= 0X00FFFFFF; //pull-up or pull-down
GPIOD->BSRRH= 0XF000; //clear or set
while(1)
{
GPIOD->BSRRH = 0XF000;
GPIOD->BSRRL = 0X1000;
Delay(100);
GPIOD->BSRRH = 0XF000;
GPIOD->BSRRL = 0X1000<<1;
Delay(100);
GPIOD->BSRRH = 0XF000;
GPIOD->BSRRL = 0X1000<<2;
Delay(100);
GPIOD->BSRRH = 0XF000;
GPIOD->BSRRL = 0X1000<<3;
Delay(100);
}
}
void Delay(uint32_t nTime) //Delay
{
Gb_TimingDelay = nTime;
while(Gb_TimingDelay!=0);
}
void SysTick_Handle() //interrupt handle
{
if(Gb_TimingDelay!=0)
{
Gb_TimingDelay--;
}
}
首先调用了
SysTick_Config,我们来看看这个函数:
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
SysTick->LOAD = ticks - 1; /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */
SysTick->VAL = 0; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0); /* Function successful */
}
可以看到这是对时钟中断进行配置,
每隔168000000/1000 *1/168000000=1ms产生一次中断。
我们重点看GPIO寄存器·:
1.GPIO端口模式寄存器GPIOx_MODER
2.GPIO端口输出类型寄存器GPIOx_OTYPER
3.GPIO端口输出速度控制器GPIOx_OSPEEDR
4.GPIO端口上拉下拉寄存器GPIOx_PUPDR
5.GPIO端口置位复位寄存器GPIOx_BSRR