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

//=======================================
void LedOnOff(uint32_t t,uint32_t xx) //T代表整個周期的時間,xx代表周期中點亮時間的長度
{
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); //點亮時間
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_RESET);
mydely_us(t-xx); //熄滅時間
}
//*****************
*****************************************
int main(void)
{
int i;
int myLongTime=1500; //ms 呼吸總體時間
int myshortTime=40; //ms
int myCYC=myLongTime/myshortTime;
delay_init(); //初始化延時函數
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,人眼的圖像滯留時間0.04s(1/24幀畫面)
按最快0.04s算,就是40ms。亮0.02S,滅0.02s,人眼看到的應該是一直亮(可以實驗)
呼吸燈,就是改變這40ms中,亮和滅所占的百分比。
1500/40=38周期,40ms/37=1052us。38個周期變比中,每個周期增長1個單位1052us,38個周期剛好是40ms.這樣達到全亮
亮的百分比多,人眼看到的就亮,反之就是暗。
利用40ms這個時間,目測感覺有閃爍,減少這個時間,變化就會緩慢,沒有閃爍感。參考用20ms
//us延時函數的實現
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庫,默認沒有辦法實現us的定時器,方法是。利用硬件定時器,產生一個1us的周期中斷,每進入一次中斷,一個全局變量加1,通過判斷這個變量的值,來確定當前的延時時間。6.問題:1.HAL庫的執行效率比較低,1us中斷的實際,還沒有處理完中斷過程,因此需要手動修改中斷函數,添加__HAL_TIM_CLEAR_IT(&htim1, TIM_IT_UPDATE);屏蔽: //HAL_TIM_IRQHandler(&htim1);這樣中斷處理時間會減少很多。2.全局變量的變化,如果總開著定時中斷,會影響正常程序的執行,因此,需要延時的時候,開啟定時器,延時結束,關閉定時器
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);