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

當前位置:首頁 > > 充電吧
[導讀]使用Xmodem有一段時間了,使用起來移植性能不夠,通過這次徹底拋離了底層通信部分,可以用在任何通信接口上面了,跟底層的通信已經(jīng)無關了,使用了大量的回調,回調主要完成通信的收發(fā),以及數(shù)據(jù)存儲等功能,我

使用Xmodem有一段時間了,使用起來移植性能不夠,通過這次徹底拋離了底層通信部分,可以用在任何通信接口上面了,跟底層的通信已經(jīng)無關了,使用了大量的回調,回調主要完成通信的收發(fā),以及數(shù)據(jù)存儲等功能,我目前主要使用在STM32 IAP升級(寫入到內部flash),app升級(寫入到外部flash W25Q128),字庫以及各種編碼下載(寫入到外部flash W25Q128)。

//數(shù)據(jù)包格式比較簡單


//	Xmodem?包格式
//	Byte1?				Byte2?			Byte3?				Byte4~131?		Byte132~133
//	Start?Of?Hearder?	Packet?Number?	~(Packet?Number)?	Packet?Data?	16-Bit?CRC


//1K-Xmodem?包格式
//	Byte1?				Byte2?			Byte3?				Byte4~1027?	Byte1028~1029
//	Start?Of?Hearder?	Packet?Number?	~(Packet?Number)?	Packet?Data?	16-Bit?CRC


//c文件



/*************************************************************************************************************
?*?文件名:????????????Xmodem.c
?*?功能:????????????Xmodem協(xié)議實現(xiàn)
?*?作者:????????????cp1300@139.com
?*?創(chuàng)建時間:????????2014-08-19
?*?最后修改時間:????2017-09-05
?*?詳細:????????????使用串口實現(xiàn)Xmodem協(xié)議應用層
????????????????????2017-03-23:修改采用回調以及句柄方式,可移植性更強
????????????????????2017-04-04:增加發(fā)送延時
????????????????????2017-09-05:發(fā)送NAK與結束增加延時,防止發(fā)送過快,并且修改如果通信超時則發(fā)送NAK,大大提高通信可靠性
????????????????????2017-09-06:修復第一包數(shù)據(jù)丟失問題,增加數(shù)據(jù)包id重復檢查,大大提高數(shù)據(jù)的可靠性,防止重復的數(shù)據(jù)包
*************************************************************************************************************/
#include?"system.h"
#include?"usart.h"
#include?"main.h"
#include?"Xmodem.h"
#if?SYS_WDG_EN_
#include?"wdg.h"????
#endif????

//調試開關
#define?XMODEM_DBUG????0
#if?XMODEM_DBUG
????#include?"system.h"
????#define?xmodem_debug(format,...)????uart_printf(format,##__VA_ARGS__)
#else
????#define?xmodem_debug(format,...)????/
/
#endif????//XMODEM_DBUG



//????Xmodem?包格式
//????Byte1?????????????????Byte2?????????????Byte3?????????????????Byte4~131?????????Byte132~133
//????Start?Of?Hearder?????Packet?Number?????~(Packet?Number)?????Packet?Data?????16-Bit?CRC


//1K-Xmodem?包格式
//????Byte1?????????????????Byte2?????????????Byte3?????????????????Byte4~1027?????Byte1028~1029
//????Start?Of?Hearder?????Packet?Number?????~(Packet?Number)?????Packet?Data?????16-Bit?CRC



/*************************************************************************************************************************
*?函數(shù)????????????:????bool?XMODE_Init(XMODE_HANDLE?*pHandle,
????????????????????????bool?(*?pSendData)(u8?*pDataBuff,?u16?DataLen),?
????????????????????????int?(*?pReadData)(u8?**pDataBuff,?u8?ByteTimeOut,?u16?TimeOut,?u16?*pReceiveDelay),?
????????????????????????void?(*pClearRxData)(void),
????????????????????????bool?(*pReceivePacket)(u8?*pPackData,u16?PackSize,u32?RecDataSize),
????????????????????????bool?(*pTransEnd)(bool?isTransOK,?u32?RecDataSize))
*?功能????????????:????初始化XMODE
*?參數(shù)????????????:????pHandle:句柄;
????????????????????pSendData:發(fā)送回調函數(shù)(pDataBuff:發(fā)送數(shù)據(jù)緩沖區(qū),DataLen:發(fā)送數(shù)據(jù)長度)
????????????????????pReadData:接收數(shù)據(jù)回調函數(shù),會等待直到數(shù)據(jù)被寫入到接收緩沖區(qū)(pDataBuff:接收數(shù)據(jù)緩沖區(qū),ByteTimeOut:等待的字節(jié)超時時間,單位ms,TimeOut:數(shù)據(jù)包超時時間,單位ms),pReceiveDelay:返回接收延時,單位ms
????????????????????pClearRxData:清除接收數(shù)據(jù)緩沖區(qū)回調函數(shù)
????????????????????pReceivePacket:收到一包數(shù)據(jù)后的回調函數(shù),(返回false會退出通信)用于應用層對數(shù)據(jù)進行存儲(pPackData:接收到的數(shù)據(jù)包,PackSize:包大??;RecDataSize:已經(jīng)接收的數(shù)據(jù)包大小,不含當前包的數(shù)據(jù))
????????????????????pTransEnd:傳輸結束時回調函數(shù),(返回false會退出通信)用于傳輸結束的處理(isTransOK:TRUE,傳輸正常完成,F(xiàn)ALSE:傳輸錯誤結束;RecDataSize:總共收到的數(shù)據(jù)大?。?*?返回????????????:????TRUE:初始化成;FALSE:初始化錯誤
*?依賴????????????:????通信接口
*?作者????????????:????cp1300@139.com
*?時間????????????:????2013-05-08
*?最后修改時間?????:?????2017-03-23
*?說明????????????:?????XMODE通信協(xié)議通信接口初始化,默認超時時間為等待啟動30秒,數(shù)據(jù)包超時2秒
;????????????????????????????????//清除接收數(shù)據(jù)緩沖區(qū)
*************************************************************************************************************************/
bool?XMODE_Init(XMODE_HANDLE?*pHandle,bool?(*?pSendData)(u8?*pDataBuff,?u16?DataLen),?int?(*?pReadData)(u8?**pDataBuff,?u8?ByteTimeOut,?u16?TimeOut,?u16?*pReceiveDelay),?
????void?(*pClearRxData)(void),bool?(*pReceivePacket)(u8?*pPackData,u16?PackSize,u32?RecDataSize),bool?(*pTransEnd)(bool?isTransOK,?u32?RecDataSize))
{
????if(pHandle?==?NULL)?return?FALSE;????????????????????//錯誤,無效的指針
????pHandle->RecDataSize?=?0;????????????????????????????//接收到的數(shù)據(jù)大小
????pHandle->RecPackCnt?=?0;????????????????????????????//接收到的數(shù)據(jù)包計數(shù)
????pHandle->pSendData?=?pSendData;????????????????????????//發(fā)送回調指針,????發(fā)送數(shù)據(jù)回調函數(shù)
????pHandle->pReadData?=?pReadData;????????????????????????//讀取數(shù)據(jù)回調指針,>0返回接收到的數(shù)據(jù)長度,否則失敗
????pHandle->pClearRxData?=?pClearRxData;????????????????//清除接收數(shù)據(jù)緩沖區(qū)
????pHandle->pReceivePacket?=?pReceivePacket;????????????//收到數(shù)據(jù)包回調指針
????pHandle->pTransEnd?=?pTransEnd;????????????????????????//傳輸結束時回調(可能是出錯結束)
????pHandle->WaitStartTimeOutSer?=?30;????????????????????//等待啟動傳輸超時時間
????pHandle->PackTimeOutSer?=?2;????????????????????????//數(shù)據(jù)包超時時間
????pHandle->pXMODEM_128Pack?=?NULL;????????????????????//128B數(shù)據(jù)包指針
????pHandle->pXMODEM_1KPack?=?NULL;????????????????????????//1KB數(shù)據(jù)包指針
????pHandle->TransRetry?=?10;????????????????????????????//失敗重試次數(shù),默認10次
????pHandle->TxByteTimeUs?=?0;????????????????????????????//發(fā)送延時默認為0
????
????return?TRUE;
}


