日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > > 嵌入式云IOT技術(shù)圈
[導(dǎo)讀]一般來說,學(xué)習(xí)任何一個(gè)RTOS,本質(zhì)是沒有什么太大的區(qū)別的,通常在最簡(jiǎn)版nano上進(jìn)行開發(fā),關(guān)于TencentOS tiny,我個(gè)人認(rèn)為,掌握以下基礎(chǔ)組件的用法足矣,其它的一些組件,可以等需要使用的時(shí)候再參考文檔學(xué)習(xí)應(yīng)用即可。

上節(jié),我們介紹了TencentOS tiny,參考官方給出的移植教程親自動(dòng)手做了一遍,文章如下:

天??!鵝廠都開始做開發(fā)板了?網(wǎng)紅騰訊物聯(lián)網(wǎng)開發(fā)板終極開箱評(píng)測(cè),讓我們一睹為快!

趁著最近有時(shí)間,這節(jié),我擼了幾個(gè)例程作為后面做項(xiàng)目參考的基本框架,當(dāng)然也有一些是直接拿了官方文檔的例程:

一般來說,學(xué)習(xí)任何一個(gè)RTOS,本質(zhì)是沒有什么太大的區(qū)別的,通常在最簡(jiǎn)版nano上進(jìn)行開發(fā),關(guān)于TencentOS tiny,我個(gè)人認(rèn)為,掌握以下基礎(chǔ)組件的用法足矣,其它的一些組件,可以等需要使用的時(shí)候再參考文檔學(xué)習(xí)應(yīng)用即可。

  • TencentOS tiny多任務(wù)
  • TencentOS tiny RTOS軟件定時(shí)器
  • TencentOS tiny RTOS任務(wù)間通信(互斥鎖、信號(hào)量、事件、隊(duì)列)

在使用基本組件之前,我們需要配置tos_config.h文件:

#ifndef?_TOS_CONFIG_H_
#define??_TOS_CONFIG_H_

//#include?"stm32l0xx.h"?//?目標(biāo)芯片頭文件,用戶需要根據(jù)情況更改
#include?"stm32l4xx_hal.h"

#define?TOS_CFG_TASK_PRIO_MAX???????????10u??//?配置TencentOS?tiny默認(rèn)支持的最大優(yōu)先級(jí)數(shù)量

#define?TOS_CFG_ROUND_ROBIN_EN??????????0u??//?配置TencentOS?tiny的內(nèi)核是否開啟時(shí)間片輪轉(zhuǎn)

#define?TOS_CFG_OBJECT_VERIFY_EN???????????1u?//?配置TencentOS?tiny是否校驗(yàn)指針合法

#define?TOS_CFG_TASK_DYNAMIC_CREATE_EN??1u??//?TencentOS?tiny?動(dòng)態(tài)任務(wù)創(chuàng)建功能宏

#define?TOS_CFG_EVENT_EN????????????????1u??//?TencentOS?tiny?事件模塊功能宏

#define?TOS_CFG_MMBLK_EN????????????????1u??//配置TencentOS?tiny是否開啟內(nèi)存塊管理模塊

#define?TOS_CFG_MMHEAP_EN???????????????1u??//配置TencentOS?tiny是否開啟動(dòng)態(tài)內(nèi)存模塊

#define?TOS_CFG_MMHEAP_DEFAULT_POOL_EN??1u??//?TencentOS?tiny?默認(rèn)動(dòng)態(tài)內(nèi)存池功能宏

#define?TOS_CFG_MMHEAP_DEFAULT_POOL_SIZE????????0x100?//?配置TencentOS?tiny默認(rèn)動(dòng)態(tài)內(nèi)存池大小

#define?TOS_CFG_MUTEX_EN????????????????1u??//?配置TencentOS?tiny是否開啟互斥鎖模塊

#define?TOS_CFG_MESSAGE_QUEUE_EN????????1u??//?配置TencentOS?tiny是否開啟消息隊(duì)列模塊

#define?TOS_CFG_MAIL_QUEUE_EN???????????1u??//?配置TencentOS?tiny是否開啟消息郵箱模塊

#define?TOS_CFG_PRIORITY_MESSAGE_QUEUE_EN?1u?//?配置TencentOS?tiny是否開啟優(yōu)先級(jí)消息隊(duì)列模塊

#define?TOS_CFG_PRIORITY_MAIL_QUEUE_EN?1u??//?配置TencentOS?tiny是否開啟優(yōu)先級(jí)消息郵箱模塊

#define?TOS_CFG_TIMER_EN????????????????1u??//?配置TencentOS?tiny是否開啟軟件定時(shí)器模塊

#define?TOS_CFG_PWR_MGR_EN??????????????0u??//?配置TencentOS?tiny是否開啟外設(shè)電源管理模塊

#define?TOS_CFG_TICKLESS_EN?????????????0u??//?配置Tickless?低功耗模塊開關(guān)

#define?TOS_CFG_SEM_EN??????????????????1u??//?配置TencentOS?tiny是否開啟信號(hào)量模塊

#define?TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN??????1u?//?配置TencentOS?tiny是否開啟任務(wù)棧深度檢測(cè)

#define?TOS_CFG_FAULT_BACKTRACE_EN??????0u??//?配置TencentOS?tiny是否開啟異常?;厮莨δ?/span>

#define?TOS_CFG_IDLE_TASK_STK_SIZE??????128u?//?配置TencentOS?tiny空閑任務(wù)棧大小

#define?TOS_CFG_CPU_TICK_PER_SECOND?????1000u?//?配置TencentOS?tiny的tick頻率

#define?TOS_CFG_CPU_CLOCK???????????????(SystemCoreClock)?//?配置TencentOS?tiny?CPU頻率

#define?TOS_CFG_TIMER_AS_PROC???????????1u??//?配置是否將TIMER配置成函數(shù)模式

#endif

這樣后面我們才能正常使用。

1、TencentOS tiny多任務(wù)

1.1 為什么要采用RTOS多任務(wù)?

