详情更多 wechat:嵌入式工程师成长日记
https://mp.weixin.qq.com/s?__biz=Mzg4Mzc3NDUxOQ==&mid=2247485624&idx=1&sn=4e553234c2624777409bd2067a07aad8&chksm=cf430de0f83484f6189b119d9d83ea6e6f2a85d13afaa04d218483918231c38e6382d3007061&token=767249363&lang=zh_CN#rdhttps://mp.weixin.qq.com/s?__biz=Mzg4Mzc3NDUxOQ==&mid=2247485624&idx=1&sn=4e553234c2624777409bd2067a07aad8&chksm=cf430de0f83484f6189b119d9d83ea6e6f2a85d13afaa04d218483918231c38e6382d3007061&token=767249363&lang=zh_CN#rd
通过配置寄存器初始化LED:
代码:
//LED IO初始化
void LED_Init(void)
{
RCC->APB2ENR|=1<<4; //使能PORTC时钟
GPIOC->CRL&=0X00000000;//清零
GPIOC->CRL|=0X33333333;//推挽50MHz输出
GPIOC->ODR=0X00FF; //输出高
}
①CRL寄存器(端口配置低寄存器):
②APB2外设时钟使能寄存器:
③ODR端口输出数据寄存器:
总结:
STM32每个IO端口都有7个寄存器控制:
-
1.两个32位 端口配置寄存器-- CRL和CRH
2.两个32位 数据寄存器-- IDR和ODR
3.一个32位 置位/复位寄存器-- BSRR
4.一个16位 复位寄存器-- BRR
5.一个32位 锁存寄存器-- LCKR -
主程序(main.c):
#include "main.h"
void KEY_IO_Init(void);//按键初始化
void EXTIx_Init(void);//外部中断
void EXTI0_IRQHandler(void);
void EXTI1_IRQHandler(void);
//LED IO初始化
void LED_Init(void)
{
RCC->APB2ENR|=1<<4; //使能PORTC时钟
GPIOC->CRL&=0X00000000;//清零
GPIOC->CRL|=0X33333333;//推挽50MHz输出
GPIOC->ODR=0X00FF; //输出高
}
int main(void){
uint8_t count_i;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断向量分组 2
KEY_IO_Init();
EXTIx_Init();//外部中断初始化
while(1){
LED_Init();//初始化与LED连接IO口
while(1)
{
}
}
return 0;
}
void KEY_IO_Init(void)//按键初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //按键输入端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void EXTIx_Init(void)//外部中断
{
NVIC_InitTypeDef NVIC_InitStructure; //NVIC寄存器结构体变量
EXTI_InitTypeDef EXTI_InitStructure; //外部中断相关寄存器结构体变量
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能IO复用功能时钟
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource0); //
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource1); //
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource2); //
//配置外部中断4相关寄存器
EXTI_InitStructure.EXTI_Line = EXTI_Line0|EXTI_Line1|EXTI_Line2;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitStructure);
//中断通道使能
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//使能外部中断通道0
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //设置抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;//设置响应优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//中断通道使能
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;//使能外部中断通道1
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //设置抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;//设置响应优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//中断通道使能
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;//使能外部中断通道2
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //设置抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;//设置响应优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void EXTI0_IRQHandler(void)
{
int i;
for(i=0;i<8;i++)
{
GPIOC->ODR=~(1<<i);//输出低
delay_ms(500);
}
GPIOC->ODR=0xff;
EXTI_ClearITPendingBit(EXTI_Line4);//清除中断挂起标志位
}
void EXTI1_IRQHandler(void)
{
int i;
for(i=8;i>=0;i--)
{
GPIOC->ODR=~(1<<i);//输出低
delay_ms(500);
}
GPIOC->ODR=0xff;
EXTI_ClearITPendingBit(EXTI_Line4);//清除中断挂起标志位
}
-
运行效果: