根據(jù) SCI 輸入信號(hào)自動(dòng)校準(zhǔn)波特率
發(fā)布時(shí)間:2021-08-10 來(lái)源:Terry Deng 責(zé)任編輯:wenwei
【導(dǎo)讀】本文檔概述了一種基于 SCI/UART 輸入信號(hào),可以自動(dòng)校準(zhǔn)本設(shè)備SCI/UART波特率的方法,該方法適用與所有第三代C2000芯片,比如F2807x/37x,F(xiàn)28004x,F(xiàn)28002x等等。
一 原理說(shuō)明
假設(shè)有2塊電路板通過(guò)SCI進(jìn)行通信。“Transmitter”向“Receiver”發(fā)送未知波特率的數(shù)據(jù),“ Receiver”則使用 eCAP 測(cè)量未知的波特率,然后修改其自身的波特率和“Transmitter”匹配。
下面款圖是一種情況,其中“Transmitter” 的波特率設(shè)置為 9889,而“Receiver”的初始波特率設(shè)置為 9601 ,相比之下“Receiver”的波特率為 -3% 偏差。 經(jīng)過(guò)算法的自動(dòng)校準(zhǔn)以后,“Receiver”將會(huì)把自身波特率校正為與“Transmitter”相同的9889。
下面框圖則是另一種情況,假如“Receiver”和“Transmitter”的初始波特率都是9889,但“Receiver”的內(nèi)部晶振INTOSC有-3%的偏差。使用上述完全相同的方法原理和步驟,“Receiver”波特率設(shè)置將會(huì)從9889校準(zhǔn)成9601,這樣“Receiver”的波特率設(shè)置被自動(dòng)校準(zhǔn)抵消內(nèi)部晶振的偏差。在測(cè)量實(shí)際信號(hào)時(shí),“Receiver”輸出到“Transmitter”的信號(hào)會(huì)是正確的 9889 波特率。
二 Receiver 的校準(zhǔn)代碼
1. 初始化
需要配置以下模塊來(lái)校準(zhǔn)波特率:
● 時(shí)鐘:使用 INTOSC2 并選擇 100MHz 的 LSPCLK
#define DEVICE_SETCLOCK_CFG (SYSCTL_OSCSRC_OSC2 | SYSCTL_IMULT(20) |
SYSCTL_FMULT_NONE | SYSCTL_SYSDIV(2) |
SYSCTL_PLL_ENABLE)
//
// Set up PLL control and clock dividers
//
SysCtl_setClock(DEVICE_SETCLOCK_CFG);
//
// Make sure the LSPCLK divider is set to the default (divide by 4)
//
SysCtl_setLowSpeedClock(SYSCTL_LSPCLK_PRESCALE_1);
● SCI 模塊:通訊數(shù)據(jù)使用,發(fā)出校準(zhǔn)以后的波形
// Initialize SCIA and its FIFO.
//
SCI_performSoftwareReset(SCIA_BASE);
//
// Configure SCIA for communications.
//
SCI_setConfig(SCIA_BASE, DEVICE_LSPCLK_FREQ, TARGETBAUD, (SCI_CONFIG_WLEN_8 |
SCI_CONFIG_STOP_ONE |
SCI_CONFIG_PAR_NONE));
SCI_resetChannels(SCIA_BASE);
SCI_resetRxFIFO(SCIA_BASE);
SCI_resetTxFIFO(SCIA_BASE);
SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_TXFF | SCI_INT_RXFF);
SCI_enableFIFO(SCIA_BASE);
SCI_enableModule(SCIA_BASE);
SCI_performSoftwareReset(SCIA_BASE);
● Xbar 輸入:將 GPIO28/SCI 內(nèi)部連接到 INPUTXBAR7 與 ECAP1 配合使用
//
// Configure GPIO 28 as eCAP input
//
XBAR_setInputPin(XBAR_INPUT7, 28);
● ECAP 模塊:監(jiān)控接收到的 SCI 通信脈沖寬度
//
// Disable ,clear all capture flags and interrupts
//
ECAP_disableInterrupt(ECAP1_BASE,
(ECAP_ISR_SOURCE_CAPTURE_EVENT_1 |
ECAP_ISR_SOURCE_CAPTURE_EVENT_2 |
ECAP_ISR_SOURCE_CAPTURE_EVENT_3 |
ECAP_ISR_SOURCE_CAPTURE_EVENT_4 |
ECAP_ISR_SOURCE_COUNTER_OVERFLOW |
ECAP_ISR_SOURCE_COUNTER_PERIOD |
ECAP_ISR_SOURCE_COUNTER_COMPARE));
ECAP_clearInterrupt(ECAP1_BASE,
(ECAP_ISR_SOURCE_CAPTURE_EVENT_1 |
ECAP_ISR_SOURCE_CAPTURE_EVENT_2 |
ECAP_ISR_SOURCE_CAPTURE_EVENT_3 |
ECAP_ISR_SOURCE_CAPTURE_EVENT_4 |
ECAP_ISR_SOURCE_COUNTER_OVERFLOW |
ECAP_ISR_SOURCE_COUNTER_PERIOD |
ECAP_ISR_SOURCE_COUNTER_COMPARE));
//
// Disable CAP1-CAP4 register loads
//
ECAP_disableTimeStampCapture(ECAP1_BASE);
//
// Configure eCAP
// Enable capture mode.
// One shot mode, stop capture at event 4.
// Set polarity of the events to rising, falling, rising, falling edge.
// Set capture in time difference mode.
// Select input from XBAR7.
// Enable eCAP module.
// Enable interrupt.
//
ECAP_stopCounter(ECAP1_BASE);
ECAP_enableCaptureMode(ECAP1_BASE);
ECAP_setCaptureMode(ECAP1_BASE, ECAP_ONE_SHOT_CAPTURE_MODE, ECAP_EVENT_4);
ECAP_setEventPolarity(ECAP1_BASE, ECAP_EVENT_1, ECAP_EVNT_FALLING_EDGE);
ECAP_setEventPolarity(ECAP1_BASE, ECAP_EVENT_2, ECAP_EVNT_RISING_EDGE);
ECAP_setEventPolarity(ECAP1_BASE, ECAP_EVENT_3, ECAP_EVNT_FALLING_EDGE);
ECAP_setEventPolarity(ECAP1_BASE, ECAP_EVENT_4, ECAP_EVNT_RISING_EDGE);
ECAP_enableCounterResetOnEvent(ECAP1_BASE, ECAP_EVENT_1);
ECAP_enableCounterResetOnEvent(ECAP1_BASE, ECAP_EVENT_2);
ECAP_enableCounterResetOnEvent(ECAP1_BASE, ECAP_EVENT_3);
ECAP_enableCounterResetOnEvent(ECAP1_BASE, ECAP_EVENT_4);
ECAP_selectECAPInput(ECAP1_BASE, ECAP_INPUT_INPUTXBAR7);
ECAP_enableLoadCounter(ECAP1_BASE);
ECAP_setSyncOutMode(ECAP1_BASE, ECAP_SYNC_OUT_DISABLED);
ECAP_startCounter(ECAP1_BASE);
ECAP_enableTimeStampCapture(ECAP1_BASE);
ECAP_reArm(ECAP1_BASE);
ECAP_enableInterrupt(ECAP1_BASE, ECAP_ISR_SOURCE_CAPTURE_EVENT_4);
2. 中斷
捕獲傳入 SCI 通信的脈沖寬度,每捕獲 4 次就中斷一次。 將這 4 個(gè)捕獲添加到陣列中。
__interrupt void ecap1ISR(void)
{
if(stopCaptures==0)
{
//
// Get the capture counts, interrupt every 4. Can be 1-bit or more wide.
// add one to account for partial eCAP counts at higher baud rates
// (e.g. count = 40, but if had higher resolution, this would be 40.5)
//
capCountArr[0] = 1+ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_1);
capCountArr[1] = 1+ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_2);
capCountArr[2] = 1+ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_3);
capCountArr[3] = 1+ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_4);
//
// Add samples to a buffer. Get average baud and tune INTOSC if buffer filled.
//
capCountIter = 0;
for (capCountIter=0; capCountIter<4; capCountIter++)
{
//
// if we still have samples left to capture, add it to the samples array
//
if(samplesArrIter<NUMSAMPLES)
{
samplesArr[samplesArrIter] = capCountArr[capCountIter];
samplesArrIter++;
}
//
// else, all samples were received, break to begin tuning
//
else
{
stopCaptures=1;
break;
}
}
}
//
// Clear interrupt flags for more interrupts.
//
ECAP_clearInterrupt(ECAP1_BASE,ECAP_ISR_SOURCE_CAPTURE_EVENT_4);
ECAP_clearGlobalInterrupt(ECAP1_BASE);
//
// Start eCAP
//
ECAP_reArm(ECAP1_BASE);
//
// Acknowledge the group interrupt for more interrupts.
//
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP4);
}
3. 主循環(huán)
捕獲陣列滿后,計(jì)算陣列的平均脈沖寬度 (也就是波特率),并更新SCI波特率寄存器,使其盡可能接近計(jì)算的平均值。
//
// Loop forever. Suspend or place breakpoints to observe the buffers.
//
for(;;)
{
//
// Array is filled, begin tuning
//
if(stopCaptures==1)
{
//
// Get an average baud rate from the array of samples
//
uint32_t avgBaud = getAverageBaud(samplesArr,NUMSAMPLES,TARGETBAUD);
//
// if the baud function returns the error code ''''''''0'''''''', then flag an error
//
if(avgBaud==0)
{
ESTOP0;
}
//
// Update the device''''''''s baud rate to match the measured baud rate
//
SCI_setBaud(SCIA_BASE, DEVICE_LSPCLK_FREQ, avgBaud);
//
// (OPTIONAL) Continuously send data to SCITX once tuning
// is complete for external observation (by logic analyzer or scope)
//
//unsigned char *msg;
//while(1)
//{
// msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?";
// SCI_writeCharArray(SCIA_BASE, (uint16_t*)msg, 91);
//}
//
// Wait for user to view the results in "Expressions" window
//
ESTOP0;
//
// If continuing, reset the array iterator and unlock the ISR for new captures
//
samplesArrIter=0;
stopCaptures=0;
}
}
4. 平均脈沖寬度
對(duì)于許多應(yīng)用的SCI 通信,傳輸?shù)臄?shù)據(jù) (例如 0xA5)是變化不固定的,因此SCI的高低電平脈沖寬度就是變化的。所以必須對(duì)樣本陣列進(jìn)行如下的預(yù)處理,然后才能計(jì)算平均脈沖寬度。
a) 丟棄大于 10 位寬的脈沖寬度 (丟棄空閑時(shí)間)
b) 將 n 位值除以 n
c) 對(duì)修改后的樣本數(shù)組進(jìn)行平均化
uint32_t getAverageBaud(volatile float arr[], int size, float targetBaudRate)
{
//
// clean up variable width array to single-bit-width array
//
uint16_t pass = arrTo1PulseWidth(arr, size, (float)DEVICE_SYSCLK_FREQ/targetBaudRate);
//
// pass only if enough good samples provided
//
if(pass == 0)
{
return 0;
}
//
// convert 2-bit width, 3-bit width, etc. to 1-bit width values by dividing, and average these values.
// skip unrelated values
//
float averageBitWidth = computeAvgWidth(arr, size);
//
// get the rounded baud rate from the average number of clocks and the sysclk frequency
//
return (uint32_t)(((float)DEVICE_SYSCLK_FREQ/(float)averageBitWidth)+0.5);
}
以下是平均脈寬計(jì)算的原理和代碼流程圖
三 結(jié)果
按照以下設(shè)置進(jìn)行測(cè)試,結(jié)果詳見(jiàn)表格,校準(zhǔn)以后的誤差從3% 改善為0.1%左右甚至更小。
1. “Transmitter”設(shè)置為正確的波特率 (我們嘗試匹配的波特率)
2. “Receiver”設(shè)置為錯(cuò)誤波特率 (-3% 或 +3%)
3. “Receiver”運(yùn)行校準(zhǔn)程序以匹配“Transmitter”
免責(zé)聲明:本文為轉(zhuǎn)載文章,轉(zhuǎn)載此文目的在于傳遞更多信息,版權(quán)歸原作者所有。本文所用視頻、圖片、文字如涉及作品版權(quán)問(wèn)題,請(qǐng)聯(lián)系小編進(jìn)行處理。
推薦閱讀:
特別推薦
- 授權(quán)代理商貿(mào)澤電子供應(yīng)Same Sky多樣化電子元器件
- 使用合適的窗口電壓監(jiān)控器優(yōu)化系統(tǒng)設(shè)計(jì)
- ADI電機(jī)運(yùn)動(dòng)控制解決方案 驅(qū)動(dòng)智能運(yùn)動(dòng)新時(shí)代
- 倍福推出采用 TwinSAFE SC 技術(shù)的 EtherCAT 端子模塊 EL3453-0090
- TDK推出新的X系列環(huán)保型SMD壓敏電阻
- Vishay 推出新款采用0102、0204和 0207封裝的精密薄膜MELF電阻
- Microchip推出新款交鑰匙電容式觸摸控制器產(chǎn)品 MTCH2120
技術(shù)文章更多>>
- 中微公司成功從美國(guó)國(guó)防部中國(guó)軍事企業(yè)清單中移除
- 華邦電子白皮書:滿足歐盟無(wú)線電設(shè)備指令(RED)信息安全標(biāo)準(zhǔn)
- 功率器件熱設(shè)計(jì)基礎(chǔ)(九)——功率半導(dǎo)體模塊的熱擴(kuò)散
- 準(zhǔn) Z 源逆變器的設(shè)計(jì)
- 第12講:三菱電機(jī)高壓SiC芯片技術(shù)
技術(shù)白皮書下載更多>>
- 車規(guī)與基于V2X的車輛協(xié)同主動(dòng)避撞技術(shù)展望
- 數(shù)字隔離助力新能源汽車安全隔離的新挑戰(zhàn)
- 汽車模塊拋負(fù)載的解決方案
- 車用連接器的安全創(chuàng)新應(yīng)用
- Melexis Actuators Business Unit
- Position / Current Sensors - Triaxis Hall
熱門搜索
單向可控硅
刀開關(guān)
等離子顯示屏
低頻電感
低通濾波器
低音炮電路
滌綸電容
點(diǎn)膠設(shè)備
電池
電池管理系統(tǒng)
電磁蜂鳴器
電磁兼容
電磁爐危害
電動(dòng)車
電動(dòng)工具
電動(dòng)汽車
電感
電工電路
電機(jī)控制
電解電容
電纜連接器
電力電子
電力繼電器
電力線通信
電流保險(xiǎn)絲
電流表
電流傳感器
電流互感器
電路保護(hù)
電路圖