對(duì)于普通的項(xiàng)目來說,比如密碼鎖類項(xiàng)目,單獨(dú)的一個(gè)傳感器模塊的開發(fā),某些簡(jiǎn)單的儀器儀表等等,對(duì)于這類場(chǎng)景單一,業(yè)務(wù)需求也單一的項(xiàng)目來說,使用狀態(tài)機(jī)或者事件驅(qū)動(dòng)的方式就足以完成項(xiàng)目的基本功能了。

但是如果開發(fā)一個(gè)巨量代碼的工程項(xiàng)目,項(xiàng)目可能設(shè)計(jì)到傳感器數(shù)據(jù)讀取、無線數(shù)據(jù)上傳與接收、數(shù)據(jù)傳輸、UI實(shí)時(shí)刷新、算法處理等等,功能諸多還需要相互配合的情況下,那么如果還在用裸機(jī)的思想去完成,那么開發(fā)者一般會(huì)面臨以下兩個(gè)問題:

  • 設(shè)計(jì)思路過于復(fù)雜,光怎么想程序的設(shè)計(jì)思路就得想好久了
  • 設(shè)計(jì)下來的各個(gè)功能,要考慮相互配合的問題,實(shí)時(shí)性可能得不到要求

RTOS的多任務(wù)就可以解決對(duì)應(yīng)的問題,它既能讓項(xiàng)目開發(fā)起來思路清晰,方便易維護(hù);同時(shí)RTOS也能保證整個(gè)產(chǎn)品運(yùn)行的實(shí)時(shí)性,典型的程序設(shè)計(jì)架構(gòu),就可以按下面的方式來劃分:

1.2 TencentOS tiny RTOS多任務(wù)實(shí)踐

關(guān)于怎么創(chuàng)建多個(gè)任務(wù),可以參考騰訊物聯(lián)網(wǎng)終端操作系統(tǒng)開發(fā)指南.pdf文檔,以下工程是我基于上一節(jié)的移植工程,在移植工程的基礎(chǔ)上,由于官方給的OLED驅(qū)動(dòng)例程是軟件模擬驅(qū)動(dòng)的,后來我將其改為I2C硬件驅(qū)動(dòng),所以,在STM32CubeMX上對(duì)OLED的I2C接口進(jìn)行了配置:

更改后重新生成軟件工程,然后修改oled.c中關(guān)于寫命令和寫數(shù)據(jù)的接口為硬件I2C驅(qū)動(dòng):

//?IIC?Write?Command
void?Write_IIC_Command(unsigned?char?IIC_Command)
{
????uint8_t?buf[2]?=?{0};
????buf[0]?=?0x00?;
????buf[1]?=?IIC_Command?;
????HAL_I2C_Master_Transmit(&hi2c3,?0x78,?buf,?2,?HAL_TICK_FREQ_100HZ);
}
/**********************************************
//?IIC?Write?Data
**********************************************/

void?Write_IIC_Data(unsigned?char?IIC_Data)
{
????uint8_t?buf[2]?=?{0};
????buf[0]?=?0x40?;
????buf[1]?=?IIC_Data?;
????HAL_I2C_Master_Transmit(&hi2c3,?0x78,?buf,?2,?HAL_TICK_FREQ_100HZ);
}

接下來,進(jìn)入多任務(wù)程序編寫,我們主要實(shí)現(xiàn)以下兩個(gè)功能:

  • task1以1s的頻率循環(huán)打印 Hello TencentOS tiny
  • task2以100ms的頻率循環(huán)翻轉(zhuǎn)。

main.c

定義兩個(gè)基本任務(wù):

//task1
#define?TASK1_STK_SIZE??256
void?task1(void?*pdata);
osThreadDef(task1,?osPriorityNormal,?1,?TASK1_STK_SIZE);

void?task1(void?*pdata)
{
????while(1)
????{
???????printf("Hello?TencentOS?tiny\n");
???????osDelay(1000);
????}
}

//task2
#define?TASK2_STK_SIZE??256
void?task2(void?*pdata);
osThreadDef(task2,?osPriorityNormal,?1,?TASK2_STK_SIZE);

void?task2(void?*pdata)
{
????while(1)
????{
???????HAL_GPIO_TogglePin(DEBUG_LED_GPIO_Port,?DEBUG_LED_Pin);
???????osDelay(100);
????}
}

在main函數(shù)中:

/**
??*?@brief??The?application?entry?point.
??*?@retval?int
??*/

int?main(void)
{
????/*?USER?CODE?BEGIN?1?*/

????/*?USER?CODE?END?1?*/

????/*?MCU?Configuration--------------------------------------------------------*/

????/*?Reset?of?all?peripherals,?Initializes?the?Flash?interface?and?the?Systick.?*/
????HAL_Init();

????/*?USER?CODE?BEGIN?Init?*/

????/*?USER?CODE?END?Init?*/

????/*?Configure?the?system?clock?*/
????SystemClock_Config();

????/*?USER?CODE?BEGIN?SysInit?*/

????/*?USER?CODE?END?SysInit?*/

????/*?Initialize?all?configured?peripherals?*/
????MX_GPIO_Init();
????MX_USART2_UART_Init();
????MX_I2C3_Init();
????/*?USER?CODE?BEGIN?2?*/
????OLED_Init();
????OLED_Clear();
????OLED_ShowString(0,?0,?(uint8_t*)"TencentOS?tiny",?16);
????OLED_ShowString(0,?2,?(uint8_t*)"Bruce.yang",?16);
????//初始化內(nèi)核
????osKernelInitialize();
????//創(chuàng)建并啟動(dòng)一個(gè)任務(wù)用于打印調(diào)試信息
????osThreadCreate(osThread(task1),?NULL);
????//創(chuàng)建并啟動(dòng)一個(gè)任務(wù)用于以100ms的間隔翻轉(zhuǎn)LED
????osThreadCreate(osThread(task2),?NULL);
????//啟動(dòng)內(nèi)核
????osKernelStart();
????/*?USER?CODE?END?2?*/

????/*?Infinite?loop?*/
????/*?USER?CODE?BEGIN?WHILE?*/
????while?(1)
????{
????????/*?USER?CODE?END?WHILE?*/

????????/*?USER?CODE?BEGIN?3?*/
????}

????/*?USER?CODE?END?3?*/
}