/*************************************************************************************************************************
*?函數(shù)????????????:????bool?XMODE_SetTimeOut(XMODE_HANDLE?*pHandle,?u16?WaitStartTimeOutSer,?u16?PackTimeOutSer,?u8?TransRetry,u8?TxByteTimeUs)
*?功能????????????:????設置XMODE超時時間
*?參數(shù)????????????:????pHandle:句柄;WaitStartTimeOutSer:等待啟動超時時間,單位秒鐘;PackTimeOutSer:數(shù)據(jù)包超時時間,單位秒鐘;TransRetry:出錯重試次數(shù),1-255次;TxByteTimeUs:發(fā)送字節(jié)延時
*?返回????????????:????TRUE:初始化成;FALSE:初始化錯誤
*?依賴????????????:????通信接口
*?作者????????????:????cp1300@139.com
*?時間????????????:????2013-05-08
*?最后修改時間?????:?????2017-03-23
*?說明????????????:?????設置超時時間
*************************************************************************************************************************/
bool?XMODE_SetTimeOut(XMODE_HANDLE?*pHandle,?u16?WaitStartTimeOutSer,?u16?PackTimeOutSer,?u8?TransRetry,u8?TxByteTimeUs)
{
????if(pHandle?==?NULL)?return?FALSE;????????????????????????????????????//錯誤,無效的指針
????pHandle->WaitStartTimeOutSer?=?WaitStartTimeOutSer;????????????????????//等待啟動傳輸超時時間
????if(pHandle->WaitStartTimeOutSer?<?1)?pHandle->WaitStartTimeOutSer?=?1;
????pHandle->PackTimeOutSer?=?PackTimeOutSer;????????????????????????????//數(shù)據(jù)包超時時間
????if(pHandle->PackTimeOutSer?<?1)?pHandle->PackTimeOutSer?=?1;
????pHandle->TransRetry?=?TransRetry;????????????????????????????????????//出錯重試次數(shù)
????if(pHandle->TransRetry?<?1)?pHandle->TransRetry?=?1;
????pHandle->TxByteTimeUs?=?TxByteTimeUs;????????????????????????????????//發(fā)送字節(jié)延時,用于RS485接口,發(fā)送后需要進行延時
????
????return?TRUE;
}

