打印
[牛人杂谈]

NUC970(ARM9)裸机串口驱动与中断控制器AIC

[复制链接]
1629|36
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zljiu|  楼主 | 2021-6-6 10:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

裸机调试时,需要使用到SDRAM,需要使用JTAG,首先将芯片启动方式设置为USB,然后安装USB驱动 “WinUSB4NuVCOM_NUC970”,最后运行软件 NuWriter

选择芯片


使用特权

评论回复
沙发
zljiu|  楼主 | 2021-6-6 10:35 | 只看该作者

连接设备


使用特权

评论回复
板凳
zljiu|  楼主 | 2021-6-6 10:36 | 只看该作者

连接成功后串口会有提示


使用特权

评论回复
地板
zljiu|  楼主 | 2021-6-6 10:37 | 只看该作者

还需要在MDK中添加DDR初始化脚本,我使用的是unlink2,不知道jlinkv9是否是一样的脚本

直接选择仿真,不要点击下载

串口测试将收到的数据原封不动发送回来,只测试过串口0,其余的串口理论上操作一样


使用特权

评论回复
5
zljiu|  楼主 | 2021-6-6 10:38 | 只看该作者
下面是代码

uart.c

/*************************************************************************************************************
* 文件名:                        uart.c
* 功能:                        NUC970 UART通讯支持
* 作者:                        cp1300@139.com
* 创建时间:                2020-08-29
* 最后修改时间:        2020-08-29
* 详细:                        串口通信底层支持,可惜串口都不支持DMA传输,只能使用中断方式接收数据
*************************************************************************************************************/
#include "nuc970_system.h"
#include "uart.h"
#include "typedef.h"
#include "irq_aic.h"

//串口中断接收函数
__inline static void UARTx_IRQHandler(UART_CH_Type ch);                                //串口中断处理
static void UART0_IRQHandler(void) {UARTx_IRQHandler(UART_CH0);}        //串口0接收中断
static void UART1_IRQHandler(void) {UARTx_IRQHandler(UART_CH1);}        //串口1接收中断
static void UART2_IRQHandler(void) {UARTx_IRQHandler(UART_CH2);}        //串口2接收中断
static void UART3_IRQHandler(void) {UARTx_IRQHandler(UART_CH3);}        //串口3接收中断
static void UART4_IRQHandler(void) {UARTx_IRQHandler(UART_CH4);}        //串口4接收中断
static void UART5_IRQHandler(void) {UARTx_IRQHandler(UART_CH5);}        //串口5接收中断
static void UART6_IRQHandler(void) {UARTx_IRQHandler(UART_CH6);}        //串口6接收中断
static void UART7_IRQHandler(void) {UARTx_IRQHandler(UART_CH7);}        //串口7接收中断
static void UART8_IRQHandler(void) {UARTx_IRQHandler(UART_CH8);}        //串口8接收中断
static void UART9_IRQHandler(void) {UARTx_IRQHandler(UART_CH9);}        //串口9接收中断
static void UART10_IRQHandler(void) {UARTx_IRQHandler(UART_CH10);}        //串口10接收中断

//中断编号
static const AIC_IRQ_Typedef scg_UartIrqType[UART_ChMax] =
{        AIC_UART0_INT,         AIC_UART1_INT,         AIC_UART2_INT,         AIC_UART3_INT,         AIC_UART4_INT,
        AIC_UART5_INT,         AIC_UART6_INT,         AIC_UART7_INT,         AIC_UART8_INT,         AIC_UART9_INT, AIC_UART10_INT};       
//中断函数集合       
static const void *scg_pUartIrqHandle[UART_ChMax] =
        {(const void *)UART0_IRQHandler,         (const void *)UART1_IRQHandler,         (const void *)UART2_IRQHandler,
        (const void *)UART3_IRQHandler,         (const void *)UART4_IRQHandler,         (const void *)UART5_IRQHandler,
        (const void *)UART6_IRQHandler,                (const void *)UART7_IRQHandler,         (const void *)UART8_IRQHandler,
        (const void *)UART9_IRQHandler,         (const void *)UART10_IRQHandler};