編譯后下載到EVB_MX+開發(fā)板后,運(yùn)行結(jié)果如下:

task1以1s的頻率循環(huán)打印Hello TencentOS tiny,task2以100ms的頻率循環(huán)翻轉(zhuǎn)。

1.3 總結(jié)

概念性總結(jié):

  • 多任務(wù)適合業(yè)務(wù)場(chǎng)景更加復(fù)雜的應(yīng)用場(chǎng)景
  • 多任務(wù)適合對(duì)實(shí)時(shí)響應(yīng)要求更高的場(chǎng)景

使用總結(jié):

詳情請(qǐng)參考騰訊物聯(lián)網(wǎng)終端操作系統(tǒng)開發(fā)指南.pdf文檔

2、TencentOS tiny RTOS軟件定時(shí)器

2.1、為什么要采用RTOS軟件定時(shí)器?

軟件定時(shí)器,顧名思義就是軟件實(shí)現(xiàn)的定時(shí)器,它是和硬件定時(shí)器有本質(zhì)區(qū)別的,軟件定時(shí)器使用的是系統(tǒng)調(diào)度所依賴的嘀嗒定時(shí)器,也就是Systick來實(shí)現(xiàn)的,它主要解決一些不需要特別精準(zhǔn)的定時(shí)觸發(fā)場(chǎng)合,目前github倉庫上有開源不少軟件定時(shí)器的實(shí)例,比如multi_timer,TecentOS tiny也在自己的內(nèi)核中集成了自己的一套軟件定時(shí)器,實(shí)現(xiàn)原理其實(shí)也是差不多的。

2.2、TencentOS tiny RTOS軟件定時(shí)器實(shí)踐

關(guān)于怎么使用定時(shí)器,可以參考騰訊物聯(lián)網(wǎng)終端操作系統(tǒng)開發(fā)指南.pdf文檔,以下工程基于多任務(wù)例程修改,接下來,進(jìn)入軟件定時(shí)器程序編寫,我們主要實(shí)現(xiàn)以下兩個(gè)功能:

  • task1以1s的頻率循環(huán)打印 Hello TencentOS tiny
  • 軟件定時(shí)器以500ms的頻率翻轉(zhuǎn)LED

main.c

/*定義一個(gè)定時(shí)器句柄*/
k_timer_t?os_tmr_handler;
//創(chuàng)建一個(gè)任務(wù)
#define?TASK1_STK_SIZE??256
void?task1(void?*pdata);
osThreadDef(task1,?osPriorityNormal,?1,?TASK1_STK_SIZE);

void?task1(void?*pdata)
{
????while(1)
????{
???????printf("Hello?TencentOS?tiny\n");
???????osDelay(1000);
????}
}

//定時(shí)器回調(diào)函數(shù)
void?os_tmr_handler_callback(void?*arg)
{
???HAL_GPIO_TogglePin(DEBUG_LED_GPIO_Port,?DEBUG_LED_Pin);
}

在main函數(shù)中:

/**
??*?@brief??The?application?entry?point.
??*?@retval?int
??*/

int?main(void)
{
????/*?USER?CODE?BEGIN?1?*/

????/*?USER?CODE?END?1?*/

????/*?MCU?Configuration--------------------------------------------------------*/

????/*?Reset?of?all?peripherals,?Initializes?the?Flash?interface?and?the?Systick.?*/
????HAL_Init();

????/*?USER?CODE?BEGIN?Init?*/

????/*?USER?CODE?END?Init?*/

????/*?Configure?the?system?clock?*/
????SystemClock_Config();

????/*?USER?CODE?BEGIN?SysInit?*/

????/*?USER?CODE?END?SysInit?*/

????/*?Initialize?all?configured?peripherals?*/
????MX_GPIO_Init();
????MX_USART2_UART_Init();
????MX_I2C3_Init();
????/*?USER?CODE?BEGIN?2?*/
????OLED_Init();
????OLED_Clear();
????OLED_ShowString(0,?0,?(uint8_t*)"TencentOS?tiny",?16);
????OLED_ShowString(0,?2,?(uint8_t*)"Bruce.yang",?16);
????//初始化內(nèi)核
????osKernelInitialize();
????//創(chuàng)建一個(gè)以500ms周期運(yùn)行的軟件定時(shí)器
????tos_timer_create(&os_tmr_handler,?500,?500,?os_tmr_handler_callback,?K_NULL,?TOS_OPT_TIMER_PERIODIC);
????//創(chuàng)建一個(gè)任務(wù)
????osThreadCreate(osThread(task1),?NULL);
????//啟動(dòng)定時(shí)器
????tos_timer_start(&os_tmr_handler);
????//啟動(dòng)內(nèi)核
????osKernelStart();
????/*?USER?CODE?END?2?*/

????/*?Infinite?loop?*/
????/*?USER?CODE?BEGIN?WHILE?*/
????while?(1)
????{
????????/*?USER?CODE?END?WHILE?*/

????????/*?USER?CODE?BEGIN?3?*/
????}

????/*?USER?CODE?END?3?*/
}

編譯后下載到EVB_MX+開發(fā)板后,運(yùn)行結(jié)果如下:

task1以1s的頻率循環(huán)打印Hello TencentOS tiny,軟件定時(shí)器以500ms的頻率執(zhí)行,此時(shí)LED會(huì)以500ms的速率循環(huán)翻轉(zhuǎn)。

2.3 總結(jié)

概念性總結(jié):

  • 軟件定時(shí)器就是用"軟件邏輯"實(shí)現(xiàn)的定時(shí)器
  • 軟件定時(shí)器適合一些不需要特別精準(zhǔn)的定時(shí)觸發(fā)場(chǎng)合.

使用總結(jié):

詳情請(qǐng)參考騰訊物聯(lián)網(wǎng)終端操作系統(tǒng)開發(fā)指南.pdf文檔

3、TencentOS tiny RTOS任務(wù)間通信

3.1、TencentOS tiny RTOS互斥鎖

3.1.1 、為什么要采用RTOS互斥鎖?

