MC9S12XEP100 SCI(UART)驱动程序

来源:互联网 发布:洛奇英雄传n卡设置优化 编辑:程序博客网 时间:2024/06/08 04:11

忙着毕设,很久没有写文章了,终于答辩完了,得了个校优秀毕业设计。毕设做的是个智能接口模块,用一周时间入门了MC9S12XEP100的开发,又用一周时间入门了uC/OS-II嵌入式操作系统,在做毕设的过程中学到了很多,现在把一些工具发上来分享。


首先先发个自己封装的MC9S12XEP100的SCI模块(也就是UART模块)的驱动。这些代码参考了 Li Yuan http://blog.csdn.net/liyuanbhu/article/details/7764851 的代码,整个代码风格是按照uCOS-II操作系统源码的风格来写的,在此表示感谢。
目前还不是特别完整完善,但基本使用是没有问题了。
首先是.h文件,除了硬件驱动程序,还有在基于uCOS-II操作系统的SCI驱动程序,这章先讲硬件驱动部分

/***********************************************************************************************                    SCI(Serial Communication Interface) SUPPORT PACKAGE*                                   Freescale MC9S12XEP100*                           飞思卡尔   MC9S12XEP100  SCI支持包** File : SCI_def.h* By   : Lin Shijun(http://blog.csdn.net/lin_strong)* Date:  2017/10/27* version: V2.1* History: 2017/04/24  V1.0   the prototype of SCI_uCOS,only support SCI0 and SCI1*          2017/07/20  V2.0   a. update the module to support the SCI0 to SCI7*                             b. expend the configure option for all SCI port*                             c. add SCI_SEND_MULTIBYTE_EN option to ignore SCI_PutLong() and SCI_PutShort()*                             d. add many marco error check*          2017/10/27  V2.1   fix a bug in SCI_uCos.c* NOTE(s):a.refer to Li Yuan's  (http://blog.csdn.net/liyuanbhu/article/details/7764851)*                      and *                  uCOS-II's Code*         b.记得把SCI_uCOS.s中的SCIx_RxTxISR中断服务程序指向对应的中断向量地址*                  this SCI PACKAGE include files —— SCI_def.h, SCI.c, SCI_uCos.c, SCI_uCos.s*                  这个SCI 开发包有以下文件:SCI_def.h,SCI.c,SCI_uCos.c, SCI_uCos.s*        **********************************************************************************************/#ifndef   SCI_DEF_H#define   SCI_DEF_H/**********************************************************************************************                                   MISCELLANEOUS*********************************************************************************************/#ifndef  FALSE#define  FALSE    0#endif#ifndef  TRUE#define  TRUE     1#endif#ifndef  NUL  #define  NUL      0x00  #endif /*********************************************************************************************                              MAIN  CONFIGURE 主配置********************************************************************************************/#define   SCI_MODULE_ENABLE        TRUE        /*   TRUE: 启用SCI驱动模块        */#define   SCI_UCOS_MODULE_ENABLE   TRUE        /*  TRUE: 启用基于uCOS-II的SCI驱动  */#if(SCI_MODULE_ENABLE == TRUE)#if(SCI_UCOS_MODULE_ENABLE == TRUE)            // 只针对uCOS-II的SCI驱动部分    #define   SCI0_CODE_INCLUDE     TRUE       /*   TRUE: 包含SCI0的代码    */    #define   SCI1_CODE_INCLUDE     TRUE       /*   TRUE: 包含SCI1的代码    */#endif  // of (SCI_UCOS_MODULE_ENABLE == TRUE)/*********************************************************************************************                                    INCLUDES********************************************************************************************/#include <MC9S12XEP100.h>#if(SCI_UCOS_MODULE_ENABLE == TRUE)   #include <os_cpu.h>#endif /********************************************************************************************                                    CONSTANT*******************************************************************************************/#define   SCI0      0x00                         /*   SCI0           */#define   SCI1      0x01                         /*   SCI1           */#define   SCI2      0x02                         /*   SCI2           */#define   SCI3      0x03                         /*   SCI3           */#define   SCI4      0x04                         /*   SCI4           */#define   SCI5      0x05                         /*   SCI5           */#define   SCI6      0x06                         /*   SCI6           */#define   SCI7      0x07                         /*   SCI7           */// Map to SCI registerextern word* const Ptr_SCIBD[];extern byte* const Ptr_SCICR1[];extern byte* const Ptr_SCICR2[];extern byte* const Ptr_SCISR1[];extern byte* const Ptr_SCISR2[];extern byte* const Ptr_SCIDRL[];extern byte* const Ptr_SCIDRH[];#define SCIBD(i) (*(Ptr_SCIBD[(i)]))#define SCICR1(i) (*(Ptr_SCICR1[(i)]))#define SCICR2(i) (*(Ptr_SCICR2[(i)]))#define SCISR1(i) (*(Ptr_SCISR1[(i)]))#define SCISR2(i) (*(Ptr_SCISR2[(i)]))#define SCIDRL(i) (*(Ptr_SCIDRL[(i)]))#define SCIDRH(i) (*(Ptr_SCIDRH[(i)]))// PARITY BIT#define   SCI_PARITY_NO          0#define   SCI_PARITY_EVEN     1#define   SCI_PARITY_ODD       2// ENDIAN#define   SCI_ENDIAN_LITTLE   0 #define   SCI_ENDIAN_BIG          1/******************************************************************************************                                  ERROR CODES*****************************************************************************************/#define  SCI_NO_ERR            0        /* Function call was successful                       */  #define  SCI_BAD_CH            1        /* Invalid communications port channel                */  #define  SCI_RX_EMPTY          2        /* Rx buffer is empty, no character available         */  #define  SCI_TX_FULL           3        /* Tx buffer is full, could not deposit character     */  #define  SCI_TX_EMPTY          4        /* If the Tx buffer is empty.                         */  #define  SCI_RX_TIMEOUT        5        /* If a timeout occurred while waiting for a character*/  #define  SCI_TX_TIMEOUT        6        /* If a timeout occurred while waiting to send a char.*///#define  SCI_PARITY_NONE       0      /* Defines for setting parity                         */  #define  SCI_ERR_UNKNOWN  7/********************************************************************************************                                 Configure    配置*******************************************************************************************//************   硬件驱动    **************/#define SCI_INIT_DYNAMIC FALSE    /*    (TRUE):include function for dynamic Initialize SCI:...                                   ...SCI_Init(unsigned char port, unsigned long baudRate, unsigned long busClk)...                                   ...(FALSE):include function:void SCI_Init(unsigned char port), ...                                   ... use the argument below to initialize SCI*/     /* The argument to initialize SCI when SCI_INIT_DYNAMIC == FALSE ...     ...  当SCI_INIT_DYNAMIC为FALSE时直接使用以下参数初始化SCI*/                                                                      #if(SCI_INIT_DYNAMIC != TRUE)            #define   SCI_BAUDRATE       9600                     #define   SCI_BUSCLK         32000000L            #define   SCI_DATABIT        8                   /*Data bits,  8 or 9; 数据位,8 或9位*/          #define   SCI_PARITY         SCI_PARITY_NO     /*SCI_PARITY_NO for disable Parity,SCI_PARITY_EVEN...                                                           for Even Parity, SCI_ODD_PARITY for Odd Parity;                                                           SCI_PARITY_NO  静止奇偶校验,SCI_PARITY_EVEN 启用奇校验,...                                                           ... SCI_PARITY_ODD 启用偶校验*/     #endif   // of (SCI_INIT_DYNAMIC != TRUE)#define SCI_DISABLE_EN         FALSE             /*   (TRUE):include codes for Disable SCI - SCI_Close();.....                                                  ....(TRUE):包含禁能SCI功能的代码    */#define SCI_SEND_MULTIBYTE_EN  FALSE            /* TRUE:include code SCI_PutShort() and SCI_PutLong() */#define SCI_SEND_ENDIANNESS    SCI_ENDIAN_BIG   /* the endianness when send mult-byte type;                                                    设置发送多字节类型时使用的字节序*//************   RTOS驱动    **************/#if(SCI_UCOS_MODULE_ENABLE == TRUE)#define SCI_RX_BUFFER_SIZE     50              /* Number of characters in Rx ring buffer  by default */#define SCI_TX_BUFFER_SIZE     10               /* Number of characters in Tx ring buffer  by default */#define SCI0_UCOS_CODE_EN          TRUE          /*   (TRUE):include codes for SCI0;(TRUE):包含SCI0的代码            */  #define SCI0_RX_BUFFER_SIZE      100            /* the size of receive buffer for SCI0; 0: turn off receive buffer for SCI0;                                                       SCI0的接收缓冲区大小; 0表示SCI0不使用接收缓冲区 */  #define SCI0_TX_BUFFER_SIZE      1000           /* the size of transmit buffer for SCI0; 0: turn off transmit buffer for SCI0;                                                       SCI0的发送缓冲区大小; 0表示SCI0不使用发送缓冲区 */  #define SCI0_TX_MUTEX_PRIO       3             /* the priority internal mutual exclusion semaphore use when send data,...                                                       ...  It is assumed that you will specify a priority that is LOWER in value than...                                                       ... ANY of the tasks  may use SCI0 to send data.                                                    在发送数据时内部互斥型信号量使用的优先级,你需要保证这值比任何..                                                       ...可能使用SCI0来发送数据的任务的优先级的数值小,当然,这个优先级...                                                       ...必须也没有其他任务会使用*/#define SCI1_UCOS_CODE_EN          TRUE           /*   (TRUE):include codes for SCI1;(TRUE):包含SCI1的代码            */  #define SCI1_RX_BUFFER_SIZE      SCI_RX_BUFFER_SIZE  /* the size of receive buffer for SCI1; 0: turn off receive buffer for SCI1;                                                     SCI1的接收缓冲区大小; 0表示SCI1不使用接收缓冲区 */  #define SCI1_TX_BUFFER_SIZE      SCI_TX_BUFFER_SIZE  /* the size of transmit buffer for SCI1; 0: turn off transmit buffer for SCI1;                                                     SCI1的发送缓冲区大小; 0表示SCI1不使用发送缓冲区 */  #define SCI1_TX_MUTEX_PRIO       4             /* the priority internal mutual exclusion semaphore use when send data,...                                                      ...  It is assumed that you will specify a priority that is LOWER in value than...                                                      ... ANY of the tasks  may use SCI1 to send data.                                                    在发送数据时内部互斥型信号量使用的优先级,你需要保证这值比任何..                                                      ...可能使用SCI1来发送数据的任务的优先级的数值小,当然,这个优先级...                                                      ...必须也没有其他任务会使用*/#define SCI2_UCOS_CODE_EN          FALSE           /*   (TRUE):include codes for SCI2;(TRUE):包含SCI2的代码            */  #define SCI2_RX_BUFFER_SIZE      SCI_RX_BUFFER_SIZE /* the size of receive buffer for SCI2; 0: turn off receive buffer for SCI2;                                                     SCI2的接收缓冲区大小; 0表示SCI2不使用接收缓冲区 */  #define SCI2_TX_BUFFER_SIZE      SCI_TX_BUFFER_SIZE /* the size of transmit buffer for SCI2; 0: turn off transmit buffer for SCI2;                                                     SCI2的发送缓冲区大小; 0表示SCI2不使用发送缓冲区 */  #define SCI2_TX_MUTEX_PRIO       5             /* the priority internal mutual exclusion semaphore use when send data,...                                                      ...  It is assumed that you will specify a priority that is LOWER in value than...                                                      ... ANY of the tasks  may use SCI2 to send data.                                                    在发送数据时内部互斥型信号量使用的优先级,你需要保证这值比任何..                                                      ...可能使用SCI2来发送数据的任务的优先级的数值小,当然,这个优先级...                                                      ...必须也没有其他任务会使用*/#define SCI3_UCOS_CODE_EN          FALSE           /*   (TRUE):include codes for SCI3;(TRUE):包含SCI3的代码            */  #define SCI3_RX_BUFFER_SIZE      SCI_RX_BUFFER_SIZE /* the size of receive buffer for SCI3; 0: turn off receive buffer for SCI3;                                                     SCI3的接收缓冲区大小; 0表示SCI3不使用接收缓冲区 */  #define SCI3_TX_BUFFER_SIZE      SCI_TX_BUFFER_SIZE /* the size of transmit buffer for SCI3; 0: turn off transmit buffer for SCI3;                                                     SCI3的发送缓冲区大小; 0表示SCI3不使用发送缓冲区 */  #define SCI3_TX_MUTEX_PRIO       6             /* the priority internal mutual exclusion semaphore use when send data,...                                                      ...  It is assumed that you will specify a priority that is LOWER in value than...                                                      ... ANY of the tasks  may use SCI3 to send data.                                                    在发送数据时内部互斥型信号量使用的优先级,你需要保证这值比任何..                                                      ...可能使用SCI3来发送数据的任务的优先级的数值小,当然,这个优先级...                                                      ...必须也没有其他任务会使用*/#define SCI4_UCOS_CODE_EN          FALSE             /*   (TRUE):include codes for SCI4;(TRUE):包含SCI4的代码            */  #define SCI4_RX_BUFFER_SIZE      200  /* the size of receive buffer for SCI4; 0: turn off receive buffer for SCI4;                                                       SCI4的接收缓冲区大小; 0表示SCI4不使用接收缓冲区 */  #define SCI4_TX_BUFFER_SIZE      SCI_TX_BUFFER_SIZE           /* the size of transmit buffer for SCI4; 0: turn off transmit buffer for SCI4;                                                       SCI4的发送缓冲区大小; 0表示SCI4不使用发送缓冲区 */  #define SCI4_TX_MUTEX_PRIO       7                /* the priority internal mutual exclusion semaphore use when send data,...                                                       ...  It is assumed that you will specify a priority that is LOWER in value than...                                                       ... ANY of the tasks  may use SCI4 to send data.                                                    在发送数据时内部互斥型信号量使用的优先级,你需要保证这值比任何..                                                       ...可能使用SCI4来发送数据的任务的优先级的数值小,当然,这个优先级...                                                       ...必须也没有其他任务会使用*/#define SCI5_UCOS_CODE_EN          FALSE              /*   (TRUE):include codes for SCI5;(TRUE):包含SCI5的代码            */  #define SCI5_RX_BUFFER_SIZE      SCI_RX_BUFFER_SIZE /* the size of receive buffer for SCI5; 0: turn off receive buffer for SCI5;                                                     SCI5的接收缓冲区大小; 0表示SCI5不使用接收缓冲区 */  #define SCI5_TX_BUFFER_SIZE      SCI_TX_BUFFER_SIZE /* the size of transmit buffer for SCI5; 0: turn off transmit buffer for SCI5;                                                     SCI5的发送缓冲区大小; 0表示SCI5不使用发送缓冲区 */  #define SCI5_TX_MUTEX_PRIO       8             /* the priority internal mutual exclusion semaphore use when send data,...                                                      ...  It is assumed that you will specify a priority that is LOWER in value than...                                                      ... ANY of the tasks  may use SCI5 to send data.                                                    在发送数据时内部互斥型信号量使用的优先级,你需要保证这值比任何..                                                      ...可能使用SCI5来发送数据的任务的优先级的数值小,当然,这个优先级...                                                      ...必须也没有其他任务会使用*/#define SCI6_UCOS_CODE_EN          FALSE              /*   (TRUE):include codes for SCI6;(TRUE):包含SCI6的代码            */  #define SCI6_RX_BUFFER_SIZE      SCI_RX_BUFFER_SIZE /* the size of receive buffer for SCI6; 0: turn off receive buffer for SCI6;                                                     SCI6的接收缓冲区大小; 0表示SCI6不使用接收缓冲区 */  #define SCI6_TX_BUFFER_SIZE      SCI_TX_BUFFER_SIZE /* the size of transmit buffer for SCI6; 0: turn off transmit buffer for SCI6;                                                     SCI6的发送缓冲区大小; 0表示SCI6不使用发送缓冲区 */  #define SCI6_TX_MUTEX_PRIO       9             /* the priority internal mutual exclusion semaphore use when send data,...                                                      ...  It is assumed that you will specify a priority that is LOWER in value than...                                                      ... ANY of the tasks  may use SCI6 to send data.                                                    在发送数据时内部互斥型信号量使用的优先级,你需要保证这值比任何..                                                      ...可能使用SCI6来发送数据的任务的优先级的数值小,当然,这个优先级...                                                      ...必须也没有其他任务会使用*/#define SCI7_UCOS_CODE_EN          FALSE             /*   (TRUE):include codes for SCI7;(TRUE):包含SCI7的代码            */  #define SCI7_RX_BUFFER_SIZE      10 /* the size of receive buffer for SCI7; 0: turn off receive buffer for SCI7;                                                     SCI7的接收缓冲区大小; 0表示SCI7不使用接收缓冲区 */  #define SCI7_TX_BUFFER_SIZE      SCI_TX_BUFFER_SIZE /* the size of transmit buffer for SCI7; 0: turn off transmit buffer for SCI7;                                                     SCI7的发送缓冲区大小; 0表示SCI7不使用发送缓冲区 */  #define SCI7_TX_MUTEX_PRIO       10             /* the priority internal mutual exclusion semaphore use when send data,...                                                      ...  It is assumed that you will specify a priority that is LOWER in value than...                                                      ... ANY of the tasks  may use SCI7 to send data.                                                    在发送数据时内部互斥型信号量使用的优先级,你需要保证这值比任何..                                                      ...可能使用SCI7来发送数据的任务的优先级的数值小,当然,这个优先级...                                                      ...必须也没有其他任务会使用*/#define SCI_CHECK_EMPTY_EN    FALSE            /* TRUE:include code SCI_RxBufferIsEmpty */#define SCI_CHECK_FULL_EN     FALSE            /* TRUE:include code SCI_TxBufferIsFull */#endif // of (SCI_UCOS_MODULE_ENABLE == TRUE)/**************************************************************************************                          FUNCTION PROTOTYPES  函数原型*************************************************************************************//************   硬件驱动    **************/#if(SCI_INIT_DYNAMIC == TRUE)       void SCI_Init(unsigned char port, unsigned long baudRate, unsigned long busClk,                                        unsigned char databits,unsigned char parity); #else     void SCI_Init(unsigned char port);#endif  // of SCI_INIT_DYNAMIC == TRUEvoid SCI_EnableTxInt(unsigned char port);  void SCI_EnableRxInt(unsigned char port);  void SCI_EnableRecv(unsigned char port);  void SCI_EnableTrans(unsigned char port);  void SCI_DisableTxInt(unsigned char port);    #if(SCI_DISABLE_EN == TRUE)     void SCI_DisableRxInt(unsigned char port);       void SCI_DisableTrans(unsigned char port);     void SCI_DisableRecv(unsigned char port);#endifvoid SCI_PutChar( unsigned char port, unsigned char c);  unsigned char SCI_GetChar(unsigned char port);  void SCI_PutShort (unsigned char port, short i);  void SCI_PutLong (unsigned char port, unsigned long i);/************   RTOS驱动    **************/#if(SCI_UCOS_MODULE_ENABLE == TRUE)void  SCI_BufferInit (void);INT8U  SCI_GetCharB (INT8U port, INT16U timeout, INT8U *err);INT8U SCI_PutCharB_Mutex (INT8U port, INT8U c, INT16U timeout);INT8U SCI_PutCharsB_Mutex (INT8U port, const INT8U *buf,INT16U length, INT16U timeout);#define SCI_PutStringB_Mutex(port,pStr,timeout) SCI_PutCharsB_Mutex(port,str,strlen(str),timeout)void  SCI_SendBuf_hold (INT8U port, INT16U timeout, INT8U *perr);INT8U SCI_PutCharB (INT8U port, INT8U c, INT16U timeout);INT8U SCI_PutCharsB(INT8U port, const INT8U *buf,INT16U length, INT16U timeout);#define SCI_PutStringB(port,pStr,timeout)    SCI_PutCharsB(port,str,strlen(str),timeout)void  SCI_SendBuf_release(INT8U port);INT8U  SCI_RxBufferIsEmpty (INT8U port); INT8U SCI_TxBufferIsFull (INT8U port);#endif // of (SCI_UCOS_MODULE_ENABLE == TRUE)#endif // of (SCI_MODULE_ENABLE == TRUE)/**************************************************************************************                          ERROR CHECK 错误检查*************************************************************************************/#ifndef SCI_MODULE_ENABLE   #error "SCI_MODULE_ENABLE must be defined."#endif#ifndef SCI_UCOS_MODULE_ENABLE   #error "SCI_UCOS_MODULE_ENABLE must be defined."#endif#if(SCI_UCOS_MODULE_ENABLE == TRUE)#if(  SCI_RX_BUFFER_SIZE < 0 || SCI_RX_BUFFER_SIZE >= 65536 || SCI0_RX_BUFFER_SIZE < 0 || SCI0_RX_BUFFER_SIZE >= 65536 \   || SCI1_RX_BUFFER_SIZE < 0 || SCI1_RX_BUFFER_SIZE >= 65536 || SCI2_RX_BUFFER_SIZE < 0 || SCI2_RX_BUFFER_SIZE >= 65536 \   || SCI3_RX_BUFFER_SIZE < 0 || SCI3_RX_BUFFER_SIZE >= 65536 || SCI4_RX_BUFFER_SIZE < 0 || SCI4_RX_BUFFER_SIZE >= 65536 \   || SCI5_RX_BUFFER_SIZE < 0 || SCI5_RX_BUFFER_SIZE >= 65536 || SCI6_RX_BUFFER_SIZE < 0 || SCI6_RX_BUFFER_SIZE >= 65536 \   || SCI7_RX_BUFFER_SIZE < 0 || SCI7_RX_BUFFER_SIZE >= 65536)   #error "SCI buffer size must between 0 and 65535"#endif #if(  SCI_TX_BUFFER_SIZE < 0 || SCI_TX_BUFFER_SIZE >= 65536 || SCI0_TX_BUFFER_SIZE < 0 || SCI0_TX_BUFFER_SIZE >= 65536 \   || SCI1_TX_BUFFER_SIZE < 0 || SCI1_TX_BUFFER_SIZE >= 65536 || SCI2_TX_BUFFER_SIZE < 0 || SCI2_TX_BUFFER_SIZE >= 65536 \   || SCI3_TX_BUFFER_SIZE < 0 || SCI3_TX_BUFFER_SIZE >= 65536 || SCI4_TX_BUFFER_SIZE < 0 || SCI4_TX_BUFFER_SIZE >= 65536 \   || SCI5_TX_BUFFER_SIZE < 0 || SCI5_TX_BUFFER_SIZE >= 65536 || SCI6_TX_BUFFER_SIZE < 0 || SCI6_TX_BUFFER_SIZE >= 65536 \   || SCI7_TX_BUFFER_SIZE < 0 || SCI7_TX_BUFFER_SIZE >= 65536)   #error "SCI buffer size must between 0 and 65535"#endif #if(SCI0_UCOS_CODE_EN != TRUE)  #undef SCI0_RX_BUFFER_SIZE  #undef SCI0_TX_BUFFER_SIZE  #define SCI0_RX_BUFFER_SIZE     0  #define SCI0_TX_BUFFER_SIZE     0#endif#if(SCI1_UCOS_CODE_EN != TRUE)  #undef SCI1_RX_BUFFER_SIZE  #undef SCI1_TX_BUFFER_SIZE  #define SCI1_RX_BUFFER_SIZE     0  #define SCI1_TX_BUFFER_SIZE     0#endif#if(SCI2_UCOS_CODE_EN != TRUE)  #undef SCI2_RX_BUFFER_SIZE  #undef SCI2_TX_BUFFER_SIZE  #define SCI2_RX_BUFFER_SIZE     0  #define SCI2_TX_BUFFER_SIZE     0#endif#if(SCI3_UCOS_CODE_EN != TRUE)  #undef SCI3_RX_BUFFER_SIZE  #undef SCI3_TX_BUFFER_SIZE  #define SCI3_RX_BUFFER_SIZE     0  #define SCI3_TX_BUFFER_SIZE     0#endif#if(SCI4_UCOS_CODE_EN != TRUE)  #undef SCI4_RX_BUFFER_SIZE  #undef SCI4_TX_BUFFER_SIZE  #define SCI4_RX_BUFFER_SIZE     0  #define SCI4_TX_BUFFER_SIZE     0#endif#if(SCI5_UCOS_CODE_EN != TRUE)  #undef SCI5_RX_BUFFER_SIZE  #undef SCI5_TX_BUFFER_SIZE  #define SCI5_RX_BUFFER_SIZE     0  #define SCI5_TX_BUFFER_SIZE     0#endif#if(SCI6_UCOS_CODE_EN != TRUE)  #undef SCI6_RX_BUFFER_SIZE  #undef SCI6_TX_BUFFER_SIZE  #define SCI6_RX_BUFFER_SIZE     0  #define SCI6_TX_BUFFER_SIZE     0#endif#if(SCI7_UCOS_CODE_EN != TRUE)  #undef SCI7_RX_BUFFER_SIZE  #undef SCI7_TX_BUFFER_SIZE  #define SCI7_RX_BUFFER_SIZE     0  #define SCI7_TX_BUFFER_SIZE     0#endif#endif // of SCI_UCOS_MODULE_ENABLE == TRUE#endif  // of  SCI_DEF_H

