查看: 4785|回复: 0

[ADSP-CM408F EZ]08、UART 串口通讯的解读

[复制链接]
  • TA的每日心情
    奋斗
    2023-7-8 16:17
  • 签到天数: 971 天

    连续签到: 1 天

    [LV.10]以坛为家III

    发表于 2015-3-29 23:08:16 | 显示全部楼层 |阅读模式
    分享到:
    UART是属于外设drivers 所以在使用时,一定要设置时钟源
    而ADI 的时钟的设置是是属于CGU clock generation
    1.jpg

    3.jpg
    在ADI 的软件开发包就提供很好的设置,属于 Dynamic Power Management Service   这内部模块
    常用的设置代码如下:
            if (adi_pwr_Init(CLKIN, CORE_MAX, SYSTEM_MAX, VCO_MIN) != ADI_PWR_SUCCESS)
            {
                DEBUG_MSG1("Failed to initialize power service \n");
                break;
            }
            if(adi_pwr_SetPowerMode(ADI_PWR_MODE_FULL_ON) != ADI_PWR_SUCCESS)
            {
                DEBUG_MSG1("Failed to initialize set the power mode \n");
                break;           
            }
            if(adi_pwr_SetFreq(CORE_MAX, SYSTEM_MAX) != ADI_PWR_SUCCESS)
            {
                DEBUG_MSG1("Failed to set the frequency \n");
               break;           
            }
    4.jpg
    由ADSP-CM40x_Device_Drivers_User_guide.pdf 可知
    Low-Level Driver Operating Modes   包含了
    1、 Blocking mode    我理解为查询读写模式
    2、 Non-Blocking mode for all devices  我理解为中断或DMA读写模式
    3、 Callback mode    我理解为回调函数模式(或事件驱动模式)
    ADI 对每个Device 都有 adi_xxx_Open  与adi_xxx_Close,我个人感觉很好的编写模式,对每个模块就有很好的管理,操作起来也很方便,而同类设备的区别在ADI_XXX_HANDLE       const hDevice 的不同
    对ADI的软件开发包有一定的理解,回到本节的关键点,UART,对于UART的初始化代码如下:
            eResult = adi_uart_Open(UART_DEVICE_NUM,
                                    ADI_UART_DIR_BIDIRECTION,
                                    &UARTMemory[0],
                                    ADI_UART_BIDIR_DMA_MEMORY_SIZE,
                                    &hDevice);
          
            if (eResult != ADI_UART_SUCCESS)
            {
                DEBUG_MSG2("Failed to Open UART driver", eResult);
                break;
            }
            eResult = adi_uart_SetBaudRate(hDevice, BAUD_RATE);
          
            if (eResult != ADI_UART_SUCCESS)
            {
                DEBUG_MSG2("Failed to Set UART Baud Rate", eResult);
                break;
            }
            eResult = adi_uart_SetNumStopBits (hDevice, ADI_UART_ONE_STOPBIT);
          
            if (eResult != ADI_UART_SUCCESS)
            {
                DEBUG_MSG2("Failed to configure UART Stop bits count", eResult);
                break;
            }
            eResult = adi_uart_SetParity (hDevice, ADI_UART_NO_PARITY);
          
            if (eResult != ADI_UART_SUCCESS)
            {
                DEBUG_MSG2("Failed to configure UART Parity bit", eResult);
                break;
            }
            eResult = adi_uart_SetWordLen (hDevice, ADI_UART_WORDLEN_8BITS);
          
            if (eResult != ADI_UART_SUCCESS)
            {
                DEBUG_MSG2("Failed to configure UART data word length", eResult);
                break;
            }
            eResult = adi_uart_EnableDMAMode(hDevice, true);
          
            if (eResult != ADI_UART_SUCCESS)
            {
                DEBUG_MSG2("Failed to enable UART DMA mode", eResult);
            }
    读写函数是
    eResult = adi_uart_Read(hDevice, &RxTxBuffer[0], 1);
    eResult = adi_uart_Write(hDevice, &RxTxBuffer[0], TxSize);
    这两函数是block 模式的,
    可以使用
    adi_uart_IsTxBufferAvailable
    adi_uart_IsRxBufferAvailable
    避免 block模式
    Submit/Get  为 Non blocking mode
    Read/Write 为 Blocking mode
    ADI的还可以自动检测波特率
    if((eResult = adi_uart_ConfigAutobaud(ghUART,
                                               AUTOBAUD_CHAR
                                            )) != ADI_UART_SUCCESS)
        {
            REPORT_ERROR("Could not configure AutoBaud 0xX \n", eResult);
            return FAILED;
        }
        printf("\nSetup the hyper terminal and press character \'%c\' (to determine baudrate)\n", AUTOBAUD_CHAR);
       
        if((eResult = adi_uart_EnableAutobaud(ghUART,
                                             true
                                            )) != ADI_UART_SUCCESS)
        {
            REPORT_ERROR("Could not enable AutoBaud 0xX \n", eResult);
            return FAILED;
        }
       
        while(nBaudRate == 0)
        {
            if((eResult = adi_uart_GetBaudRate(ghUART,
                                               &nBaudRate
                                                )) != ADI_UART_SUCCESS)
            {
                REPORT_ERROR("Could not get the Baud Rate 0xX \n", eResult);
                return FAILED;
            }
        }
        printf("\n\t Detected Baudrate is: %d\n", (int)nBaudRate);
        printf("\n\n Press any key on hyperterminal and see that it is echoed \n\n");
        printf("\n\n Press Enter key to stop the code \n\n ");
    默认下是使用DMA传输模式,如果只想使用Interrupt 默认下,采用 adi_uart_RegisterCallback 函数进行设置,其函数如下
    5.jpg
    当注册回调函数后 adi_uart_Read/Write  和adi_uart_GetRx/TxBuffer就不能使用
    成功注册后,adi_uart_EnableAutobaud 与 adi_uart_ConfigAutobaud
                         adi_uart_IsTxBufferAvailable与 adi_uart_IsRxBufferAvailable
                        adi_uart_GetHWErrorStatus
                        adi_uart_SetRxFifoWM
    如果想取消注册回调函数, pfCallBack =NULL
    回调函数的形式如下 void callback(void *pCBParam, uint32_t nEvent, void *pArg)
    Enumeration of events generated by UART driver
    Enumerator: ADI_UART_EVENT_OVERRUN_ERROR
    Receive overrun.
    ADI_UART_EVENT_PARITY_ERROR
    Detected Rx parity error.
    ADI_UART_EVENT_FRAMING_ERROR
    Detected Rx framing error.
    ADI_UART_EVENT_BREAK_INTERRUPT
    Detected break condition.
    ADI_UART_EVENT_RX_FIFO_WM
    Reached Rx FIFO watermark level.
    ADI_UART_EVENT_RECIEVED_ADDR
    Received Address (valid only in MDB mode).
    ADI_UART_EVENT_AUTOBAUD_COMPLETE
    The initiated autobuad is complete.
    ADI_UART_EVENT_TX_COMPLETE
    Completed sending out the data from device buffers.
    ADI_UART_EVENT_RX_BUFFER_PROCESSED
    The given Rx buffer is processed.
    ADI_UART_EVENT_TX_BUFFER_PROCESSED
    The given Tx buffer is processed.
    ADI_UART_EVENT_RX_DMA_ERROR
    DMA error occurred in Rx channel.
    ADI_UART_EVENT_TX_DMA_ERROR
    DMA error occurred in Tx channel.
    回调函数出在的位置 static void OnBufferCompletion(     ADI_UART_DEVICE         const *pDevice,     ADI_UART_CHANNEL              *pChannel,     ADI_UART_BUF_INFO             *pBufInfo ) { ................         pDevice->pfCallback( pDevice->pCBParam,                              (uint32_t)pChannel->eBufProcessedEvent,                              pBuffer) ................... } static void UARTStatusHandler(uint32_t SID, void *pCBParam) {......................                     pDevice->pfCallback(pDevice->pCBParam,                                         (Event | ErrorEvent),                                         NULL); ...................... } 如果手动设置如下 void UARTUARTStatusHandlerCallBack(void *pCBParam, uint32_t nEvent, void *pArg) {         ADI_UART_HANDLE     *pDevice = (ADI_UART_HANDLE  *)pCBParam;     uint32_t * pulBuf = pArg;     switch(nEvent)     {       case ADI_UART_EVENT_TX_COMPLETE:         /         break;     } }         eResult = adi_uart_RegisterCallback(hDevice, UARTUARTStatusHandlerCallBack,(void*)hDevice);                 if (eResult != ADI_UART_SUCCESS)         {             DEBUG_MSG2("Failed to enable UART DMA mode", eResult);         } 原文地址:[ADSP-CM408F EZ]08、UART 串口通讯的解读 http://blog.sina.com.cn/s/blog_7e7fa4c80102vipx.html


    2.jpg
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-4-20 10:51 , Processed in 0.116376 second(s), 16 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.