互斥鎖適用于實(shí)現(xiàn)臨界區(qū)資源的互斥性訪問,當(dāng)有多個(gè)任務(wù)同時(shí)并行對(duì)一個(gè)數(shù)據(jù)操作時(shí),就會(huì)存在不確定性,典型的案例就是全局變量,在不帶操作系統(tǒng)的裸機(jī)功能開發(fā)中,我們通常會(huì)使用全局變量,讓其在整個(gè)工程中通過外部引用的方式全局可見,這樣我們就可以很方便的在任何一個(gè)地方對(duì)其進(jìn)行讀寫操作,但如果在操作系統(tǒng)中卻恰恰相反,這種奇怪的現(xiàn)象被稱為不可重入,通常在操作系統(tǒng)里叫臨界區(qū)資源,在字符串操作中,典型的不可重入函數(shù)是strtok,strtok函數(shù)內(nèi)部有一個(gè)static變量,這種類型的變量可以被多次重入調(diào)用共同控制,其最終的結(jié)果依賴于它們的執(zhí)行順序,所以,使用互斥鎖可以解決這種不確定性的問題,也就是說在任意時(shí)刻,只會(huì)有一個(gè)任務(wù)對(duì)其進(jìn)行訪問。

3.1.2、TencentOS tiny RTOS互斥鎖實(shí)踐

關(guān)于怎么使用互斥鎖,可以參考騰訊物聯(lián)網(wǎng)終端操作系統(tǒng)開發(fā)指南.pdf文檔,以下工程基于多任務(wù)例程修改,接下來,進(jìn)入互斥鎖程序編寫,我們主要實(shí)現(xiàn)三個(gè)任務(wù)同時(shí)執(zhí)行一段代碼:

main.c

k_mutex_t?mutex;
int?number?=?0?;

//task1
#define?TASK1_STK_SIZE??256
void?task1(void?*pdata);
osThreadDef(task1,?osPriorityNormal,?1,?TASK1_STK_SIZE);

void?count_sample_code(void)
{
????tos_mutex_pend(&mutex);
????number=0;
????number+=1;
????number+=2;
????number+=3;
????tos_mutex_post(&mutex);
}

void?task1(void?*pdata)
{
????while(1)
????{
????????number?=?0?;
????????osDelay(300);
????????count_sample_code();
????????printf("task1?number=%d\n",number);
????????osDelay(100);
????}
}

//task2
#define?TASK2_STK_SIZE??256
void?task2(void?*pdata);
osThreadDef(task2,?osPriorityNormal,?1,?TASK2_STK_SIZE);
void?task2(void?*pdata)
{
????while(1)
????{
????????osDelay(300);
????????count_sample_code();
????????printf("task2?number=%d\n",number);
????????osDelay(200);
????}
}

//task3
#define?TASK3_STK_SIZE??256
void?task3(void?*pdata);
osThreadDef(task3,?osPriorityNormal,?1,?TASK3_STK_SIZE);
void?task3(void?*pdata)
{
????while(1)
????{
????????osDelay(300);
????????count_sample_code();
????????printf("task3?number=%d\n",number);
????????osDelay(300);
????}
}

在main函數(shù)中:

/**
??*?@brief??The?application?entry?point.
??*?@retval?int
??*/

int?main(void)
{
????/*?USER?CODE?BEGIN?1?*/

????/*?USER?CODE?END?1?*/

????/*?MCU?Configuration--------------------------------------------------------*/

????/*?Reset?of?all?peripherals,?Initializes?the?Flash?interface?and?the?Systick.?*/
????HAL_Init();

????/*?USER?CODE?BEGIN?Init?*/

????/*?USER?CODE?END?Init?*/

????/*?Configure?the?system?clock?*/
????SystemClock_Config();

????/*?USER?CODE?BEGIN?SysInit?*/

????/*?USER?CODE?END?SysInit?*/

????/*?Initialize?all?configured?peripherals?*/
????MX_GPIO_Init();
????MX_USART2_UART_Init();
????MX_I2C3_Init();
????/*?USER?CODE?BEGIN?2?*/
????OLED_Init();
????OLED_Clear();
????OLED_ShowString(0,?2,?(uint8_t*)"TencentOS?tiny",?16);
????tos_mutex_create(&mutex);
????//初始化內(nèi)核
????osKernelInitialize();
????//分別創(chuàng)建任務(wù),用于驗(yàn)證互斥鎖
????osThreadCreate(osThread(task1),?NULL);
????osThreadCreate(osThread(task2),?NULL);
????osThreadCreate(osThread(task3),?NULL);
????//啟動(dòng)內(nèi)核
????osKernelStart();
????/*?USER?CODE?END?2?*/

????/*?Infinite?loop?*/
????/*?USER?CODE?BEGIN?WHILE?*/
????while?(1)
????{
????????/*?USER?CODE?END?WHILE?*/

????????/*?USER?CODE?BEGIN?3?*/
????}

????/*?USER?CODE?END?3?*/
}

編譯后下載到EVB_MX+開發(fā)板后,運(yùn)行結(jié)果如下:

3.1.3、總結(jié)

概念性總結(jié):

  • 互斥鎖在任意時(shí)刻,只會(huì)有一個(gè)任務(wù)對(duì)臨界資源進(jìn)行訪問
  • 互斥鎖用于實(shí)現(xiàn)臨界區(qū)資源的互斥性訪問

使用總結(jié):

詳情請(qǐng)參考騰訊物聯(lián)網(wǎng)終端操作系統(tǒng)開發(fā)指南.pdf文檔

3.2、TencentOS tiny RTOS信號(hào)量

3.2.1、為什么要采用RTOS信號(hào)量?

信號(hào)量,俗話說就是信號(hào)的數(shù)量,它是一種任務(wù)間傳遞系統(tǒng)可用資源的機(jī)制;舉一個(gè)生產(chǎn)者與消費(fèi)者的問題;也就是說消費(fèi)者在消費(fèi)了一個(gè)資源之前需要等待資源釋放,生產(chǎn)者生產(chǎn)資源以后要即時(shí)去通知其它的消費(fèi)者,簡(jiǎn)單的說就是凡事都要有個(gè)先來后到,所以信號(hào)量最常用的地方就是實(shí)現(xiàn)任務(wù)間同步。

3.2.2、TencentOS tiny RTOS信號(hào)量實(shí)踐