//串口基址       
static const u32 scg_UARTx_Base[UART_ChMax] =
{        UART0_BASE,         UART1_BASE,         UART2_BASE,         UART3_BASE,         UART4_BASE,         UART5_BASE,
        UART6_BASE,         UART7_BASE,         UART8_BASE,         UART9_BASE,         UART10_BASE};
//时钟使能       
static const SYS_DEV_CLOCK scg_UARTx_DeviceClockEnable[UART_ChMax]         =
{        DEV_UART0,         DEV_UART1,         DEV_UART2,         DEV_UART3,         DEV_UART4,         DEV_UART5,
        DEV_UART6,         DEV_UART7,         DEV_UART8,         DEV_UART9,         DEV_UART10};               
//外设复位       
static const SYS_DEV_RESET scg_UARTx_DeviceReset[UART_ChMax] =
{        DEV_RESET_UART0,         DEV_RESET_UART1,         DEV_RESET_UART2,         DEV_RESET_UART3, DEV_RESET_UART4,         DEV_RESET_UART5,
        DEV_RESET_UART6,         DEV_RESET_UART7,         DEV_RESET_UART8,         DEV_RESET_UART9, DEV_RESET_UART10};                       
//IO复用功能
static const GPIO_AF_Type scg_UARTx_AF_GPIO[UART_ChMax][2] =
{
        {GPIO_PE0_UART0_TXD,         GPIO_PE1_UART0_RXD},         {GPIO_PE2_UART1_TXD,         GPIO_PE3_UART1_RXD},         {GPIO_PF11_UART2_TXD,         GPIO_PF12_UART2_RXD},
        {GPIO_PE12_UART3_TXD,         GPIO_PE13_UART3_RXD},        {GPIO_PH8_UART4_TXD,        GPIO_PH9_UART4_RXD},        {GPIO_PB0_UART5_TXD,        GPIO_PB1_UART5_RXD},
        {GPIO_PB2_UART6_TXD,        GPIO_PB3_UART6_RXD},        {GPIO_PG4_UART7_TXD,        GPIO_PG5_UART7_RXD},        {GPIO_PH12_UART8_TXD,        GPIO_PH13_UART8_RXD},
        {GPIO_PD14_UART9_TXD,        GPIO_PD15_UART9_RXD},        {GPIO_PB12_UART10_TXD,        GPIO_PB13_UART10_RXD}
};
       
       
       
//相关UART状态结构
typedef struct
{
        bool                isNewDataFlag;        //接收到新数据
        bool                isBuffFull;                //接收Buff满
        bool                isIntRx;                //是否开启中断接收
        u8                         *RxBuff;                //接收Buff指针
        u16                        RxBuffSize;                //接收缓冲区大小,一帧数据大小
        u16                 UartRxCnt;                //接收数据计数器
        u8                        TempData;                //用于接收溢出后读取数据寄存器,清除读取数据标志
} UartRx_TypeDef;
static UartRx_TypeDef sg_UartRx[UART_ChMax];


使用特权