/*************************************************************************************************************************
*?函數(shù)????????????:????int?XMODEM_Start(XMODE_HANDLE?*pHandle,?u8?**pRxBuff)
*?功能????????????:????發(fā)送啟動請求
*?參數(shù)????????????:????pHandle:句柄;pRxBuff:接收緩沖區(qū)(存放第一包數(shù)據(jù))
*?返回????????????:????WaitStartTimeOutSer*10;????????????//轉換為100m單位
????int?len;
????
????if(pHandle?==?NULL)?return?FALSE;
????pHandle->DataBuff[0]?=?X_CRC_MODE;????????????????????????//采用CRC模式的校驗請求頭
????while(TimeOut?--)
????{
????????pHandle->pSendData(pHandle->DataBuff,1);????????????//發(fā)送請求信號
????????if(pHandle->TxByteTimeUs?>?0)?XMODEM_DelayMS((10*pHandle->TxByteTimeUs)/1000+1);????//發(fā)送延時
????????pHandle->pClearRxData();????????????????????????????//清除接收
????????len?=?pHandle->pReadData(pRxBuff,10,100,NULL);????????//接收數(shù)據(jù)
????????if(len?>?0)????????????????????//等待接收
????????{
????????????pHandle->RecDataSize?=?0;????????????????????????//接收到的數(shù)據(jù)大小清零
????????????pHandle->RecPackCnt?=?0;????????????????????????//接收到的數(shù)據(jù)包計數(shù)清零
????????????return?len;
????????}????????????????
????????????
#if?SYS_WDG_EN_
????????IWDG_Feed();????????????????????????????????????????//喂狗
#endif????????????
????}
????return?-1;
}





//發(fā)送ACK
__inline?void?XMODEM_SendACK(XMODE_HANDLE?*pHandle)
{
????pHandle->DataBuff[0]?=?(u8)X_ACK;
????pHandle->pSendData(pHandle->DataBuff,1);????????????//發(fā)送請求信號
????if(pHandle->TxByteTimeUs?>?0)?XMODEM_DelayMS((10*pHandle->TxByteTimeUs)/1000+1);????//發(fā)送延時
}


//發(fā)送NAK
__inline?void?XMODEM_SendNAK(XMODE_HANDLE?*pHandle)
{
????XMODEM_DelayMS(20);
????pHandle->DataBuff[0]?=?(u8)X_NAK;
????pHandle->pSendData(pHandle->DataBuff,1);????????????//發(fā)送請求信號
????if(pHandle->TxByteTimeUs?>?0)?XMODEM_DelayMS((10*pHandle->TxByteTimeUs)/1000+1);????//發(fā)送延時
}


//取消傳輸
__inline?void?XMODEM_CancelTran(XMODE_HANDLE?*pHandle)
{
????XMODEM_DelayMS(20);
????pHandle->DataBuff[0]?=?(u8)X_CAN;
????pHandle->pSendData(pHandle->DataBuff,1);????????????//發(fā)送請求信號
????if(pHandle->TxByteTimeUs?>?0)?XMODEM_DelayMS((10*pHandle->TxByteTimeUs)/1000+1);????//發(fā)送延時
}



//判斷是否結束
__inline?bool?XMODEM_isTranEnd(u8?Data,?XMODE_HANDLE?*pHandle)
{
????if(Data?==?X_EOT)?return?TRUE;
????else?return?FALSE;
}




/*************************************************************************************************************************
*?函數(shù)????????????:????u16?XMODEM_CRC16(u8?*pData,?u16?DataLen)
*?功能????????????:????crc16校驗
*?參數(shù)????????????:????pData:數(shù)據(jù)緩沖區(qū);DataLen:數(shù)據(jù)長度
*?返回????????????:????crc16結果
*?依賴????????????:????通信接口
*?作者????????????:????cp1300@139.com
*?時間????????????:????2013-05-08
*?最后修改時間?????:?????2017-03-23
*?說明????????????:?????用于通信數(shù)據(jù)校驗,僅用于XMODEM,不可與modbus-rtu協(xié)議用的crc16混用(兩者計算結果會不一致)
????????????????????多項式碼0x1021
*************************************************************************************************************************/
u16?XMODEM_CRC16(u8?*pData,?u16?DataLen)
{
????u16?crc?=?0;
????char?i;
????u16?j;

????for(j?=?0;j?<?DataLen;j?++)
????{
????????crc?=?crc?^?(int)?*pData++?<<?8;
????????i?=?8;
????????do
????????{
????????????if?(crc?&?0x8000)
????????????????crc?=?crc?<<?1?^?0x1021;
????????????else
????????????????crc?=?crc?<<?1;
????????}?while?(--i);
????}

????return?(crc);
}