關(guān)于怎么使用信號(hào)量,可以參考騰訊物聯(lián)網(wǎng)終端操作系統(tǒng)開發(fā)指南.pdf文檔,以下工程基于多任務(wù)例程修改,接下來,進(jìn)入信號(hào)量程序編寫,我們主要實(shí)現(xiàn)生產(chǎn)者和消費(fèi)者的問題,這段程序在參考文檔里可以找到:

main.c

#define?STK_SIZE_TASK_PRODUCER?512
#define?STK_SIZE_TASK_CONSUMER?512
k_stack_t?stack_task_producer[STK_SIZE_TASK_PRODUCER];

k_stack_t?stack_task_consumer[STK_SIZE_TASK_CONSUMER];
k_task_t?task_producer;
k_task_t?task_consumer;
extern?void?entry_task_producer(void?*arg);
extern?void?entry_task_consumer(void?*arg);
k_mutex_t?buffer_locker;
k_sem_t?full;
k_sem_t?empty;
#define?RESOURCE_COUNT_MAX?3
struct?resource_st
{

????int?cursor;
????uint32_t?buffer[RESOURCE_COUNT_MAX];
}?resource?=?{?0,?{0}?};

static?void?produce_item(int?salt)
{
????printf("produce?item:\n");
????printf("%d",?salt);
????resource.buffer[resource.cursor++]?=?salt;
????printf("\n");
}
void?entry_task_producer(void?*arg)
{
????size_t?salt?=?0;
????k_err_t?err;

????while?(K_TRUE)
????{
????????err?=?tos_sem_pend(&empty,?TOS_TIME_FOREVER);

????????if?(err?!=?K_ERR_NONE)
????????{
????????????continue;
????????}

????????err?=?tos_mutex_pend(&buffer_locker);

????????if?(err?!=?K_ERR_NONE)
????????{
????????????continue;
????????}

????????produce_item(salt);
????????tos_mutex_post(&buffer_locker);
????????tos_sem_post(&full);
????????tos_task_delay(1000);
????????++salt;
????}
}
static?void?consume_item(void)
{
????printf("cosume?item:\n");
????printf("%d\t",?resource.buffer[--resource.cursor]);
????printf("\n");
}
void?entry_task_consumer(void?*arg)
{
????k_err_t?err;

????while?(K_TRUE)
????{
????????err?=?tos_sem_pend(&full,?TOS_TIME_FOREVER);

????????if?(err?!=?K_ERR_NONE)
????????{
????????????continue;
????????}

????????tos_mutex_pend(&buffer_locker);

????????if?(err?!=?K_ERR_NONE)
????????{
????????????continue;
????????}

????????consume_item();
????????tos_mutex_post(&buffer_locker);
????????tos_sem_post(&empty);
????????tos_task_delay(2000);
????}
}

main函數(shù)實(shí)現(xiàn)如下:

int?main(void)
{
????/*?USER?CODE?BEGIN?1?*/

????/*?USER?CODE?END?1?*/

????/*?MCU?Configuration--------------------------------------------------------*/

????/*?Reset?of?all?peripherals,?Initializes?the?Flash?interface?and?the?Systick.?*/
????HAL_Init();

????/*?USER?CODE?BEGIN?Init?*/

????/*?USER?CODE?END?Init?*/

????/*?Configure?the?system?clock?*/
????SystemClock_Config();

????/*?USER?CODE?BEGIN?SysInit?*/

????/*?USER?CODE?END?SysInit?*/

????/*?Initialize?all?configured?peripherals?*/
????MX_GPIO_Init();
????MX_USART2_UART_Init();
????MX_I2C3_Init();
????/*?USER?CODE?BEGIN?2?*/
????OLED_Init();
????OLED_Clear();
????OLED_ShowString(0,?0,?(uint8_t*)"TencentOS?tiny",?16);
????OLED_ShowString(0,?2,?(uint8_t*)"Bruce.yang",?16);
????//初始化內(nèi)核
????osKernelInitialize();
????tos_mutex_create(&buffer_locker);
????tos_sem_create(&full,?0);
????tos_sem_create(&empty,?RESOURCE_COUNT_MAX);
????(void)tos_task_create(&task_producer,?"producer",?entry_task_producer,?NULL,
??????????????????????????4,?stack_task_producer,?STK_SIZE_TASK_PRODUCER,?0);

????(void)tos_task_create(&task_consumer,?"consumer",?entry_task_consumer,?NULL,
??????????????????????????4,?stack_task_consumer,?STK_SIZE_TASK_CONSUMER,?0);
????//啟動(dòng)內(nèi)核
????osKernelStart();
????/*?USER?CODE?END?2?*/

????/*?Infinite?loop?*/
????/*?USER?CODE?BEGIN?WHILE?*/
????while?(1)
????{
????????/*?USER?CODE?END?WHILE?*/

????????/*?USER?CODE?BEGIN?3?*/
????}

????/*?USER?CODE?END?3?*/
}

編譯后下載到EVB_MX+開發(fā)板后,運(yùn)行結(jié)果如下:

3.2.3、總結(jié)

概念性總結(jié):

  • 信號(hào)量可以用于實(shí)現(xiàn)任務(wù)間同步
  • 信號(hào)量最典型的應(yīng)用就是處理生產(chǎn)者與消費(fèi)者的問題

使用總結(jié):

詳情請(qǐng)參考騰訊物聯(lián)網(wǎng)終端操作系統(tǒng)開發(fā)指南.pdf文檔

3.3、TencentOS tiny RTOS事件

3.3.1、為什么要采用RTOS事件?

事件,是RTOS任務(wù)間用來傳遞的一種信號(hào)的信息,它可以傳遞多個(gè)信息,事件和信號(hào)量的區(qū)別就是信號(hào)量只能傳遞0和1兩個(gè)信息,而事件的類型通常用k_event_flag_t進(jìn)行描述,它的本質(zhì)是一個(gè)uint32_t數(shù)據(jù)類型,也就是說事件最多可以定義32個(gè),使用事件可以很方便的實(shí)現(xiàn)任務(wù)間同步和信息傳遞,但是要注意的是事件達(dá)到的是一種類似通知的效果,本身是不帶負(fù)載的。