评论回复
6
zljiu|  楼主 | 2021-6-6 10:39 | 只看该作者
/*************************************************************************************************************************
*函数                :        bool UARTx_Config(UART_CH_Type ch,UART_Config_TypeDef * cfg)
*功能                :        串口配置
*参数                :        ch:串口号;cfg:配置结构体
*返回                :        TRUE:配置成功; FALSE: 配置失败
*依赖                        :         底层宏定义
*作者               :        cp1300@139.com
*时间                     :        2020-08-11
*最后修改时间        :        2020-08-30
*说明                :        配置前最好确保数据已经发送完成,没有数据正在发送
*************************************************************************************************************************/
bool UARTx_Config(UART_CH_Type ch,UART_Config_TypeDef * cfg)
{
        u32 temp;
        UART_TypeDef *UARTx;
       
        if(ch > (UART_ChMax - 1)) return FALSE;                                                        //端口号超出范围
        UARTx = (UART_TypeDef *) scg_UARTx_Base[ch];                                        //获取设备基址
       
        temp = 0;
        //奇偶校验
        switch(cfg->OddEvenVerify)       
        {
                case UART_ODD:        //奇校验
                {
                        temp |= BIT3;        //使能奇偶校验-校验位发送
                }break;
                case UART_EVEN:        //偶校验
                {
                        temp |= BIT4;        //偶校验
                        temp |= BIT3;        //使能奇偶校验-校验位发送
                }break;
                default:break;        //无校验
        }
        //停止位
        if(cfg->StopBitWidth != UART_STOP_1BIT)        //不止1个停止位
        {
                temp |= BIT2;        //当选择6位,7位和8位字长时,将生成两个“ STOP位”
        }
        //数据长度
        temp |= cfg->DataBitWidth & 0x03;        //数据位长度设置
       
        while((UARTx->FSR & BIT28) == 0);        //等待发送移位寄存器为空,等待数据发送完成再进行配置
        UARTx->LCR = temp;

        return TRUE;
}



使用特权

评论回复
7
zljiu|  楼主 | 2021-6-6 10:40 | 只看该作者

/*************************************************************************************************************************
* 函数        :        void UARTx_SetBaudRate(UART_CH_Type ch,u32 baud)
* 功能        :        串口波特率设置
* 参数        :        ch:通道选择,baud:波特率,如9600,115200等等
* 返回        :        无
* 依赖        :        底层宏定义
* 作者        :        cp1300@139.com
* 时间        :        2013316
* 最后修改时间 : 2013316
* 说明        :         USART1~UART5,对应通道UART_CH1-UART_CH5
                        设置前必须关闭串口
                        会自动获取系统当前的时钟,并进行计算.
*************************************************************************************************************************/
bool UARTx_SetBaudRate(UART_CH_Type ch,u32 baud)
{
        u32 temp = 0;
        UART_TypeDef *UARTx;
       
        if(ch > (UART_ChMax - 1)) return FALSE;                        //端口号超出范围
        UARTx = (UART_TypeDef *) scg_UARTx_Base[ch];        //获取设备基址
        temp = 12000000;                                                                //获取系统时钟
        temp = temp / baud;                                                                //计算波特率分频系数
        temp -= 2;
        if(temp < 9) temp = 9;
        temp |= 0x03 << 28;                                                                //DIV_X_EN=1 DIV_X_ONE=1 模式3 波特率=时钟/(A+2), A 必须大于9
       
        while((UARTx->FSR & BIT28) == 0);                                //等待发送移位寄存器为空,等待数据发送完成再进行配置
        UARTx->BAUD = temp;

        return TRUE;
}



使用特权

