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

//=======================================
void LedOnOff(uint32_t t,uint32_t xx) //T代表整個(gè)周期的時(shí)間,xx代表周期中點(diǎn)亮時(shí)間的長(cháng)度
{
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)亮時(shí)間
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í)函數
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幀畫(huà)面)
按最快0.04s算,就是40ms。亮0.02S,滅0.02s,人眼看到的應該是一直亮(可以實(shí)驗)
呼吸燈,就是改變這40ms中,亮和滅所占的百分比。
1500/40=38周期,40ms/37=1052us。38個(gè)周期變比中,每個(gè)周期增長(cháng)1個(gè)單位1052us,38個(gè)周期剛好是40ms.這樣達到全亮
亮的百分比多,人眼看到的就亮,反之就是暗。
利用40ms這個(gè)時(shí)間,目測感覺(jué)有閃爍,減少這個(gè)時(shí)間,變化就會(huì )緩慢,沒(méi)有閃爍感。參考用20ms
//us延時(shí)函數的實(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);
}
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.說(shuō)明:
利用HAL庫,默認沒(méi)有辦法實(shí)現us的定時(shí)器,方法是。利用硬件定時(shí)器,產(chǎn)生一個(gè)1us的周期中斷,每進(jìn)入一次中斷,一個(gè)全局變量加1,通過(guò)判斷這個(gè)變量的值,來(lái)確定當前的延時(shí)時(shí)間。6.問(wèn)題:1.HAL庫的執行效率比較低,1us中斷的實(shí)際,還沒(méi)有處理完中斷過(guò)程,因此需要手動(dòng)修改中斷函數,添加__HAL_TIM_CLEAR_IT(&htim1, TIM_IT_UPDATE);屏蔽: //HAL_TIM_IRQHandler(&htim1);這樣中斷處理時(shí)間會(huì )減少很多。2.全局變量的變化,如果總開(kāi)著(zhù)定時(shí)中斷,會(huì )影響正常程序的執行,因此,需要延時(shí)的時(shí)候,開(kāi)啟定時(shí)器,延時(shí)結束,關(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);