/*************************************************************************************************************************
*?函數(shù)????????????:????u32?XMODEM_DownloadFile(XMODE_HANDLE?*pHandle,?u32?MaxDataSize)
*?功能????????????:????使用XMODEM下載文件
*?參數(shù)????????????:????pHandle:句柄;MaxDataSize:限制最大下載數(shù)據(jù)量
*?返回????????????:????0:錯誤;其它:接收的數(shù)據(jù)長度
*?依賴????????????:????底層
*?作者????????????:????cp1300@139.com
*?時間????????????:????2013-05-08
*?最后修改時間?????:?????2017-03-23
*?說明????????????:?????使用CRC校驗模式,支持128,1K數(shù)據(jù)包
*************************************************************************************************************************/
u32?XMODEM_DownloadFile(XMODE_HANDLE?*pHandle,?u32?MaxDataSize)
{
????u16?crc16;
????u16?temp;
????u16?retry?=?0;
????int?len;
????bool?isStart?=?FALSE;
????u8?*pRxBuff;
????u8?LastPackCnt?=?0;????????????????????????//用于記錄上一次包序號,每次包序號不能重復
????
????len?=?XMODEM_Start(pHandle,?&pRxBuff);????//等待開始傳輸
????if(len?pClearRxData();????????????????????????????????????????????????????//清除接收緩沖區(qū)
????????????len?=?pHandle->pReadData(&pRxBuff,?2,pHandle->PackTimeOutSer*1000,NULL);????//接收數(shù)據(jù)
????????}
????????isStart?=?FALSE;????????????????//第一次開始傳輸狀態(tài)無效
????????if(len?pXMODEM_128Pack?=?(XMODEM_128B_PACK?*)pRxBuff;????????????????????//128B數(shù)據(jù)包指針
????????????pHandle->pXMODEM_1KPack?=?(XMODEM_1KB_PACK?*)pRxBuff;????????????????????//1KB數(shù)據(jù)包指針
????????????switch(pHandle->pXMODEM_128Pack->X_Start)
????????????{
????????????????case?X_SOH:????//128
????????????????{
????????????????????if(len?<?128)?
????????????????????{
????????????????????????XMODEM_SendNAK(pHandle);?//發(fā)送NAK?
????????????????????????retry++;
????????????????????}
????????????????????else
????????????????????{
????????????????????????crc16?=?XMODEM_CRC16(pHandle->pXMODEM_128Pack->X_PackData,?128);
????????????????????????temp?=?pHandle->pXMODEM_128Pack->X_CRC16H;
????????????????????????temp?<pXMODEM_128Pack->X_CRC16L;
????????????????????????if(crc16?!=?temp)????????????//CRC校驗錯誤,重傳
????????????????????????{
????????????????????????????XMODEM_SendNAK(pHandle);?//發(fā)送NAK?
????????????????????????????retry++;
????????????????????????}
????????????????????????else
????????????????????????{
????????????????????????????if(LastPackCnt!=pHandle->pXMODEM_128Pack->X_PackNum)?????//包序號不一樣
????????????????????????????{
????????????????????????????????LastPackCnt?=?pHandle->pXMODEM_128Pack->X_PackNum;????//記錄上一次的包序號
????????????????????????????????if(pHandle->pReceivePacket(pHandle->pXMODEM_128Pack->X_PackData,?128,?pHandle->RecDataSize)==FALSE)????//收到數(shù)據(jù)包,調用回調
????????????????????????????????{
????????????????????????????????????//用戶返回退出下載
????????????????????????????????????if(pHandle->pTransEnd?!=?NULL)????//判斷回調是否有效
????????????????????????????????????{
????????????????????????????????????????pHandle->pTransEnd(FALSE,?pHandle->RecDataSize);????//傳輸完成,調用回調,有錯誤
????????????????????????????????????}
????????????????????????????????????
????????????????????????????????????XMODEM_CancelTran(pHandle);????????????????????//發(fā)送結束傳輸
????????????????????????????????????XMODEM_DelayMS(10);
????????????????????????????????????XMODEM_CancelTran(pHandle);????????????????????//發(fā)送結束傳輸
????????????????????????????????????XMODEM_DelayMS(500);
????????????????????????????????????xmodem_debug("用戶取消下載!rn");
????????????????????????????????????return?0;
????????????????????????????????}
????????????????????????????????
????????????????????????????????pHandle->RecDataSize?+=?128;????????????????????//接收到的數(shù)據(jù)大小增加
????????????????????????????????pHandle->RecPackCnt?++;????????????????????????????//接收到的數(shù)據(jù)包計數(shù)增加

????????????????????????????????if(pHandle->RecDataSize?>?MaxDataSize)
????????????????????????????????{
????????????????????????????????????if(pHandle->pTransEnd?!=?NULL)????//判斷回調是否有效
????????????????????????????????????{
????????????????????????????????????????pHandle->pTransEnd(FALSE,?pHandle->RecDataSize);????//傳輸完成,調用回調,有錯誤
????????????????????????????????????}
????????????????????????????????????
????????????????????????????????????XMODEM_CancelTran(pHandle);????????????????????//發(fā)送結束傳輸
????????????????????????????????????XMODEM_DelayMS(10);
????????????????????????????????????XMODEM_CancelTran(pHandle);????????????????????//發(fā)送結束傳輸
????????????????????????????????????XMODEM_DelayMS(500);
????????????????????????????????????xmodem_debug("文件下載失敗,大小超出范圍(%dB)!rn",?MaxDataSize);
????????????????????????????????????return?0;
????????????????????????????????}
????????????????????????????}
????????????????????????????else????//故障,重復的數(shù)據(jù)包
????????????????????????????{
????????????????????????????????XMODEM_DelayMS(10);
????????????????????????????}

????????????????????????????XMODEM_SendACK(pHandle);????????????????????????//發(fā)送ACK響應
????????????????????????????retry?=?0;
????????????????????????}
????????????????????}????
????????????????}break;
????????????????case?X_STX:????//1k
????????????????{
????????????????????if(len?<?1024)?
????????????????????{
????????????????????????XMODEM_SendNAK(pHandle);?//發(fā)送NAK?
????????????????????????retry++;
????????????????????}
????????????????????else
????????????????????{
????????????????????????crc16?=?XMODEM_CRC16(pHandle->pXMODEM_1KPack->X_PackData,?1024);
????????????????????????temp?=?pHandle->pXMODEM_1KPack->X_CRC16H;
????????????????????????temp?<pXMODEM_1KPack->X_CRC16L;
????????????????????????if(crc16?!=?temp)????????????????????????????????????//CRC校驗錯誤,重傳
????????????????????????{
????????????????????????????XMODEM_SendNAK(pHandle);????????????????????????//發(fā)送NAK?
????????????????????????????retry++;
????????????????????????}
????????????????????????else
????????????????????????{
????????????????????????????if(LastPackCnt!=pHandle->pXMODEM_128Pack->X_PackNum)?????//包序號不一樣
????????????????????????????{
????????????????????????????????LastPackCnt?=?pHandle->pXMODEM_128Pack->X_PackNum;????//記錄上一次的包序號
????????????????????????????????
????????????????????????????????if(pHandle->pReceivePacket?!=?NULL)????//判斷回調是否有效
????????????????????????????????{
????????????????????????????????????if(pHandle->pReceivePacket(pHandle->pXMODEM_1KPack->X_PackData,?1024,?pHandle->RecDataSize)==FALSE)????//收到數(shù)據(jù)包,調用回調
????????????????????????????????????{
????????????????????????????????????????//用戶返回退出下載
????????????????????????????????????????if(pHandle->pTransEnd?!=?NULL)????//判斷回調是否有效
????????????????????????????????????????{
????????????????????????????????????????????pHandle->pTransEnd(FALSE,?pHandle->RecDataSize);????//傳輸完成,調用回調,有錯誤
????????????????????????????????????????}
????????????????????????????????????????
????????????????????????????????????????XMODEM_CancelTran(pHandle);????????????????????//發(fā)送結束傳輸
????????????????????????????????????????XMODEM_DelayMS(10);
????????????????????????????????????????XMODEM_CancelTran(pHandle);????????????????????//發(fā)送結束傳輸
????????????????????????????????????????XMODEM_DelayMS(500);
????????????????????????????????????????xmodem_debug("用戶取消下載!rn");
????????????????????????????????????????return?0;
????????????????????????????????????}
????????????????????????????????}
????????????????????????????????
????????????????????????????????pHandle->RecDataSize?+=?1024;????????????????????//接收到的數(shù)據(jù)大小增加
????????????????????????????????pHandle->RecPackCnt?++;????????????????????????????//接收到的數(shù)據(jù)包計數(shù)增加
????????????????????????????????
????????????????????????????????if(pHandle->RecDataSize?>?MaxDataSize)
????????????????????????????????{
????????????????????????????????????if(pHandle->pTransEnd?!=?NULL)????//判斷回調是否有效
????????????????????????????????????{
????????????????????????????????????????pHandle->pTransEnd(FALSE,?pHandle->RecDataSize);????//傳輸完成,調用回調,有錯誤
????????????????????????????????????}
????????????????????????????
????????????????????????????????????XMODEM_CancelTran(pHandle);????????????????????//發(fā)送結束傳輸
????????????????????????????????????XMODEM_DelayMS(10);
????????????????????????????????????XMODEM_CancelTran(pHandle);????????????????????//發(fā)送結束傳輸
????????????????????????????????????XMODEM_DelayMS(500);
????????????????????????????????????xmodem_debug("文件下載失敗,代碼超出范圍(%dB)!rn",?MaxDataSize);
????????????????????????????????????return?0;
????????????????????????????????}
????????????????????????????}
????????????????????????????else????//故障,重復的數(shù)據(jù)包
????????????????????????????{
????????????????????????????????XMODEM_DelayMS(10);
????????????????????????????}
????????????????????????????XMODEM_SendACK(pHandle);????????????????????????//發(fā)送ACK響應
????????????????????????????retry?=?0;
????????????????????????}
????????????????????}????
????????????????}break;
????????????????case?X_EOT:????//傳輸結束,最后一包
????????????????{
????????????????????if(pHandle->pTransEnd?!=?NULL)????//判斷回調是否有效
????????????????????{
????????????????????????if(pHandle->pTransEnd(TRUE,?pHandle->RecDataSize)?==?FALSE)????//傳輸完成,調用回調,有錯誤則退出
????????????????????????{
????????????????????????????XMODEM_CancelTran(pHandle);????????????????????//發(fā)送結束傳輸
????????????????????????????XMODEM_DelayMS(10);
????????????????????????????XMODEM_CancelTran(pHandle);????????????????????//發(fā)送結束傳輸
????????????????????????????XMODEM_DelayMS(500);
????????????????????????????xmodem_debug("用戶取消下載!rn");
????????????????????????????return?0;
????????????????????????}
????????????????????}
????????????????????XMODEM_SendACK(pHandle);
????????????????????retry?=?0;
????????????????????XMODEM_DelayMS(10);
????????????????????XMODEM_SendACK(pHandle);
????????????????????XMODEM_DelayMS(500);
????????????????????xmodem_debug("文件下載成功!rn");
????????????????????return?pHandle->RecDataSize;
????????????????}
????????????????default:XMODEM_SendNAK(pHandle);?retry++;break;
????????????}
????????}
????????
????????if(retry?>?pHandle->TransRetry)?????//重傳過多
????????{
????????????if(pHandle->pTransEnd?!=?NULL)????//判斷回調是否有效
????????????{
????????????????pHandle->pTransEnd(FALSE,?pHandle->RecDataSize);????//傳輸完成,調用回調,有錯誤
????????????}
????????????????????????
????????????XMODEM_CancelTran(pHandle);????????????????????????????//取消傳輸
????????????XMODEM_DelayMS(10);
????????????XMODEM_CancelTran(pHandle);????????????????????????????//取消傳輸
????????????XMODEM_DelayMS(500);
????????????xmodem_debug("下載失敗,重試次數(shù)過多!rn");
????????????return?0;
????????}
#if?SYS_WDG_EN_
????????IWDG_Feed();????????????????????????????????????????//喂狗
#endif
????}
}