评论回复
8
zljiu|  楼主 | 2021-6-6 10:40 | 只看该作者
/*************************************************************************************************************************
* 函数        :        bool UARTx_Init(UART_CH_Type ch,u32 Speed,bool isEnableRx)
* 功能        :        串口初始化
* 参数        :        ch:通道选择,0->usart1,Speed:串口速度,isEnableRx:是否使能接收
* 返回        :        TRUE:成功,FALSE:失败
* 依赖        :        底层宏定义
* 作者        :        cp1300@139.com
* 时间        :        20120403
* 最后修改时间 : 2020-08-17
* 说明        :        
*************************************************************************************************************************/
bool UARTx_Init(UART_CH_Type ch,u32 Speed,bool isEnableRx)
{
        UART_Config_TypeDef cfg;
        UART_TypeDef *UARTx;

        if(ch > (UART_ChMax - 1)) return FALSE;                                                        //端口号超出范围
        UARTx = (UART_TypeDef *) scg_UARTx_Base[ch];                                        //获取设备基址
       
        SYS_DeviceClockEnable(scg_UARTx_DeviceClockEnable[ch], TRUE);        //使能时钟
        SYS_DeviceReset(scg_UARTx_DeviceReset[ch]);                                                //复位外设

        UARTx->IER = 0;                                                                                                        //关闭所有中断
        UARTx->FCR = (5<<4) | BIT2 | BIT1;                                                                //接收FIFO阈值46/14,开启接收,收发FIFO复位
        if(isEnableRx)                                                                                                        //是否使能接收-禁用接收
        {
                UARTx->IER = BIT11 | BIT4 | BIT0;                                                        //开启接收超时计数器,开启接收超时中断,使能接收数据有效中断
        }
        else
        {
                AIC_IrqEnable(scg_UartIrqType[ch], FALSE);                                        //关闭串口AIC中断
        }
        //配置
        UARTx->TOR = (0<<8) | (6*10);                                                                        //发送字节延时为0,接收超时计数器为6个字节时间
        cfg.DataBitWidth = UART_DATA_8BIT;                                                                //数据宽度8
        cfg.OddEvenVerify = UART_VERIFY_NULL;                                                        //无奇偶校验
        cfg.StopBitWidth = UART_STOP_1BIT;                                                                //1个停止位
        if(UARTx_SetBaudRate(ch, Speed) == FALSE) return FALSE;                        //设置波特率
        if(UARTx_Config(ch, &cfg) == FALSE) return FALSE;                                //设置串口数据格式
        sg_UartRx[ch].isIntRx = FALSE;                                                                        //没有开启中断接收
       
        //IO初始化
        SYS_GPIOx_SetAF(scg_UARTx_AF_GPIO[ch][0]);                                                 //TXD 复用功能设置
        SYS_GPIOx_SetAF(scg_UARTx_AF_GPIO[ch][1]);                                                 //RXD 复用功能设置
        if(isEnableRx)
        {
                UARTx->ISR = UARTx->ISR;                                                                                                //清除中断信息
                AIC_SetIrqTriggered(scg_UartIrqType[ch], AIC_HIGHT_EDGE);                                //设置串口中断上升沿触发
                AIC_SetIrqPriority(scg_UartIrqType[ch], UART_INT_PRIO);                                        //设置一个中断优先级
                AIC_RegisterIRQHandler(scg_UartIrqType[ch], (void (*)(void))scg_pUartIrqHandle[ch]);        //注册中断服务程序
                AIC_IrqEnable(scg_UartIrqType[ch], TRUE);                                                                //开启串口AIC中断
               
                sg_UartRx[ch].isIntRx = FALSE;                                                                                        //开启了中断接收
        }

        return TRUE;
}



使用特权

评论回复
9
zljiu|  楼主 | 2021-6-6 10:41 | 只看该作者
/*************************************************************************************************************************
* 函数        :        void UARTx_SendByte(UART_CH_Type ch,u8 data)
* 功能        :        UART单字节发送
* 参数        :        ch:通道号,dataL:要发送的数据
* 返回        :        无
* 依赖        :        底层宏定义
* 作者        :        cp1300@139.com
* 时间        :        20120403
* 最后修改时间 : 2020-08-12
* 说明        :         单字节发送不要使用DMA,浪费
*************************************************************************************************************************/
void UARTx_SendByte(UART_CH_Type ch,u8 data)
{
        UART_TypeDef *UARTx;
       
        if(ch > (UART_ChMax - 1)) return;                                                //端口号超出范围
        UARTx = (UART_TypeDef *) scg_UARTx_Base[ch];                        //获取设备基址
        while(UARTx->FSR & BIT23);                                                                //等待TX FIFO未满
        UARTx->RBR_THR = data;                                                                        //发送数据-写到FIFO中而已,并不会等待数据发送完成
}



使用特权