3.3.2、TencentOS tiny RTOS事件實(shí)踐

關(guān)于怎么使用事件,可以參考騰訊物聯(lián)網(wǎng)終端操作系統(tǒng)開發(fā)指南.pdf文檔,以下工程基于多任務(wù)例程修改,我們?cè)诙嗳蝿?wù)例程的基礎(chǔ)上,移植了multi_button組件,這個(gè)組件的移植方法在之前寫小熊派相關(guān)的文章中都有詳細(xì)的方法,這里就不再多說了,參考文章如下:

第1期 | MultiButton,一個(gè)小巧簡(jiǎn)單易用的事件驅(qū)動(dòng)型按鍵驅(qū)動(dòng)模塊

開源按鍵組件MultiButton支持菜單操作(事件驅(qū)動(dòng)型)

這里的button_ticks()我把它放在SysTick_Handler函數(shù)中進(jìn)行處理,實(shí)現(xiàn)如下:

/**
??*?@brief?This?function?handles?System?tick?timer.
??*/

void?SysTick_Handler(void)
{
????/*?USER?CODE?BEGIN?SysTick_IRQn?0?*/
????static?uint8_t?timer_ticks?=?0?;
????++timer_ticks?;
?????//5ms循環(huán)調(diào)用一次button_ticks();
????if(5?==?timer_ticks)
????{
????????timer_ticks?=?0?;
????????button_ticks();
????}

????/*?USER?CODE?END?SysTick_IRQn?0?*/
????HAL_IncTick();

????/*?USER?CODE?BEGIN?SysTick_IRQn?1?*/
????if(tos_knl_is_running())
????{
????????tos_knl_irq_enter();
????????tos_tick_handler();
????????tos_knl_irq_leave();
????}

????/*?USER?CODE?END?SysTick_IRQn?1?*/
}

接下來進(jìn)入事件程序的編寫,我們主要實(shí)現(xiàn)以下兩個(gè)功能:

  • 定義任務(wù)task1,用于初始化multi_button,通過按鍵回調(diào)發(fā)送事件
  • 定義任務(wù)task2,用于接收task1發(fā)送過來的事件,并進(jìn)行處理

main.c

定義multi_button結(jié)構(gòu)體變量以及事件相關(guān)的變量

#include?"multi_button.h"
/*創(chuàng)建一個(gè)按鍵事件*/
k_event_t?key_event;
//創(chuàng)建幾個(gè)按鍵的事件標(biāo)志
const?k_event_flag_t?event_key1?=?(k_event_flag_t)(1?<0);
const?k_event_flag_t?event_key2?=?(k_event_flag_t)(1?<1);
const?k_event_flag_t?event_key3?=?(k_event_flag_t)(1?<2);
const?k_event_flag_t?event_key4?=?(k_event_flag_t)(1?<3);
const?k_event_flag_t?event_key5?=?(k_event_flag_t)(1?<4);
//定義描述按鍵的結(jié)構(gòu)體變量
struct?Button?button1,?button2,?button3,?button4;

定義按鍵電平讀取以及按鍵處理的函數(shù):

uint8_t?key1_read_pin(void);
uint8_t?key2_read_pin(void);
uint8_t?key3_read_pin(void);
uint8_t?key4_read_pin(void);
void?key_handler(void*?btn);

uint8_t?key1_read_pin(void)
{
????return?HAL_GPIO_ReadPin(KEY1_GPIO_Port,?KEY1_Pin);
}
uint8_t?key2_read_pin(void)
{
????return?HAL_GPIO_ReadPin(KEY2_GPIO_Port,?KEY2_Pin);
}
uint8_t?key3_read_pin(void)
{
????return?HAL_GPIO_ReadPin(KEY3_GPIO_Port,?KEY3_Pin);
}
uint8_t?key4_read_pin(void)
{
????return?HAL_GPIO_ReadPin(KEY4_GPIO_Port,?KEY4_Pin);
}
//按鍵處理
void?key_handler(void*?btn)
{
????struct?Button?*button?=?btn?;
????if(btn?==?&button1)
????{
??????if(button->event?==?PRESS_DOWN)
????????tos_event_post(&key_event,?event_key1);
??????else?if(button->event?==?PRESS_UP)
????????tos_event_post(&key_event,?event_key5);
????}
????else?if(btn?==?&button2)
????{
??????if(button->event?==?PRESS_DOWN)
????????tos_event_post(&key_event,?event_key2);
??????else?if(button->event?==?PRESS_UP)
????????tos_event_post(&key_event,?event_key5);
????}
????else?if(btn?==?&button3)
????{
??????if(button->event?==?PRESS_DOWN)
????????tos_event_post(&key_event,?event_key3);
??????else?if(button->event?==?PRESS_UP)
????????tos_event_post(&key_event,?event_key5);
????}
????else?if(btn?==?&button4)
????{
??????if(button->event?==?PRESS_DOWN)
????????tos_event_post(&key_event,?event_key4);
??????else?if(button->event?==?PRESS_UP)
????????tos_event_post(&key_event,?event_key5);
????}
}

在main函數(shù)中:

/**
??*?@brief??The?application?entry?point.
??*?@retval?int
??*/