这个.h文件中包含了硬件驱动与uCOS的驱动的定义。宏定义了SCI0-7(MC9S12XEP100有8个SCI口),在剩下的程序中名为port的参数需要传的就是这个宏定义的名称。然后还定义了映射寄存器的数组以及对应的宏等,这样可以很方便的直接访问任意端口的寄存器。
如果不想编译SCI相关代码,则把#define SCI_MODULE_ENABLE 后面改为FALSE就行。如果不使用uCOS的驱动,则把SCI_UCOS_MODULE_ENABLE 后面改为FALSE(这章只说硬件驱动部分,所以直接改为了FALSE)。SCI0_CODE_INCLUDE和SCI1_CODE_INCLUDE只用于基于uCOS的驱动代码。
配置部分应该已经注释的很清楚了,就是一些裁剪代码的功能,其中SCI_INIT_DYNAMIC 这个宏决定了方法SCI_Init()是要使用固定的值初始化端口还是使用可变的值(多很多输入参数)来初始化,这根据需求决定。还有个发送多字节时的字节序选择。
而函数声明部分没有注释,因为注释都写在函数实现部分的前面了,以下是SCI硬件驱动模块.c文件。

/*************************************************************************************************************                    SCI(Serial Communication Interface) SUPPORT PACKAGE*                                         Freescale MC9S12XEP100*                               飞思卡尔   MC9S12XEP100  SCI支持包** File : SCI.c* By   : Lin Shijun(http://blog.csdn.net/lin_strong)* Date : 2017/10/27* version: V2.1* History: 2017/04/24  V1.0   the prototype of SCI_uCOS,only support SCI0 and SCI1*          2017/10/27  V2.1   modify some #pragma statement* NOTE(s): refer to Li Yuan's  (http://blog.csdn.net/liyuanbhu/article/details/7764851)*                    and *                  uCOS-II's Code**********************************************************************************************************//***********************************************************************************************************                                       INCLUDES**********************************************************************************************************/#include "SCI_def.h"#if(SCI_MODULE_ENABLE == TRUE)/***********************************************************************************************************                                        CONSTANTS**********************************************************************************************************/// Map to SCI registerword* const Ptr_SCIBD[]={&SCI0BD,&SCI1BD,&SCI2BD,&SCI3BD,&SCI4BD,&SCI5BD,&SCI6BD,&SCI7BD};byte* const Ptr_SCICR1[]={&SCI0CR1,&SCI1CR1,&SCI2CR1,&SCI3CR1,&SCI4CR1,&SCI5CR1,&SCI6CR1,&SCI7CR1};byte* const Ptr_SCICR2[]={&SCI0CR2,&SCI1CR2,&SCI2CR2,&SCI3CR2,&SCI4CR2,&SCI5CR2,&SCI6CR2,&SCI7CR2};byte* const Ptr_SCISR1[]={&SCI0SR1,&SCI1SR1,&SCI2SR1,&SCI3SR1,&SCI4SR1,&SCI5SR1,&SCI6SR1,&SCI7SR1};byte* const Ptr_SCISR2[]={&SCI0SR2,&SCI1SR2,&SCI2SR2,&SCI3SR2,&SCI4SR2,&SCI5SR2,&SCI6SR2,&SCI7SR2};byte* const Ptr_SCIDRL[]={&SCI0DRL,&SCI1DRL,&SCI2DRL,&SCI3DRL,&SCI4DRL,&SCI5DRL,&SCI6DRL,&SCI7DRL};byte* const Ptr_SCIDRH[]={&SCI0DRH,&SCI1DRH,&SCI2DRH,&SCI3DRH,&SCI4DRH,&SCI5DRH,&SCI6DRH,&SCI7DRH};/***********************************************************************************************************                                        SCI_Init()** Description : Initialize SCI support hardware.  初始化SCI硬件** Arguments   : port               SCI0-SCI7 the port to Initialize;       选择要初始化的端口;*                       baudRate       baudRate to set;                               要设置的波特率;*                       busClk           the current bus clock;                       当前的总线时钟频率;*                       databits          Data bits,  8 or 9;                             数据位,8 或9位;*                       parity             SCI_PARITY_NO for disable Parity,SCI_PARITY_EVEN for Even Parity, ...*                                              ... SCI_ODD_PARITY for Odd Parity;*                                             SCI_PARITY_NO禁用奇偶校验, SCI_PARITY_EVEN启用奇校验, ...*                                              ... SCI_ODD_PARITY启用偶校验;*Note(s):  1.this function is availible only when SCI_INIT_DYNAMIC == TRUE*               2. this will disable all function accosiated with transmit and receive.*                        使用这个函数会禁能对应SCI口的发送接收相关功能(发送(中断)使能,接收(中断)使能)**********************************************************************************************************/#if(SCI_INIT_DYNAMIC == TRUE)     void SCI_Init(unsigned char port, unsigned long baudRate, unsigned long busClk,                unsigned char databits,unsigned char parity){     // 用baudRate临时存储最终赋予BD寄存器的值     baudRate = ( busClk >> 4) /baudRate;    // SCI0BD = BUS_CLOCK/16/BAUD     baudRate &= 0x1FFF;     // 用databits 临时存储最终赋予CR1寄存器的值     databits =  (databits > 8 ) << 4;                                                // M     if(parity > SCI_PARITY_NO) {                                               // PE = 1          if(parity>SCI_PARITY_EVEN) {               databits |= 0x02;                                                            // PT = 0          }else{               databits |= 0x03;                                                            // PT = 1          }     }     SCICR2(port) = 0x00;     SCIBD(port) = (word)baudRate;     SCICR1(port) = databits;}#else/***********************************************************************************************************                                        SCI_Init()** Description : Initialize SCI support hardware.  初始化SCI硬件** Arguments   : port               SCI0-SCI7 the port to Initialize;       选择要初始化的端口;**Note(s):  1.this function is availible only when SCI_INIT_DYNAMIC == FALSE;*               2.will use the SCI_BAUDRATE & SCI_BUSCLK & SCI_DATABIT & SCI_PARITY to Initialize SCI;*               3. this will disable all function accosiated with transmit and receive.*                        使用这个函数会禁能对应SCI口的发送接收相关功能(发送(中断)使能,接收(中断)使能)**********************************************************************************************************/ void SCI_Init(unsigned char port){     SCICR2(port) = 0x00;     SCIBD(port) = SCI_BUSCLK/16/SCI_BAUDRATE & 0x1FFF;      SCICR1(port) = 0x00#if(SCI_DATABIT >8)                               |SCI0CR1_M_MASK#endif#if(SCI_PARITY == 0)#elif (SCI_PARITY > 1)                              |SCI0CR1_PE_MASK#else                              |SCI0CR1_PE_MASK|SCI0CR1_PT_MASK#endif          ;}#endif/***********************************************************************************************************                                        SCI_EnableTxInt()** Description : Enable Tx interrupt(Transmitter Interrupt Enable Bit)   使能传输中断** Arguments   : port               SCI0-SCI7 the port to Choose;       选择端口;** Note: **********************************************************************************************************/void SCI_EnableTxInt(unsigned char port){     SCICR2(port) |= SCI0CR2_TIE_MASK; } /***********************************************************************************************************                                        SCI_EnableRxInt()** Description : Enable Rx interrupt(Receiver Interrupt Enable Bit)   使能接收中断** Arguments   : port               SCI0-SCI7 the port to Choose;       选择端口;** Note: **********************************************************************************************************/void SCI_EnableRxInt(unsigned char port){     SCICR2(port) |= SCI0CR2_RIE_MASK;} /***********************************************************************************************************                                        SCI_EnableRecv()** Description : Enable SCI Receiver    使能接收** Arguments   : port               SCI0-SCI7 the port to Choose;       选择端口;** Note: **********************************************************************************************************/void SCI_EnableRecv(unsigned char port){     SCICR2(port) |= SCI0CR2_RE_MASK;}/***********************************************************************************************************                                        SCI_EnableTrans()** Description : Enable SCI Transmitter    使能发送** Arguments   : port               SCI0-SCI7 the port to Choose;       选择端口;** Note: **********************************************************************************************************/void SCI_EnableTrans(unsigned char port){     SCICR2(port) |= SCI0CR2_TE_MASK;} /***********************************************************************************************************                                        SCI_DisableTxInt()** Description : Disable The Tx interrupt  (Transmitter Interrupt Enable Bit)     禁能发送** Arguments   : port               SCI0-SCI7 the port to Choose;       选择端口;** Note: **********************************************************************************************************/void SCI_DisableTxInt(unsigned char port){     SCICR2(port) &= ~(byte)SCI0CR2_TIE_MASK;}#if(SCI_DISABLE_EN == TRUE)/***********************************************************************************************************                                        SCI_DisableRxInt()** Description : Disable The Rx interrupt  (Receiver Interrupt Enable Bit)     禁能接收中断** Arguments   : port               SCI0-SCI7 the port to Choose;       选择端口;** Note: **********************************************************************************************************/void SCI_DisableRxInt(unsigned char port) {     SCICR2(port) &= ~(byte)SCI0CR2_RIE_MASK;}/***********************************************************************************************************                                        SCI_DisableTrans()** Description : Disable SCI Transmitter    禁能发送** Arguments   : port               SCI0-SCI7 the port to Choose;       选择端口;** Note: **********************************************************************************************************/void SCI_DisableTrans(unsigned char port) {     SCICR2(port) &= ~(byte)SCI0CR2_TE_MASK;}/***********************************************************************************************************                                        SCI_DisableRecv()** Description : Disable SCI Receiver    禁能接收** Arguments   : port               SCI0-SCI7 the port to Choose;       选择端口;** Note: **********************************************************************************************************/void SCI_DisableRecv(unsigned char port) {     SCICR2(port) &= ~(byte)SCI0CR2_RE_MASK;}#endif/***********************************************************************************************************                                        SCI_PutChar()** Description : Transmit one char    发送一个字符/字节** Arguments   : port               SCI0-SCI7 the port to Choose;       选择端口;*                       c                    the char to transmit;                        要发送的字符;                   * Note:   1. this function will block until transmiter idle and transmit the char;*              这个函数会阻塞到发送器空闲,然后发送字符*             2. not implement bit 9**********************************************************************************************************/void SCI_PutChar( unsigned char port, unsigned char c) {     while((SCISR1(port) & SCI0SR1_TDRE_MASK) == 0);    // 等待发送寄存器为空     SCIDRL(port) = c;}/***********************************************************************************************************                                        SCI_GetChar()** Description : Receive one char    接收一个字符/字节** Arguments   : port               SCI0-SCI7 the port to Choose;       选择端口;*                       * Return       :                        the char received;                             接收到的字符;          * Note:   1.this function will block until receiver get a char,and return the char;*              这个函数会阻塞到接收器寄存器满,然后返回字符*             2. not implement bit 9**********************************************************************************************************/unsigned char SCI_GetChar(unsigned char port){     while((SCISR1(port) & SCI0SR1_RDRF_MASK) == 0);    // 等待接收寄存器满     return SCIDRL(port);}/***********************************************************************************************************                                        SCI_PutShort()** Description : Transmit one short int.    发送一个短整型** Arguments   : port               SCI0-SCI7 the port to Choose;       选择端口;* * Return       :                        the char received;                             接收到的字符;          * Note:   1. this function will block until transmiter idle and transmit the char;*              这个函数会阻塞到发送器空闲,然后发送字符**********************************************************************************************************/#if (SCI_SEND_MULTIBYTE_EN == TRUE)void SCI_PutShort (unsigned char port, short i)  {#if(SCI_SEND_ENDIANNESS == SCI_ENDIAN_BIG)    char * p = (char *)&i;      SCI_PutChar( port, p[0]);      SCI_PutChar( port, p[1]);  #endif#if(SCI_SEND_ENDIANNESS == SCI_ENDIAN_LITTLE)    char * p = (char *)&i;      SCI_PutChar( port, p[1]);      SCI_PutChar( port, p[0]);  #endif}/***********************************************************************************************************                                        SCI_PutLong()** Description : Transmit one long int.    发送一个长整型** Arguments   : port               SCI0-SCI7 the port to Choose;       选择端口;* * Return       :                        the char received;                             接收到的字符;          * Note:   1. this function will block until transmiter idle and transmit the char;*              这个函数会阻塞到发送器空闲,然后发送字符**********************************************************************************************************/void SCI_PutLong (unsigned char port, unsigned long i){#if(SCI_SEND_ENDIANNESS == SCI_ENDIAN_BIG)    char * p = (char *)&i;      SCI_PutChar( port, p[0]);      SCI_PutChar( port, p[1]);      SCI_PutChar( port, p[2]);      SCI_PutChar( port, p[3]);  #endif#if(SCI_SEND_ENDIANNESS == SCI_ENDIAN_LITTLE)    char * p = (char *)&i;      SCI_PutChar( port, p[3]);      SCI_PutChar( port, p[2]);      SCI_PutChar( port, p[1]);      SCI_PutChar( port, p[0]);  #endif}#endif // of SCI_SEND_MULTIBYTE_EN == TRUE#endif  // of SCI_MODULE_ENABLE == TRUE