评论回复
10
zljiu|  楼主 | 2021-6-6 10:42 | 只看该作者
/*************************************************************************************************************************
* 函数        :        void UARTx_SendData(UART_CH_Type ch,u8 *tx_buff,u16 byte_number)
* 功能        :        UART数据发送函数
* 参数        :        ch:通道号,tx_buff:发送缓冲区,byte_number:需要发送的字节
* 返回        :        无
* 依赖        :        void UART_SendByte(u8 ch,u8 data)
* 作者        :        cp1300@139.com
* 时间        :        20120403
* 最后修改时间 : 20120403
* 说明        :        
*************************************************************************************************************************/
void UARTx_SendData(UART_CH_Type ch,u8 *pTxBuff,u16 DataLen)
{
        u16 i;
        if(ch > (UART_ChMax - 1)) return;                                        //端口号超出范围
       
        for(i = 0;i < DataLen;i++)                                                        //循环发送,直至发送完毕
        {
                 UARTx_SendByte(ch, pTxBuff);
        }
#if (!UART_TX_TO_FIFI)        //要求等待数据发送完成
        UARTx_WaitSendComplete(ch);                                //等待数据发送完成-从串口发送完成
#endif //UART_TX_TO_FIFI       
}



使用特权

评论回复
11
zljiu|  楼主 | 2021-6-6 10:42 | 只看该作者
/*************************************************************************************************************************
* 函数                        :        void UARTx_WaitSendComplete(UART_CH_Type ch)
* 功能                        :        等待数据发送完成-从串口发送完成
* 参数                        :        ch:通道号
* 返回                        :        无
* 依赖                        :        无
* 作者                        :        cp1300@139.com
* 时间                        :        2020-08-29
* 最后修改时间         :         2020-08-29
* 说明                        :
*************************************************************************************************************************/
void UARTx_WaitSendComplete(UART_CH_Type ch)
{
        UART_TypeDef *UARTx;
       
        if(ch > (UART_ChMax - 1)) return;                                                //端口号超出范围
        UARTx = (UART_TypeDef *) scg_UARTx_Base[ch];                        //获取设备基址
        while((UARTx->FSR & BIT28) == 0);                                                //等待发送移位寄存器为空
}



使用特权

评论回复
12
zljiu|  楼主 | 2021-6-6 10:43 | 只看该作者

/*************************************************************************************************************************
* 函数        :        void UARTx_SendString(UART_CH_Type ch,char *pString)
* 功能        :        UART发送字符串
* 参数        :        ch:通道号
                        pString:字符串指针
* 返回        :        无
* 依赖        :        void UART_SendByte(u8 ch,u8 data)
* 作者        :        cp1300@139.com
* 时间        :        2013-04-18
* 最后修改时间 : 2013-04-18
* 说明        :         非DMA方式,非FIFO方式发送
*************************************************************************************************************************/
#include "string.h"
void UARTx_SendString(UART_CH_Type ch,char *pString)
{       
        if(ch > (UART_ChMax - 1)) return;                                        //端口号超出范围
       
        UARTx_SendData(ch, (u8 *)pString, strlen(pString));
}



使用特权

评论回复
13
zljiu|  楼主 | 2021-6-6 10:44 | 只看该作者
/*************************************************************************************************************************
* 函数        :        bool UARTx_GetNewDataFlag(UART_CH_Type ch)
* 功能        :        获取串口新数据标志
* 参数        :        ch:通道选择
* 返回        :        TRUE:成功,FALSE:失败
* 依赖        :        底层宏定义
* 作者        :        cp1300@139.com
* 时间        :        20120403
* 最后修改时间 : 20120403
* 说明        :         用于判断是否有新的数据,会清除掉新数据标志的
*************************************************************************************************************************/
bool UARTx_GetNewDataFlag(UART_CH_Type ch)
{
        UART_TypeDef *UARTx;
       
        if(ch > (UART_ChMax - 1)) return FALSE;                                                //端口号超出范围
        UARTx = (UART_TypeDef *) scg_UARTx_Base[ch];                                //获取设备基址

        if(sg_UartRx[ch].isIntRx == TRUE)                                                        //开启了中断接收
        {
                if(sg_UartRx[ch].isNewDataFlag == TRUE)                                 //有新数据
                {
                         sg_UartRx[ch].isNewDataFlag = FALSE;                                //清除标志
                        return TRUE;                                                                                //返回有新数据
                }
        }
        else                                                                                                                //没开启中断接收
        {
                 if((UARTx->FSR & BIT14) == 0)                                                        //接收FIFO不为空
                {
                        return TRUE;
                }
        }
        return FALSE;
}