int?main(void)
{
????/*?USER?CODE?BEGIN?1?*/

????/*?USER?CODE?END?1?*/

????/*?MCU?Configuration--------------------------------------------------------*/

????/*?Reset?of?all?peripherals,?Initializes?the?Flash?interface?and?the?Systick.?*/
????HAL_Init();

????/*?USER?CODE?BEGIN?Init?*/

????/*?USER?CODE?END?Init?*/

????/*?Configure?the?system?clock?*/
????SystemClock_Config();

????/*?USER?CODE?BEGIN?SysInit?*/

????/*?USER?CODE?END?SysInit?*/

????/*?Initialize?all?configured?peripherals?*/
????MX_GPIO_Init();
????MX_USART2_UART_Init();
????MX_I2C3_Init();
????/*?USER?CODE?BEGIN?2?*/
????OLED_Init();
????OLED_Clear();
????OLED_ShowString(0,?0,?(uint8_t*)"TencentOS?tiny",?16);
????OLED_ShowString(0,?2,?(uint8_t*)"Bruce.yang",?16);
????//初始化內(nèi)核
????osKernelInitialize();
????//創(chuàng)建一個(gè)按鍵事件
????tos_event_create(&key_event,?(k_event_flag_t)0u);
????//創(chuàng)建并啟動(dòng)一個(gè)任務(wù)用于通過按鍵發(fā)送事件
????osThreadCreate(osThread(task1),?NULL);
????//創(chuàng)建并啟動(dòng)一個(gè)任務(wù)用于接收按鍵事件并執(zhí)行相應(yīng)的軟件邏輯
????osThreadCreate(osThread(task2),?NULL);
????//啟動(dòng)TencentOS?tiny內(nèi)核
????osKernelStart();
????/*?USER?CODE?END?2?*/

????/*?Infinite?loop?*/
????/*?USER?CODE?BEGIN?WHILE?*/
????while?(1)
????{
????????/*?USER?CODE?END?WHILE?*/

????????/*?USER?CODE?BEGIN?3?*/
????}

????/*?USER?CODE?END?3?*/
}

編譯后下載到EVB_MX+開發(fā)板后,運(yùn)行結(jié)果如下:

當(dāng)分別按下四個(gè)按鍵后,task2接收到具體消息后執(zhí)行不同的邏輯

3.3.3 總結(jié)

概念性總結(jié):

  • 事件區(qū)別于信號(hào)量,信號(hào)量是0-1傳遞,而事件可以傳遞多個(gè)信息
  • 事件是用于RTOS任務(wù)間傳遞的一種沒有信息負(fù)載的信號(hào)類信息

使用總結(jié):

詳情請(qǐng)參考騰訊物聯(lián)網(wǎng)終端操作系統(tǒng)開發(fā)指南.pdf文檔

3.4、TencentOS tiny RTOS隊(duì)列

3.4.1、為什么要采用RTOS隊(duì)列?

隊(duì)列也是任務(wù)間傳遞信息的一種方式,它和事件最本質(zhì)的區(qū)別就是,事件傳遞沒有負(fù)載,而隊(duì)列的傳遞是包含數(shù)據(jù)負(fù)載的,在事件章節(jié)中,當(dāng)我們按下按鍵的時(shí)候其中一個(gè)任務(wù)發(fā)出事件,另一個(gè)任務(wù)則接收事件,而接收的這個(gè)事件是非常單一的,除此之外并沒有更多具體的新信息載體,而隊(duì)列就是為了解決這個(gè)問題而誕生的,比如串口接收數(shù)據(jù),當(dāng)數(shù)據(jù)接收滿了,此時(shí)我們就可以使用隊(duì)列將接收滿的數(shù)據(jù)通過隊(duì)列的信息發(fā)出去,然后任務(wù)里進(jìn)行接收處理。

3.4.2、TencentOS tiny RTOS隊(duì)列實(shí)踐

關(guān)于怎么使用隊(duì)列,可以參考騰訊物聯(lián)網(wǎng)終端操作系統(tǒng)開發(fā)指南.pdf文檔,但該文檔的API過老,可能不適合現(xiàn)在的版本,于是找來了一個(gè)新版的API,參考網(wǎng)友修改的,以下工程基于多任務(wù)例程修改:

main.c

#define?STK_SIZE_TASK_RECEIVER??????512
#define?STK_SIZE_TASK_SENDER????????512

#define?PRIO_TASK_RECEIVER_HIGHER_PRIO??????4
#define?PRIO_TASK_RECEIVER_LOWER_PRIO???????(PRIO_TASK_RECEIVER_HIGHER_PRIO?+?1)

#define?MESSAGE_MAX?????10

k_stack_t?stack_task_receiver_higher_prio[STK_SIZE_TASK_RECEIVER];
k_stack_t?stack_task_receiver_lower_prio[STK_SIZE_TASK_RECEIVER];
k_stack_t?stack_task_sender[STK_SIZE_TASK_SENDER];

uint8_t?msg_pool[MESSAGE_MAX?*?sizeof(void?*)];

k_task_t?task_receiver_higher_prio;
k_task_t?task_receiver_lower_prio;
k_task_t?task_sender;

k_msg_q_t?msg_q;

void?entry_task_receiver_higher_prio(void?*arg)
{
????k_err_t?err;
????void?*msg_received;

????while?(K_TRUE)
????{
????????err?=?tos_msg_q_pend(&msg_q,?&msg_received,?TOS_TIME_FOREVER);

????????if?(err?==?K_ERR_NONE)
????????{
????????????printf("higher:?msg?incoming[%s]\n",?(char?*)msg_received);
????????}
????}
}

void?entry_task_receiver_lower_prio(void?*arg)
{
????k_err_t?err;
????void?*msg_received;

????while?(K_TRUE)
????{
????????err?=?tos_msg_q_pend(&msg_q,?&msg_received,?TOS_TIME_FOREVER);

????????if?(err?==?K_ERR_NONE)
????????{
????????????printf("lower:?msg?incoming[%s]\n",?(char?*)msg_received);
????????}
????}
}

void?entry_task_sender(void?*arg)
{
????int?i?=?1;
????char?*msg_to_one_receiver?=?"message?for?one?receiver(with?highest?priority)";
????char?*msg_to_all_receiver?=?"message?for?all?receivers";

????while?(K_TRUE)
????{
????????if?(i?==?2)
????????{
????????????printf("sender:?send?a?message?to?one?receiver,?and?shoud?be?the?highest?priority?one\n");
????????????tos_msg_q_post(&msg_q,?msg_to_one_receiver);
????????}

????????if?(i?==?3)
????????{
????????????printf("sender:?send?a?message?to?all?recevier\n");
????????????tos_msg_q_post_all(&msg_q,?msg_to_all_receiver);
????????}

????????if?(i?==?4)
????????{
????????????printf("sender:?send?a?message?to?one?receiver,?and?shoud?be?the?highest?priority?one\n");
????????????tos_msg_q_post(&msg_q,?msg_to_one_receiver);
????????}

????????if?(i?==?5)
????????{
????????????printf("sender:?send?a?message?to?all?recevier\n");
????????????tos_msg_q_post_all(&msg_q,?msg_to_all_receiver);
????????}

????????tos_task_delay(1000);
????????++i;
????}
}