//.h文件


/*************************************************************************************************************
?*?文件名:			Xmodem.h
?*?功能:			Xmodem協(xié)議實現(xiàn)
?*?作者:			cp1300@139.com
?*?創(chuàng)建時間:		2014-08-19
?*?最后修改時間:	2014-08-19
?*?詳細:			使用串口實現(xiàn)Xmodem協(xié)議應用層
*************************************************************************************************************/
#ifndef?_X_MODEM_H_
#define?_X_MODEM_H_
#include?"system.h"
#include?"USART.h"


#ifdef?_UCOS_II_	//支持ucos操作系統(tǒng),使用系統(tǒng)延時
#define?XMODEM_DelayMS(x)				OSTimeDlyHMSM(0,0,0,x)						//延時ms,最大延時999ms
#else
#define?XMODEM_DelayMS(x)				Delay_MS(x)						
#endif?//_UCOS_II_


//XMODEM?相關定義說明
#define?X_SOH		0x01		//?Xmodem數(shù)據(jù)頭
#define?X_STX		0x02		//?1K-Xmodem數(shù)據(jù)頭
#define?X_EOT		0x04		//?發(fā)送結束
#define?X_ACK		0x06		//?認可響應
#define?X_NAK		0x15		//?不認可響應
#define?X_CAN		0x18		//?撤銷傳送
#define?X_EOF		0x1A		//?填充數(shù)據(jù)包

//128B數(shù)據(jù)包格式
typedef?struct
{
	u8	X_Start;
	u8	X_PackNum;
	u8	X_bPackNum;
	u8	X_PackData[128];
	u8	X_CRC16H;
	u8	X_CRC16L;
}XMODEM_128B_PACK;


//1024B數(shù)據(jù)包格式
typedef?struct
{
	u8	X_Start;
	u8	X_PackNum;
	u8	X_bPackNum;
	u8	X_PackData[1024];
	u8	X_CRC16H;
	u8	X_CRC16L;
}XMODEM_1KB_PACK;



typedef?struct
{
	u32?RecDataSize;										//接收到的數(shù)據(jù)大小
	u32?RecPackCnt;											//接收到的數(shù)據(jù)包計數(shù)
	bool?(*?pSendData)(u8?*pDataBuff,?u16?DataLen);			//發(fā)送回調指針,	發(fā)送數(shù)據(jù)回調函數(shù)
	int?(*?pReadData)(u8?**pDataBuff,?u8?ByteTimeOut,?u16?TimeOut,?u16?*pReceiveDelay);	//讀取數(shù)據(jù)回調指針,>0返回接收到的數(shù)據(jù)長度,否則失敗
	bool?(*pReceivePacket)(u8?*pPackData,u16?PackSize,u32?RecDataSize);	//收到數(shù)據(jù)包回調指針,返回false會退出傳輸
	bool?(*pTransEnd)(bool?isTransOK,?u32?RecDataSize);		//傳輸結束回調指針,返回false會退出傳輸
	void?(*pClearRxData)(void);								//清除接收數(shù)據(jù)緩沖區(qū)
	XMODEM_128B_PACK?*pXMODEM_128Pack;						//128bit數(shù)據(jù)包格式
	XMODEM_1KB_PACK?*pXMODEM_1KPack;						//1K數(shù)據(jù)包格式
	u16?WaitStartTimeOutSer;								//等待啟動傳輸超時時間
	u16?PackTimeOutSer;										//數(shù)據(jù)包超時時間
	u8?TxByteTimeUs;										//發(fā)送字節(jié)延時,微秒,用于RS485通信延時
	u8?DataBuff[2];											//分配的臨時緩沖區(qū)
	u8?TransRetry;											//失敗重試次數(shù),默認10次
}XMODE_HANDLE;