使用特权

评论回复
14
zljiu|  楼主 | 2021-6-6 10:45 | 只看该作者

/*************************************************************************************************************************
* 函数        :        bool UARTx_GetRxBuffFullFlag(UART_CH_Type ch)
* 功能        :        获取串口接收缓冲区满标志
* 参数        :        ch:通道选择
* 返回        :        TRUE:成功,FALSE:失败
* 依赖        :        底层宏定义
* 作者        :        cp1300@139.com
* 时间        :        20120403
* 最后修改时间 : 20120403
* 说明        :         用于判断接收缓冲区是否满,会清除标志
*************************************************************************************************************************/
bool UARTx_GetRxBuffFullFlag(UART_CH_Type ch)
{
        if(ch > (UART_ChMax - 1)) return FALSE;                                        //端口号超出范围

        if(sg_UartRx[ch].isBuffFull == TRUE)                        //缓冲区已满
        {
                 sg_UartRx[ch].isBuffFull = FALSE;                        //清除满标志
                return TRUE;
        }
        return FALSE;
}



使用特权

评论回复
15
zljiu|  楼主 | 2021-6-6 10:46 | 只看该作者

/*************************************************************************************************************************
* 函数        :        u8 UARTx_GetNewData(UART_CH_Type ch)
* 功能        :        获取串口新数据
* 参数        :        ch:通道选择
* 返回        :        收到的数据
* 依赖        :        底层宏定义
* 作者        :        cp1300@139.com
* 时间        :        20120403
* 最后修改时间 : 20120403
* 说明        :         用于接收一个字节数据
*************************************************************************************************************************/
u8 UARTx_GetNewData(UART_CH_Type ch)
{
        UART_TypeDef *UARTx;
       
        if(ch > (UART_ChMax - 1)) return FALSE;                                                //端口号超出范围
        UARTx = (UART_TypeDef *) scg_UARTx_Base[ch];                                //获取设备基址

        return UARTx->RBR_THR;                                                                                        //返回数据
}




使用特权

评论回复
16
zljiu|  楼主 | 2021-6-6 10:47 | 只看该作者
/*************************************************************************************************************************
* 函数        :        void UARTx_SetRxBuff(UART_CH_Type ch,u8 *RxBuff,u16 RxBuffSize)
* 功能        :        设置串口接收缓冲区
* 参数        :        ch:通道选择,RxBuffSize:缓冲区大小,RxBuff:缓冲区指针
* 返回        :        无
* 依赖        :        底层宏定义
* 作者        :        cp1300@139.com
* 时间        :        20120403
* 最后修改时间 : 20120403
* 说明        :         一定要设置,否则开启中断接收时可能会异常
*************************************************************************************************************************/
void UARTx_SetRxBuff(UART_CH_Type ch,u8 *RxBuff,u16 RxBuffSize)
{
#ifdef _UCOS_II_
        OS_CRITICAL_SR_VAL;
#endif        //_UCOS_II_
       
        if(ch > (UART_ChMax - 1)) return;                                        //端口号超出范围
               
#ifdef _UCOS_II_
        OS_EnterCriticalSection();                         //进入临界区
#endif        //_UCOS_II_
        sg_UartRx[ch].RxBuffSize = RxBuffSize;                                 //设置缓冲区大小
        sg_UartRx[ch].RxBuff = RxBuff;                                                //设置缓冲区指针       
        sg_UartRx[ch].UartRxCnt = 0;                                                //计数器清零
#ifdef _UCOS_II_
        OS_LeaveCriticalSection();                         //退出临界区
#endif        //_UCOS_II_
}



