ADSP-BF706之UART串列埠DMA模式
阿新 • • 發佈:2021-02-18
2. ADSP-BF706之UART串列埠DMA模式
上一篇是時鐘配置,我今天會進一步驗證一下外部和內部時鐘的穩定性,對於中斷配置的話,我是在配置各個外設時順便就配置的,所以就不單獨列出來了,相關的配置會在文中提及。
今天來梳理一下uart的DMA配置模式:
UART的DMA模式配置分兩步走:
1、DMA配置。
2、UART模式配置。
DMA配置:
a. 配置傳輸地址
b. 一次傳送/接收的數量,如果是中斷模式,即接收或者傳送多少個位元組進入中斷
c. 地址增量
d. 配置DMA控制暫存器
首先在硬體手冊上找到:
首先在硬體手冊上找到相應的DMA通道,以下我使用的是UART1
其次分別配置傳送通道和接收通道:
/* *傳送通道 */ *pREG_DMA12_ADDRSTART = tx_data; //UART0 Transmit DMA---DMA10 *pREG_DMA12_XCNT = 12; *pREG_DMA12_XMOD = 1; *pREG_DMA12_CFG |= ENUM_DMA_CFG_MSIZE01 | ENUM_DMA_CFG_STOP | //設定停止模式,在一次DMA完成之後,DMA通道自動停止 ENUM_DMA_CFG_READ | //Read from memory ENUM_DMA_CFG_PSIZE01 | ENUM_DMA_CFG_XCNT_INT| ENUM_DMA_CFG_SYNC; /* *接收通道: */ *pREG_DMA13_ADDRSTART = rx_data; //UART0 Receive DMA--DMA11 *pREG_DMA13_XCNT = 1; *pREG_DMA13_XMOD = 1; *pREG_DMA13_CFG |= ENUM_DMA_CFG_MSIZE01| //Memory Transfer Word Size ENUM_DMA_CFG_AUTO | //在自動模式,在一次完成之後DMA立即恢復。 ENUM_DMA_CFG_WRITE | //Write/Read Channel Direction:Receive (Write to memory) ENUM_DMA_CFG_PSIZE01| //Peripheral Transfer Word Size. ENUM_DMA_CFG_SYNC | //clears the DMA FIFO and pointers before starting ENUM_DMA_CFG_XCNT_INT; //The DMA_XCNT value = DMA_CFG.MSIZE transfers *pREG_DMA13_CFG |= ENUM_DMA_CFG_EN;//使能接收
接收通道和傳送通道不同注意點:
接收通道是一個位元組一個位元組的接收,傳送通道的*pREG_DMA12_XCNT = 12;是可以在後期根據需求自行修改的;
傳送通道在傳送之後通道會自行關閉,需要傳送的時候再使能DMA12通道,而接收通道,要一直準備著接收,所以選擇自動模式。
UART配置:
直接上程式碼吧,思路和MCU串列埠配置類似:
*pREG_UART1_STAT = ENUM_UART_STAT_OVR_ERR | \ ENUM_UART_STAT_FRAMING_ERR | \ ENUM_UART_STAT_PARITY_ERR | \ ENUM_UART_STAT_FRAMING_ERR | \ ENUM_UART_STAT_BREAK_INT | \ ENUM_UART_STAT_TX_DONE | \ ENUM_UART_STAT_ADDR_HI_STKY | \ ENUM_UART_STAT_ADDR_HI | \ ENUM_UART_STAT_CTS_HI_STKY ; *pREG_UART1_IMSK_CLR = 0x3FF;//關閉所有中斷 *pREG_UART1_IMSK_SET |= BITM_UART_IMSK_SET_ETBEI|BITM_UART_IMSK_SET_ERBFI; ClkDivide_1 = (uint32_t) ( ((float)fsclk0 / ((float)BAUD_RATE))) ); //115200u波特率 *pREG_UART1_CLK = (ENUM_UART_CLK_EN_DIV_BY_ONE|(ClkDivide_1)); *pREG_UART1_CTL |=ENUM_UART_CTL_UART_MODE | ENUM_UART_CTL_WL8BITS | ENUM_UART_CTL_NO_EXTRA_STBH | ENUM_UART_CTL_RX_IRQ_TH7 | BITM_UART_CTL_EN; adi_sec_EnableSource(INTR_UART1_RXDMA,true); adi_sec_SetPriority(INTR_UART1_RXDMA,0); //優先順序最高 adi_int_InstallHandler(INTR_UART1_RXDMA,UART1Callback,gUARTMemory,true);
中斷在初始化配置的時候設定了等級的數量:
adi_sec_SetPriorityLevels(ADI_SEC_CORE_0,ADI_SEC_8_PRIORITY_LEVELS);
設定為總共有8個等級。
UART1Callback,回撥函式裡面是,進中斷過後需要處理接收到的命令,比如我的:
void UART1Callback(uint32_t SID, void *pCBParam)
{
tasktype=UART_TIME_BEGIN; //開始空閒計時
RecvUart[uartRecvCount++]= rx_data[0];
if(rx_data[0]=='\n')
{
tasktype=IDLE_TIME_HANDLE;
ClearIdleTime;
uartRecvOk=true;
uartRecvCount=0;
}
*pREG_DMA13_STAT |= ENUM_DMA_STAT_IRQDONE | ENUM_DMA_STAT_IRQERR; //DMA完成一次接收產生一次中斷
}
這些就根據需求來開發了。
這一部分的配置即使給出了程式碼,但是具體的還需要仔細看硬體手冊,看懂了理解才會更深,即使可能一段時間之後就忘了,哈哈。 我上面的配置只能說能用,可能還是比較累贅。
上面是關於DMA模式的,下一篇會寫UART關於中斷模式的。