

GPIO输出实验完成后,开始做GPIO输入实验也就是按键输入的查询方式。
本次实验使用User按键和LED作为实验的基本电路,如上图所示当按键按下时PF11为0,释放时PF11为1.初始化PF11为输入方式代码如下:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);
GPIO_InitStructureF.GPIO_Pin = GPIO_KEY1;
GPIO_InitStructureF.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructureF.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIO_KEY_PORT, &GPIO_InitStructureF);
通过uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin);这个函数读取I/O口的值。本实验具体操作代码如下:
if(GPIO_ReadInputDataBit(GPIO_KEY_PORT,GPIO_KEY1)==0)
{
GPIO_ResetBits(GPIO_LED,DS1_PIN);
}
else
{
GPIO_SetBits(GPIO_LED,DS1_PIN);
}
宏定义:
#define GPIO_KEY_PORT GPIOF
#define GPIO_KEY1 GPIO_Pin_11

本实验效果是通过User按键,控制LD6灯的亮灭。
按键中断初始化代码:
GPIO_EXTILineConfig(GPIO_PortSourceGPIOF, GPIO_PinSource11);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
EXIT_Type.EXTI_Line = EXTI_Line11;
EXIT_Type.EXTI_Mode = EXTI_Mode_Interrupt;
EXIT_Type.EXTI_Trigger = EXTI_Trigger_Falling;
EXIT_Type.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXIT_Type);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//强占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //次优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //通道中断使能
NVIC_Init(&NVIC_InitStructure); //初始化中断
中断函数:
void EXTI15_10_IRQHandler(void)
{
if(Led_State)
{
GPIO_SetBits(GPIO_LED,DS1_PIN);
Led_State = 0;
}
else
{
GPIO_ResetBits(GPIO_LED,DS1_PIN);
Led_State = 1;
}
EXTI_ClearITPendingBit(EXTI_Line11);
}
按键中断初始化代码:
GPIO_EXTILineConfig(GPIO_PortSourceGPIOF, GPIO_PinSource11);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
EXIT_Type.EXTI_Line = EXTI_Line11;
EXIT_Type.EXTI_Mode = EXTI_Mode_Interrupt;
EXIT_Type.EXTI_Trigger = EXTI_Trigger_Falling;
EXIT_Type.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXIT_Type);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//强占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //次优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //通道中断使能
NVIC_Init(&NVIC_InitStructure); //初始化中断
中断函数:
void EXTI15_10_IRQHandler(void)
{
if(Led_State)
{
GPIO_SetBits(GPIO_LED,DS1_PIN);
Led_State = 0;
}
else
{
GPIO_ResetBits(GPIO_LED,DS1_PIN);
Led_State = 1;
}
EXTI_ClearITPendingBit(EXTI_Line11);
}

STM32F10XX通过设置SCB_AIRCR寄存器中的PRIGROUP[2:0],将优先级PRI_N[7:4]可以分成两部分:一部分是优先级组(先占优先级),另一部分是次优先级。
当一个中断执行的时候,不能被同一个优先级组的中断打断。
当多个中断请求时,若是相同的优先级组,就由次优先级确定响应的顺序。
PRIGROUP | PRI_N | Group priorities | Sub priorities |
0b001 | 0bxxxx | 16 | None |
0b100 | 0bxxxy | 8 | 2 |
0b101 | 0bxxyy | 4 | 4 |
0b110 | 0bxyyy | 2 | 8 |
0b111 | 0byyyy | None | 16 |
当多个中断请求时,若是相同的优先级组,就由次优先级确定响应的顺序。

SysTick实验:
本实验以LED控制实验为基础,增加delay_nms()精确延时实现走马灯效果。本实验使用的是8MHz的晶振。使用官方3.5.0的库。
从stm32f10.h分析得知PLLCLK = HSE * 9 = 72Mhz,PLLCLK = SYSCLK = HCLK = 72Mhz
初始化代码如下:
SysTick->CTRL = 0x00; //设置SysTick的时钟为HCLK/8 = 9Mhz
SysTick->VAL = 0; //清倒计数值
延时函数
void delay_nms(uint16_t n)
{
uint32_t temp;
SysTick->LOAD = 9000*n; //以9000为基准值也就是1ms,n输入有效值控制在1~1864.
SysTick->CTRL = 0x01;
do
{
temp = SysTick->CTRL;
}
while( (temp&0x01)&&! (temp&(1<<16)) );
SysTick->CTRL = 0x0000;
SysTick->LOAD = 0x0000;
}
本实验以LED控制实验为基础,增加delay_nms()精确延时实现走马灯效果。本实验使用的是8MHz的晶振。使用官方3.5.0的库。
从stm32f10.h分析得知PLLCLK = HSE * 9 = 72Mhz,PLLCLK = SYSCLK = HCLK = 72Mhz
初始化代码如下:
SysTick->CTRL = 0x00; //设置SysTick的时钟为HCLK/8 = 9Mhz
SysTick->VAL = 0; //清倒计数值
延时函数
void delay_nms(uint16_t n)
{
uint32_t temp;
SysTick->LOAD = 9000*n; //以9000为基准值也就是1ms,n输入有效值控制在1~1864.
SysTick->CTRL = 0x01;
do
{
temp = SysTick->CTRL;
}
while( (temp&0x01)&&! (temp&(1<<16)) );
SysTick->CTRL = 0x0000;
SysTick->LOAD = 0x0000;
}