1.呼吸燈原理分析:模擬人體呼吸,吸氣和呼氣各占1.5S,人眼的圖像滯留時(shí)間0.04s(1/24幀畫面),按最快0.04s算,就是40ms。亮0.02S,滅0.02s,人眼看到的應(yīng)該是一直亮(可以實(shí)驗(yàn))。
2.呼吸燈程序設(shè)計(jì):就是改變這40ms中,亮和滅所占的百分比(40ms相對(duì)不柔和,20ms效果柔和)。
亮的百分比多,人眼看到的就亮,反之就是暗(實(shí)驗(yàn),為了提高呼吸燈的柔和效果,采用設(shè)置20ms一個(gè)周期,20ms內(nèi)調(diào)整亮和滅的比例)
因此程序設(shè)計(jì):1.5S需要1500/20=75個(gè)周期,75個(gè)周期中,亮度百分比有0%增長到100%,因此每個(gè)周期增長時(shí)間為20ms/75=266us(點(diǎn)亮)。熄滅的原理,正好相反,熄滅時(shí)間增長。程序中需要兩個(gè)循環(huán),一個(gè)用來點(diǎn)亮一個(gè)用來熄滅。3.STM32程序?qū)崿F(xiàn)代碼 程序要靈活設(shè)計(jì),能夠調(diào)整呼吸時(shí)間的長短,1.5s這個(gè)參數(shù)。可以調(diào)整柔和度,可以調(diào)整40ms這個(gè)周期參數(shù),這樣就實(shí)現(xiàn)了呼吸燈的靈活調(diào)整。源代碼先不放出來了,等做完實(shí)驗(yàn)放出。 ***********

//=======================================
void LedOnOff(uint32_t t,uint32_t xx) //T代表整個(gè)周期的時(shí)間,xx代表周期中點(diǎn)亮?xí)r間的長度
{
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET); //GPIO_PIN_SET
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_SET);
mydely_us(xx); //點(diǎn)亮?xí)r間
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_RESET);
mydely_us(t-xx); //熄滅時(shí)間
}
//*****************
*****************************************
int main(void)
{
int i;
int myLongTime=1500; //ms 呼吸總體時(shí)間
int myshortTime=40; //ms
int myCYC=myLongTime/myshortTime;
delay_init(); //初始化延時(shí)函數(shù)
LED_Init(); //初始化LED端口
while(1)
{
for(i=1; i<myCYC; i++)
LedOnOff(myshortTime*1000,i*myshortTime*1000.0/myCYC);
for(i=myCYC; i>1; i-=1)
LedOnOff(myshortTime*1000,i*myshortTime*1000.0/myCYC);
}
}
/*

4.原理分析,
模擬人體呼吸,吸氣和呼氣各占1.5S,人眼的圖像滯留時(shí)間0.04s(1/24幀畫面)
按最快0.04s算,就是40ms。亮0.02S,滅0.02s,人眼看到的應(yīng)該是一直亮(可以實(shí)驗(yàn))
呼吸燈,就是改變這40ms中,亮和滅所占的百分比。
1500/40=38周期,40ms/37=1052us。38個(gè)周期變比中,每個(gè)周期增長1個(gè)單位1052us,38個(gè)周期剛好是40ms.這樣達(dá)到全亮
亮的百分比多,人眼看到的就亮,反之就是暗。
利用40ms這個(gè)時(shí)間,目測(cè)感覺有閃爍,減少這個(gè)時(shí)間,變化就會(huì)緩慢,沒有閃爍感。參考用20ms
//us延時(shí)函數(shù)的實(shí)現(xiàn)
void mydely_us(uint32_t count)
{
HAL_TIM_Base_Stop_IT(&htim1);
my_tim1_count=0;
HAL_TIM_Base_Start_IT(&htim1);
while(my_tim1_count<count);
HAL_TIM_Base_Stop_IT(&htim1);
}
void TIM1_UP_IRQHandler(void)
{
/* USER CODE BEGIN TIM1_UP_IRQn 0 */
extern uint32_t my_tim1_count;
my_tim1_count++;
__HAL_TIM_CLEAR_IT(&htim1, TIM_IT_UPDATE);
/* USER CODE END TIM1_UP_IRQn 0 */
//HAL_TIM_IRQHandler(&htim1);
/* USER CODE BEGIN TIM1_UP_IRQn 1 */
/* USER CODE END TIM1_UP_IRQn 1 */
}

5.說明:
利用HAL庫,默認(rèn)沒有辦法實(shí)現(xiàn)us的定時(shí)器,方法是。利用硬件定時(shí)器,產(chǎn)生一個(gè)1us的周期中斷,每進(jìn)入一次中斷,一個(gè)全局變量加1,通過判斷這個(gè)變量的值,來確定當(dāng)前的延時(shí)時(shí)間。6.問題:1.HAL庫的執(zhí)行效率比較低,1us中斷的實(shí)際,還沒有處理完中斷過程,因此需要手動(dòng)修改中斷函數(shù),添加__HAL_TIM_CLEAR_IT(&htim1, TIM_IT_UPDATE);屏蔽: //HAL_TIM_IRQHandler(&htim1);這樣中斷處理時(shí)間會(huì)減少很多。2.全局變量的變化,如果總開著定時(shí)中斷,會(huì)影響正常程序的執(zhí)行,因此,需要延時(shí)的時(shí)候,開啟定時(shí)器,延時(shí)結(jié)束,關(guān)閉定時(shí)器
void mydely_us(uint32_t count)
{
HAL_TIM_Base_Stop_IT(&htim1);
my_tim1_count=0;
HAL_TIM_Base_Start_IT(&htim1);
while(my_tim1_count<count);
HAL_TIM_Base_Stop_IT(&htim1);