- /*sci_ucos.h*/
#ifndef _SCI_RTOS_H_
#define _SCI_RTOS_H_
#define SCI_RX_BUF_SIZE 64 /* Number of characters in Rx ring buffer */
- #define SCI_TX_BUF_SIZE 64 /* Number of characters in Tx ring buffer */
/*
- *********************************************************************************************************
- * CONSTANTS
- *********************************************************************************************************
- */
#ifndef NUL
- #define NUL 0x00
- #endif
/* 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_PARITY_ODD 1
- #define SCI_PARITY_EVEN 2
- /*
- *********************************************************************************************************
- * DATA TYPES
- *********************************************************************************************************
- */
- typedef struct {
- short RingBufRxCtr; /* Number of characters in the Rx ring buffer */
- OS_EVENT *RingBufRxSem; /* Pointer to Rx semaphore */
- unsigned char *RingBufRxInPtr; /* Pointer to where next character will be inserted */
- unsigned char *RingBufRxOutPtr; /* Pointer from where next character will be extracted */
- unsigned char RingBufRx[SCI_RX_BUF_SIZE]; /* Ring buffer character storage (Rx) */
- short RingBufTxCtr; /* Number of characters in the Tx ring buffer */
- OS_EVENT *RingBufTxSem; /* Pointer to Tx semaphore */
- unsigned char *RingBufTxInPtr; /* Pointer to where next character will be inserted */
- unsigned char *RingBufTxOutPtr; /* Pointer from where next character will be extracted */
- unsigned char RingBufTx[SCI_TX_BUF_SIZE]; /* Ring buffer character storage (Tx) */
- } SCI_RING_BUF;
- /**
- * To obtain a character from the communications channel.
- * @param port, port can be SCI0 / SCI1
- * @param to, is the amount of time (in clock ticks) that the calling function is willing to
- * wait for a character to arrive. If you specify a timeout of 0, the function will
- * wait forever for a character to arrive.
- * @param err, is a pointer to where an error code will be placed:
- * *err is set to SCI_NO_ERR if a character has been received
- * *err is set to SCI_RX_TIMEOUT if a timeout occurred
- * *err is set to SCI_BAD_CH if you specify an invalid channel number
- * @return The character in the buffer (or NUL if a timeout occurred)
- */
- unsigned char SCIGetCharB (unsigned char ch, unsigned short to, unsigned char *err);
/**
- * This function is called by your application to send a character on the communications
- * channel. The function will wait for the buffer to empty out if the buffer is full.
- * The function returns to your application if the buffer doesn't empty within the specified
- * timeout. A timeout value of 0 means that the calling function will wait forever for the
- * buffer to empty out. The character to send is first inserted into the Tx buffer and will
- * be sent by the Tx ISR. If this is the first character placed into the buffer, the Tx ISR
- * will be enabled.
- *
- * @param port, port can be SCI0 / SCI1
- * @param c is the character to send.
- * @param to is the timeout (in clock ticks) to wait in case the buffer is full. If you
- * specify a timeout of 0, the function will wait forever for the buffer to empty.
- * @return SCI_NO_ERR if the character was placed in the Tx buffer
- * SCI_TX_TIMEOUT if the buffer didn't empty within the specified timeout period
- * SCI_BAD_CH if you specify an invalid channel number
- */
- unsigned char SCIPutCharB (unsigned char port, unsigned char c, unsigned short to);
/**
- * To initialize the communications module.
- * You must call this function before calling any other functions.
- */
- void SCIBufferInit (void);
/**
- * To see if any character is available from the communications channel.
- *
- * @param port, port can be SCI0 / SCI1
- * @return If at least one character is available, the function returns
- * FALSE(0) otherwise, the function returns TRUE(1).
- */
- unsigned char SCIBufferIsEmpty (unsigned char port);
- /**
- * To see if any more characters can be placed in the Tx buffer.
- * In other words, this function check to see if the Tx buffer is full.
- *
- * @param port, port can be SCI0 / SCI1
- * @return If the buffer is full, the function returns TRUE
- * otherwise, the function returns FALSE.
- */
- unsigned char SCIBufferIsFull (unsigned char port);
#endif
/**
- * SCI(Serial Communication Interface) Buffered Serial I/O
- * @file sci_ucos.c
- * @author Li Yuan
- * @platform mc9s12XX
- * @date 2012-7-22
- * @version 1.0.1
- */
- #include "derivative.h" /* derivative-specific definitions */
- #include
- #include "includes.H"
- #include "sci.h"
- #include "sci_rtos.h"
/**
- * GLOBAL VARIABLES
- */
- SCI_RING_BUF SCI0Buf;
- SCI_RING_BUF SCI1Buf;
- /**
- * To obtain a character from the communications channel.
- * @param port, port can be SCI0 / SCI1
- * @param to, is the amount of time (in clock ticks) that the calling function is willing to
- * wait for a character to arrive. If you specify a timeout of 0, the function will
- * wait forever for a character to arrive.
- * @param err, is a pointer to where an error code will be placed:
- * *err is set to SCI_NO_ERR if a character has been received
- * *err is set to SCI_RX_TIMEOUT if a timeout occurred
- * *err is set to SCI_BAD_CH if you specify an invalid channel number
- * @return The character in the buffer (or NUL if a timeout occurred)
- */
- unsigned char SCIGetCharB (unsigned char port, unsigned short to, INT8U *err)
- {
- #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
- OS_CPU_SR cpu_sr = 0u;
- #endif
- unsigned char c;
- unsigned char oserr;
- SCI_RING_BUF *pbuf;
switch (port)
- { /* Obtain pointer to communications channel */
- case SCI0:
- pbuf = &SCI0Buf;
- break;
case SCI1:
- pbuf = &SCI1Buf;
- break;
default:
- *err = SCI_BAD_CH;
- return (0);
- }
- OSSemPend(pbuf->RingBufRxSem, to, &oserr); /* Wait for character to arrive */
- if (oserr == OS_TIMEOUT)
- { /* See if characters received within timeout*/
- *err = SCI_RX_TIMEOUT; /* No, return error code */
- return (NUL);
- }
- else
- {
- OS_ENTER_CRITICAL();
- pbuf->RingBufRxCtr--; /* Yes, decrement character count */
- c = *pbuf->RingBufRxOutPtr++; /* Get character from buffer */
- if (pbuf->RingBufRxOutPtr == &pbuf->RingBufRx[SCI_RX_BUF_SIZE]) { /* Wrap OUT pointer */
- pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];
- }
- OS_EXIT_CRITICAL();
- *err = SCI_NO_ERR;
- return (c);
- }
- }
/**
- * This function is called by your application to send a character on the communications
- * channel. The function will wait for the buffer to empty out if the buffer is full.
- * The function returns to your application if the buffer doesn't empty within the specified
- * timeout. A timeout value of 0 means that the calling function will wait forever for the
- * buffer to empty out. The character to send is first inserted into the Tx buffer and will
- * be sent by the Tx ISR. If this is the first character placed into the buffer, the Tx ISR
- * will be enabled.
- *
- * @param port, port can be SCI0 / SCI1
- * @param c is the character to send.
- * @param to is the timeout (in clock ticks) to wait in case the buffer is full. If you
- * specify a timeout of 0, the function will wait forever for the buffer to empty.
- * @return SCI_NO_ERR if the character was placed in the Tx buffer
- * SCI_TX_TIMEOUT if the buffer didn't empty within the specified timeout period
- * SCI_BAD_CH if you specify an invalid channel number
- */
- unsigned char SCIPutCharB (unsigned char port, unsigned char c, unsigned short to)
- {
- #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
- OS_CPU_SR cpu_sr = 0u;
- #endif
SCI_RING_BUF *pbuf;
- unsigned char oserr;
- switch (port)
- { /* Obtain pointer to communications channel */
- case SCI0:
- pbuf = &SCI0Buf;
- break;
case SCI1:
- pbuf = &SCI1Buf;
- break;
default:
- return (SCI_BAD_CH);
- }
OSSemPend(pbuf->RingBufTxSem, to, &oserr); /* Wait for space in Tx buffer */
- if (oserr == OS_TIMEOUT)
- {
- return (SCI_TX_TIMEOUT); /* Timed out, return error code */
- }
- OS_ENTER_CRITICAL();
- pbuf->RingBufTxCtr++; /* No, increment character count */
- *pbuf->RingBufTxInPtr++ = c; /* Put character into buffer */
- if (pbuf->RingBufTxInPtr == &pbuf->RingBufTx[SCI_TX_BUF_SIZE])
- {
- pbuf->RingBufTxInPtr = &pbuf->RingBufTx[0]; /* Wrap IN pointer */
- }
- if (pbuf->RingBufTxCtr == 1) /* See if this is the first character */
- {
- SCIEnableTxInt(port); /* Yes, Enable Tx interrupts */
- }
- OS_EXIT_CRITICAL();
- return (SCI_NO_ERR);
- }
/**
- * To initialize the communications module.
- * You must call this function before calling any other functions.
- */
- void SCIBufferInit (void)
- {
- SCI_RING_BUF *pbuf;
pbuf = &SCI0Buf; /* Initialize the ring buffer for SCI0 */
- pbuf->RingBufRxCtr = 0;
- pbuf->RingBufRxInPtr = &pbuf->RingBufRx[0];
- pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];
- pbuf->RingBufRxSem = OSSemCreate(0);
- pbuf->RingBufTxCtr = 0;
- pbuf->RingBufTxInPtr = &pbuf->RingBufTx[0];
- pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];
- pbuf->RingBufTxSem = OSSemCreate(SCI_TX_BUF_SIZE);
pbuf = &SCI1Buf; /* Initialize the ring buffer for SCI1 */
- pbuf->RingBufRxCtr = 0;
- pbuf->RingBufRxInPtr = &pbuf->RingBufRx[0];
- pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];
- pbuf->RingBufRxSem = OSSemCreate(0);
- pbuf->RingBufTxCtr = 0;
- pbuf->RingBufTxInPtr = &pbuf->RingBufTx[0];
- pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];
- pbuf->RingBufTxSem = OSSemCreate(SCI_TX_BUF_SIZE);
- }
/**
- * To see if any character is available from the communications channel.
- *
- * @param port, port can be SCI0 / SCI1
- * @return If at least one character is available, the function returns
- * FALSE(0) otherwise, the function returns TRUE(1).
- */
- unsigned char SCIBufferIsEmpty (unsigned char port)
- {
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
- OS_CPU_SR cpu_sr = 0u;
- #endif
- unsigned char empty;
- SCI_RING_BUF *pbuf;
- switch (port)
- { /* Obtain pointer to communications channel */
- case SCI0:
- pbuf = &SCI0Buf;
- break;
case SCI1:
- pbuf = &SCI1Buf;
- break;
- default:
- return (0xff);
- break;
- }
- OS_ENTER_CRITICAL();
- if (pbuf->RingBufRxCtr > 0)
- { /* See if buffer is empty */
- empty = 0; /* Buffer is NOT empty */
- }
- else
- {
- empty = 1; /* Buffer is empty */
- }
- OS_EXIT_CRITICAL();
- return (empty);
}
/**
- * To see if any more characters can be placed in the Tx buffer.
- * In other words, this function check to see if the Tx buffer is full.
- *
- * @param port, port can be SCI0 / SCI1
- * @return If the buffer is full, the function returns TRUE
- * otherwise, the function returns FALSE.
- */
- unsigned char SCIBufferIsFull (unsigned char port)
- {
- #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
- OS_CPU_SR cpu_sr = 0u;
- #endif
- char full;
- SCI_RING_BUF *pbuf;
- switch (port)
- { /* Obtain pointer to communications channel */
- case SCI0:
- pbuf = &SCI0Buf;
- break;
case SCI1:
- pbuf = &SCI1Buf;
- break;
default:
- return (255);
- }
- OS_ENTER_CRITICAL();
- if (pbuf->RingBufTxCtr < SCI_TX_BUF_SIZE) { /* See if buffer is full */
- full = 0; /* Buffer is NOT full */
- } else {
- full = 1; /* Buffer is full */
- }
- OS_EXIT_CRITICAL();
- return (full);
- }
- // This function is called by the Rx ISR to insert a character into the receive ring buffer.
- static void SCIPutRxChar (unsigned char port, unsigned char c)
- {
SCI_RING_BUF *pbuf;
switch (port)
- { /* Obtain pointer to communications channel */
- case SCI0:
- pbuf = &SCI0Buf;
- break;
case SCI1:
- pbuf = &SCI1Buf;
- break;
default:
- return;
- }
- if (pbuf->RingBufRxCtr < SCI_RX_BUF_SIZE) { /* See if buffer is full */
- pbuf->RingBufRxCtr++; /* No, increment character count */
- *pbuf->RingBufRxInPtr++ = c; /* Put character into buffer */
- if (pbuf->RingBufRxInPtr == &pbuf->RingBufRx[SCI_RX_BUF_SIZE]) { /* Wrap IN pointer */
- pbuf->RingBufRxInPtr = &pbuf->RingBufRx[0];
- }
- (void)OSSemPost(pbuf->RingBufRxSem); /* Indicate that character was received */
- }
- }
- // This function is called by the Tx ISR to extract the next character from the Tx buffer.
- // The function returns FALSE if the buffer is empty after the character is extracted from
- // the buffer. This is done to signal the Tx ISR to disable interrupts because this is the
- // last character to send.
- static unsigned char SCIGetTxChar (unsigned char port, unsigned char *err)
- {
- unsigned char c;
- SCI_RING_BUF *pbuf;
switch (port)
- { /* Obtain pointer to communications channel */
- case SCI0:
- pbuf = &SCI0Buf;
- break;
case SCI1:
- pbuf = &SCI1Buf;
- break;
default:
- *err = SCI_BAD_CH;
- return (0);
- }
- if (pbuf->RingBufTxCtr > 0) { /* See if buffer is empty */
- pbuf->RingBufTxCtr--; /* No, decrement character count */
- c = *pbuf->RingBufTxOutPtr++; /* Get character from buffer */
- if (pbuf->RingBufTxOutPtr == &pbuf->RingBufTx[SCI_TX_BUF_SIZE]) { /* Wrap OUT pointer */
- pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];
- }
- (void)OSSemPost(pbuf->RingBufTxSem); /* Indicate that character will be sent */
- *err = SCI_NO_ERR;
- return (c); /* Characters are still available */
- } else {
- *err = SCI_TX_EMPTY;
- return (NUL); /* Buffer is empty */
- }
- }
- void SCI0_ISR_Handler(void)
- {
- char status;
- char data;
- unsigned char err;
- status = SCI0SR1;
if(status & 0x0F) // 0x1F = 0001 1111, if status is not Receive Data Reg Full Flag
- {
- // See if we have some kind of error
- // Clear interrupt (do nothing about it!)
- data = SCI0DRL;
- }
- else if(status & 0x20) //Receive Data Reg Full Flag
- {
- data = SCI0DRL;
- SCIPutRxChar(SCI0, data); // Insert received character into buffer
- }
- else if(status & 0x80)
- {
- data = SCIGetTxChar(SCI0, &err); // Get next character to send.
- if (err == SCI_TX_EMPTY)
- { // Do we have anymore characters to send ?
- // No, Disable Tx interrupts
- SCIDisTxInt(SCI0);
- }
- else
- {
- SCI0DRL = data; // Yes, Send character
- }
- }
- }
- void SCI1_ISR_Handler (void)
- {
- char status;
- char data;
- unsigned char err;
- status = SCI1SR1;
if(status & 0x0F) // 0x1F = 0001 1111, if status is not Receive Data Reg Full Flag
- {
- // See if we have some kind of error
- // Clear interrupt (do nothing about it!)
- data = SCI1DRL;
- }
- else if(status & 0x20) //Receive Data Reg Full Flag
- {
- data = SCI1DRL;
- SCIPutRxChar(SCI1, data); // Insert received character into buffer
- }
- else if(status & 0x80)
- {
- data = SCIGetTxChar(SCI1, &err); // Get next character to send.
- if (err == SCI_TX_EMPTY)
- { // Do we have anymore characters to send ?
- // No, Disable Tx interrupts
- SCIDisTxInt(SCI1);
- }
- else
- {
- SCI1DRL = data; // Yes, Send character
- }
- }
- }
#pragma CODE_SEG NON_BANKED
- interrupt VectorNumber_Vsci0 void SCI0_ISR(void)
- {
#if defined( __BANKED__) || defined(__LARGE__) || defined(__PPAGE__)
- __asm ldaa PPAGE; // 3~, Get current value of PPAGE register
- __asm psha; // 2~, Push PPAGE register onto current task's stack
- #endif
- __asm inc OSIntNesting; //OSIntNesting++;
//if (OSIntNesting == 1)
- //{
- // OSTCBCur->OSTCBStkPtr = Stack Pointer ;
- //}
- __asm
- {
- ldab OSIntNesting
- cmpb #$01
- bne SCI0ISR1
ldx OSTCBCur
- sts 0, x
- SCI0ISR1:
- }
#if defined( __BANKED__) || defined(__LARGE__) || defined(__PPAGE__)
- __asm call SCI0_ISR_Handler;
- __asm call OSIntExit;
- #else
- __asm jsr SCI0_ISR_Handler;
- __asm jsr OSIntExit;
- #endif
#if defined( __BANKED__) || defined(__LARGE__) || defined(__PPAGE__)
- __asm pula; // 3~, Get value of PPAGE register
- __asm staa PPAGE; // 3~, Store into CPU's PPAGE register
- #endif
}
interrupt VectorNumber_Vsci1 void SCI1_ISR(void)
- {
#if defined( __BANKED__) || defined(__LARGE__) || defined(__PPAGE__)
- __asm ldaa PPAGE; // 3~, Get current value of PPAGE register
- __asm psha; // 2~, Push PPAGE register onto current task's stack
- #endif
- __asm inc OSIntNesting; //OSIntNesting++;
//if (OSIntNesting == 1)
- //{
- // OSTCBCur->OSTCBStkPtr = Stack Pointer ;
- //}
- __asm
- {
- ldab OSIntNesting
- cmpb #$01
- bne SCI1ISR1
ldx OSTCBCur
- sts 0, x
- SCI1ISR1:
- }
#if defined( __BANKED__) || defined(__LARGE__) || defined(__PPAGE__)
- __asm call SCI1_ISR_Handler;
- __asm call OSIntExit;
- #else
- __asm jsr SCI1_ISR_Handler;
- __asm jsr OSIntExit;
- #endif
#if defined( __BANKED__) || defined(__LARGE__) || defined(__PPAGE__)
- __asm pula; // 3~, Get value of PPAGE register
- __asm staa PPAGE; // 3~, Store into CPU's PPAGE register
- #endif
}
下面给个简单的例子:
#include
/* common defines and macros */ - #include "derivative.h" /* derivative-specific definitions */
#include "INCLUDES.H"
- #include "crg.h"
- #include "sci.h"
- #include "sci_rtos.h"
OS_STK AppStartTaskStk[64];
static void AppStartTask (void *pdata);
void main(void)
- {
- /* put your own code here */
- OS_CPU_SR cpu_sr;
CRGInit();
- CRGSetRTIFreqency(0x54); // 200Hz
EnableInterrupts;
- OS_ENTER_CRITICAL() ;
- SCIInit(SCI0) ;
- SCIInit(SCI1) ;
- OS_EXIT_CRITICAL() ;
- OSInit();
- SCISetIEBit(SCI0, SCI_RIE) ;
- SCISetIEBit(SCI1, SCI_RIE) ;
- SCIBufferInit();
- (void) OSTaskCreate(AppStartTask, (void *)0x4321, (void *)&AppStartTaskStk[63], 0);
- (void)OSStart();
- for(;;)
- {
- _FEED_COP(); /* feeds the dog */
- } /* loop forever */
- /* please make sure that you never leave main */
- }
static void AppStartTask (void *pdata)
- {
- INT8U err;
- char C;
- (void) pdata;
- for(;;)
- {
- C = SCIGetCharB(SCI1, 0, &err);
- if(err == SCI_NO_ERR)
- (void) SCIPutCharB (SCI1, C, 0);
- }
- }
上一篇:基于P89LPC922的多点温度采集系统
下一篇:Freescale 9S12 系列单片机应用笔记(SCI)2
推荐阅读最新更新时间:2024-03-16 14:53
- 热门资源推荐
- 热门放大器推荐
设计资源 培训 开发板 精华推荐
- 微灵医疗李骁健:脑机接口技术正在开启意识与AI融合的新纪元
- USB Type-C® 和 USB Power Delivery:专为扩展功率范围和电池供电型系统而设计
- 景昱医疗耿东:脑机接口DBS治疗技术已实现国产替代
- 首都医科大学王长明:针对癫痫的数字疗法已进入使用阶段
- 非常见问题解答第223期:如何在没有软启动方程的情况下测量和确定软启动时序?
- 兆易创新GD25/55全系列车规级SPI NOR Flash荣获ISO 26262 ASIL D功能安全认证证书
- 新型IsoVu™ 隔离电流探头:为电流测量带来全新维度
- 英飞凌推出简化电机控制开发的ModusToolbox™电机套件
- 意法半导体IO-Link执行器电路板为工业监控和设备厂商带来一站式参考设计
- Melexis采用无磁芯技术缩小电流感测装置尺寸