硬件驱动并没有完整实现SCI模块的全部功能,比如目前实际上数据位只能是8位,因为发送和接收函数都不支持第9位;而且那些LOOPS,等待模式之类的也没有封装,主要是因为目前用不到。
硬件驱动实现了所有8个SCI口的驱动。然后是示例:

#include <hidef.h>      /* common defines and macros */#include "derivative.h"      /* derivative-specific definitions */#include "SCI_def.h"#define  BUS_CLOCK         32000000    //总线频率#define  OSC_CLOCK         16000000    //晶振频率/*************************************************************//*                      初始化锁相环                         *//*************************************************************/void INIT_PLL(void) {    CLKSEL &= 0x7f;       //设置OSCCLK作为系统时钟    PLLCTL &= 0x8F;       //禁止锁相环    #if(BUS_CLOCK == 32000000)      SYNR = 0x43;        #endif     REFDV = 0x81;    PLLCTL |=0x70;  //使能锁相环    asm NOP;    asm NOP;    while(!(CRGFLG&0x08)); //PLLCLK锁定    CLKSEL |= 0x80;        //设置PLLCLK为系统时钟}void main(void) {    unsigned char c;    // 设置总线频率为32MHz    DisableInterrupts;    INIT_PLL();    EnableInterrupts;    SCI_Init(SCI0,9600,BUS_CLOCK,8,SCI_PARITY_NO);    SCI_EnableRecv(SCI0);      SCI_EnableTrans(SCI0);      // 每接收一个字符就返回0x33和那个字符    for(;;) {        c = SCI_GetChar(SCI0);        SCI_PutShort(SCI0,c | 0x3300);     } }

通信测试

然后下一章来讲基于uCOS的SCI驱动。


更改历史:

2017/10/29 更新到 V2.1

原创粉丝点击