//啟動傳輸校驗模式
typedef?enum
{
	X_CRC_MODE?=?'C',		//傳輸使用CRC16校驗模式
	X_ACC_MODE?=?X_NAK,		//傳輸使用累加校驗模式
}XMODEM_START_MODE;


//數(shù)據(jù)包大小
typedef?enum
{
	X_PACK128B?=?X_SOH,		//128B數(shù)據(jù)包
	X_PACK1kB?=?X_STX,		//1KB數(shù)據(jù)包
}XMODEM_PACK_MODE;

//XMODEM?通信初始化
bool?XMODE_Init(XMODE_HANDLE?*pHandle,?bool?(*?pSendData)(u8?*pDataBuff,?u16?DataLen),?int?(*?pReadData)(u8?**pDataBuff,?u8?ByteTimeOut,?u16?TimeOut,?u16?*pReceiveDelay),?
	void?(*pClearRxData)(void),bool?(*pReceivePacket)(u8?*pPackData,u16?PackSize,u32?RecDataSize),bool?(*pTransEnd)(bool?isTransOK,?u32?RecDataSize));
//XMODEM?超時設置
bool?XMODE_SetTimeOut(XMODE_HANDLE?*pHandle,?u16?WaitStartTimeOutSer,?u16?PackTimeOutSer,?u8?TransRetry,u8?TxByteTimeUs);
//XMODEM?下載數(shù)據(jù)
u32?XMODEM_DownloadFile(XMODE_HANDLE?*pHandle,?u32?MaxDataSize);


#endif?/*_X_MODEM_H_*/


下面是2個下載的例子,我主要是示意通信與存儲接口格式,實際使用需要按照自己的平臺進行移植


//例子1:下載程序到STM32內部flash,主要提供數(shù)據(jù)收發(fā)接口,以及存儲接口示意,這些接口需要根據(jù)自己的平臺做移植
/*************************************************************************************************************
?*?文件名:			UpgradeBIOS.c
?*?功能:			升級BIOS相關
?*?作者:			cp1300@139.com
?*?創(chuàng)建時間:		2017-05-16
?*?最后修改時間:	2017-05-16
?*?詳細:			使用xmodem直接刷STM32flash,如果失敗了請不要重啟,否則會無法進入系統(tǒng)
*************************************************************************************************************/
#include?"system.h"
#include?"usart.h"
#include?"main.h"
#include?"xmodem.h"
#include?"UpgradeBIOS.h"
#include?"STM32Flash.h"
#include?"w25x16.h"
#include?"STM32_CRC.h"
#include?"rtu.h"
#include?"board.h"
#if?SYS_WDG_EN_
#include?"wdg.h"
#endif
#include#define?UP_PROGRAM_STM32_BIOS_ADDR		STM32_FLASH_BASE	//BIOS程序內部flash基址


static?u32?UpgradeBiosDataSaveCnt?=?0;		//升級應用程序已經(jīng)存儲的數(shù)據(jù)大小

//升級文件接口XMODE句柄
XMODE_HANDLE?UpgradeBIOSHandle;


//發(fā)送數(shù)據(jù)接口
bool?UpgradeBiosSendData(u8?DataBuff[],?u16?DataLen)
{
	UARTx_SendData(UART_PRINTF_CH,?DataBuff,?DataLen);
	
	return?TRUE;
}


//接收數(shù)據(jù)接口
int?UpgradeBiosReadData(u8?**pDataBuff,u8?ByteTimeOutMs,?u16?TimeOutMs,?u16?*pReceiveDelayMs)
{
	u32?cnt?=?0;
	u16?TempTime;
	
	UARTx_ClearRxCnt(UART_PRINTF_CH);	//清除串口接收緩沖區(qū),開始結束數(shù)據(jù)
	if(ByteTimeOutMs?<?1)?ByteTimeOutMs?=?1;	//字節(jié)超時時間,2個幀之間的間隔最小時間
	TimeOutMs?/=?ByteTimeOutMs;
	TimeOutMs?+=?1;
	TempTime?=?TimeOutMs;
	while(TimeOutMs?--)
	{
		cnt?=?UARTx_GetRxCnt(UART_PRINTF_CH);
		OSTimeDlyHMSM(0,0,0,ByteTimeOutMs);;
		if((cnt?>?0)?&&?(cnt?==?UARTx_GetRxCnt(UART_PRINTF_CH)))
		{
			if(pReceiveDelayMs!=NULL)	//需要返回延時
			{
				*pReceiveDelayMs?=?(TempTime-TimeOutMs)*ByteTimeOutMs;
			}
			*pDataBuff?=?SysCommBuff;						//接收緩沖區(qū)
			
			return?cnt;
		}
#if?SYS_WDG_EN_
		IWDG_Feed();										//喂狗
#endif			
	}
	
	return?0;
}


//清除接收緩沖區(qū)
void?UpgradeBiosClearData(void)
{
	UARTx_ClearRxCnt(UART_PRINTF_CH);	//清除串口緩沖區(qū)
}


//收到數(shù)據(jù)包回調-用于寫數(shù)據(jù)到內部flash
bool?UpgradeBiosReceivePacketExitFlash(u8?*pPackData,u16?PackSize,u32?RecDataSize)
{
	if((PackSize?!=?128)?&&?(PackSize!=1024))?return?FALSE;										//xmodem只支持128字節(jié)或1024字節(jié)的數(shù)據(jù)包
	
	//寫入數(shù)據(jù)到內部flash
	STM32FLASH_Write(UP_PROGRAM_STM32_BIOS_ADDR+RecDataSize,?(u16?*)pPackData,?(PackSize+1)/2);
	UpgradeBiosDataSaveCnt?+=?PackSize;

	return?TRUE;
}