使用特权

评论回复
17
zljiu|  楼主 | 2021-6-6 10:48 | 只看该作者
/*************************************************************************************************************************
* 函数        :        u32 UARTx_GetRxCnt(UART_CH_Type ch)
* 功能        :        获取串口接收数据计数器
* 参数        :        ch:通道选择
* 返回        :        接收到的数据数量
* 依赖        :        底层宏定义
* 作者        :        cp1300@139.com
* 时间        :        20130307
* 最后修改时间 : 20130307
* 说明        :         无
*************************************************************************************************************************/
u32 UARTx_GetRxCnt(UART_CH_Type ch)
{        
        if(ch > (UART_ChMax - 1)) return 0;                                        //端口号超出范围
        
        return sg_UartRx[ch].UartRxCnt;                                                //返回计数值        
}



使用特权

评论回复
18
zljiu|  楼主 | 2021-6-6 10:49 | 只看该作者
/*************************************************************************************************************************
* 函数        :        void UARTx_ClearRxCnt(UART_CH_Type ch)
* 功能        :        清除串口接收数据计数器
* 参数        :        ch:通道选择
* 返回        :        无
* 依赖        :        底层宏定义
* 作者        :        cp1300@139.com
* 时间        :        20130307
* 最后修改时间 : 20130307
* 说明        :         无
*************************************************************************************************************************/
void UARTx_ClearRxCnt(UART_CH_Type ch)
{
        if(ch > (UART_ChMax - 1)) return;                                        //端口号超出范围
        sg_UartRx[ch].UartRxCnt = 0;                                                //计数器清零
}



使用特权

评论回复
19
zljiu|  楼主 | 2021-6-6 10:49 | 只看该作者

//用于串口中断中循环读取数据
__inline static void UARTx_ReadRxData(UART_CH_Type ch, UART_TypeDef *UARTx)
{
    while((UARTx->FSR & BIT14) == 0)                                                                                                                                                   //接收FIFO中有数据,循环读取
    {
        if((sg_UartRx[ch].RxBuffSize) > 0 && (sg_UartRx[ch].UartRxCnt < sg_UartRx[ch].RxBuffSize))                        //接收缓冲区大于0,并且没有满
        {
            (sg_UartRx[ch].RxBuff)[(sg_UartRx[ch].UartRxCnt) ++] = UARTx->RBR_THR;                                                         //将数据存放到缓冲区
            if(sg_UartRx[ch].UartRxCnt == sg_UartRx[ch].RxBuffSize)                                                                                 //缓冲区已满
            {
                 //sg_UartRx[ch].UartRxCnt = 0;                                                                                                                                //接收计数器清零
                  sg_UartRx[ch].isBuffFull = TRUE;                                                                                                                        //缓冲区已满标志
            }       
        }
        else //缓冲区满了,清除接收到的数据
        {
            sg_UartRx[ch].TempData = UARTx->RBR_THR;
        }
    }
}



使用特权

评论回复
20
zljiu|  楼主 | 2021-6-6 10:50 | 只看该作者
//串口中断处理
__inline static void UARTx_IRQHandler(UART_CH_Type ch)
{
        UART_TypeDef *UARTx;
       
        UARTx = (UART_TypeDef *) scg_UARTx_Base[ch];                                //获取设备基址
        if(UARTx->ISR & BIT0)                                                                                //FIFO收到指定数据的数据了
        {
                UARTx_ReadRxData(ch, UARTx);
        }
       
        if(UARTx->ISR & BIT4)                                                                                //FIFO有数据,但是收到足够数据并且超时了,需要去除余下的数据
        {
        UARTx_ReadRxData(ch, UARTx);                                                        //收到的数据没有满足FIFO阈值
        }
       
        UARTx->ISR = UARTx->ISR;                                                                        //清除中断
}



使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

50

主题

3323

帖子

3

粉丝