- interrupt_t * attach (uintptr_t irq)
- 挂接本中断对象到指定的中断号上
-
该功能实现当前的中断对象和对应的中断向量类进行相关联,无聊找出了其中的一些关系
这段是中断的attach函数,看到和vector::table[中断号].attach(this),还有vector_t::attach
- __OPT_INLINE__ look::interrupt_t* look::interrupt_t::attach(uintptr_t irq)
- {
- return vector_t::table[irq - -1/*SysTick_IRQn*/].attach(this);
- }
- _OPT_INLINE__ look::interrupt_t*
- look::vector_t::attach(interrupt_t* intr)
- {
- interrupt_t*
- old = interrupt;
- interrupt
- = intr;
- return
- old;
- }
在vector_t类中找到table[], 从这几段代码看出在产生中断时就可以通过table[中断号].interrupt.isr/dsr来调用
对应中断的相关中断函数了,应为每个table[]中都用了interrupt *将其联系起来了,好了中断就讲到这
- #ifndef __DOXYGEN__
- union {
- struct {
- interrupt_t* interrupt;
- uint16_t count;
- uint8_t next;
- };
- uint64_t data;
- };
- #endif // __DOXYGEN__
- static vector_t table[] __attribute__((aligned(4)));
-
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
下面是我写的代码,一个uart0_int_c:public interrupt_t类实现串口的一些功能,可以设置参数,也可以用默认设置
这些代码有些都是照着MO库来改写的,并在一个任务中实现了mmbox_t<T,SIZE>多信息邮箱,如果串口中断接收到数据,则通过
邮箱将数据送到一个任务函数中并通过串口发送出去,邮箱的get()函数在没有信息时会使当前任务进入阻塞状态,只有有信息时,才能
激活任务,并读取邮箱里的数据。
uart.h
- /*****************************************
- //
- //
- ******************************************/
- #ifndef _Uart_h_
- #define _Uart_h_
- #include"look.h"
- /*---------------------------------------------------------------------------------------------------------*/
- /* DATA BIT */
- /*---------------------------------------------------------------------------------------------------------*/
- typedef enum
- {
- DRVUART_DATABITS_5 = 0x0,
- DRVUART_DATABITS_6 = 0x1,
- DRVUART_DATABITS_7 = 0x2,
- DRVUART_DATABITS_8 = 0x3
- } DATABITS_SET;
- /*---------------------------------------------------------------------------------------------------------*/
- /* PARITY Setting */
- /*---------------------------------------------------------------------------------------------------------*/
- typedef enum
- {
- DRVUART_PARITY_NONE = 0x0,
- DRVUART_PARITY_ODD = 0x1,
- DRVUART_PARITY_EVEN = 0x3,
- DRVUART_PARITY_MARK = 0x5,
- DRVUART_PARITY_SPACE = 0x7
- } PARITY_SET;
- /*---------------------------------------------------------------------------------------------------------*/
- /* STOP BIT */
- /*---------------------------------------------------------------------------------------------------------*/
- typedef enum
- {
- DRVUART_STOPBITS_1 = 0x0,
- DRVUART_STOPBITS_1_5 = 0x1,
- DRVUART_STOPBITS_2 = 0x1
- } STOPBITS_SET;
- /*---------------------------------------------------------------------------------------------------------*/
- /* FIFO Select */
- /*---------------------------------------------------------------------------------------------------------*/
- typedef enum
- {
- DRVUART_FIFO_1BYTES = 0x0,
- DRVUART_FIFO_4BYTES = 0x1,
- DRVUART_FIFO_8BYTES = 0x2,
- DRVUART_FIFO_14BYTES = 0x3,
- DRVUART_FIFO_30BYTES = 0x4,
- DRVUART_FIFO_46BYTES = 0x5,
- DRVUART_FIFO_62BYTES = 0x6
- }FIFO_SET;
- /*****************************************
- //串口中断类
- *****************************************/
- class uart0_int_c :public interrupt_t{
- public:
- uart0_int_c(uint32_t u32Bandrate = 9600 ,PARITY_SET u8cParity=DRVUART_PARITY_NONE,\
- STOPBITS_SET u8cStopBits=DRVUART_STOPBITS_1,DATABITS_SET u8cDataBits=DRVUART_DATABITS_8,\
- FIFO_SET u8cRxTriggerLevel= DRVUART_FIFO_1BYTES);
- void Uart0Close();
- void Uart0RxEnableInt();//接收中断使能
- void Uart0RxDisableInt();//接受中断失效
- uint8_t Wstr(const char *);
- uint8_t Write(uint32_t *,uint32_t);//发送数据
- uint8_t Read(uint32_t * ,uint32_t);//读接收的数据
- protected:
- bool isr(int vector);
- void dsr(int vector,uintptr_t count);
- private:
- void BaudRateSet(uint32_t clk, uint32_t baudRate);
- };
- #endif
uart.cpp串口代码
- #include <NUC1xx.h>
- #include"NUC1xxM051Seriescfg.h"
- #include"LOOK_config.h"
- #include"Uart.h"
- //构造函数,并可以设置波特率,校验,数据位,停止位,UART_FIFO
- uart0_int_c::uart0_int_c(uint32_t u32Bandrate ,PARITY_SET u8cParity,\
- STOPBITS_SET u8cStopBits,DATABITS_SET u8cDataBits,\
- FIFO_SET u8cRxTriggerLevel){
-
- //将管脚设置为UART0模式
- SYSs.GPBMFP.Bits.UART0_RX=1;
- SYSs.GPBMFP.Bits.UART0_TX=1;
- SYSs.GPBMFP.Bits.UART0_nRTS_nWRL=1;
- SYSs.GPBMFP.Bits.UART0_nCTS_nWRH=1; //SYSs.GPBMFP.Regs|=0x0f;
- /* Reset IP */
- SYSs.IPRSTC2.Bits.UART0_RST = 1;
- SYSs.IPRSTC2.Bits.UART0_RST = 0;
-
- /* Enable UART0 clock */
- SYSCLKs.APBCLK.Bits.UART0_EN=1;
-
- UART0s.FCR.Bits.TFR =1;//TX/RX软复位
- UART0s.FCR.Bits.RFR =1;
- /* Set Rx Trigger Level */
- UART0s.FCR.Bits.RFITL = u8cRxTriggerLevel;
-
- /* Set Parity & Data bits & Stop bits */
- UART0s.LCR.Bits.SPE =(u8cParity&0x4)?1:0;
- UART0s.LCR.Bits.EPE =(u8cParity&0x2)?1:0;
- UART0s.LCR.Bits.PBE =(u8cParity&0x1)?1:0;
-
- UART0s.LCR.Bits.WLS =u8cDataBits;
- UART0s.LCR.Bits.NSB =DRVUART_STOPBITS_1;
-
- /* Set Time-Out */
- UART0s.TOR.Bits.TOIC =0x7f;
- //设置UART时钟为外部12M时钟
- SYSCLKs.CLKSEL1.Bits.UART_S = 0;
- BaudRateSet(F_CPU,u32Bandrate);//设置波特率
- }
- //关闭UART0串口
- void uart0_int_c::Uart0Close()
- {
- while(UART0s.FSR.Bits.TE_FLAG);
- SYSCLKs.APBCLK.Bits.UART0_EN = 0;
- vector_t::disable(UART0_IRQn);
- }
- //使能UART0接收中断
- void uart0_int_c::Uart0RxEnableInt()
- {
- UART0s.IER.Bits.RDA_IEN=1; //使能中断
- attach(UART0_IRQn);
- vector_t::enable(UART0_IRQn);
- }
- //失效
- void uart0_int_c::Uart0RxDisableInt()
- {
- UART0s.IER.Bits.RDA_IEN=0;
- vector_t::disable(UART0_IRQn);
- }
- uint8_t uart0_int_c::Wstr(const char *wstrbuf)
- {
- uint32_t u32delayno=0;
- do{
- u32delayno = 0;
- UART0s.DATA.Regs=*wstrbuf++;
-
- while (UART0s.FSR.Bits.TE_FLAG !=1) /* Wait Tx empty and Time-out manner */
- {
- u32delayno++;
- if ( u32delayno >= 0x1000)
- return 0;
- }
- }while(*wstrbuf!='\0');
- return 1;
- }
- //发送数据
- uint8_t uart0_int_c::Write(uint32_t *pu32TxBuf, uint32_t u32WriteBytes)
- {
- uint32_t u32Count, u32delayno;
- for (u32Count=0; u32Count<u32WriteBytes; u32Count++)
- {
- u32delayno = 0;
- while (UART0s.FSR.Bits.TE_FLAG !=1) /* Wait Tx empty and Time-out manner */
- {
- u32delayno++;
- if ( u32delayno >= 0x1000)
- return 0;
-
- }
- UART0s.DATA.Regs = pu32TxBuf[u32Count]; /* Send UART Data from buffer */
- }
- return 1;
-
-
- }
- //读数据
- uint8_t uart0_int_c::Read(uint32_t *pu32RxBuf, uint32_t u32ReadBytes)
- {
- uint32_t u32Count, u32delayno;
- for (u32Count=0; u32Count < u32ReadBytes; u32Count++)
- {
- u32delayno = 0;
- while (UART0s.FSR.Bits.RX_EMPTY ==1) /* Check RX empty => failed */
- {
- u32delayno++;
- if ( u32delayno >= 0x1000 )
- return 0;
- }
- pu32RxBuf[u32Count] = UART0s.DATA.Regs; /* Get Data from UART RX */
- }
- return 1;
-
- }
- //M0库中的波特率设置函数
- void uart0_int_c::BaudRateSet(uint32_t clk, uint32_t baudRate)
- {
- int32_t tmp;
- int32_t div;
- if(((clk / baudRate)%16)<3) /* Source Clock mod 16 <3 => Using Divider X =16 (MODE#0) */
- {
- UART0s.BAUD.Bits.DIV_X_EN = 0;
- UART0s.BAUD.Bits.DIV_X_ONE = 0;
- tmp = clk / baudRate/16 -2;
- }
- else /* Source Clock mod 16 >3 => Up 5% Error BaudRate */
- {
- UART0s.BAUD.Bits.DIV_X_EN = 1; /* Try to Set Divider X = 1 (MODE#2)*/
- UART0s.BAUD.Bits.DIV_X_ONE = 1;
- tmp = clk / baudRate -2;
- if(tmp > 0xFFFF) /* If Divider > Range */
- {
- UART0s.BAUD.Bits.DIV_X_EN = 1; /* Try to Set Divider X up 10 (MODE#1) */
- UART0s.BAUD.Bits.DIV_X_ONE = 0;
- for(div = 8; div <16;div++)
- {
- if(((clk / baudRate)%(div+1))<3)
- {
- UART0s.BAUD.Bits.DIVIDER_X = div;
- tmp = clk / baudRate / (div+1) -2;
- break;
- }
- }
- }
- }
- UART0s.BAUD.Bits.BRD = tmp;
- }
main.cpp主文件
其他代码不贴了,要的大家看程序,希望老师、大叔和大家多多提提意见,好让我提高下
有问题也可以一起多多交流下