1. 程式人生 > >用中斷實現流水燈

用中斷實現流水燈

#include <stm32f4xx.h>

#define GPIO_Pin_6                 0x0040  /* LED2 */
#define GPIO_Pin_7 0x0080  /* LED1 */
#definePLL_M 8
#definePLL_N 336
#definePLL_P 2
#definePLL_Q 7

uint32_t flag = 0;

int main()
{
RCC_config();
TIMER_config();
GPIO_config();
NVIC_config();

while(1)
{
;
}

}

// 中斷函式處理
void TIM4_IRQHandler(void)
{  
if((TIM4->SR&TIM_SR_UIF)){
flag = !flag;
// 清除標誌位
CLEAR_BIT(TIM4->SR, TIM_SR_UIF); 
if(flag == 0){  
// LED2亮,LED1滅
GPIOG->ODR&= ~GPIO_Pin_6;  
GPIOG->ODR|= GPIO_Pin_7;  
}
if(flag == 1){
// LED1亮,LED2滅
GPIOG->BSRRL|= GPIO_Pin_6;
GPIOG->BSRRH|= GPIO_Pin_7;
}
}

}


void RCC_config(void)
{
// -------------------- 配置HSE時鐘 -------------------- 
// 配置PLL預分頻
RCC->PLLCFGR= 0x00000000;  // 將該暫存器預設值初始化為零
RCC->PLLCFGR|= PLL_M;
RCC->PLLCFGR|= PLL_N<<6;
RCC->PLLCFGR|= (PLL_P/2-1)<<16;
RCC->PLLCFGR|= PLL_Q<<24;
// 開啟HSE晶振
SET_BIT(RCC->CR, RCC_CR_HSEON);
// 等待HSE晶振進入穩定狀態
while(!(RCC->CR&RCC_CR_HSERDY)){
;
}
// 配置AHB預分頻
SET_BIT(RCC->CFGR, RCC_CFGR_HPRE_DIV1);
// 配置APB1預分頻,得到84M的時鐘頻率
SET_BIT(RCC->CFGR, RCC_CFGR_PPRE1_DIV4);
// 配置APB2預分頻
SET_BIT(RCC->CFGR, RCC_CFGR_PPRE2_DIV2);
// 將HSE作為PLLCLK的輸入
SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC_HSE);
// 使能PLLCLK
SET_BIT(RCC->CR, RCC_CR_PLLON);
// 等待PLLCLK穩定
while(!(RCC->CR&RCC_CR_PLLRDY)){
;
}
// 正確設定FLASH延遲時間
FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
// 檢查設定是否成功
if((FLASH->ACR & FLASH_ACR_LATENCY) != FLASH_ACR_LATENCY_5WS){
;
}
// 將PLLCLK作為SYSCLK,關閉HSI
SET_BIT(RCC->CFGR, RCC_CFGR_SW_PLL);
CLEAR_BIT(RCC->CR, RCC_CR_HSION);
// 等待設定成功
while((RCC->CFGR & RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL){
;
}
}

void TIMER_config(void)
{
// -------------------- 配置定時器 -------------------- 
// 開啟TIM4時鐘
RCC->APB1ENR|= RCC_APB1ENR_TIM4EN;
// 設定預分頻值,對84M進行8400分頻,得到10k的計數器時鐘頻率
TIM4->PSC= 8399;
// 設定自動過載值,定時器頻率為1s
TIM4->ARR= 10000;
// 設定計數模式,向上計數
CLEAR_BIT(TIM4->CR1, TIM_CR1_DIR);
// 清空計數器的值
TIM4->CNT= 0;
// 中斷使能
TIM4->DIER|= TIM_DIER_UIE;
// 自動重灌載預裝載使能
SET_BIT(TIM4->CR1, TIM_CR1_ARPE);
// 開啟定時器4
SET_BIT(TIM4->CR1, TIM_CR1_CEN); 
}

void NVIC_config(void)

// TIM4全域性中斷
NVIC->ISER[0]|= 1<<30;
}

void GPIO_config(void)
{
// -------------------- 配置GPIO -------------------- 
// 開啟G埠的時鐘
RCC->AHB1ENR|= RCC_AHB1ENR_GPIOGEN;
// 輸出模式
GPIOG->MODER|= GPIO_MODER_MODER6_0;
GPIOG->MODER|= GPIO_MODER_MODER7_0;
// 有上拉電阻,開漏輸出
GPIOG->OTYPER|= GPIO_OTYPER_OT_6;
GPIOG->OTYPER|= GPIO_OTYPER_OT_7;
// 中等速度
GPIOG->OSPEEDR|= GPIO_OSPEEDER_OSPEEDR6_0;
GPIOG->OSPEEDR|= GPIO_OSPEEDER_OSPEEDR7_0;
}