[技术问答] 串口驱动与中断控制器

[复制链接]
 楼主| elsaflower 发表于 2025-6-16 20:10 | 显示全部楼层 |阅读模式

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

选择芯片

连接设备

连接成功后串口会有提示

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

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

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

下面是代码


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

  13. //串口中断接收函数
  14. __inline static void UARTx_IRQHandler(UART_CH_Type ch);                                //串口中断处理
  15. static void UART0_IRQHandler(void) {UARTx_IRQHandler(UART_CH0);}        //串口0接收中断
  16. static void UART1_IRQHandler(void) {UARTx_IRQHandler(UART_CH1);}        //串口1接收中断
  17. static void UART2_IRQHandler(void) {UARTx_IRQHandler(UART_CH2);}        //串口2接收中断
  18. static void UART3_IRQHandler(void) {UARTx_IRQHandler(UART_CH3);}        //串口3接收中断
  19. static void UART4_IRQHandler(void) {UARTx_IRQHandler(UART_CH4);}        //串口4接收中断
  20. static void UART5_IRQHandler(void) {UARTx_IRQHandler(UART_CH5);}        //串口5接收中断
  21. static void UART6_IRQHandler(void) {UARTx_IRQHandler(UART_CH6);}        //串口6接收中断
  22. static void UART7_IRQHandler(void) {UARTx_IRQHandler(UART_CH7);}        //串口7接收中断
  23. static void UART8_IRQHandler(void) {UARTx_IRQHandler(UART_CH8);}        //串口8接收中断
  24. static void UART9_IRQHandler(void) {UARTx_IRQHandler(UART_CH9);}        //串口9接收中断
  25. static void UART10_IRQHandler(void) {UARTx_IRQHandler(UART_CH10);}        //串口10接收中断

  26. //中断编号
  27. static const AIC_IRQ_Typedef scg_UartIrqType[UART_ChMax] =
  28. {        AIC_UART0_INT,         AIC_UART1_INT,         AIC_UART2_INT,         AIC_UART3_INT,         AIC_UART4_INT,
  29.         AIC_UART5_INT,         AIC_UART6_INT,         AIC_UART7_INT,         AIC_UART8_INT,         AIC_UART9_INT, AIC_UART10_INT};       
  30. //中断函数集合       
  31. static const void *scg_pUartIrqHandle[UART_ChMax] =
  32.         {(const void *)UART0_IRQHandler,         (const void *)UART1_IRQHandler,         (const void *)UART2_IRQHandler,
  33.         (const void *)UART3_IRQHandler,         (const void *)UART4_IRQHandler,         (const void *)UART5_IRQHandler,
  34.         (const void *)UART6_IRQHandler,                (const void *)UART7_IRQHandler,         (const void *)UART8_IRQHandler,
  35.         (const void *)UART9_IRQHandler,         (const void *)UART10_IRQHandler};
  36. //串口基址       
  37. static const u32 scg_UARTx_Base[UART_ChMax] =
  38. {        UART0_BASE,         UART1_BASE,         UART2_BASE,         UART3_BASE,         UART4_BASE,         UART5_BASE,
  39.         UART6_BASE,         UART7_BASE,         UART8_BASE,         UART9_BASE,         UART10_BASE};
  40. //时钟使能       
  41. static const SYS_DEV_CLOCK scg_UARTx_DeviceClockEnable[UART_ChMax]         =
  42. {        DEV_UART0,         DEV_UART1,         DEV_UART2,         DEV_UART3,         DEV_UART4,         DEV_UART5,
  43.         DEV_UART6,         DEV_UART7,         DEV_UART8,         DEV_UART9,         DEV_UART10};               
  44. //外设复位       
  45. static const SYS_DEV_RESET scg_UARTx_DeviceReset[UART_ChMax] =
  46. {        DEV_RESET_UART0,         DEV_RESET_UART1,         DEV_RESET_UART2,         DEV_RESET_UART3, DEV_RESET_UART4,         DEV_RESET_UART5,
  47.         DEV_RESET_UART6,         DEV_RESET_UART7,         DEV_RESET_UART8,         DEV_RESET_UART9, DEV_RESET_UART10};                       
  48. //IO复用功能
  49. static const GPIO_AF_Type scg_UARTx_AF_GPIO[UART_ChMax][2] =
  50. {
  51.         {GPIO_PE0_UART0_TXD,         GPIO_PE1_UART0_RXD},         {GPIO_PE2_UART1_TXD,         GPIO_PE3_UART1_RXD},         {GPIO_PF11_UART2_TXD,         GPIO_PF12_UART2_RXD},
  52.         {GPIO_PE12_UART3_TXD,         GPIO_PE13_UART3_RXD},        {GPIO_PH8_UART4_TXD,        GPIO_PH9_UART4_RXD},        {GPIO_PB0_UART5_TXD,        GPIO_PB1_UART5_RXD},
  53.         {GPIO_PB2_UART6_TXD,        GPIO_PB3_UART6_RXD},        {GPIO_PG4_UART7_TXD,        GPIO_PG5_UART7_RXD},        {GPIO_PH12_UART8_TXD,        GPIO_PH13_UART8_RXD},
  54.         {GPIO_PD14_UART9_TXD,        GPIO_PD15_UART9_RXD},        {GPIO_PB12_UART10_TXD,        GPIO_PB13_UART10_RXD}
  55. };
  56.        
  57.        
  58.        
  59. //相关UART状态结构
  60. typedef struct
  61. {
  62.         bool                isNewDataFlag;        //接收到新数据
  63.         bool                isBuffFull;                //接收Buff满
  64.         bool                isIntRx;                //是否开启中断接收
  65.         u8                         *RxBuff;                //接收Buff指针
  66.         u16                        RxBuffSize;                //接收缓冲区大小,一帧数据大小
  67.         u16                 UartRxCnt;                //接收数据计数器
  68.         u8                        TempData;                //用于接收溢出后读取数据寄存器,清除读取数据标志
  69. } UartRx_TypeDef;
  70. static UartRx_TypeDef sg_UartRx[UART_ChMax];

  71. /*************************************************************************************************************************
  72. *函数                :        bool UARTx_Config(UART_CH_Type ch,UART_Config_TypeDef * cfg)
  73. *功能                :        串口配置
  74. *参数                :        ch:串口号;cfg:配置结构体
  75. *返回                :        TRUE:配置成功; FALSE: 配置失败
  76. *依赖                        :         底层宏定义
  77. *作者               :        cp1300@139.com
  78. *时间                     :        2020-08-11
  79. *最后修改时间        :        2020-08-30
  80. *说明                :        配置前最好确保数据已经发送完成,没有数据正在发送
  81. *************************************************************************************************************************/
  82. bool UARTx_Config(UART_CH_Type ch,UART_Config_TypeDef * cfg)
  83. {
  84.         u32 temp;
  85.         UART_TypeDef *UARTx;
  86.        
  87.         if(ch > (UART_ChMax - 1)) return FALSE;                                                        //端口号超出范围
  88.         UARTx = (UART_TypeDef *) scg_UARTx_Base[ch];                                        //获取设备基址
  89.        
  90.         temp = 0;
  91.         //奇偶校验
  92.         switch(cfg->OddEvenVerify)       
  93.         {
  94.                 case UART_ODD:        //奇校验
  95.                 {
  96.                         temp |= BIT3;        //使能奇偶校验-校验位发送
  97.                 }break;
  98.                 case UART_EVEN:        //偶校验
  99.                 {
  100.                         temp |= BIT4;        //偶校验
  101.                         temp |= BIT3;        //使能奇偶校验-校验位发送
  102.                 }break;
  103.                 default:break;        //无校验
  104.         }
  105.         //停止位
  106.         if(cfg->StopBitWidth != UART_STOP_1BIT)        //不止1个停止位
  107.         {
  108.                 temp |= BIT2;        //当选择6位,7位和8位字长时,将生成两个“ STOP位”
  109.         }
  110.         //数据长度
  111.         temp |= cfg->DataBitWidth & 0x03;        //数据位长度设置
  112.        
  113.         while((UARTx->FSR & BIT28) == 0);        //等待发送移位寄存器为空,等待数据发送完成再进行配置
  114.         UARTx->LCR = temp;

  115.         return TRUE;
  116. }



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

  145.         return TRUE;
  146. }




  147. /*************************************************************************************************************************
  148. * 函数        :        bool UARTx_Init(UART_CH_Type ch,u32 Speed,bool isEnableRx)
  149. * 功能        :        串口初始化
  150. * 参数        :        ch:通道选择,0->usart1,Speed:串口速度,isEnableRx:是否使能接收
  151. * 返回        :        TRUE:成功,FALSE:失败
  152. * 依赖        :        底层宏定义
  153. * 作者        :        cp1300@139.com
  154. * 时间        :        20120403
  155. * 最后修改时间 : 2020-08-17
  156. * 说明        :        
  157. *************************************************************************************************************************/
  158. bool UARTx_Init(UART_CH_Type ch,u32 Speed,bool isEnableRx)
  159. {
  160.         UART_Config_TypeDef cfg;
  161.         UART_TypeDef *UARTx;

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

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

  199.         return TRUE;
  200. }




  201. /*************************************************************************************************************************
  202. * 函数        :        void UARTx_SendByte(UART_CH_Type ch,u8 data)
  203. * 功能        :        UART单字节发送
  204. * 参数        :        ch:通道号,dataL:要发送的数据
  205. * 返回        :        无
  206. * 依赖        :        底层宏定义
  207. * 作者        :        cp1300@139.com
  208. * 时间        :        20120403
  209. * 最后修改时间 : 2020-08-12
  210. * 说明        :         单字节发送不要使用DMA,浪费
  211. *************************************************************************************************************************/
  212. void UARTx_SendByte(UART_CH_Type ch,u8 data)
  213. {
  214.         UART_TypeDef *UARTx;
  215.        
  216.         if(ch > (UART_ChMax - 1)) return;                                                //端口号超出范围
  217.         UARTx = (UART_TypeDef *) scg_UARTx_Base[ch];                        //获取设备基址
  218.         while(UARTx->FSR & BIT23);                                                                //等待TX FIFO未满
  219.         UARTx->RBR_THR = data;                                                                        //发送数据-写到FIFO中而已,并不会等待数据发送完成
  220. }




  221. /*************************************************************************************************************************
  222. * 函数        :        void UARTx_SendData(UART_CH_Type ch,u8 *tx_buff,u16 byte_number)
  223. * 功能        :        UART数据发送函数
  224. * 参数        :        ch:通道号,tx_buff:发送缓冲区,byte_number:需要发送的字节
  225. * 返回        :        无
  226. * 依赖        :        void UART_SendByte(u8 ch,u8 data)
  227. * 作者        :        cp1300@139.com
  228. * 时间        :        20120403
  229. * 最后修改时间 : 20120403
  230. * 说明        :        
  231. *************************************************************************************************************************/
  232. void UARTx_SendData(UART_CH_Type ch,u8 *pTxBuff,u16 DataLen)
  233. {
  234.         u16 i;
  235.         if(ch > (UART_ChMax - 1)) return;                                        //端口号超出范围
  236.        
  237.         for(i = 0;i < DataLen;i++)                                                        //循环发送,直至发送完毕
  238.         {
  239.                  UARTx_SendByte(ch, pTxBuff[i]);
  240.         }
  241. #if (!UART_TX_TO_FIFI)        //要求等待数据发送完成
  242.         UARTx_WaitSendComplete(ch);                                //等待数据发送完成-从串口发送完成
  243. #endif //UART_TX_TO_FIFI       
  244. }


  245. /*************************************************************************************************************************
  246. * 函数                        :        void UARTx_WaitSendComplete(UART_CH_Type ch)
  247. * 功能                        :        等待数据发送完成-从串口发送完成
  248. * 参数                        :        ch:通道号
  249. * 返回                        :        无
  250. * 依赖                        :        无
  251. * 作者                        :        cp1300@139.com
  252. * 时间                        :        2020-08-29
  253. * 最后修改时间         :         2020-08-29
  254. * 说明                        :
  255. *************************************************************************************************************************/
  256. void UARTx_WaitSendComplete(UART_CH_Type ch)
  257. {
  258.         UART_TypeDef *UARTx;
  259.        
  260.         if(ch > (UART_ChMax - 1)) return;                                                //端口号超出范围
  261.         UARTx = (UART_TypeDef *) scg_UARTx_Base[ch];                        //获取设备基址
  262.         while((UARTx->FSR & BIT28) == 0);                                                //等待发送移位寄存器为空
  263. }


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






  283. /*************************************************************************************************************************
  284. * 函数        :        bool UARTx_GetNewDataFlag(UART_CH_Type ch)
  285. * 功能        :        获取串口新数据标志
  286. * 参数        :        ch:通道选择
  287. * 返回        :        TRUE:成功,FALSE:失败
  288. * 依赖        :        底层宏定义
  289. * 作者        :        cp1300@139.com
  290. * 时间        :        20120403
  291. * 最后修改时间 : 20120403
  292. * 说明        :         用于判断是否有新的数据,会清除掉新数据标志的
  293. *************************************************************************************************************************/
  294. bool UARTx_GetNewDataFlag(UART_CH_Type ch)
  295. {
  296.         UART_TypeDef *UARTx;
  297.        
  298.         if(ch > (UART_ChMax - 1)) return FALSE;                                                //端口号超出范围
  299.         UARTx = (UART_TypeDef *) scg_UARTx_Base[ch];                                //获取设备基址

  300.         if(sg_UartRx[ch].isIntRx == TRUE)                                                        //开启了中断接收
  301.         {
  302.                 if(sg_UartRx[ch].isNewDataFlag == TRUE)                                 //有新数据
  303.                 {
  304.                          sg_UartRx[ch].isNewDataFlag = FALSE;                                //清除标志
  305.                         return TRUE;                                                                                //返回有新数据
  306.                 }
  307.         }
  308.         else                                                                                                                //没开启中断接收
  309.         {
  310.                  if((UARTx->FSR & BIT14) == 0)                                                        //接收FIFO不为空
  311.                 {
  312.                         return TRUE;
  313.                 }
  314.         }
  315.         return FALSE;
  316. }


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

  331.         if(sg_UartRx[ch].isBuffFull == TRUE)                        //缓冲区已满
  332.         {
  333.                  sg_UartRx[ch].isBuffFull = FALSE;                        //清除满标志
  334.                 return TRUE;
  335.         }
  336.         return FALSE;
  337. }




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

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



  357. /*************************************************************************************************************************
  358. * 函数        :        void UARTx_SetRxBuff(UART_CH_Type ch,u8 *RxBuff,u16 RxBuffSize)
  359. * 功能        :        设置串口接收缓冲区
  360. * 参数        :        ch:通道选择,RxBuffSize:缓冲区大小,RxBuff:缓冲区指针
  361. * 返回        :        无
  362. * 依赖        :        底层宏定义
  363. * 作者        :        cp1300@139.com
  364. * 时间        :        20120403
  365. * 最后修改时间 : 20120403
  366. * 说明        :         一定要设置,否则开启中断接收时可能会异常
  367. *************************************************************************************************************************/
  368. void UARTx_SetRxBuff(UART_CH_Type ch,u8 *RxBuff,u16 RxBuffSize)
  369. {
  370. #ifdef _UCOS_II_
  371.         OS_CRITICAL_SR_VAL;
  372. #endif        //_UCOS_II_
  373.        
  374.         if(ch > (UART_ChMax - 1)) return;                                        //端口号超出范围
  375.                
  376. #ifdef _UCOS_II_
  377.         OS_EnterCriticalSection();                         //进入临界区
  378. #endif        //_UCOS_II_
  379.         sg_UartRx[ch].RxBuffSize = RxBuffSize;                                 //设置缓冲区大小
  380.         sg_UartRx[ch].RxBuff = RxBuff;                                                //设置缓冲区指针       
  381.         sg_UartRx[ch].UartRxCnt = 0;                                                //计数器清零
  382. #ifdef _UCOS_II_
  383.         OS_LeaveCriticalSection();                         //退出临界区
  384. #endif        //_UCOS_II_
  385. }





  386. /*************************************************************************************************************************
  387. * 函数        :        u32 UARTx_GetRxCnt(UART_CH_Type ch)
  388. * 功能        :        获取串口接收数据计数器
  389. * 参数        :        ch:通道选择
  390. * 返回        :        接收到的数据数量
  391. * 依赖        :        底层宏定义
  392. * 作者        :        cp1300@139.com
  393. * 时间        :        20130307
  394. * 最后修改时间 : 20130307
  395. * 说明        :         无
  396. *************************************************************************************************************************/
  397. u32 UARTx_GetRxCnt(UART_CH_Type ch)
  398. {       
  399.         if(ch > (UART_ChMax - 1)) return 0;                                        //端口号超出范围
  400.        
  401.         return sg_UartRx[ch].UartRxCnt;                                                //返回计数值       
  402. }




  403. /*************************************************************************************************************************
  404. * 函数        :        void UARTx_ClearRxCnt(UART_CH_Type ch)
  405. * 功能        :        清除串口接收数据计数器
  406. * 参数        :        ch:通道选择
  407. * 返回        :        无
  408. * 依赖        :        底层宏定义
  409. * 作者        :        cp1300@139.com
  410. * 时间        :        20130307
  411. * 最后修改时间 : 20130307
  412. * 说明        :         无
  413. *************************************************************************************************************************/
  414. void UARTx_ClearRxCnt(UART_CH_Type ch)
  415. {
  416.         if(ch > (UART_ChMax - 1)) return;                                        //端口号超出范围
  417.         sg_UartRx[ch].UartRxCnt = 0;                                                //计数器清零
  418. }



  419. //用于串口中断中循环读取数据
  420. __inline static void UARTx_ReadRxData(UART_CH_Type ch, UART_TypeDef *UARTx)
  421. {
  422.     while((UARTx->FSR & BIT14) == 0)                                                                                                                                                   //接收FIFO中有数据,循环读取
  423.     {
  424.         if((sg_UartRx[ch].RxBuffSize) > 0 && (sg_UartRx[ch].UartRxCnt < sg_UartRx[ch].RxBuffSize))                        //接收缓冲区大于0,并且没有满
  425.         {
  426.             (sg_UartRx[ch].RxBuff)[(sg_UartRx[ch].UartRxCnt) ++] = UARTx->RBR_THR;                                                         //将数据存放到缓冲区
  427.             if(sg_UartRx[ch].UartRxCnt == sg_UartRx[ch].RxBuffSize)                                                                                 //缓冲区已满
  428.             {
  429.                  //sg_UartRx[ch].UartRxCnt = 0;                                                                                                                                //接收计数器清零
  430.                   sg_UartRx[ch].isBuffFull = TRUE;                                                                                                                        //缓冲区已满标志
  431.             }       
  432.         }
  433.         else //缓冲区满了,清除接收到的数据
  434.         {
  435.             sg_UartRx[ch].TempData = UARTx->RBR_THR;
  436.         }
  437.     }
  438. }



  439. //串口中断处理
  440. __inline static void UARTx_IRQHandler(UART_CH_Type ch)
  441. {
  442.         UART_TypeDef *UARTx;
  443.        
  444.         UARTx = (UART_TypeDef *) scg_UARTx_Base[ch];                                //获取设备基址
  445.         if(UARTx->ISR & BIT0)                                                                                //FIFO收到指定数据的数据了
  446.         {
  447.                 UARTx_ReadRxData(ch, UARTx);
  448.         }
  449.        
  450.         if(UARTx->ISR & BIT4)                                                                                //FIFO有数据,但是收到足够数据并且超时了,需要去除余下的数据
  451.         {
  452.         UARTx_ReadRxData(ch, UARTx);                                                        //收到的数据没有满足FIFO阈值
  453.         }
  454.        
  455.         UARTx->ISR = UARTx->ISR;                                                                        //清除中断
  456. }
  1. /*************************************************************************************************************
  2. * 文件名:                        uart.h
  3. * 功能:                        NUC970 UART通讯支持
  4. * 作者:                        cp1300@139.com
  5. * 创建时间:                2020-08-29
  6. * 最后修改时间:        2020-08-29
  7. * 详细:                        串口通信底层支持
  8. *************************************************************************************************************/
  9. #ifndef _UART_H_  
  10. #define _UART_H_
  11. #include "nuc970_system.h"

  12. /***********************配置相关************************/
  13. #define UART_TX_TO_FIFI        1                        //1:数据发送到发送FIFO则认为发送完成; 0:数据从移位寄存器发送完成则认为发送完成
  14. #define UART_ChMax                11                        //串口通道数量
  15. #define UART_INT_PRIO        3                        //中断优先级,1-7

  16. /*********************************************************/



  17. //串口选择,串口1开始,到串口3
  18. typedef enum
  19. {
  20.         UART_CH0        =                0,        //UART0
  21.         UART_CH1        =                1,        //UART1-高速
  22.         UART_CH2        =                2,        //UART2-高速
  23.         UART_CH3        =                3,        //UART3
  24.         UART_CH4        =                4,        //UART4-高速
  25.         UART_CH5        =                5,        //UART5
  26.         UART_CH6        =                6,        //UART6-高速
  27.         UART_CH7        =                7,        //UART7
  28.         UART_CH8        =                8,        //UART8-高速
  29.         UART_CH9        =                9,        //UART9
  30.         UART_CH10        =                10,        //UART10
  31. }UART_CH_Type;


  32. //UART配置相关结构定义
  33. typedef struct
  34. {
  35.         u8 OddEvenVerify;        //奇偶校验,奇,偶,无
  36.         u8 StopBitWidth;        //停止位位宽1,2
  37.         u8 DataBitWidth;        //数据位宽度
  38. } UART_Config_TypeDef;


  39. //奇偶校验
  40. #define UART_VERIFY_NULL        0        //无校验
  41. #define UART_ODD                        1        //奇校验
  42. #define UART_EVEN                        2        //偶校验
  43. //停止位
  44. #define UART_STOP_1BIT                0        //一个停止位
  45. #define UART_STOP_2BIT                1        //2个停止位
  46. //数据位数
  47. #define UART_DATA_5BIT                0        //5位数据长度
  48. #define UART_DATA_6BIT                1        //6位数据长度
  49. #define UART_DATA_7BIT                2        //7位数据长度
  50. #define UART_DATA_8BIT                3        //8位数据长度

  51. //相关API
  52. bool UARTx_Init(UART_CH_Type ch,u32 Speed, bool isEnableRx);                //串口初始化
  53. void UARTx_SendByte(UART_CH_Type ch,u8 data);                                                //UART单字节发送
  54. void UARTx_SendData(UART_CH_Type ch,u8 *pTxBuff,u16 DataLen);                //UART数据发送函数
  55. void UARTx_WaitSendComplete(UART_CH_Type ch);                                                //等待数据发送完成-从串口发送完成
  56. void UARTx_SendString(UART_CH_Type ch,char *pString);                                //UART发送字符串
  57. bool UARTx_GetNewDataFlag(UART_CH_Type ch);                                                        //获取串口新数据标志
  58. bool UARTx_GetRxBuffFullFlag(UART_CH_Type ch);                                                //获取串口接收缓冲区满标志
  59. u8          UARTx_GetNewData(UART_CH_Type ch);                                                                //获取串口新数据
  60. void UARTx_SetRxBuff(UART_CH_Type ch,u8 *RxBuff,u16 RxBuffSize);        //设置串口接收缓冲区
  61. void UARTx_ClearRxInt(UART_CH_Type ch);                                                                //清除串口接收中断标志
  62. u32  UARTx_GetRxCnt(UART_CH_Type ch);                                                                //获取串口接收数据计数器
  63. void UARTx_ClearRxCnt(UART_CH_Type ch);                                                                //清除串口接收数据计数器

  64. #endif //_UART_H_

  1. /*************************************************************************************************************
  2. * 文件名:                        irq_aic.c
  3. * 功能:                        NUC970 中断控制器
  4. * 作者:                        cp1300@139.com
  5. * 创建时间:                2020-08-30
  6. * 最后修改时间:        2020-08-30
  7. * 详细:                        中断控制器驱动
  8. *************************************************************************************************************/
  9. #include "nuc970_system.h"
  10. #include "irq_aic.h"
  11. #include "typedef.h"

  12. static void NULL_IRQHandler(void){};                                //一个空的中断服务程序
  13. static void *sg_IRQHandlerTable[NUMBER_OF_INT_VECTORS];             //中断服务程序入口列表
  14. static bool sg_AIC_InitStatus = FALSE;                                                                //AIC初始化状态,防止重复初始化
  15.        

  16. /*************************************************************************************************************************
  17. * 函数                        :        void AIC_Init(void)
  18. * 功能                        :        AIC中断控制器初始化(在系统初始化中调用,请勿重复调用)
  19. * 参数                        :        无
  20. * 返回                        :        无
  21. * 依赖                        :        底层
  22. * 作者                        :        cp1300@139.com
  23. * 时间                        :        2020-08-30
  24. * 最后修改时间         :         2020-08-30
  25. * 说明                        :        初始化屏蔽所有中断,设置所有中断优先级为最低,并初始化所有中断服务程序入口
  26.                                         请不要重复初始化
  27. *************************************************************************************************************************/
  28. void AIC_Init(void)
  29. {
  30.         u32 i;
  31.        
  32.         if(sg_AIC_InitStatus == TRUE)        return;
  33.         for(i = 0;i < NUMBER_OF_INT_VECTORS;i ++)
  34.         {
  35.                 sg_IRQHandlerTable[i] = NULL_IRQHandler;                                //设置默认的中断函数
  36.                 AIC_ClearIrqActive((AIC_IRQ_Typedef) i);                                //AIC软件中断激活状态清除
  37.                 AIC_IrqEnable((AIC_IRQ_Typedef)i, FALSE);                                //设置一个中断使能状态-关闭
  38.                 AIC_SetIrqTriggered((AIC_IRQ_Typedef)i, AIC_LOW_LEVEL);        //设置一个中断触发方式-低电平触发
  39.                 AIC_SetIrqPriority((AIC_IRQ_Typedef)i, 7);                                //设置一个中断优先级-最低优先级
  40.         }
  41.         sg_AIC_InitStatus = TRUE;                                                                        //已经初始化了
  42.         AIC->EOSCR = 1;                //写入任何值,告诉AIC中断执行完毕了,防止之前有未退出的中断
  43. }
  44.        


  45. /*************************************************************************************************************************
  46. * 函数                        :        void AIC_RegisterIRQHandler(AIC_IRQ_Typedef AIC_IRQ_n, void (*pIRQHandler)(void))
  47. * 功能                        :        注册中断服务程序
  48. * 参数                        :        AIC_IRQ_n:中断源;pIRQHandler:中断服务程序
  49. * 返回                        :        无
  50. * 依赖                        :        底层
  51. * 作者                        :        cp1300@139.com
  52. * 时间                        :        2020-08-30
  53. * 最后修改时间         :         2020-08-30
  54. * 说明                        :       
  55. *************************************************************************************************************************/
  56. void AIC_RegisterIRQHandler(AIC_IRQ_Typedef AIC_IRQ_n, void (*pIRQHandler)(void))
  57. {
  58.     if(AIC_IRQ_n >= NUMBER_OF_INT_VECTORS) return;
  59.     if(pIRQHandler == NULL) //无效的,则使用默认的替代,防止为空
  60.     {
  61.         sg_IRQHandlerTable[AIC_IRQ_n] = (void *)NULL_IRQHandler;
  62.     }
  63.     else
  64.     {
  65.         sg_IRQHandlerTable[AIC_IRQ_n] = (void *)pIRQHandler;
  66.     }
  67. }




  68. /*************************************************************************************************************************
  69. * 函数                        :        void AIC_SetIrqTriggered(AIC_IRQ_Typedef AIC_IRQ_n, AIC_IntType AIC_INT_Triggered)
  70. * 功能                        :        设置一个中断触发方式
  71. * 参数                        :        AIC_IRQ_n:中断源;AIC_INT_Triggered:触发方式,见AIC_IntType
  72. * 返回                        :        无
  73. * 依赖                        :        底层
  74. * 作者                        :        cp1300@139.com
  75. * 时间                        :        2020-08-30
  76. * 最后修改时间         :         2020-08-30
  77. * 说明                        :       
  78. *************************************************************************************************************************/
  79. void AIC_SetIrqTriggered(AIC_IRQ_Typedef AIC_IRQ_n, AIC_IntType AIC_INT_Triggered)
  80. {
  81.         u8 n,i;
  82.         u32 temp;
  83.        
  84.         if(AIC_IRQ_n >= NUMBER_OF_INT_VECTORS) return;
  85.         n = AIC_IRQ_n / 4;
  86.         i = AIC_IRQ_n % 4;

  87.         temp = AIC->SCR[n];
  88.         temp &= ~(0x03 << (i*8 + 6));                                                        //清除之前配置
  89.         temp |= (AIC_INT_Triggered & 0x03) << (i*8 + 6);                //重新配置
  90.         AIC->SCR[n] = temp;
  91. }

  92. /*************************************************************************************************************************
  93. * 函数                        :        void AIC_SetIrqPriority(AIC_IRQ_Typedef AIC_IRQ_n, u8 AIC_INT_Prio)
  94. * 功能                        :        设置一个中断优先级
  95. * 参数                        :        AIC_IRQ_n:中断源;AIC_INT_Prio:优先级0-7
  96. * 返回                        :        无
  97. * 依赖                        :        底层
  98. * 作者                        :        cp1300@139.com
  99. * 时间                        :        2020-08-30
  100. * 最后修改时间         :         2020-08-30
  101. * 说明                        :        优先级0会变为快速中断
  102. *************************************************************************************************************************/
  103. void AIC_SetIrqPriority(AIC_IRQ_Typedef AIC_IRQ_n, u8 AIC_INT_Prio)
  104. {
  105.         u8 n,i;
  106.         u32 temp;

  107.         if(AIC_IRQ_n >= NUMBER_OF_INT_VECTORS) return;
  108.         n = AIC_IRQ_n / 4;
  109.         i = AIC_IRQ_n % 4;
  110.        
  111.         if(AIC_INT_Prio > 7) AIC_INT_Prio = 7;                                        //优先级限制最低为7
  112.         temp = AIC->SCR[n];
  113.         temp &= ~(0x07 << (i*8 + 0));                                                        //清除之前配置
  114.         temp |= (AIC_INT_Prio & 0x07) << (i*8 + 0);                                //重新配置
  115.         AIC->SCR[n] = temp;
  116. }

  117. /*************************************************************************************************************************
  118. * 函数                        :        bool AIC_GetIrqRawStatus(AIC_IRQ_Typedef AIC_IRQ_n)
  119. * 功能                        :        获取中断原始触发状态
  120. * 参数                        :        AIC_IRQ_n:中断源
  121. * 返回                        :        TRUE:中断已经触发;FALSE:中断未触发
  122. * 依赖                        :        底层
  123. * 作者                        :        cp1300@139.com
  124. * 时间                        :        2020-08-30
  125. * 最后修改时间         :         2020-08-30
  126. * 说明                        :        获取的是每个中断通道内的内部状态,不受中断屏蔽影响
  127. *************************************************************************************************************************/
  128. bool AIC_GetIrqRawStatus(AIC_IRQ_Typedef AIC_IRQ_n)
  129. {
  130.         if(AIC_IRQ_n >= NUMBER_OF_INT_VECTORS) return FALSE;
  131.         if(AIC->IRSR[AIC_IRQ_n/32] & (1 << (AIC_IRQ_n%32)))
  132.         {
  133.                 return TRUE;
  134.         }
  135.         else
  136.         {
  137.                 return FALSE;
  138.         }
  139. }


  140. /*************************************************************************************************************************
  141. * 函数                        :        bool AIC_GetIrqActiveStatus(AIC_IRQ_Typedef AIC_IRQ_n)
  142. * 功能                        :        获取中断活动状态
  143. * 参数                        :        AIC_IRQ_n:中断源
  144. * 返回                        :        TRUE:中断已经激活;FALSE:中断未激活
  145. * 依赖                        :        底层
  146. * 作者                        :        cp1300@139.com
  147. * 时间                        :        2020-08-30
  148. * 最后修改时间         :         2020-08-30
  149. * 说明                        :        不受中断屏蔽影响
  150. *************************************************************************************************************************/
  151. bool AIC_GetIrqActiveStatus(AIC_IRQ_Typedef AIC_IRQ_n)
  152. {
  153.         if(AIC_IRQ_n >= NUMBER_OF_INT_VECTORS) return FALSE;
  154.         if(AIC->IASR[AIC_IRQ_n/32] & (1 << (AIC_IRQ_n%32)))
  155.         {
  156.                 return TRUE;
  157.         }
  158.         else
  159.         {
  160.                 return FALSE;
  161.         }
  162. }


  163. /*************************************************************************************************************************
  164. * 函数                        :        bool AIC_GetIrqStatus(AIC_IRQ_Typedef AIC_IRQ_n)
  165. * 功能                        :        获取中断状态(中断使能并有效的状态)
  166. * 参数                        :        AIC_IRQ_n:中断源
  167. * 返回                        :        TRUE:中断有效;FALSE:中断无效
  168. * 依赖                        :        底层
  169. * 作者                        :        cp1300@139.com
  170. * 时间                        :        2020-08-30
  171. * 最后修改时间         :         2020-08-30
  172. * 说明                        :        会受到中断屏蔽影响
  173. *************************************************************************************************************************/
  174. bool AIC_GetIrqStatus(AIC_IRQ_Typedef AIC_IRQ_n)
  175. {
  176.         if(AIC_IRQ_n >= NUMBER_OF_INT_VECTORS) return FALSE;
  177.         if(AIC->ISR[AIC_IRQ_n/32] & (1 << (AIC_IRQ_n%32)))
  178.         {
  179.                 return TRUE;
  180.         }
  181.         else
  182.         {
  183.                 return FALSE;
  184.         }
  185. }


  186. /*************************************************************************************************************************
  187. * 函数                        :        u8 AIC_GetThisIntIRQorFIQ(void)
  188. * 功能                        :        获取当前的中断是IRQ还是FIQ
  189. * 参数                        :        无
  190. * 返回                        :        0:无中断;1:IRQ;2:FIQ
  191. * 依赖                        :        底层
  192. * 作者                        :        cp1300@139.com
  193. * 时间                        :        2020-08-30
  194. * 最后修改时间         :         2020-08-30
  195. * 说明                        :       
  196. *************************************************************************************************************************/
  197. u8 AIC_GetThisIntIRQorFIQ(void)
  198. {
  199.         if(AIC->OISR & BIT1) return 1;
  200.         else if(AIC->OISR & BIT0) return 2;
  201.         else return 0;
  202. }


  203. /*************************************************************************************************************************
  204. * 函数                        :        bool AIC_GetIrqEnableStatus(AIC_IRQ_Typedef AIC_IRQ_n)
  205. * 功能                        :        获取中断使能状态
  206. * 参数                        :        AIC_IRQ_n:中断源
  207. * 返回                        :        TRUE:中断使能;FALSE:中断关闭
  208. * 依赖                        :        底层
  209. * 作者                        :        cp1300@139.com
  210. * 时间                        :        2020-08-30
  211. * 最后修改时间         :         2020-08-30
  212. * 说明                        :        获取对应中断开关状态
  213. *************************************************************************************************************************/
  214. bool AIC_GetIrqEnableStatus(AIC_IRQ_Typedef AIC_IRQ_n)
  215. {
  216.         if(AIC_IRQ_n >= NUMBER_OF_INT_VECTORS) return FALSE;
  217.         if(AIC->IMR[AIC_IRQ_n/32] & (1 << (AIC_IRQ_n%32)))
  218.         {
  219.                 return TRUE;
  220.         }
  221.         else
  222.         {
  223.                 return FALSE;
  224.         }
  225. }


  226. /*************************************************************************************************************************
  227. * 函数                        :        void AIC_IrqEnable(AIC_IRQ_Typedef AIC_IRQ_n, bool isEnable)
  228. * 功能                        :        设置一个中断使能状态
  229. * 参数                        :        AIC_IRQ_n:中断源;isEnable:是否使能中断
  230. * 返回                        :        无
  231. * 依赖                        :        底层
  232. * 作者                        :        cp1300@139.com
  233. * 时间                        :        2020-08-30
  234. * 最后修改时间         :         2020-08-30
  235. * 说明                        :       
  236. *************************************************************************************************************************/
  237. void AIC_IrqEnable(AIC_IRQ_Typedef AIC_IRQ_n, bool isEnable)
  238. {
  239.         if(AIC_IRQ_n >= NUMBER_OF_INT_VECTORS) return;
  240.         if(isEnable)        //使能对应中断
  241.         {
  242.                 AIC->MECR[AIC_IRQ_n/32] = 1 << (AIC_IRQ_n%32);        //写1开启对应中断
  243.         }
  244.         else //关闭对应中断
  245.         {
  246.                 AIC->MDCR[AIC_IRQ_n/32] = 1 << (AIC_IRQ_n%32);        //写1关闭对应中断
  247.         }
  248. }


  249. /*************************************************************************************************************************
  250. *函数                :        void AIC_SetIrqActive(AIC_IRQ_Typedef AIC_IRQ_n)
  251. *功能                :        AIC中断设置为激活状态(软件触发某个中断)
  252. *参数                :        AIC_IRQ_n:中断源
  253. *返回                :        无
  254. *依赖                        :         底层宏定义
  255. *作者               :        cp1300@139.com
  256. *时间                     :        2020-08-30
  257. *最后修改时间        :        2020-08-30
  258. *说明                :        相当于软件触发某个中断
  259. *************************************************************************************************************************/
  260. void AIC_SetIrqActive(AIC_IRQ_Typedef AIC_IRQ_n)
  261. {
  262.         if(AIC_IRQ_n >= NUMBER_OF_INT_VECTORS) return;
  263.         AIC->SSCR[AIC_IRQ_n/32] = 1 << (AIC_IRQ_n%32);        //写1软件触发对应中断
  264. }


  265. /*************************************************************************************************************************
  266. *函数                :        void AIC_ClearIrqActive(AIC_IRQ_Typedef AIC_IRQ_n)
  267. *功能                :        AIC软件中断激活状态清除
  268. *参数                :        V3S_IRQ_n:中断编号
  269. *返回                :        无
  270. *依赖                        :         底层宏定义
  271. *作者               :        cp1300@139.com
  272. *时间                     :        2020-08-30
  273. *最后修改时间        :        2020-08-30
  274. *说明                :        相当于清除1个已经触发软件中断的状态
  275. *************************************************************************************************************************/
  276. void AIC_ClearIrqActive(AIC_IRQ_Typedef AIC_IRQ_n)
  277. {
  278.         if(AIC_IRQ_n >= NUMBER_OF_INT_VECTORS) return;
  279.         AIC->SCCR[AIC_IRQ_n/32] = 1 << (AIC_IRQ_n%32);        //写1清除软件触发对应中断
  280. }


  281. #if(UCOS_II_EN) //使能了操作系统

  282. #else
  283. /*************************************************************************************************************************
  284. * 函数                        :        void SystemIrqHandler(void)
  285. * 功能                        :        系统中断处理(无操作系统接口)
  286. * 参数                        :        无
  287. * 返回                        :        无
  288. * 依赖                        :        需要在中断程序汇编中编写保护现场,并调用
  289. * 作者                        :        cp1300@139.com
  290. * 时间                        :        2020-08-21
  291. * 最后修改时间         :         2020-08-21
  292. * 说明                        :        用于非OS情况下调用,会直接在startup.s中调用
  293. *************************************************************************************************************************/
  294. void SystemIrqHandler(void)
  295. {
  296.         u32 mISNR;       
  297.         u32 intNum;

  298.         mISNR = AIC->IPER;        //需要先读取IPER,否则ISNR可能没更新,IPER的值>>2位是等于ISNR的,必须先读取IPRE
  299.         mISNR >>= 2;
  300.         //mISNR = AIC->ISNR;        //这个寄存器只能读取一次,下次读取会被清零的,ISNR有时候没有及时更新
  301.         intNum = mISNR & 0X3F;
  302.         if ((intNum == 0) || (intNum>=NUMBER_OF_INT_VECTORS))   
  303.         {
  304.                 AIC->EOSCR = 1;        //写入任何值,告诉AIC中断执行完毕了
  305.                 return;
  306.         }
  307.         //执行中断服务程序
  308.         ((void (*)(void)) sg_IRQHandlerTable[intNum])();     //执行中断服务程序
  309.         AIC->EOSCR = 1;                //写入任何值,告诉AIC中断执行完毕了
  310. }

  311. #endif //UCOS_II_EN
  1. /*************************************************************************************************************
  2. * 文件名:                        irq_aic.h
  3. * 功能:                        NUC970 中断控制器
  4. * 作者:                        cp1300@139.com
  5. * 创建时间:                2020-08-30
  6. * 最后修改时间:        2020-08-30
  7. * 详细:                        中断控制器驱动
  8. *************************************************************************************************************/
  9. #ifndef _IRQ_AIC_H_  
  10. #define _IRQ_AIC_H_
  11. #include "nuc970_system.h"



  12. //中断源
  13. typedef enum
  14. {
  15.         AIC_NULL_INT        =        0,                        //无效的中断
  16.         AIC_WDT_INT                =        1,                        //Watch Dog Timer Interrupt
  17.         AIC_WWDT_INT        =        2,                        //Windowed-WDT Interrupt
  18.         AIC_LVD_INT                =        3,                        //Low Voltage Detect Interrupt
  19.         AIC_EXT0_INT        =        4,                        //外部中断0
  20.         AIC_EXT1_INT        =        5,                        //外部中断1
  21.         AIC_EXT2_INT        =        6,                        //外部中断2
  22.         AIC_EXT3_INT        =        7,                        //外部中断3
  23.         AIC_EXT4_INT        =        8,                        //外部中断4
  24.         AIC_EXT5_INT        =        9,                        //外部中断5
  25.         AIC_EXT6_INT        =        10,                        //外部中断6
  26.         AIC_EXT7_INT        =        11,                        //外部中断7
  27.         AIC_ACTL_INT        =        12,                        //Audio Controller Interrupt
  28.         AIC_LCD_INT                =        13,                        //LCD Controller Interrupt
  29.         AIC_CAP_INT                =        14,                        //Sensor Interface Controller Interrupt
  30.         AIC_RTC_INT                =        15,                        //RTC Interrupt
  31.         AIC_TMR0_INT        =        16,                        //Timer 0 Interrupt
  32.         AIC_TMR1_INT        =        17,                        //Timer 1 Interrupt
  33.         AIC_ADC_INT                =        18,                        //ADC Interrupt
  34.         AIC_EMC0_RX_INT        =        19,                        //EMC 0 RX Interrupt
  35.         AIC_EMC1_RX_INT        =        20,                        //EMC 1 RX Interrupt
  36.         AIC_EMC0_TX_INT        =        21,                        //EMC 0 TX Interrupt
  37.         AIC_EMC1_TX_INT        =        22,                        //EMC 1 TX Interrupt
  38.         AIC_EHCI_INT        =        23,                        //USB 2.0 Host Controller Interrupt
  39.         AIC_OHCI_INT        =        24,                        //USB 1.1 Host Controller Interrupt
  40.         AIC_GDMA0_INT        =        25,                        //GDMA Channel 0 Interrupt
  41.         AIC_GDMA1_INT        =        26,                        //GDMA Channel 1 Interrupt
  42.         AIC_SDH_INT                =        27,                        //SD/SDIO Host Interrupt
  43.         AIC_SIC_INT                =        28,                        //SIC Interrupt
  44.         AIC_UDC_INT                =        29,                        //USB Device Controller Interrupt
  45.         AIC_TMR2_INT        =        30,                        //Timer 2 Interrupt
  46.         AIC_TMR3_INT        =        31,                        //Timer 3 Interrupt
  47.         AIC_TMR4_INT        =        32,                        //Timer 4 Interrupt
  48.         AIC_JPEG_INT        =        33,                        //JPEG Engine Interrupt
  49.         AIC_GE2D_INT        =        34,                        //2D Graphic Engine Interrupt
  50.         AIC_CRYPTO_INT        =        35,                        //CRYPTO Engine Interrupt
  51.         AIC_UART0_INT        =        36,                        //UART 0 Interrupt
  52.         AIC_UART1_INT        =        37,                        //UART 1 Interrupt
  53.         AIC_UART2_INT        =        38,                        //UART 2 Interrupt
  54.         AIC_UART4_INT        =        39,                        //UART 4 Interrupt
  55.         AIC_UART6_INT        =        40,                        //UART 6 Interrupt
  56.         AIC_UART8_INT        =        41,                        //UART 8 Interrupt
  57.         AIC_UART10_INT        =        42,                        //UART 10 Interrupt
  58.         AIC_UART3_INT        =        43,                        //UART 3 Interrupt
  59.         AIC_UART5_INT        =        44,                        //UART 5 Interrupt
  60.         AIC_UART7_INT        =        45,                        //UART 7 Interrupt
  61.         AIC_UART9_INT        =        46,                        //UART 9 Interrupt
  62.         AIC_ETMR0_INT        =        47,                        //Enhanced Timer 0 Interrupt
  63.         AIC_ETMR1_INT        =        48,                        //Enhanced Timer 1 Interrupt
  64.         AIC_ETMR2_INT        =        49,                        //Enhanced Timer 2 Interrupt
  65.         AIC_ETMR3_INT        =        50,                        //Enhanced Timer 3 Interrupt
  66.         AIC_USI0_INT        =        51,                        //USI 0 Interrupt
  67.         AIC_USI1_INT        =        52,                        //USI 1 Interrupt
  68.         AIC_I2C0_INT        =        53,                        //I2C 0 Interrupt
  69.         AIC_I2C1_INT        =        54,                        //I2C 1 Interrupt
  70.         AIC_SMC0_INT        =        55,                        //SmartCard 0 Interrupt
  71.         AIC_SMC1_INT        =        56,                        //SmartCard 1 Interrupt
  72.         AIC_GPIO_INT        =        57,                        //GPIO Interrupt
  73.         AIC_CAN0_INT        =        58,                        //CAN 0 Interrupt
  74.         AIC_CAN1_INT        =        59,                        //CAN 1 Interrupt
  75.         AIC_PWM_INT                =        60,                        //PWM Interrupt
  76.         AIC_KPI_INT                =        61,                        //KPI Interrupt
  77. }AIC_IRQ_Typedef;
  78. #define NUMBER_OF_INT_VECTORS   62       //中断数量


  79. //中断类型
  80. typedef enum
  81. {
  82.         AIC_LOW_LEVEL        =        0,        //低电平触发-注意:电平触发的中断会被自动清除,电平消失后就没了
  83.         AIC_HIGHT_LEVEL        =        1,        //高电平触发-注意:电平触发的中断会被自动清除,电平消失后就没了
  84.         AIC_LOW_EDGE        =        2,        //下降沿触发
  85.         AIC_HIGHT_EDGE        =        3,        //上升沿触发
  86. }AIC_IntType;

  87. //相关API
  88. void AIC_Init(void);                                                                                                                                //AIC中断控制器初始化(在系统初始化中调用,请勿重复调用)
  89. void AIC_RegisterIRQHandler(AIC_IRQ_Typedef AIC_IRQ_n, void (*pIRQHandler)(void));        //注册中断服务程序
  90. void AIC_IrqEnable(AIC_IRQ_Typedef AIC_IRQ_n, bool isEnable);                                                //设置一个中断使能状态
  91. void AIC_SetIrqTriggered(AIC_IRQ_Typedef AIC_IRQ_n, AIC_IntType AIC_INT_Triggered);        //设置一个中断触发方式
  92. void AIC_SetIrqPriority(AIC_IRQ_Typedef AIC_IRQ_n, u8 AIC_INT_Prio);                                //设置一个中断优先级
  93. bool AIC_GetIrqRawStatus(AIC_IRQ_Typedef AIC_IRQ_n);                                                                //获取中断原始触发状态
  94. bool AIC_GetIrqActiveStatus(AIC_IRQ_Typedef AIC_IRQ_n);                                                                //获取中断活动状态
  95. bool AIC_GetIrqStatus(AIC_IRQ_Typedef AIC_IRQ_n);                                                                        //获取中断状态(中断使能并有效的状态)
  96. u8 AIC_GetThisIntIRQorFIQ(void);                                                                                                        //获取当前的中断是IRQ还是FIQ
  97. bool AIC_GetIrqEnableStatus(AIC_IRQ_Typedef AIC_IRQ_n);                                                                //获取中断使能状态
  98. void AIC_SetIrqActive(AIC_IRQ_Typedef AIC_IRQ_n);                                                                        //AIC中断设置为激活状态(软件触发某个中断)
  99. void AIC_ClearIrqActive(AIC_IRQ_Typedef AIC_IRQ_n);                                                                        //AIC软件中断激活状态清除


  100. #endif //_IRQ_AIC_H_

  1. static u8 buff[1024];
  2. u32 cnt1=0,cnt2 = 0;

  3. UARTx_Init(UART_CH0, 115200, TRUE);                        //串口初始化
  4. UARTx_SetRxBuff(UART_CH0, (u8 *)buff, 1024-1);
  5.         SYS_EnableIrq();        //使能系统总中断
  6.         while(1)
  7.         {
  8.                 cnt1 = UARTx_GetRxCnt(UART_CH0);
  9.                 SYS_DelayMS(10);
  10.                 GPIOB->DATAOUT &= ~BIT1;
  11.                 cnt2 = UARTx_GetRxCnt(UART_CH0);
  12.                 if(cnt2 > 0 && cnt1 == cnt2)
  13.                 {
  14.             //uart_printf("接收数据长度:%d\r\n", cnt1);
  15.                         UARTx_SendData(UART_CH0, (u8 *)buff, cnt2);
  16.                         UARTx_ClearRxCnt(UART_CH0);
  17.                 }
  18.                 SYS_DelayMS(20);
  19.                
  20.                 GPIOB->DATAOUT |= BIT1;
  21.                
  22.         }

https://blog.csdn.net/cp1300/article/details/108314587


永久冻结 发表于 2025-7-17 12:37 | 显示全部楼层
串口驱动是实现数据收发的软件程序,中断控制器是硬件,管理中断优先级和触发,二者协同实现异步通信。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

35

主题

1537

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部