国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

C語言實現呼吸燈(HAL庫)

104828720 / 2731人閱讀

摘要:關于的塊不打算展開說,這里針對呼吸燈的詳細說明。描述定時器底層回調初始化參數無返回無描述定時器中斷處理函數參數無返回無呼吸燈注意由于產生中斷過快,反轉實現不了電平反轉上面代碼是中斷處理函數,對呼吸燈的引腳電平反轉。

1. 呼吸燈原理

呼吸燈的實現可以通過控制燈的亮度連續變化,當變化的頻率大于24幀時,肉眼看上去就會逐漸變暗,逐漸變亮。

2. PWM控制亮度

PWM通過設置亮度在一段時間內的占空比,亮的百分比多,人眼看到的就亮,反之就是暗。
關于PWM的塊不打算展開說,這里針對呼吸燈的PWM詳細說明。

/* * 描述  :呼吸燈PWM初始化 * 參數  : *        無 * 返回  : *        無 */void bspBreathLedTIMInit(void){  TIM_ClockConfigTypeDef sClockSourceConfig = {0};  TIM_MasterConfigTypeDef sMasterConfig = {0};  TIM_OC_InitTypeDef sConfigOC = {0};  g_breathled_tim_handle.Instance = TIM2;  g_breathled_tim_handle.Init.Prescaler = 83;  g_breathled_tim_handle.Init.CounterMode = TIM_COUNTERMODE_UP;  g_breathled_tim_handle.Init.Period = (BREATHLED_PWM_VALUE - 1);  g_breathled_tim_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;  g_breathled_tim_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;  if (HAL_TIM_Base_Init(&g_breathled_tim_handle) != HAL_OK)  {    Error_Handler();  }  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;  if (HAL_TIM_ConfigClockSource(&g_breathled_tim_handle, &sClockSourceConfig) != HAL_OK)  {    Error_Handler();  }  if (HAL_TIM_PWM_Init(&g_breathled_tim_handle) != HAL_OK)  {    Error_Handler();  }  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;  if (HAL_TIMEx_MasterConfigSynchronization(&g_breathled_tim_handle, &sMasterConfig) != HAL_OK)  {    Error_Handler();  }  sConfigOC.OCMode = TIM_OCMODE_PWM1;  sConfigOC.Pulse = 0;  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;  if (HAL_TIM_PWM_ConfigChannel(&g_breathled_tim_handle, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)  {    Error_Handler();  }  GPIO_InitTypeDef GPIO_InitStruct;  BREATHLED_GPIO_CLK_ENABLE();  /* TIM2 GPIO Configuration   * PA3     ------> TIM2_CH4   */  GPIO_InitStruct.Pin = BREATHLED_GPIO_GREEN_PIN;  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;  GPIO_InitStruct.Pull = GPIO_NOPULL;  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;  GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;  HAL_GPIO_Init(BREATHLED_GPIO_TYPE, &GPIO_InitStruct);  HAL_TIM_Base_Start_IT(&g_breathled_tim_handle);}

我這里使用了PA3引腳,定時器2做實驗。時鐘頻率是84MHz,Prescaler設置(84 - 1) = 83,Period這里設置是(10000 - 1) = 9999,所以定時器是 (83 + 1) * (9999 + 1) / 84000000 = 0.01s = 10ms一個周期。
這個頻率各位可以根據實際情況去計算,盡量設置成看上去平滑,而且對系統也不會造成產生過多中斷。

/* * 描述  :定時器底層回調初始化 * 參數  : *        無 * 返回  : *        無 */void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim_base){  if (htim_base->Instance == TIM2)  {    __HAL_RCC_TIM2_CLK_ENABLE();    HAL_NVIC_SetPriority(TIM2_IRQn, 5, 0);    HAL_NVIC_EnableIRQ(TIM2_IRQn);  }}/* * 描述  :定時器中斷處理函數 * 參數  : *        無 * 返回  : *        無 */void TIM2_IRQHandler(void){  HAL_TIM_IRQHandler(&g_breathled_tim_handle);	  HAL_TIM_PeriodElapsedCallback(&g_breathled_tim_handle);	}void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){  /* USER CODE BEGIN Callback 0 */  /* USER CODE END Callback 0 */  if (htim->Instance == TIM11) {    HAL_IncTick();  }  //呼吸燈  else if (htim->Instance == TIM2)  {    //注意由于產生中斷過快,反轉實現不了    //LED電平反轉    HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_3);  }  /* USER CODE BEGIN Callback 1 */  /* USER CODE END Callback 1 */}

上面代碼是中斷處理函數,對呼吸燈的引腳電平反轉。是通過設置占空比的參數,定時器自動觸發中斷后反轉電平。

3. 呼吸燈亮度曲線

//PWM設置的Period值#define BREATHLED_PWM_VALUE                10000//呼吸燈x軸變暗或變亮步數#define BREATHLED_X_DIVIDE                 100//呼吸燈x軸總步數#define BREATHLED_X_TOTAL                 (BREATHLED_X_DIVIDE * 2)//呼吸燈y軸比例#define BREATHLED_Y_RATIO                 (BREATHLED_PWM_VALUE / BREATHLED_X_DIVIDE)//亮度變化頻率,也就是幀數,單位毫秒#define BREATHLED_FRAMES_MS											10

一些宏定義,BREATHLED_PWM_VALUE值是上面PWM設置的Period值。
BREATHLED_X_DIVIDE是x軸,變暗或變亮時,x軸的步數。
BREATHLED_X_TOTAL是x軸變暗加上變亮一個周期的總步數。
BREATHLED_Y_RATIO是y軸比例。
BREATHLED_FRAMES_MS亮度變化頻率,注意這個值必須大于24幀,也就是小于40毫秒的時間,為了更加平滑,可以適量提高幀數,這樣看起來呼吸燈更加流暢。

3.1 線性折線

y = 10000時代表占空比100%,x軸為時間。

/* * 描述  :呼吸燈函數,由x軸得出y軸值 * 參數  : *        [in]  x     x軸,時間 * 返回  : *        y軸值,PWM值 */static unsigned int breathLedCurve(unsigned int x){  unsigned int y;  if (x < BREATHLED_X_DIVIDE)  {    y = BREATHLED_Y_RATIO * x;  }  else  {    y = -BREATHLED_Y_RATIO * (x - BREATHLED_X_TOTAL);  }  return y;}/* * 描述  :呼吸燈過程 * 參數  : *        無 * 返回  : *        無 */void breathLedProgress(void){  static unsigned int time_x = 0;  unsigned int pwm_value_y = 0;  while (1)  {    time_x = (time_x + 1) % BREATHLED_X_TOTAL;    pwm_value_y = breathLedCurve(time_x);    //修改占空比    __HAL_TIM_SetCompare(&g_breathled_tim_handle, TIM_CHANNEL_4, pwm_value_y);			     sysDelay(BREATHLED_FRAMES_MS);    if (time_x % BREATHLED_X_DIVIDE == 0)    {      sysDelay(500);    }  }}

實現方式可以參考上面的,但是人眼感受的卻不是線性的,是由于在燈光微亮區,很小的光通量改變也讓人眼感到光通量變化很大,而在光通量比較大的區域,很大的光通量跳躍,人眼感覺到的光通量變化不大,簡單理解為,人眼對亮度暗的比較敏感,而對亮度量的不敏感。
所以你嘗試后發現,當由亮變暗時感覺時間長,由暗變亮時時間短,會有突然變亮的感覺。這個曲線是有缺陷的。

3.2 呼吸燈曲線


由上圖可知,當亮度由暗變亮時,程序的呼吸燈曲線需要如同圖3。
為了方便我這里使用一元二次曲線,有條件的可以使用sin函數,但是效果或許看起來會差不多。但是sin函數計算量會比一元二次方程大的多,所以衡量之下,選擇通過一元二次曲線來實現。

通過這個曲線,你可能感覺到和線性折線差不多的效果。所以還需要降低由暗變亮時的亮度變化頻率,即可讓人眼看上去平滑。

有需要的可以移步呼吸燈曲線代碼下載。或者有能力的可以自行參考上面代碼,實現該曲線

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/118972.html

相關文章

  • 使用STM32CubeMX初始化STM32F031F6Px系列

    摘要:利用可視化界面來進行的相關配置,所以時鐘滴答定時器串口等就不用根據數據手冊去操作標準庫甚至是寄存器了,可以通過軟件直接生成。 使用STM32CubeMX初始化ST...

    Zhuxy 評論0 收藏0
  • STM32學習筆記 第二章 STM32資源介紹

    摘要:總線掛載的外設有等。外設地址映射片上外設區分為三條總線,根據外設速度的不同,不同總線掛載著不同的外設,掛載低速外設,和掛載高速外設。 第二章 STM32資源介紹 2...

    G9YH 評論0 收藏0
  • 通過css3動畫和opacity透明度實現呼吸效果

    摘要:呼吸燈也可以通過加層罩,通過設置層罩透明度來實現亮度動畫 呼吸燈 /*也可以通過加層罩,通過設置層罩透明度來實現亮度動畫*/ body{ background-color: black; } div{ margin: 0 auto; margin-top: 200px; width: 300p...

    Cristalven 評論0 收藏0
  • 第一課:超級hello Arduino.使用多種知識串聯一個入門小項目,很適合初學第一課喲.

    摘要:開關旋鈕電位器的實驗視頻已經購買開發版的同學開始上課來一場緊張刺激的之旅吧前言開發工具的下載安裝使用都很簡單我這里就不贅述了附上官方的說明跟著步驟來十分鐘搞定相關連接下載官方為什么成為開發函數 ...

    philadelphia 評論0 收藏0
  • 基于STM32的實驗室點大師

    摘要:初始化引腳和基礎設置利用宏定義定義引腳高或者低全部引腳為高原理圖是低平點亮高電平滅利用宏定義設置時間關閉燈流水燈延時時間為的值先關閉全部燈循環流水燈 /* US...

    KunMinX 評論0 收藏0

發表評論

0條評論

104828720

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<