//傳輸結束時回調(可能是出錯結束)
bool?UpgradeBiosTransEndtExitFlash(bool?isTransOK,?u32?RecDataSize)
{
	if(isTransOK==FALSE)?return?FALSE;	//失敗返回
	
	if(UpgradeBiosDataSaveCnt?==?RecDataSize)?return?TRUE;
	if(UpgradeBiosDataSaveCnt?>?RecDataSize)?return?FALSE;			//存儲的數(shù)據(jù)不能大于接收的數(shù)據(jù)
	if((RecDataSize-UpgradeBiosDataSaveCnt)?>?0)?return?FALSE;		//不能有未存儲的數(shù)據(jù)

	return?FALSE;	//存儲出錯
}



//使用XMODEM下載數(shù)據(jù)到內部flash
//返回程序大小,如果失敗了返回<=0
int?XMODEM_DownloadFileToSTM32Flash(u32?MaxFileSize)
{
	XMODE_Init(&UpgradeBIOSHandle,?			//句柄
		UpgradeBiosSendData,?				//發(fā)送數(shù)據(jù)回調函數(shù)
		UpgradeBiosReadData,?				//讀取數(shù)據(jù)回調函數(shù)
		UpgradeBiosClearData,?				//清除接收數(shù)據(jù)緩沖回調函數(shù)
		UpgradeBiosReceivePacketExitFlash,?	//接收到數(shù)據(jù)包回調函數(shù)
		UpgradeBiosTransEndtExitFlash		//傳輸結束回調函數(shù)
		);
	UpgradeBiosDataSaveCnt?=?0;				//已經(jīng)存儲的數(shù)據(jù)大小清零
	return?XMODEM_DownloadFile(&UpgradeBIOSHandle,?MaxFileSize);
}



//使能系統(tǒng)命令行
#if?SYS_CMD_EN_
#include?"cmd.h"
#include?"string.h"

CMD_TYPE?const?CMD_UP_BIOS	=?{"UP?BIOS",?0XD3476564,?CMD_UpBIOS,?"tt升級BIOS"};				//升級BIOS程序


//進入升級BIOS模式
void?CMD_UpBIOS(char?*pStr)
{
	cmd_printf("已經(jīng)進入升級BIOS模式,等待連接,超時10S!rn>");
	cmd_printf("請在10S內進入Xmodem下載模式!rn>");
	RTC_DisableInt();									//關閉RTC中斷,防止喚醒后臺任務
	
	OSTaskSuspend(BACK_TASK_Prio);						//掛起后臺任務線程
	OSTaskSuspend(LED_TASK_Prio);						//掛起LED任務線程
	OSTaskSuspend(GPRS_TASK_Prio);						//掛起GPRS進程
	OSTaskSuspend(COLL_TASK_Prio);						//數(shù)據(jù)采集時間查詢進程
	OSTaskSuspend(OTHER_TASK_Prio);						//OTHER
	OSTaskSuspend(MODBUS1_TASK_Prio);					//MODBUS1	
	OSTaskSuspend(MODBUS2_TASK_Prio);					//MODBUS2
	OSTaskSuspend(KEY_TASK_Prio);						//KEY

	OSTimeDlyHMSM(0,0,0,500);							//延時500毫秒
	if(XMODEM_DownloadFileToSTM32Flash(100*1024)?==?0)//寫入BIOS程序
	{
		cmd_printf("升級BIOS失敗,重啟后將無法啟動,建議重新升級!rn");
	}
	else
	{
		cmd_printf("升級BIOS成功!rn");
	}
	CMD_Help(NULL);
	
	OSTaskResume(LED_TASK_Prio);						//恢復掛起LED任務線程
	OSTaskResume(GPRS_TASK_Prio);						//恢復掛起GPRS進程
	OSTaskResume(COLL_TASK_Prio);						//恢復數(shù)據(jù)采集時間查詢進程
	OSTaskResume(OTHER_TASK_Prio);						//恢復OTHER
	OSTaskResume(MODBUS1_TASK_Prio);					//恢復MODBUS1	
	OSTaskResume(MODBUS2_TASK_Prio);					//恢復MODBUS2
	OSTaskResume(KEY_TASK_Prio);						//恢復KEY
	
	RTC_EnableInt();									//恢復RTC中斷
}



#endif?//SYS_CMD_EN_



//例子2:下載字庫編碼到外部flash,使用的是SPI?接口flash,W25Q128,存儲接口稍有不同,因為我每次將數(shù)據(jù)集齊4K才進行存儲,這樣可以提高存儲效率,降低flash損耗,當然最后一包可能不足4K,會另外進行處理的。

/*************************************************************************************************************
?*?文件名:			DownFont.c
?*?功能:			下載字庫相關
?*?作者:			cp1300@139.com
?*?創(chuàng)建時間:		2017-03-29
?*?最后修改時間:	2017-03-29
?*?詳細:			使用xmodem或tFileModem下載文件
*************************************************************************************************************/
#include?"system.h"
#include?"usart.h"
#include?"main.h"
#include?"xmodem.h"
#include?"tFileModem.h"
#include?"upgrade.h"
#include?"STM32Flash.h"
#include?"STM32_CRC.h"
#if?SYS_WDG_EN_
#include?"wdg.h"
#endif
#include#include?"DownFont.h"
#include?"RTU.h"
#include?"BOARD.h"

#define?DOWN_FONT_EXIT_SECTOR		FLASH_BIN_SECTOR				//存儲到外部flash的位置


static?u32?DownFontDataSaveCnt?=?0;		//升級應用程序已經(jīng)存儲的數(shù)據(jù)大小


