根據(jù) SCI 輸入信號(hào)自動(dòng)校準(zhǔn)波特率
發(fā)布時(shí)間:2021-08-10 來源: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等等。
一 原理說明
假設(shè)有2塊電路板通過SCI進(jìn)行通信。“Transmitter”向“Receiver”發(fā)送未知波特率的數(shù)據(jù),“ Receiver”則使用 eCAP 測量未知的波特率,然后修改其自身的波特率和“Transmitter”匹配。
下面款圖是一種情況,其中“Transmitter” 的波特率設(shè)置為 9889,而“Receiver”的初始波特率設(shè)置為 9601 ,相比之下“Receiver”的波特率為 -3% 偏差。 經(jīng)過算法的自動(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)部晶振的偏差。在測量實(shí)際信號(hào)時(shí),“Receiver”輸出到“Transmitter”的信號(hào)會(huì)是正確的 9889 波特率。
二 Receiver 的校準(zhǔn)代碼
1. 初始化
需要配置以下模塊來校準(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)行測試,結(jié)果詳見表格,校準(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)問題,請(qǐng)聯(lián)系小編進(jìn)行處理。
推薦閱讀:
特別推薦
- 增強(qiáng)視覺傳感器功能:3D圖像拼接算法幫助擴(kuò)大視場
- PNP 晶體管:特性和應(yīng)用
- 使用IO-Link收發(fā)器管理數(shù)據(jù)鏈路如何簡化微控制器選擇
- 用好 DMA控制器這兩種模式 MCU效率大大提高!
- 深入分析帶耦合電感多相降壓轉(zhuǎn)換器的電壓紋波問題
- Honda(本田)與瑞薩簽署協(xié)議,共同開發(fā)用于軟件定義汽車的高性能SoC
- 第13講:超小型全SiC DIPIPM
技術(shù)文章更多>>
- 芯耀輝:從傳統(tǒng)IP到IP2.0,AI時(shí)代國產(chǎn)IP機(jī)遇與挑戰(zhàn)齊飛
- 解決模擬輸入IEC系統(tǒng)保護(hù)問題
- 當(dāng)過壓持續(xù)較長時(shí)間時(shí),使用開關(guān)浪涌抑制器
- 用于狀態(tài)監(jiān)測的振動(dòng)傳感器
- 解鎖多行業(yè)解決方案——AHTE 2025觀眾預(yù)登記開啟!
技術(shù)白皮書下載更多>>
- 車規(guī)與基于V2X的車輛協(xié)同主動(dòng)避撞技術(shù)展望
- 數(shù)字隔離助力新能源汽車安全隔離的新挑戰(zhàn)
- 汽車模塊拋負(fù)載的解決方案
- 車用連接器的安全創(chuàng)新應(yīng)用
- Melexis Actuators Business Unit
- Position / Current Sensors - Triaxis Hall
熱門搜索
精密電阻
精密工具
景佑能源
聚合物電容
君耀電子
開發(fā)工具
開關(guān)
開關(guān)電源
開關(guān)電源電路
開關(guān)二極管
開關(guān)三極管
科通
可變電容
可調(diào)電感
可控硅
空心線圈
控制變壓器
控制模塊
藍(lán)牙
藍(lán)牙4.0
藍(lán)牙模塊
浪涌保護(hù)器
雷度電子
鋰電池
利爾達(dá)
連接器
流量單位
漏電保護(hù)器
濾波電感
濾波器