STM32學習筆記:基礎例子
阿新 • • 發佈:2019-02-16
本例子程式碼參考了STM32庫開發實戰指南中的程式碼,由於使用的板子是尚學STM32F103ZET6,為了配合板上已有資源,也參考了其配套程式碼。為了便於書寫文字,我儘量將程式碼都寫到了一個檔案中,這種方式是不推薦的,在做具體工程時最好程式碼分類管理,使工程邏輯清晰。
現在對板上一些資源說明:板上有兩個LED燈,引腳為PE5、PE6,均為ResetBits時點亮。有三個按鈕,依次為黃色復位,紅色PE4(按下接GND)、紅色PA0(按下接3.3V,WAKE UP按鈕)。ISP口為靠近電源開關的USB,也是USART1口。USART2口為PA3(Rx)、PA2(Tx)。IPD為高電平中斷(按鍵一邊接高電平),IPU為低電平中斷。
接下來例舉基本操作:
1、用GPIO點亮燈(GPIO輸出)
實現效果:PE6、PE5兩盞燈閃爍。#include "stm32f10x.h" void Delay(__IO u32 nCount) //簡單的延時函式 { for(; nCount != 0; nCount--); } void GPIO_Config(void) //配置LED用到的I/O口 { GPIO_InitTypeDef GPIO_InitStructure; //定義一個GPIO_InitTypeDef型別的結構體 RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOE, ENABLE); //開啟GPIOE的外設時鐘 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6; //選擇要控制的GPIOE引腳,這裡選了PE5、PE6 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //設定引腳模式為:通用推輓輸出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //設定引腳速率為:50MHz GPIO_Init(GPIOE, &GPIO_InitStructure); //呼叫庫函式,初始化GPIOE GPIO_SetBits(GPIOE, GPIO_Pin_5 | GPIO_Pin_6); //關閉所有LED燈 } int main(void) { GPIO_Config(); while(1) { GPIO_SetBits(GPIOE , GPIO_Pin_5); //PE5輸出高電平 GPIO_ResetBits(GPIOE,GPIO_Pin_6); //PE6輸出低電平 Delay(1000000);//1,000,000 六個零以上才有明顯閃爍 GPIO_SetBits(GPIOE , GPIO_Pin_6); //PE6輸出高電平 GPIO_ResetBits(GPIOE,GPIO_Pin_5); //PE5輸出低電平 Delay(1000000); } }
2、按鍵輸入(GPIO輸入)
實現效果:PE4按下控制PE5燈反轉,PA0按下控制PE6燈反轉(亮、滅)。#include "stm32f10x.h" #define KEY1 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4) //讀PE4(GND) #define KEY2 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) //讀PA0(VCC) void Delay(__IO u32 nCount) //簡單的延時函式 { for(; nCount != 0; nCount--); } void GPIO_Config(void) //配置LED用到的PE5、PE6 { GPIO_InitTypeDef GPIO_InitStructure; //定義一個GPIO_InitTypeDef型別的結構體 RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOE, ENABLE); //開啟GPIOE的外設時鐘 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6; //選擇要控制的GPIOE引腳,這裡選了PE5、PE6 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //設定引腳模式為:通用推輓輸出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //設定引腳速率為:50MHz GPIO_Init(GPIOE, &GPIO_InitStructure); //呼叫庫函式,初始化GPIOE GPIO_SetBits(GPIOE, GPIO_Pin_5 | GPIO_Pin_6); //關閉所有LED燈 } void Key_GPIO_Config(void)//按鍵配置,這裡用PE4、PE5輸入 { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);//開啟GPIOE的時鐘 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //設定引腳PE4 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉輸入模式(按鍵按下接GND用這個) GPIO_Init(GPIOE, &GPIO_InitStructure); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //下拉輸入模式(按鍵按下接VCC用這個) GPIO_Init(GPIOA, &GPIO_InitStructure); } unsigned char KEY1_Scan(void) { static char key_up0=0;//按鍵按鬆開標誌 if(KEY1==0) { Delay(10000);//延時去抖動 if(KEY1==0) { key_up0=1; } } if(KEY1==1&&key_up0==1) { key_up0=0; return 1; } return 0; } unsigned char KEY2_Scan(void) { static char key_up2=0;//按鍵按鬆開標誌 if(KEY2==1) { Delay(10000);//延時去抖動 if(KEY2==1) { key_up2=1; } } if(KEY2==0&&key_up2==1) { key_up2=0; return 1; } return 0; } unsigned char KEY_Scan(void) { unsigned char key_code; if(KEY1_Scan()==1) key_code=1; else if(KEY2_Scan()==1) key_code=2; else key_code=0; return key_code; } int main(void) { int value=0; GPIO_Config(); Key_GPIO_Config();//配置按鍵 while(1) { value=KEY_Scan();//獲取按鍵值 if(value==1) GPIO_WriteBit(GPIOE, GPIO_Pin_5, (BitAction)(1-(GPIO_ReadOutputDataBit(GPIOE, GPIO_Pin_5))));//LED燈PE5反轉 else if(value==2) GPIO_WriteBit(GPIOE, GPIO_Pin_6, (BitAction)(1-(GPIO_ReadOutputDataBit(GPIOE, GPIO_Pin_6))));//LED燈PE6反轉 } }
3、按鍵中斷(EXTI外部中斷操作)
#include "stm32f10x.h"
void Delay(__IO u32 nCount) //簡單的延時函式
{
for(; nCount != 0; nCount--);
}
void GPIO_Config(void) //配置LED用到的PE5、PE6
{
GPIO_InitTypeDef GPIO_InitStructure; //定義一個GPIO_InitTypeDef型別的結構體
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOE, ENABLE); //開啟GPIOE的外設時鐘
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6; //選擇要控制的GPIOE引腳,這裡選了PE5、PE6
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //設定引腳模式為:通用推輓輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //設定引腳速率為:50MHz
GPIO_Init(GPIOE, &GPIO_InitStructure); //呼叫庫函式,初始化GPIOE
GPIO_SetBits(GPIOE, GPIO_Pin_5 | GPIO_Pin_6); //關閉所有LED燈
}
static void NVIC_Configuration(void)//NVIC(中斷控制器)初始化配置,這裡配PE4、PA0
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//把NVIC中斷優先順序分組設為第1組
NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;//PE4對應EXTI線為EXTI4,填EXTI4_IRQn。(EXTI5~EXTI9使用同一中斷向量,則填EXTI9_5_IRQn)
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;//搶佔優先順序2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//響應優先順序1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);//向暫存器寫入引數
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//PA0對應EXTI線為EXTI0,填EXTI0_IRQn
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;//搶佔優先順序2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;//響應優先順序2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ(中斷請求)通道使能
NVIC_Init(&NVIC_InitStructure);//向暫存器寫入引數
}
void EXTI_Config(void)//配置PE4、PA0為線中斷口,並設定中斷優先順序
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,ENABLE);//配置中斷線(PA0)時鐘和第二功能AFIO時鐘,AFIO指GPIO口的複用功能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO,ENABLE);//配置中斷線(PE4)時鐘和第二功能AFIO時鐘
NVIC_Configuration();//配置NVIC中斷控制器
//以下配PE4
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //選定要配置為EXTI線的gpio口和設定其工作模式
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉輸入
GPIO_Init(GPIOE, &GPIO_InitStructure);
//以下配PA0
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//選PA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;//下拉輸入
GPIO_Init(GPIOA, &GPIO_InitStructure);
//以下配PE4中斷線、初始化配置
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource4); //EXTI中斷線(PE5)工作模式配置
EXTI_InitStructure.EXTI_Line = EXTI_Line4;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿中斷
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
//以下配PA0中斷線、初始化配置
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); //EXTI中斷線(PA0)工作模式配置
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿中斷
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
int main(void)
{
GPIO_Config();//LED(PE5、PE6)配置
EXTI_Config(); //外部中斷EXTI配置,這裡是選PE4、PA0
while(1)//等待中斷
{
}
}
在stm32f10x_it.c中加入名為EXTI0_IRQHandler(void)和EXTI4_IRQHandler(void)函式:
void EXTI0_IRQHandler(void)
{
Delay(10000);//延時消抖
if(EXTI_GetITStatus(EXTI_Line0) != RESET)//檢查指定的EXTI0線路觸發請求發生與否
{
GPIO_WriteBit(GPIOE, GPIO_Pin_6, (BitAction)(1-(GPIO_ReadOutputDataBit(GPIOE, GPIO_Pin_6))));//控制LED的PE6翻轉
}
EXTI_ClearITPendingBit(EXTI_Line0);//清除EXTI0線路掛起位
}
void EXTI4_IRQHandler(void)
{
Delay(10000);//延時消抖
if(EXTI_GetITStatus(EXTI_Line4) != RESET)//確保是否產生了EXTI4 Line中斷
{
GPIO_WriteBit(GPIOE, GPIO_Pin_5, (BitAction)(1-(GPIO_ReadOutputDataBit(GPIOE, GPIO_Pin_5))));//控制LED的PE5翻轉
}
EXTI_ClearITPendingBit(EXTI_Line4);//清除中斷標誌位
}
實現效果:PE4按下觸發中斷,控制PE5燈反轉;PA0按下觸發中斷,控制PE6燈反轉(亮、滅)。
4、串列埠列印(用USART1)
#include "stm32f10x.h"
#include "stdio.h"
void Delay(__IO u32 nCount) //簡單的延時函式
{
for(; nCount != 0; nCount--);
}
int fputc(int ch, FILE *f)//重定向c庫函式printf到USART1
{
USART_SendData(USART1, (unsigned char) ch);//將Printf內容發往串列埠
while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);
return (ch);
}
void USART1_Config(unsigned int bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);//配置串列埠1時鐘
//以下串列埠GPIO埠配置
//以下配置串列埠1的Tx(PA9)引數
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;//PA9為Tx
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//複用推輓輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//以下配置串列埠1的Rx(PA10)引數
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入模式,Rx不需配Speed
GPIO_Init(GPIOA, &GPIO_InitStructure);
//以下配置串列埠1的模式mode
USART_InitStructure.USART_BaudRate = bound;//USART1的波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//串列埠傳輸的字長
USART_InitStructure.USART_StopBits = USART_StopBits_1;//停止位1位
USART_InitStructure.USART_Parity = USART_Parity_No;//不設定奇偶校驗位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//不用硬體流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//雙線全雙工。Rx、Tx都開啟
USART_Init(USART1, &USART_InitStructure);//向暫存器寫入配置
USART_Cmd(USART1, ENABLE); //使能串列埠1
}
int main(void)
{
int a=0;
USART1_Config(115200);
while(1)
{
printf("\r\n Sandeepin poi %d \r\n",a);
a++;
Delay(2000000);
Delay(2000000);
}
}
實現效果:可在串列埠除錯助手中看到Sandeepin poi 0、Sandeepin poi 1……等資訊。
5、串列埠中斷(用USART1)
#include "stm32f10x.h"
#include "stdio.h"
void Delay(__IO u32 nCount) //簡單的延時函式
{
for(; nCount != 0; nCount--);
}
int fputc(int ch, FILE *f)//重定向c庫函式printf到USART1
{
USART_SendData(USART1, (unsigned char) ch);//將Printf內容發往串列埠
while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);
return (ch);
}
void USART1_Config(unsigned int bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);//配置串列埠1時鐘
//以下串列埠GPIO埠配置
//以下配置串列埠1的Tx(PA9)引數
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;//PA9為Tx
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//複用推輓輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//以下配置串列埠1的Rx(PA10)引數
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入模式,Rx不需配Speed
GPIO_Init(GPIOA, &GPIO_InitStructure);
//以下配置串列埠1的模式mode
USART_InitStructure.USART_BaudRate = bound;//USART1的波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//串列埠傳輸的字長
USART_InitStructure.USART_StopBits = USART_StopBits_1;//停止位1位
USART_InitStructure.USART_Parity = USART_Parity_No;//不設定奇偶校驗位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//不用硬體流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//雙線全雙工。Rx、Tx都開啟
USART_Init(USART1, &USART_InitStructure);//向暫存器寫入配置
USART_Cmd(USART1, ENABLE); //使能串列埠1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//開啟中斷
}
void NVIC_Configuration(void)//NVIC(中斷控制器)初始化配置,這裡配USART1
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//把NVIC中斷優先順序分組設為第0組
//以下使能串列埠1中斷
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//搶佔優先順序1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//響應優先順序0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ(中斷請求)通道使能
NVIC_Init(&NVIC_InitStructure);//根據NVIC_InitStruct中指定的引數初始化外設NVIC暫存器USART1
}
int main(void)
{
USART1_Config(115200);
NVIC_Configuration();
while(1)
{
Delay(2000000);
}
}
在stm32f10x_it.c中加入名為USART1_IRQHandler(void)函式:
USART1_IRQHandler(void)
{
unsigned char code;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
code=USART_ReceiveData(USART1);
printf("%c",code);//將接受到的資料直接返回列印
}
}
實現效果:在串列埠除錯助手中輸入一系列字元,STM32接收到後直接將收到字元原樣打印出來。
6、定時器(用TIM3)
#include "stm32f10x.h"
void Delay(__IO u32 nCount) //簡單的延時函式
{
for(; nCount != 0; nCount--);
}
void LED_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_5;//PE5、PE6
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//通用推輓輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_SetBits(GPIOE,GPIO_Pin_5);//PE5初始輸出高
GPIO_ResetBits(GPIOE,GPIO_Pin_6);//PE6初始輸出低
}
void TIME_NVIC_Configuration(void)//TIM3中斷優先順序配置
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設定NVIC中斷分組2
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//搶佔優先順序0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//響應優先順序3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure);//初始化外設
}
void TIME_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //定時器TIM3時鐘使能
TIM_TimeBaseStructure.TIM_Period = 5000; //設定在下一個更新事件裝入活動的自動重灌載暫存器週期的值,計數到5000為500ms
TIM_TimeBaseStructure.TIM_Prescaler =(7200-1);//設定用來作為TIMx時鐘頻率除數的預分頻值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設定時鐘分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計數模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根據TIM_TimeBaseInitStruct中指定的引數初始化TIMx的時間基數單位
TIM_ITConfig(TIM3,TIM_IT_Update|TIM_IT_Trigger,ENABLE);//使能、失能指定的TIM中斷
TIM_Cmd(TIM3, ENABLE);//使能TIMx外設
}
int main(void)
{
LED_GPIO_Config();//開LED的GPIO
TIME_NVIC_Configuration();//TIM3定時器中斷配置
TIME_Configuration();//TIM3定時器配置
while(1)
{
}
}
在stm32f10x_it.c中加入名為TIM3_IRQHandler(void)函式:
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //檢查指定的TIM中斷髮生與否
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIMx的中斷待處理位
GPIO_WriteBit(GPIOE, GPIO_Pin_5, (BitAction)(1-(GPIO_ReadOutputDataBit(GPIOE, GPIO_Pin_5))));//控制LED燈PE5翻轉
GPIO_WriteBit(GPIOE, GPIO_Pin_6, (BitAction)(1-(GPIO_ReadOutputDataBit(GPIOE, GPIO_Pin_6))));//控制LED燈PE6翻轉
}
}
實現效果:每隔500ms後LED燈PE5、PE6翻轉。
7、SysTick(系統滴答定時器)
#include "stm32f10x.h"
u32 TimingDelay;
void LED_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_5;//PE5、PE6
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//通用推輓輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_SetBits(GPIOE,GPIO_Pin_5);//PE5初始輸出高
GPIO_ResetBits(GPIOE,GPIO_Pin_6);//PE6初始輸出低
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設定中斷組為2
NVIC_InitStructure.NVIC_IRQChannel = SysTick_IRQn;//中斷線
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //搶佔優先順序為2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//響應優先順序為0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //允許SysTick_IRQn中斷
NVIC_Init(&NVIC_InitStructure);
}
void SysTick_Init(void)
{
/* SystemFrequency / 1000 1ms中斷一次
* SystemFrequency / 100000 10us中斷一次,分析:ticks=SystemFrequency / 100000=720,T=ticks/f,f=72000000,T=720/72=10us
* SystemFrequency / 1000000 1us中斷一次*/
while(SysTick_Config( SystemCoreClock / 1000));//Systick 配置延時n*ms。輸入的引數為兩個中斷之間的脈衝數。
}
void Delay(u32 nTime)//用Systick延時
{
TimingDelay = nTime;
while(TimingDelay != 0);
}
int main(void)
{
SysTick_Init();
LED_GPIO_Config();
NVIC_Configuration();//中斷配置
while(1)
{
GPIO_SetBits(GPIOE,GPIO_Pin_6);
GPIO_ResetBits(GPIOE,GPIO_Pin_5);
Delay(200);//Systick 配置延時200*ms
GPIO_SetBits(GPIOE,GPIO_Pin_5);
GPIO_ResetBits(GPIOE,GPIO_Pin_6);
Delay(200);//Systick 配置延時200*ms
}
}
在stm32f10x_it.c中找SysTick_Handler(void)函式,填入如下內容:
extern u32 TimingDelay;
void SysTick_Handler(void)
{
if (TimingDelay != 0x00)
{
TimingDelay--;
}
}
實現效果:每隔200ms後LED燈PE5、PE6翻轉。