//收到數(shù)據(jù)包回調-用于寫數(shù)據(jù)到外部flash
//需要使用到W25X16的4K臨時緩沖區(qū),在升級與校驗的時候確保沒有其它線程訪問W25X16,最好掛起其它線程
bool?DownFontReceivePacketExitFlash(u8?*pPackData,u16?PackSize,u32?RecDataSize)
{
	if((PackSize?!=?128)?&&?(PackSize!=1024))?return?FALSE;										//xmodem只支持128字節(jié)或1024字節(jié)的數(shù)據(jù)包
	
	memcpy(&SPI_FLASH_BUF[RecDataSize%4096],?pPackData,?PackSize);
	if(((RecDataSize+PackSize)%4096)?==?0)														//4K對齊,一次寫入到外部flash
	{
		if(W25X16_EraseSector((RecDataSize+PackSize)/4096-1?+?DOWN_FONT_EXIT_SECTOR)?==?FALSE)	//擦除一個扇區(qū)
		{
			return?FALSE;
		}
		if(W25X16_WriteNoCheck(SPI_FLASH_BUF,?DOWN_FONT_EXIT_SECTOR*4096+RecDataSize+PackSize-4096,?4096)??==?FALSE)	//寫入一個扇區(qū)
		{
			return?FALSE;
		}
		DownFontDataSaveCnt?+=?4096;
	}
	
	return?TRUE;
}


//傳輸結束時回調(可能是出錯結束)
//由于需要4K對齊,因此最后一包不足4K需要單獨進行處理
//需要使用到W25X16的4K臨時緩沖區(qū),在升級與校驗的時候確保沒有其它線程訪問W25X16,最好掛起其它線程
bool?DownFontTransEndtExitFlash(bool?isTransOK,?u32?RecDataSize)
{
	if(isTransOK==FALSE)?return?FALSE;	//失敗返回
	
	if(DownFontDataSaveCnt?==?RecDataSize)?return?TRUE;
	if(DownFontDataSaveCnt?>?RecDataSize)?return?FALSE;			//存儲的數(shù)據(jù)不能大于接收的數(shù)據(jù)
	if((RecDataSize-DownFontDataSaveCnt)?>=?4096)?return?FALSE;	//未存儲的數(shù)據(jù)大小不能超過4K
	if(W25X16_EraseSector(DownFontDataSaveCnt/4096?+?DOWN_FONT_EXIT_SECTOR)?==?TRUE)													//擦除一個扇區(qū)
	{
		if(W25X16_WriteNoCheck(SPI_FLASH_BUF,?DOWN_FONT_EXIT_SECTOR*4096+DownFontDataSaveCnt,?RecDataSize-DownFontDataSaveCnt)??==?TRUE)	//寫入一個扇區(qū)
		{
			return?TRUE;
		}
	}

	return?FALSE;	//存儲出錯
}


//使用XMODEM下載字庫數(shù)據(jù)到外部flash
//返回程序大小,如果失敗了返回<=0
int?XMODEM_DownloadFontToExitFlash(u32?MaxFileSize)
{
	XMODE_Init(&UpgradeHandle,?			//句柄
		UpgradeSendData,?				//發(fā)送數(shù)據(jù)回調函數(shù)
		UpgradeReadData,?				//讀取數(shù)據(jù)回調函數(shù)
		UpgradeClearData,?				//清除接收數(shù)據(jù)緩沖回調函數(shù)
		DownFontReceivePacketExitFlash,?//接收到數(shù)據(jù)包回調函數(shù)
		DownFontTransEndtExitFlash		//傳輸結束回調函數(shù)
		);
	DownFontDataSaveCnt?=?0;				//已經(jīng)存儲的數(shù)據(jù)大小清零
	return?XMODEM_DownloadFile(&UpgradeHandle,?MaxFileSize);
}




//使能系統(tǒng)命令行
#if?SYS_CMD_EN_
#include?"cmd.h"
#include?"string.h"

CMD_TYPE?const?CMD_DOWN_BIN	=?{"DOWN?BIN",?0X51A36D01,?CMD_DownFont,?"t下載字庫數(shù)據(jù)"};			//下載字庫數(shù)據(jù)

//升級應用層-需要使用到W25X16的4K臨時緩沖區(qū),在升級與校驗的時候確保沒有其它線程訪問W25X16,最好掛起其它線程
void?CMD_DownFont(char?*pStr)
{
	u32?DataSize;
	
	cmd_printf("已經(jīng)進入升級程序模式,等待連接,超時10S!rn>");
	cmd_printf("請在10S內進入Xmodem下載字庫模式!rn>");
	
	RTC_DisableInt();									//關閉RTC中斷,防止喚醒后臺任務
	OSTaskSuspend(BACK_TASK_Prio);						//掛起后臺任務線程
	OSTaskSuspend(LED_TASK_Prio);						//掛起LED任務線程
	OSTaskSuspend(GPRS_TASK_Prio);						//掛起GPRS進程
	OSTaskSuspend(COLL_TASK_Prio);						//數(shù)據(jù)采集時間查詢進程
	OSTaskSuspend(OTHER_TASK_Prio);						//OTHER
	OSTaskSuspend(MODBUS1_TASK_Prio);					//MODBUS1	
	OSTaskSuspend(MODBUS2_TASK_Prio);					//MODBUS2
	OSTaskSuspend(KEY_TASK_Prio);						//KEY
	
	DataSize?=?XMODEM_DownloadFontToExitFlash(FLASH_BIN_SIZE);//下載字庫
	if(DataSize==0)
	{
		cmd_printf("下載字庫失敗!rn>");
	}
	else
	{
		cmd_printf("下載字庫成功(%dB)!rn",DataSize);
	}
	CMD_Help(NULL);
	OSTaskResume(LED_TASK_Prio);						//恢復掛起LED任務線程
	OSTaskResume(GPRS_TASK_Prio);						//恢復掛起GPRS進程
	OSTaskResume(COLL_TASK_Prio);
本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

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

關鍵字: 驅動電源

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

關鍵字: 工業(yè)電機 驅動電源

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

關鍵字: 驅動電源 照明系統(tǒng) 散熱

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

關鍵字: LED 設計 驅動電源

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

關鍵字: 電動汽車 新能源 驅動電源

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

關鍵字: 發(fā)光二極管 驅動電源 LED

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

關鍵字: LED 驅動電源 功率因數(shù)校正

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

關鍵字: LED照明技術 電磁干擾 驅動電源

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

關鍵字: LED 驅動電源 開關電源

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

關鍵字: LED 隧道燈 驅動電源
關閉