下面是軟件定時(shí)器部分.C 源碼:#include "Time_Triggered.h"
#include "ILI9341.h"
#include "key.h"
#include "bsp_timer.h"
#include "stm32f10x_tim.h"
#include "stm32f10x_rcc.h"
#include "led.h"
/*
定義用于硬件定時(shí)器的TIM, 可以使 TIM2 - TIM5
TIM3 和TIM4 是16位
TIM2 和TIM5 是32位
*/
#define TIM_HARD TIM5
#define TIM_HARD_IRQn TIM5_IRQn
#define TIM_HARD_RCC RCC_APB1Periph_TIM5
/* 這2個(gè)全局變量轉(zhuǎn)用于 bsp_DelayMS() 函數(shù) */
static volatile uint32_t s_uiDelayCount = 0;
static volatile uint8_t s_ucTimeOutFlag = 0;
/* 定于軟件定時(shí)器結(jié)構(gòu)體變量 */
static SOFT_TMR s_tTmr[TMR_COUNT];
/*
全局運(yùn)行時(shí)間,單位1ms
最長(zhǎng)可以表示 24.85天,如果你的產(chǎn)品連續(xù)運(yùn)行時(shí)間超過(guò)這個(gè)數(shù),則必須考慮溢出問(wèn)題
*/
__IO int32_t g_iRunTime = 0;
static void bsp_SoftTimerDec(SOFT_TMR *_tmr);
/* 保存 TIM定時(shí)中斷到后執(zhí)行的回調(diào)函數(shù)指針 */
static void (*s_TIM_CallBack1)(void);
static void (*s_TIM_CallBack2)(void);
static void (*s_TIM_CallBack3)(void);
static void (*s_TIM_CallBack4)(void);
/*
*********************************************************************************************************
* 函 數(shù) 名: bsp_InitTimer
* 功能說(shuō)明: 配置systick中斷,并初始化軟件定時(shí)器變量
* 形 參: 無(wú)
* 返 回 值: 無(wú)
*********************************************************************************************************
*/
void bsp_InitTimer(void)
{
uint8_t i;
/* 清零所有的軟件定時(shí)器 */
for (i = 0; i < TMR_COUNT; i++)
{
s_tTmr[i].Count = 0;
s_tTmr[i].PreLoad = 0;
s_tTmr[i].Flag = 0;
s_tTmr[i].Mode = TMR_ONCE_MODE; /* 缺省是1次性工作模式 */
}
/*
配置systic中斷周期為1ms,并啟動(dòng)systick中斷。
SystemCoreClock 是固件中定義的系統(tǒng)內(nèi)核時(shí)鐘,對(duì)于STM32F4XX,一般為 168MHz
SysTick_Config() 函數(shù)的形參表示內(nèi)核時(shí)鐘多少個(gè)周期后觸發(fā)一次Systick定時(shí)中斷.
-- SystemCoreClock / 1000 表示定時(shí)頻率為 1000Hz, 也就是定時(shí)周期為 1ms
-- SystemCoreClock / 500 表示定時(shí)頻率為 500Hz, 也就是定時(shí)周期為 2ms
-- SystemCoreClock / 2000 表示定時(shí)頻率為 2000Hz, 也就是定時(shí)周期為 500us
對(duì)于常規(guī)的應(yīng)用,我們一般取定時(shí)周期1ms。對(duì)于低速CPU或者低功耗應(yīng)用,可以設(shè)置定時(shí)周期為 10ms
*/
SysTick_Config(SystemCoreClock / 1000);
bsp_InitHardTimer(); /* 開(kāi)啟硬件定時(shí)中斷 */
}
/*
*********************************************************************************************************
* 函 數(shù) 名: bsp_RunPer10ms
* 功能說(shuō)明: 該函數(shù)每隔10ms被Systick中斷調(diào)用1次。詳見(jiàn) bsp_timer.c的定時(shí)中斷服務(wù)程序。一些需要周期性處理
* 的事務(wù)可以放在此函數(shù)。比如:按鍵掃描、蜂鳴器鳴叫控制等。
* 形 參:無(wú)
* 返 回 值: 無(wú)
*********************************************************************************************************
*/
//void LedTest()
//{
// LED0=0;
// LED1=0;
// bsp_DelayMS(50);
// LED0=1;
// LED1=1;
//}
void bsp_RunPer30ms(void)
{
if(key0()==0)
{
LCD_ShowString(16 ,66,240,240,24,"hello!");
}
if(key1()==1)
{
LCD_Clear(WHITE);
}
// bsp_DelayMS(50);
// GUI_Clear();
}
/*
*********************************************************************************************************
* 函 數(shù) 名: bsp_RunPer1ms
* 功能說(shuō)明: 該函數(shù)每隔1ms被Systick中斷調(diào)用1次。詳見(jiàn) bsp_timer.c的定時(shí)中斷服務(wù)程序。一些需要周期性處理的
* 事務(wù)可以放在此函數(shù)。比如:觸摸坐標(biāo)掃描。
* 形 參:無(wú)
* 返 回 值: 無(wú)
*********************************************************************************************************
*/
void bsp_RunPer1ms(void)
{
}
/*
*********************************************************************************************************
* 函 數(shù) 名: SysTick_ISR
* 功能說(shuō)明: SysTick中斷服務(wù)程序,每隔1ms進(jìn)入1次
* 形 參: 無(wú)
* 返 回 值: 無(wú)
*********************************************************************************************************
*/
//extern void bsp_RunPer1ms(void);
//extern void bsp_RunPer10ms(void);
void SysTick_ISR(void)
{
static uint8_t s_count = 0;
uint8_t i;
/* 每隔1ms進(jìn)來(lái)1次 (僅用于 bsp_DelayMS) */
if (s_uiDelayCount > 0)
{
if (--s_uiDelayCount == 0)
{
s_ucTimeOutFlag = 1;
}
}
/* 每隔1ms,對(duì)軟件定時(shí)器的計(jì)數(shù)器進(jìn)行減一操作 */
for (i = 0; i < TMR_COUNT; i++)
{
bsp_SoftTimerDec(&s_tTmr[i]);
}
hSCH_Update();
/* 全局運(yùn)行時(shí)間每1ms增1 */
g_iRunTime++;
// if (g_iRunTime == 0x7FFFFFFF) /* 這個(gè)變量是 int32_t 類(lèi)型,最大數(shù)為 0x7FFFFFFF */
// {
// g_iRunTime = 0;
// }
// bsp_RunPer1ms(); /* 每隔1ms調(diào)用一次此函數(shù),此函數(shù)在 bsp.c */
// if (++s_count >= 30)
// {
// s_count = 0;
// bsp_RunPer30ms(); /* 每隔10ms調(diào)用一次此函數(shù),此函數(shù)在 bsp.c */
// }
}
/*
*********************************************************************************************************
* 函 數(shù) 名: bsp_SoftTimerDec
* 功能說(shuō)明: 每隔1ms對(duì)所有定時(shí)器變量減1。必須被SysTick_ISR周期性調(diào)用。
* 形 參: _tmr : 定時(shí)器變量指針
* 返 回 值: 無(wú)
*********************************************************************************************************
*/
static void bsp_SoftTimerDec(SOFT_TMR *_tmr)
{
if (_tmr->Count > 0)
{
/* 如果定時(shí)器變量減到1則設(shè)置定時(shí)器到達(dá)標(biāo)志 */
if (--_tmr->Count == 0)
{
_tmr->Flag = 1;
/* 如果是自動(dòng)模式,則自動(dòng)重裝計(jì)數(shù)器 */
if(_tmr->Mode == TMR_AUTO_MODE)
{
_tmr->Count = _tmr->PreLoad;
}
}
}
}
/*
*********************************************************************************************************
* 函 數(shù) 名: bsp_DelayMS
* 功能說(shuō)明: ms級(jí)延遲,延遲精度為正負(fù)1ms
* 形 參: n : 延遲長(zhǎng)度,單位1 ms。 n 應(yīng)大于2
* 返 回 值: 無(wú)
*********************************************************************************************************
*/
void bsp_DelayMS(uint32_t n)
{
if (n == 0)
{
return;
}
else if (n == 1)
{
n = 2;
}
DISABLE_INT(); /* 關(guān)中斷 */
s_uiDelayCount = n;
s_ucTimeOutFlag = 0;
ENABLE_INT(); /* 開(kāi)中斷 */
while (1)
{
//bsp_Idle(); /* CPU空閑執(zhí)行的操作, 見(jiàn) bsp.c 和 bsp.h 文件 */
/*
等待延遲時(shí)間到
注意:編譯器認(rèn)為 s_ucTimeOutFlag = 0,所以可能優(yōu)化錯(cuò)誤,因此 s_ucTimeOutFlag 變量必須申明為 volatile
*/
if (s_ucTimeOutFlag == 1)
{
break;
}
}
}
/*
*********************************************************************************************************
* 函 數(shù) 名: bsp_DelayUS
* 功能說(shuō)明: us級(jí)延遲。 必須在systick定時(shí)器啟動(dòng)后才能調(diào)用此函數(shù)。
* 形 參: n : 延遲長(zhǎng)度,單位1 us
* 返 回 值: 無(wú)
*********************************************************************************************************
*/
void bsp_DelayUS(uint32_t n)
{
uint32_t ticks;
uint32_t told;
uint32_t tnow;
uint32_t tcnt = 0;
uint32_t reload;
reload = SysTick->LOAD;
ticks = n * (SystemCoreClock / 1000000); /* 需要的節(jié)拍數(shù) */
tcnt = 0;
told = SysTick->VAL; /* 剛進(jìn)入時(shí)的計(jì)數(shù)器值 */
while (1)
{
tnow = SysTick->VAL;
if (tnow != told)
{
/* SYSTICK是一個(gè)遞減的計(jì)數(shù)器 */
if (tnow < told)
{
tcnt += told - tnow;
}
/* 重新裝載遞減 */
else
{
tcnt += reload - tnow + told;
}
told = tnow;
/* 時(shí)間超過(guò)/等于要延遲的時(shí)間,則退出 */
if (tcnt >= ticks)
{
break;
}
}
}
}
/*
*********************************************************************************************************
* 函 數(shù) 名: bsp_StartTimer
* 功能說(shuō)明: 啟動(dòng)一個(gè)定時(shí)器,并設(shè)置定時(shí)周期。
* 形 參: _id : 定時(shí)器ID,值域【0,TMR_COUNT-1】。用戶必須自行維護(hù)定時(shí)器ID,以避免定時(shí)器ID沖突。
* _period : 定時(shí)周期,單位1ms
* 返 回 值: 無(wú)
*********************************************************************************************************
*/
void bsp_StartTimer(uint8_t _id, uint32_t _period)
{
if (_id >= TMR_COUNT)
{
/* 打印出錯(cuò)的源代碼文件名、函數(shù)名稱 */
BSP_Printf("Error: file %s, function %s()\r\n", __FILE__, __FUNCTION__);
while(1); /* 參數(shù)異常,死機(jī)等待看門(mén)狗復(fù)位 */
}
DISABLE_INT(); /* 關(guān)中斷 */
s_tTmr[_id].Count = _period; /* 實(shí)時(shí)計(jì)數(shù)器初值 */
s_tTmr[_id].PreLoad = _period; /* 計(jì)數(shù)器自動(dòng)重裝值,僅自動(dòng)模式起作用 */
s_tTmr[_id].Flag = 0; /* 定時(shí)時(shí)間到標(biāo)志 */
s_tTmr[_id].Mode = TMR_ONCE_MODE; /* 1次性工作模式 */
ENABLE_INT(); /* 開(kāi)中斷 */
}
/*
*********************************************************************************************************
* 函 數(shù) 名: bsp_StartAutoTimer
* 功能說(shuō)明: 啟動(dòng)一個(gè)自動(dòng)定時(shí)器,并設(shè)置定時(shí)周期。
* 形 參: _id : 定時(shí)器ID,值域【0,TMR_COUNT-1】。用戶必須自行維護(hù)定時(shí)器ID,以避免定時(shí)器ID沖突。
* _period : 定時(shí)周期,單位10ms
* 返 回 值: 無(wú)
*********************************************************************************************************
*/
void bsp_StartAutoTimer(uint8_t _id, uint32_t _period)
{
if (_id >= TMR_COUNT)
{
/* 打印出錯(cuò)的源代碼文件名、函數(shù)名稱 */
BSP_Printf("Error: file %s, function %s()\r\n", __FILE__, __FUNCTION__);
while(1); /* 參數(shù)異常,死機(jī)等待看門(mén)狗復(fù)位 */
}
DISABLE_INT(); /* 關(guān)中斷 */
s_tTmr[_id].Count = _period; /* 實(shí)時(shí)計(jì)數(shù)器初值 */
s_tTmr[_id].PreLoad = _period; /* 計(jì)數(shù)器自動(dòng)重裝值,僅自動(dòng)模式起作用 */
s_tTmr[_id].Flag = 0; /* 定時(shí)時(shí)間到標(biāo)志 */
s_tTmr[_id].Mode = TMR_AUTO_MODE; /* 自動(dòng)工作模式 */
ENABLE_INT(); /* 開(kāi)中斷 */
}
/*
*********************************************************************************************************
* 函 數(shù) 名: bsp_StopTimer
* 功能說(shuō)明: 停止一個(gè)定時(shí)器
* 形 參: _id : 定時(shí)器ID,值域【0,TMR_COUNT-1】。用戶必須自行維護(hù)定時(shí)器ID,以避免定時(shí)器ID沖突。
* 返 回 值: 無(wú)
*********************************************************************************************************
*/
void bsp_StopTimer(uint8_t _id)
{
if (_id >= TMR_COUNT)
{
/* 打印出錯(cuò)的源代碼文件名、函數(shù)名稱 */
BSP_Printf("Error: file %s, function %s()\r\n", __FILE__, __FUNCTION__);
while(1); /* 參數(shù)異常,死機(jī)等待看門(mén)狗復(fù)位 */
}
DISABLE_INT(); /* 關(guān)中斷 */
s_tTmr[_id].Count = 0; /* 實(shí)時(shí)計(jì)數(shù)器初值 */
s_tTmr[_id].Flag = 0; /* 定時(shí)時(shí)間到標(biāo)志 */
s_tTmr[_id].Mode = TMR_ONCE_MODE; /* 自動(dòng)工作模式 */
ENABLE_INT(); /* 開(kāi)中斷 */
}
/*
*********************************************************************************************************
* 函 數(shù) 名: bsp_CheckTimer
* 功能說(shuō)明: 檢測(cè)定時(shí)器是否超時(shí)
* 形 參: _id : 定時(shí)器ID,值域【0,TMR_COUNT-1】。用戶必須自行維護(hù)定時(shí)器ID,以避免定時(shí)器ID沖突。
* _period : 定時(shí)周期,單位1ms
* 返 回 值: 返回 0 表示定時(shí)未到, 1表示定時(shí)到
*********************************************************************************************************
*/
uint8_t bsp_CheckTimer(uint8_t _id)
{
if (_id >= TMR_COUNT)
{
return 0;
}
if (s_tTmr[_id].Flag == 1)
{
s_tTmr[_id].Flag = 0;
return 1;
}
else
{
return 0;
}
}
/*
*********************************************************************************************************
* 函 數(shù) 名: bsp_GetRunTime
* 功能說(shuō)明: 獲取CPU運(yùn)行時(shí)間,單位1ms。最長(zhǎng)可以表示 24.85天,如果你的產(chǎn)品連續(xù)運(yùn)行時(shí)間超過(guò)這個(gè)數(shù),則必須考慮溢出問(wèn)題
* 形 參: 無(wú)
* 返 回 值: CPU運(yùn)行時(shí)間,單位1ms
*********************************************************************************************************
*/
int32_t bsp_GetRunTime(void)
{
int32_t runtime;
DISABLE_INT(); /* 關(guān)中斷 */
runtime = g_iRunTime; /* 這個(gè)變量在Systick中斷中被改寫(xiě),因此需要關(guān)中斷進(jìn)行保護(hù) */
ENABLE_INT(); /* 開(kāi)中斷 */
return runtime;
}
/*
*********************************************************************************************************
* 函 數(shù) 名: SysTick_Handler
* 功能說(shuō)明: 系統(tǒng)嘀嗒定時(shí)器中斷服務(wù)程序。啟動(dòng)文件中引用了該函數(shù)。
* 形 參: 無(wú)
* 返 回 值: 無(wú)
*********************************************************************************************************
*/
void SysTick_Handler(void)
{
SysTick_ISR();
}
/*
*********************************************************************************************************
* 函 數(shù) 名: bsp_InitHardTimer
* 功能說(shuō)明: 配置 TIM4,用于us級(jí)別硬件定時(shí)。TIM4將自由運(yùn)行,永不停止.
* TIM4可以用TIM2 - TIM5 之間的TIM, 這些TIM有4個(gè)通道, 掛在 APB1 上,輸入時(shí)鐘=SystemCoreClock / 2
* 形 參: 無(wú)
* 返 回 值: 無(wú)
*********************************************************************************************************
*/
void bsp_InitHardTimer(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
uint16_t usPeriod;
uint16_t usPrescaler;
uint32_t uiTIMxCLK;
/* 使能TIM時(shí)鐘 */
RCC_APB1PeriphClockCmd(TIM_HARD_RCC, ENABLE);
/*-----------------------------------------------------------------------
system_stm32f4xx.c 文件中 void SetSysClock(void) 函數(shù)對(duì)時(shí)鐘的配置如下:
HCLK = SYSCLK / 1 (AHB1Periph)
PCLK2 = HCLK / 2 (APB2Periph)
PCLK1 = HCLK / 4 (APB1Periph)
因?yàn)锳PB1 prescaler != 1, 所以 APB1上的TIMxCLK = PCLK1 x 2 = SystemCoreClock / 2;
因?yàn)锳PB2 prescaler != 1, 所以 APB2上的TIMxCLK = PCLK2 x 2 = SystemCoreClock;
APB1 定時(shí)器有 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM7, TIM12, TIM13,TIM14
APB2 定時(shí)器有 TIM1, TIM8 ,TIM9, TIM10, TIM11
----------------------------------------------------------------------- */
uiTIMxCLK = SystemCoreClock / 2;
usPrescaler = uiTIMxCLK / 1000000 ; /* 分頻到周期 1us */
usPeriod = 0xFFFF;
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = usPeriod;
TIM_TimeBaseStructure.TIM_Prescaler = usPrescaler;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM_HARD, &TIM_TimeBaseStructure);
//TIM_ARRPreloadConfig(TIMx, ENABLE);
/* TIMx enable counter */
TIM_Cmd(TIM_HARD, ENABLE);
/* 配置TIM定時(shí)中斷 (Update) */
{
NVIC_InitTypeDef NVIC_InitStructure; /* 中斷結(jié)構(gòu)體在 misc.h 中定義 */
NVIC_InitStructure.NVIC_IRQChannel = TIM_HARD_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; /* 比串口優(yōu)先級(jí)低 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
}
/*
*********************************************************************************************************
* 函 數(shù) 名: bsp_StartHardTimer
* 功能說(shuō)明: 使用TIM2-5做單次定時(shí)器使用, 定時(shí)時(shí)間到后執(zhí)行回調(diào)函數(shù)?梢酝瑫r(shí)啟動(dòng)4個(gè)定時(shí)器,互不干擾。
* 定時(shí)精度正負(fù)10us (主要耗費(fèi)在調(diào)用本函數(shù)的執(zhí)行時(shí)間,函數(shù)內(nèi)部進(jìn)行了補(bǔ)償減小誤差)
* TIM2和TIM5 是32位定時(shí)器。定時(shí)范圍很大
* TIM3和TIM4 是16位定時(shí)器。
* 形 參: _CC : 捕獲通道幾,1,2,3, 4
* _uiTimeOut : 超時(shí)時(shí)間, 單位 1us. 對(duì)于16位定時(shí)器,最大 65.5ms; 對(duì)于32位定時(shí)器,最大 4294秒
* _pCallBack : 定時(shí)時(shí)間到后,被執(zhí)行的函數(shù)
* 返 回 值: 無(wú)
*********************************************************************************************************
*/
void bsp_StartHardTimer(uint8_t _CC, uint32_t _uiTimeOut, void * _pCallBack)
{
uint32_t cnt_now;
uint32_t cnt_tar;
/*
執(zhí)行下面這個(gè)語(yǔ)句,時(shí)長(zhǎng) = 18us (通過(guò)邏輯分析儀測(cè)量IO翻轉(zhuǎn))
bsp_StartTimer2(3, 500, (void *)test1);
*/
if (_uiTimeOut < 5)
{
;
}
else
{
_uiTimeOut -= 5;
}
cnt_now = TIM_GetCounter(TIM_HARD); /* 讀取當(dāng)前的計(jì)數(shù)器值 */
cnt_tar = cnt_now + _uiTimeOut; /* 計(jì)算捕獲的計(jì)數(shù)器值 */
if (_CC == 1)
{
s_TIM_CallBack1 = (void (*)(void))_pCallBack;
TIM_SetCompare1(TIM_HARD, cnt_tar); /* 設(shè)置捕獲比較計(jì)數(shù)器CC1 */
TIM_ClearITPendingBit(TIM_HARD, TIM_IT_CC1);
TIM_ITConfig(TIM_HARD, TIM_IT_CC1, ENABLE); /* 使能CC1中斷 */
}
else if (_CC == 2)
{
s_TIM_CallBack2 = (void (*)(void))_pCallBack;
TIM_SetCompare2(TIM_HARD, cnt_tar); /* 設(shè)置捕獲比較計(jì)數(shù)器CC2 */
TIM_ClearITPendingBit(TIM_HARD, TIM_IT_CC2);
TIM_ITConfig(TIM_HARD, TIM_IT_CC2, ENABLE); /* 使能CC2中斷 */
}
else if (_CC == 3)
{
s_TIM_CallBack3 = (void (*)(void))_pCallBack;
TIM_SetCompare3(TIM_HARD, cnt_tar); /* 設(shè)置捕獲比較計(jì)數(shù)器CC3 */
TIM_ClearITPendingBit(TIM_HARD, TIM_IT_CC3);
TIM_ITConfig(TIM_HARD, TIM_IT_CC3, ENABLE); /* 使能CC3中斷 */
}
else if (_CC == 4)
{
s_TIM_CallBack4 = (void (*)(void))_pCallBack;
TIM_SetCompare4(TIM_HARD, cnt_tar); /* 設(shè)置捕獲比較計(jì)數(shù)器CC4 */
TIM_ClearITPendingBit(TIM_HARD, TIM_IT_CC4);
TIM_ITConfig(TIM_HARD, TIM_IT_CC4, ENABLE); /* 使能CC4中斷 */
}
else
{
return;
}
}
/*
*********************************************************************************************************
* 函 數(shù) 名: TIMx_IRQHandler
* 功能說(shuō)明: TIM 中斷服務(wù)程序
* 形 參:無(wú)
* 返 回 值: 無(wú)
*********************************************************************************************************
*/
//void TIM2_IRQHandler(void)
//void TIM3_IRQHandler(void)
//void TIM4_IRQHandler(void)
void TIM5_IRQHandler(void)
{
if (TIM_GetITStatus(TIM_HARD, TIM_IT_CC1))
{
TIM_ClearITPendingBit(TIM_HARD, TIM_IT_CC1);
TIM_ITConfig(TIM_HARD, TIM_IT_CC1, DISABLE); /* 禁能CC1中斷 */
/* 先關(guān)閉中斷,再執(zhí)行回調(diào)函數(shù)。因?yàn)榛卣{(diào)函數(shù)可能需要重啟定時(shí)器 */
s_TIM_CallBack1();
}
if (TIM_GetITStatus(TIM_HARD, TIM_IT_CC2))
{
TIM_ClearITPendingBit(TIM_HARD, TIM_IT_CC2);
TIM_ITConfig(TIM_HARD, TIM_IT_CC2, DISABLE); /* 禁能CC2中斷 */
/* 先關(guān)閉中斷,再執(zhí)行回調(diào)函數(shù)。因?yàn)榛卣{(diào)函數(shù)可能需要重啟定時(shí)器 */
s_TIM_CallBack2();
}
if (TIM_GetITStatus(TIM_HARD, TIM_IT_CC3))
{
TIM_ClearITPendingBit(TIM_HARD, TIM_IT_CC3);
TIM_ITConfig(TIM_HARD, TIM_IT_CC3, DISABLE); /* 禁能CC3中斷 */
/* 先關(guān)閉中斷,再執(zhí)行回調(diào)函數(shù)。因?yàn)榛卣{(diào)函數(shù)可能需要重啟定時(shí)器 */
s_TIM_CallBack3();
}
if (TIM_GetITStatus(TIM_HARD, TIM_IT_CC4))
{
TIM_ClearITPendingBit(TIM_HARD, TIM_IT_CC4);
TIM_ITConfig(TIM_HARD, TIM_IT_CC4, DISABLE); /* 禁能CC4中斷 */
/* 先關(guān)閉中斷,再執(zhí)行回調(diào)函數(shù)。因?yàn)榛卣{(diào)函數(shù)可能需要重啟定時(shí)器 */
s_TIM_CallBack4();
}
}
//void bsp_Init(void)
//{
// /*
// 由于ST固件庫(kù)的啟動(dòng)文件已經(jīng)執(zhí)行了CPU系統(tǒng)時(shí)鐘的初始化,所以不必再次重復(fù)配置系統(tǒng)時(shí)鐘。
// 啟動(dòng)文件配置了CPU主時(shí)鐘頻率、內(nèi)部Flash訪問(wèn)速度和可選的外部SRAM FSMC初始化。
// 系統(tǒng)時(shí)鐘缺省配置為168MHz,如果需要更改,可以修改 system_stm32f4xx.c 文件
// */
// //bsp_InitUart(); /* 初始化串口 */
//// bsp_InitTimer(); /* 初始化系統(tǒng)滴答定時(shí)器 */
// /* 針對(duì)不同的應(yīng)用程序,添加需要的底層驅(qū)動(dòng)模塊初始化函數(shù) */
// //bsp_InitLed(); /* 初始LED指示燈端口 */
//}
/*
*********************************************************************************************************
* 函 數(shù) 名: bsp_Idle
* 功能說(shuō)明: 空閑時(shí)執(zhí)行的函數(shù)。一般主程序在for和while循環(huán)程序體中需要插入 CPU_IDLE() 宏來(lái)調(diào)用本函數(shù)。
* 本函數(shù)缺省為空操作。用戶可以添加喂狗、設(shè)置CPU進(jìn)入休眠模式的功能。
* 形 參:無(wú)
* 返 回 值: 無(wú)
*********************************************************************************************************
*/
//void bsp_Idle(void)
//{
// /* --- 喂狗 */
// /* --- 讓CPU進(jìn)入休眠,由Systick定時(shí)中斷喚醒或者其他中斷喚醒 */
// /* 對(duì)于 emWin 圖形庫(kù),可以插入圖形庫(kù)需要的輪詢函數(shù) */
// //GUI_Exec();
// /* 對(duì)于 uIP 協(xié)議實(shí)現(xiàn),可以插入uip輪詢函數(shù) */
//}
軟件定時(shí)器相應(yīng)的.H 頭文件:
#ifndef __BSP_TIMER_H
#define __BSP_TIMER_H
#include "bsp_timer.h"
/* 開(kāi)關(guān)全局中斷的宏 */
#define ENABLE_INT() __set_PRIMASK(0) /* 使能全局中斷 */
#define DISABLE_INT() __set_PRIMASK(1) /* 禁止全局中斷 */
/* 這個(gè)宏僅用于調(diào)試階段排錯(cuò) */
#define BSP_Printf printf
//#define BSP_Printf(...)
#include "stm32f10x.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
/*
在此定義若干個(gè)軟件定時(shí)器全局變量
注意,必須增加__IO 即 volatile,因?yàn)檫@個(gè)變量在中斷和主程序中同時(shí)被訪問(wèn),有可能造成編譯器錯(cuò)誤優(yōu)化。
*/
#define TMR_COUNT 4 /* 軟件定時(shí)器的個(gè)數(shù) (定時(shí)器ID范圍 0 - 3) */
/* 定時(shí)器結(jié)構(gòu)體,成員變量必須是 volatile, 否則C編譯器優(yōu)化時(shí)可能有問(wèn)題 */
typedef enum
{
TMR_ONCE_MODE = 0, /* 一次工作模式 */
TMR_AUTO_MODE = 1 /* 自動(dòng)定時(shí)工作模式 */
}TMR_MODE_E;
/* 定時(shí)器結(jié)構(gòu)體,成員變量必須是 volatile, 否則C編譯器優(yōu)化時(shí)可能有問(wèn)題 */
typedef struct
{
volatile u8 Mode; /* 計(jì)數(shù)器模式,1次性 */
volatile u8 Flag; /* 定時(shí)到達(dá)標(biāo)志 */
volatile u32 Count; /* 計(jì)數(shù)器 */
volatile u32 PreLoad; /* 計(jì)數(shù)器預(yù)裝值 */
}SOFT_TMR;
/* 提供給其他C文件調(diào)用的函數(shù) */
void bsp_InitTimer(void);
void bsp_DelayMS(uint32_t n);
void bsp_DelayUS(uint32_t n);
void bsp_StartTimer(uint8_t _id, uint32_t _period);
void bsp_StartAutoTimer(uint8_t _id, uint32_t _period);
void bsp_StopTimer(uint8_t _id);
uint8_t bsp_CheckTimer(uint8_t _id);
int32_t bsp_GetRunTime(void);
void bsp_InitHardTimer(void);
void bsp_StartHardTimer(uint8_t _CC, uint32_t _uiTimeOut, void * _pCallBack);
#endif
/*
*/
/* 通過(guò)取消注釋或者添加注釋的方式控制是否包含底層驅(qū)動(dòng)模塊 */
/***************************** (END OF FILE) *********************************/
最后感謝
安富萊電子提供的資源。
------------------------------GKXW-----2015年12月5日21:35:25----------------------------------------------------