main函數(shù)實(shí)現(xiàn):

/**
??*?@brief??The?application?entry?point.
??*?@retval?int
??*/

int?main(void)
{
????/*?USER?CODE?BEGIN?1?*/

????/*?USER?CODE?END?1?*/

????/*?MCU?Configuration--------------------------------------------------------*/

????/*?Reset?of?all?peripherals,?Initializes?the?Flash?interface?and?the?Systick.?*/
????HAL_Init();

????/*?USER?CODE?BEGIN?Init?*/

????/*?USER?CODE?END?Init?*/

????/*?Configure?the?system?clock?*/
????SystemClock_Config();

????/*?USER?CODE?BEGIN?SysInit?*/

????/*?USER?CODE?END?SysInit?*/

????/*?Initialize?all?configured?peripherals?*/
????MX_GPIO_Init();
????MX_USART2_UART_Init();
????MX_I2C3_Init();
????/*?USER?CODE?BEGIN?2?*/
????OLED_Init();
????OLED_Clear();
????OLED_ShowString(0,?0,?(uint8_t*)"TencentOS?tiny",?16);
????OLED_ShowString(0,?2,?(uint8_t*)"Bruce.yang",?16);
????//初始化內(nèi)核
????osKernelInitialize();
????tos_msg_q_create(&msg_q,?msg_pool,?MESSAGE_MAX);
????(void)tos_task_create(&task_receiver_higher_prio,?"receiver_higher_prio",
??????????????????????????entry_task_receiver_higher_prio,?NULL,?PRIO_TASK_RECEIVER_HIGHER_PRIO,
??????????????????????????stack_task_receiver_higher_prio,?STK_SIZE_TASK_RECEIVER,?0);
????(void)tos_task_create(&task_receiver_lower_prio,?"receiver_lower_prio",
??????????????????????????entry_task_receiver_lower_prio,?NULL,?PRIO_TASK_RECEIVER_LOWER_PRIO,
??????????????????????????stack_task_receiver_lower_prio,?STK_SIZE_TASK_RECEIVER,?0);
????(void)tos_task_create(&task_sender,?"sender",?entry_task_sender,?NULL,
??????????????????????????4,?stack_task_sender,?STK_SIZE_TASK_SENDER,?0);
????//啟動(dòng)內(nèi)核
????osKernelStart();
????/*?USER?CODE?END?2?*/

????/*?Infinite?loop?*/
????/*?USER?CODE?BEGIN?WHILE?*/
????while?(1)
????{
????????/*?USER?CODE?END?WHILE?*/

????????/*?USER?CODE?BEGIN?3?*/
????}

????/*?USER?CODE?END?3?*/
}

編譯后下載到EVB_MX+開發(fā)板后,運(yùn)行結(jié)果如下:

3.4.3、總結(jié)

概念性總結(jié):

  • 事件傳遞不帶信息負(fù)載,而隊(duì)列是帶信息負(fù)載的
  • 隊(duì)列除了可以告訴我們發(fā)生了什么事,還可以告訴我們發(fā)生這件事情的詳細(xì)過程

使用總結(jié):

詳情請(qǐng)參考騰訊物聯(lián)網(wǎng)終端操作系統(tǒng)開發(fā)指南.pdf文檔

4、總結(jié)

關(guān)于TencentOS tiny還有非常多的組件可以學(xué)習(xí),這里只是列出了最常用的幾種,最后我們給本文做下簡(jiǎn)短的總結(jié):

  • 多任務(wù)

解決復(fù)雜需求、實(shí)時(shí)性問題。

  • 互斥鎖

解決不可重入,資源的競(jìng)爭(zhēng)關(guān)系。

  • 信號(hào)量

解決任務(wù)間同步問題,典型為生產(chǎn)者-消費(fèi)者的問一體。

  • 事件

解決任務(wù)間同步問題,相比信號(hào)量,事件可以傳遞多個(gè),但不帶負(fù)載。

  • 隊(duì)列

解決任務(wù)間傳遞帶負(fù)載的問題。

案例下載

公眾號(hào)后臺(tái)回復(fù):TencentOS tiny即可獲取本節(jié)所有程序案例及參考文檔下載鏈接。

全文參考資料

騰訊物聯(lián)網(wǎng)終端操作系統(tǒng)SDK文檔.pdf

騰訊物聯(lián)網(wǎng)終端操作系統(tǒng)開發(fā)指南.pdf

TencentOS tiny技術(shù)講解與開發(fā)實(shí)踐PPT.pdf

云加社區(qū)沙龍(騰訊物聯(lián)網(wǎng)操作系統(tǒng)TencentOS tiny架構(gòu)解析與實(shí)踐).pdf

公眾號(hào)粉絲福利時(shí)刻

這里我給大家申請(qǐng)到了福利,本公眾號(hào)讀者購買小熊派開發(fā)板可享受9折優(yōu)惠,有需要購買小熊派以及騰訊物聯(lián)網(wǎng)開發(fā)板的朋友,淘寶搜索即可,跟客服說你是公眾號(hào):嵌入式云IOT技術(shù)圈 的粉絲,立享9折優(yōu)惠!

往期精彩

網(wǎng)紅騰訊物聯(lián)網(wǎng)開發(fā)板終極開箱評(píng)測(cè),讓我們一睹為快!

STM32硬核DIY機(jī)械鍵盤|藍(lán)牙USB雙模|燈控

一個(gè)超火超給力的STM32開源疫情監(jiān)控項(xiàng)目

一個(gè)超酷的開源uHand2.0機(jī)械手掌項(xiàng)目

居民身份證閱讀器產(chǎn)品開發(fā)學(xué)習(xí)心得(再談標(biāo)準(zhǔn)-軟件-協(xié)議)

覺得本次分享的文章對(duì)您有幫助,隨手點(diǎn)[在看]并轉(zhuǎn)發(fā)分享,也是對(duì)我的支持。

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問題,請(qǐng)聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢(shì)抑制與過流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問題卻十分常見,不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車場(chǎng)照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢(shì)逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對(duì)周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