?? softuart.c
字號:
//------------------------------------------------------------------------------------
//
// Copyright 2001 Cygnal Integrated Products, Inc.
//
// FILE NAME : SoftUart.c
// TARGET DEVICE : C8051F02x
// Modify ON : 01/10/02
// Modify BY : WWW.XHL.COM.CN
//
// Software UART program, using PCA as baud rate source.
// PCA module 4 is used as receive baud rate source and START detector. For START
// detection, module 4 is configured in negative-edge capture mode. For all other
// SW_UART operations, module 4 is configured as a software timer. Module match
// interrupts are used to generate the baud rate. Module 3 generates the transmit
// baud rate in software timer mode.
// Code assumes an external crystal is attached between the XTAL1 and XTAL2 pins.
// The frequency of the external crystal should be defined in the SYSCLK constant.
//
// INITIALIZATION PROCEDURE:
// 1) Define SYSCLK according to external crystal frequency.
// 2) Define desired BAUD_RATE.
// 3) Call SW_UART_INIT().
// 4) Set SREN to enable SW_UART receiver.
// 5) Set SES only if user-level interrupt support is desired.
// 6) Call SW_UART_ENABLE().
//
// TO TRANSMIT:
// 1) Poll STXBSY for zero.
// 2) Write data to TDR.
// 3) Set CCF1 to initiate transmit.
// 4) STI will be set upon transmit completion. An IE7 interrupt is generated if
// user-level interrupts are enabled.
//
// TO RECEIVE:
// 1) If in polled mode, poll SRI. If in interrupt mode, check SRI in IE7 Interrupt
// Service Routine.
// 2) Read data from RDR.
//
// P1.2 -> CEX0 (SW_UART0 TX)
// P1.3 -> CEX1 (SW_UART0 RX)
// P1.4 -> CEX0 (SW_UART1 TX)
// P1.5 -> CEX1 (SW_UART1 RX)
//
/* 端口配置
XBR0 = 0x27; // XBAR0: Initial Reset Value
XBR1 = 0x00; // XBAR1: Initial Reset Value
XBR2 = 0x44; // XBAR2: Initial Reset Value
P0MDOUT = 0x1D; // Output configuration for P0
P1MDOUT = 0x01; // Output configuration for P1
// P0.0 = UART TX0 (Push-Pull Output)
// P0.1 = UART RX0 (Open-Drain Output/Input)
// P0.2 = SPI Bus SCK (Push-Pull Output)
// P0.3 = SPI Bus MISO (Push-Pull Output)
// P0.4 = SPI Bus MOSI (Push-Pull Output)
// P0.5 = SPI Bus NSS (Open-Drain Output/Input)
// P0.6 = SMBus SDA (Open-Drain Output/Input)
// P0.7 = SMBus SCL (Open-Drain Output/Input)
// Port 1
// P1.0 = UART TX1 (Push-Pull Output)
// P1.1 = UART RX1 (Open-Drain Output/Input)
// P1.2 = PCA CEX0 (Push-Pull Output)
// P1.3 = PCA CEX1 (Push-Pull Output)
// P1.4 = PCA CEX2 (Push-Pull Output)
// P1.5 = PCA CEX3 (Push-Pull Output)
// P1.6 = GP I/O (Open-Drain Output/Input)
// P1.7 = GP I/O (Open-Drain Output/Input)
*/
//-----------------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------------
#include "TestSerial.h"
#define BAUDRATE2 19200 // 用戶定義的SW_UART 波特率
#define UART2_TIMER SYSCLK/BAUDRATE2/4 //對應一個位時間的PCA 計數值(PCA 配置為對SYSCLK/4 計數)
#define UART2_STARTTIME UART2_TIMER*3/2 // 3/2 位時間用于接收到一個起始位后在起始位邊沿之后RX
//應在一個位時間內保持低電平第一個位采樣在下一個位時間的中間開始
#define BAUDRATE3 19200
#define UART3_TIMER SYSCLK/BAUDRATE3/4
#define UART3_STARTTIME UART3_TIMER*3/2
#define NULL ((void *) 0L)
#define DB_SENDMAXSIZE2 0xf0
#define DB_RECMAXSIZE2 0xf0
#define DB_SENDMAXSIZE3 0xf0
#define DB_RECMAXSIZE3 0xf0
bit FlagRecComm2,SendItComm2;
unsigned char CommSendBufferHead2, CommSendBufferTail2;
unsigned char xdata CommSendBuffer2[DB_SENDMAXSIZE2];
unsigned char CommRecBufferHead2, CommRecBufferTail2;
unsigned char xdata CommRecBuffer2[DB_RECMAXSIZE2];
bit FlagRecComm3,SendItComm3;
unsigned char CommSendBufferHead3, CommSendBufferTail3;
unsigned char xdata CommSendBuffer3[DB_SENDMAXSIZE3];
unsigned char CommRecBufferHead3, CommRecBufferTail3;
unsigned char xdata CommRecBuffer3[DB_RECMAXSIZE3];
//-----------------------------------------------------------------------------------
//Global VARIABLES
//-----------------------------------------------------------------------------------
bit SRI0; // SW_UART Receive Complete Indicator
bit STI0; // SW_UART Transmit Complete Indicator
bit STXBSY0; // SW_UART TX Busy flag
bit SREN0; // SW_UART RX Enable
bit SES0; // SW_UART User-level Interrupt Support Enable
sbit SW_RX0 = P1^3; // SW_UART Receive pin
sbit SW_TX0 = P1^2; // SW_UART Transmit pin
char TDR0; // SW_UART TX Data Register
char RDR0; // SW_UART RX Data Register (latch)
bit SRI1; // SW_UART Receive Complete Indicator
bit STI1; // SW_UART Transmit Complete Indicator
bit STXBSY1; // SW_UART TX Busy flag
bit SREN1; // SW_UART RX Enable
bit SES1; // SW_UART User-level Interrupt Support Enable
sbit SW_RX1 = P1^5; // SW_UART Receive pin
sbit SW_TX1 = P1^4; // SW_UART Transmit pin
char TDR1; // SW_UART TX Data Register
char RDR1; // SW_UART RX Data Register (latch)
//------------------------------------------------------------------------------------
// Function PROTOTYPES
//------------------------------------------------------------------------------------
void SW_UART_INIT0(); // SW_UART initialization routine
void SW_UART_ENABLE0(); // SW_UART enable routine
void PCA_ISR(); // SW_UART interrupt service routine
void USER_ISR0(void); // SW_UART test interrupt service routine
void SW_UART_INIT1(); // SW_UART initialization routine
void SW_UART_ENABLE1(); // SW_UART enable routine
void USER_ISR1(void); // SW_UART test interrupt service routine
void ClearCommRecBuffer2(void)
{
CommRecBufferHead2=CommRecBufferTail2=0;
FlagRecComm2=0;
}
void SendCommChar2(char ch) //發送一字節
{
CommSendBuffer2[CommSendBufferTail2]=ch; // 將欲發送的字節存入發送緩沖區
CommSendBufferTail2++; // 移動發送緩沖區隊列指針
if (CommSendBufferTail2==DB_SENDMAXSIZE2) // 檢查循環隊列指針
{
CommSendBufferTail2=0;
}
if (SendItComm2) // 空閑狀態啟動發送
{
STXBSY0 = 1; // 發送標志置位
TDR0 = CommSendBuffer2[CommSendBufferHead2];
CCF0 = 1; // 強制PCA模塊0中斷,啟動發送
}
return ;
}
void SendCommBuffer2(unsigned char *base, unsigned char size) //發送多字節
{
unsigned char i=0;
if (!size) return; // 發送字節為空
while (i<size) // 將發送的數據存入發送緩沖區,注意緩沖區的大小,本例程未考慮緩沖區溢出情況
{
CommSendBuffer2[CommSendBufferTail2]=base[i];
i++;
CommSendBufferTail2++;
if (CommSendBufferTail2==DB_SENDMAXSIZE2)
{
CommSendBufferTail2=0;
}
}
if (SendItComm2)
{
STXBSY0 = 1;
TDR0 = CommSendBuffer2[CommSendBufferHead2];
CCF0 = 1;
}
}
bit GetCommChar2(unsigned char idata *ch) //讀取一字節數據, 有數據返回1,無數據返回0.
{
if (CommRecBufferTail2==CommRecBufferHead2) return 0;
*ch=CommRecBuffer2[CommRecBufferHead2];
CommRecBufferHead2++;
if (CommRecBufferHead2==DB_RECMAXSIZE2)
{
CommRecBufferHead2=0;
}
if (CommRecBufferTail2==CommRecBufferHead2) FlagRecComm2=0;
return 1;
}
//------------------------------------------------------------------------------------------
// SW_UART_INIT: 軟件UART 初始化程序
// - 配置PCA: 模塊1 設置為下跳沿捕捉方式; 模塊0 設置為軟件定時方式
// PCA 時基 = 系統時鐘/4; 關閉PCA中斷
//
void SW_UART_INIT0(void)
{
PCA0CPM1 = 0x10; // Module 1 in negative capture mode; module 1 interrupt disabled.
PCA0CPM0 = 0x48; // Module 0 in software timer mode; module 0 interrupt disabled.
PCA0CN = 0; // Leave PCA disabled
PCA0MD = 0x02; // PCA timebase = SYSCLK/4; PCA counter
// interrupt disabled.
CCF1 = 0; // Clear pending PCA module 0 and
CCF0 = 0; // module 1 capture/compare interrupts.
SRI0 = 0; // Clear Receive complete flag.
STI0 = 0; // Clear Transmit complete flag.
SW_TX0 = 1; // TX line initially high.
STXBSY0 = 0; // Clear SW_UART Busy flag
SREN0 = 1; // Enable SW_UART Receiver
SES0 = 1; // User-level interrupt support enabled.
SendItComm2=1;
}
//------------------------------------------------------------------------------------------
// SW_UART_ENABLE: SW_UART Enable Routine
// Enables SW_UART for use.
// - Enables PCA module 0 interrupts
// - Enables PCA module 1 interrupts
// - Starts PCA counter.
//
void SW_UART_ENABLE0(void)
{
PCA0CPM1 |= 0x01; // Enable module 1 (receive) interrupts.
PCA0CPM0 |= 0x01; // Enable module 0 (transmit) interrupts.
CR = 1; // Start PCA counter.
EIE1 |= 0x08; // Enable PCA interrupts
EA = 1; // Globally enable interrupts
}
void ClearCommRecBuffer3(void)
{
CommRecBufferHead3=CommRecBufferTail3=0;
FlagRecComm3=0;
}
void SendCommChar3(char ch) //發送一字節
{
CommSendBuffer3[CommSendBufferTail3]=ch; // 將欲發送的字節存入發送緩沖區
CommSendBufferTail3++; // 移動發送緩沖區隊列指針
if (CommSendBufferTail3==DB_SENDMAXSIZE3) // 檢查循環隊列指針
{
CommSendBufferTail3=0;
}
if (SendItComm3) // 空閑狀態啟動發送
{
STXBSY1 = 1; // 發送標志置位
TDR1 = CommSendBuffer3[CommSendBufferHead3];
CCF2 = 1; // 強制PCA模塊0中斷,啟動發送
}
return ;
}
void SendCommBuffer3(unsigned char *base, unsigned char size) //發送多字節
{
unsigned char i=0;
if (!size) return; // 發送字節為空
while (i<size) // 將發送的數據存入發送緩沖區,注意緩沖區的大小,本例程未考慮緩沖區溢出情況
{
CommSendBuffer3[CommSendBufferTail3]=base[i];
i++;
CommSendBufferTail3++;
if (CommSendBufferTail3==DB_SENDMAXSIZE3)
{
CommSendBufferTail3=0;
}
}
if (SendItComm3)
{
STXBSY1 = 1;
TDR1 = CommSendBuffer2[CommSendBufferHead2];
CCF2 = 1;
}
}
bit GetCommChar3(unsigned char idata *ch) //讀取一字節數據, 有數據返回1,無數據返回0.
{
if (CommRecBufferTail3==CommRecBufferHead3) return 0;
*ch=CommRecBuffer3[CommRecBufferHead3];
CommRecBufferHead3++;
if (CommRecBufferHead3==DB_RECMAXSIZE2)
{
CommRecBufferHead3=0;
}
if (CommRecBufferTail3==CommRecBufferHead3) FlagRecComm3=0;
return 1;
}
void SW_UART_INIT1(void)
{
PCA0CPM3 = 0x10; // Module 1 in negative capture mode; module 1 interrupt disabled.
PCA0CPM2 = 0x48; // Module 0 in software timer mode; module 0 interrupt disabled.
PCA0CN = 0; // Leave PCA disabled
PCA0MD = 0x02; // PCA timebase = SYSCLK/4; PCA counter
// interrupt disabled.
CCF3 = 0; // Clear pending PCA module 0 and
CCF2 = 0; // module 1 capture/compare interrupts.
SRI1 = 0; // Clear Receive complete flag.
STI1 = 0; // Clear Transmit complete flag.
SW_TX1 = 1; // TX line initially high.
STXBSY1 = 0; // Clear SW_UART Busy flag
SREN1 = 1; // Enable SW_UART Receiver
SES1 = 1; // User-level interrupt support enabled.
SendItComm3=1;
}
void SW_UART_ENABLE1(void)
{
PCA0CPM3 |= 0x01; // Enable module 1 (receive) interrupts.
PCA0CPM2 |= 0x01; // Enable module 0 (transmit) interrupts.
CR = 1; // Start PCA counter.
EIE1 |= 0x08; // Enable PCA interrupts
EA=1;
}
//------------------------------------------------------------------------------------
// Interrupt Service Routines
//------------------------------------------------------------------------------------
//
// PCA_ISR: PCA Interrupt Service Routine.
// This ISR is triggered by both transmit and receive functions, for each bit that
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -