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
- MC9S12XEP100 SCI(UART)驱动程序
- MC9S12XEP100 SCI(UART)驱动程序2
- MC9S12XEP100 ATD模块 驱动程序
- SCI、UART与RS232区别
- SCI、UART与RS232区别
- UART驱动程序设计
- SCI,SPI,UART三种串行总线协议的区别
- Linux串口(serial、uart)驱动程序设计
- Linux串口(serial、uart)驱动程序设计
- Linux串口(serial、uart)驱动程序设计
- Linux串口(serial、uart)驱动程序设计
- Linux串口(serial、uart)驱动程序设计
- Linux串口(serial、uart)驱动程序设计
- Linux串口(serial、uart)驱动程序设计
- Linux串口(serial、uart)驱动程序设计
- Linux串口(serial、uart)驱动程序设计
- Linux串口(serial、uart)驱动程序设计
- Linux串口(serial、uart)驱动程序设计
- document.ready和window.onload的区别
- Java StringBuilder
- ip(点分十进制 <==> 二进制整数)之间的转换
- Hibernate的二级缓存和查询缓存
- LeetCode动态规划
- MC9S12XEP100 SCI(UART)驱动程序
- Unity Learning for Day 20
- FPGA编程注意事项
- char与signed char, unsigned char的区别
- 415Add Strings
- 6.列表
- 学生、成绩、课程表,要求查询001课程比002课程成绩高的所有学生的学号解决办法
- 《剑指offer》-第2章(2)
- MySQL重建或修复表或索引