?? softuart.c
字號:
// is transmitted or received.
// - Checks module 1 interrupt flag (CCF1); if set, services receive state.
// - Checks module 0 interrupt flag (CCF0); if set, services transmit state.
// - Checks module 3 interrupt flag (CCF3); if set, services receive state.
// - Checks module 2 interrupt flag (CCF2); if set, services transmit state.
//
void PCA_ISR(void) interrupt 9
{
static char SUTXST0 = 0; // SW_UART TX state variable
static char SURXST0 = 0; // SW_UART RX state variable
static unsigned char RXSHIFT0; // SW_UART RX Shift Register
unsigned int PCA_TEMP0; // Temporary storage variable for manipulating PCA module high & low bytes.
// Check receive interrupt flag first; service if CCF0 is set.
static char SUTXST1 = 0; // SW_UART TX state variable
static char SURXST1 = 0; // SW_UART RX state variable
static unsigned char RXSHIFT1; // SW_UART RX Shift Register
unsigned int PCA_TEMP1; // Temporary storage variable for manipulating PCA module high & low bytes.
// Check receive interrupt flag first; service if CCF0 is set.
if (CCF1){
CCF1 = 0; // Clear interrupt flag.
switch (SURXST0){
// State 0: START bit received.
// In this state, a negative edge on SW_TX has caused the interrupt,
// meaning a START has been detected and the PCA0CP0 registers have
// captured the value of PCA0.
// - Check for receive enable and good START bit
// - Switch PCA module 0 to software timer mode
// - Add 3/2 bit time to module 0 capture registers to sample LSB.
// - Increment RX state variable.
case 0:
if (SREN0 & ~SW_RX0){ // Check for receive enable and a good START bit.
PCA_TEMP0 = (PCA0CPH1 << 8); // Read module 0 contents into
PCA_TEMP0 |= PCA0CPL1; // PCA_TEMP.
PCA_TEMP0 += UART2_STARTTIME;// Add 3/2 bit times to PCA_TEMP
PCA0CPL1 = PCA_TEMP0; // Restore PCA0CPL0 and PCA0CPH0
PCA0CPH1 = (PCA_TEMP0 >> 8); // with the updated value
PCA0CPM1 = 0x49; // Change module 0 to software timer mode, interrupts enabled.
SURXST0++; // Update RX state variable.
}
break;
// States 1-8: Bit Received
// - Sample SW_RX pin
// - Shift new bit into RXSHIFT
// - Add 1 bit time to module 0 capture registers
// - Increment RX state variable
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
RXSHIFT0 = RXSHIFT0 >> 1; // Shift right 1 bit
if (SW_RX0) // If SW_RX=1,
RXSHIFT0 |= 0x80; // shift '1' into RXSHIFT msb
PCA_TEMP0 = (PCA0CPH1 << 8); // Read module 0 contents into
PCA_TEMP0 |= PCA0CPL1; // PCA_TEMP.
PCA_TEMP0 += UART2_TIMER; // Add 1 bit time to PCA_TEMP
PCA0CPL1 = PCA_TEMP0; // Restore PCA0CPL0 and PCA0CPH0
PCA0CPH1 = (PCA_TEMP0 >> 8); // with the updated value
SURXST0++; // Update RX state variable.
break;
// State 9: 8-bits received, Capture STOP bit.
// - Move RXSHIFT into RDR.
// - Set SRI (indicate receive complete).
// - Prepare module 0 for next transfer.
// - Reset RX state variable.
// - Trigger IE7 if user-level interrupt support is enabled.
case 9:
RDR0 = RXSHIFT0; // Move received data to receive register.
SRI0 = 1; // Set receive complete indicator.
PCA0CPM1 = 0x11; // Switch module 0 to negative capture
// mode; interrupt enabled for START detection.
SURXST0 = 0; // Reset RX state variable.
if (SES0){ // If user-level interrupt support enabled
EIE2 |= 0x20; // Enable IE7.
P3IF |= 0x80; // Trigger IE7.
}
break;
}
}
// Check Transmit interrupt; service if CCF1 is set.
else if (CCF0){
CCF0 = 0; // Clear interrupt flag
switch (SUTXST0){
// State 0: Transmit Initiated.
// Here, the user has loaded a byte to transmit into TDR, and set the
// module 1 interrupt to initiate the transfer.
// - Transmit START bit (drop SW_TX)
// - Read PCA0, add one bit time, & store in module 1 capture registers
// for first bit.
// - Increment TX state variable.
case 0:
SW_TX0 = 0; // Drop TX pin as START bit.
PCA_TEMP0 = PCA0L; // Read PCA counter value into
PCA_TEMP0 |= (PCA0H << 8); // PCA_TEMP.
PCA_TEMP0 += UART2_TIMER; // Add 1 bit time.
PCA0CPL0 = PCA_TEMP0; // Store updated match value into
PCA0CPH0 = (PCA_TEMP0 >> 8); // module 1 capture/compare registers.
PCA0CPM0 |= 0x48; // Enable module 1 software timer.
SUTXST0++; // Update TX state variable.
break;
// States 1-9: Transmit Bit.
// - Output LSB of TDR onto TX
// - Shift TDR 1 bit right.
// - Shift a '1' into MSB of TDR for STOP bit in State 9.
// - Add 1 bit time to module 1 capture register
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
SW_TX0 = (TDR0 & 0x01); // Output LSB of TDR onto SW_TX pin.
TDR0 >>= 1; // Shift TDR right 1 bit.
TDR0 |= 0x80; // Shift '1' into MSB of TDR for
// STOP bit in State 9.
PCA_TEMP0 = (PCA0CPH0 << 8); // Read module 1 contents into
PCA_TEMP0 |= PCA0CPL0; // PCA_TEMP.
PCA_TEMP0 += UART2_TIMER; // Add 1 bit time to PCA_TEMP
PCA0CPL0 = PCA_TEMP0; // Restore PCA0CPL1 and PCA0CPH1
PCA0CPH0 = (PCA_TEMP0 >> 8); // with the updated value
SUTXST0++; // Update TX state variable.
break;
// State 10: Last bit has been transmitted. Transmit STOP bit
// and end transfer.
// - Transmit STOP bit
// - Set TX Complete indicator, clear Busy flag
// - Reset TX state
// - Prepare module 1 for next transfer.
// - Trigger IE7 interrupt if user-level interrupts enabled.
case 10:
STI0 = 1; // Indicate TX complete.
SUTXST0 = 0; // Reset TX state.
SW_TX0 = 1; // SW_TX should remain high.
PCA0CPM0 = 0x01; // Disable module 1 software timer; leave
// interrupt enabled for next transmit.
if (SES0){ // If user-level interrupt support enabled:
EIE2 |= 0x20; // Enable IE7.
P3IF |= 0x80; // Trigger IE7.
}
STXBSY0 = 0; // SW_UART TX free.
break;
}
}
//第二個串行口
if (CCF3){
CCF3 = 0; // Clear interrupt flag.
switch (SURXST1){
case 0:
if (SREN1 & ~SW_RX1){ // Check for receive enable and a good START bit.
PCA_TEMP1 = (PCA0CPH3 << 8); // Read module 3 contents into
PCA_TEMP1 |= PCA0CPL3; // PCA_TEMP.
PCA_TEMP1 += UART3_STARTTIME;// Add 3/2 bit times to PCA_TEMP
PCA0CPL3 = PCA_TEMP1; // Restore PCA0CPL0 and PCA0CPH0
PCA0CPH3 = (PCA_TEMP1 >> 8); // with the updated value
PCA0CPM3 = 0x49; // Change module 0 to software timer mode, interrupts enabled.
SURXST1++; // Update RX state variable.
}
break;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
RXSHIFT1 = RXSHIFT1 >> 1; // Shift right 1 bit
if (SW_RX1) // If SW_RX=1,
RXSHIFT1 |= 0x80; // shift '1' into RXSHIFT msb
PCA_TEMP1 = (PCA0CPH3 << 8); // Read module 3 contents into
PCA_TEMP1 |= PCA0CPL3; // PCA_TEMP.
PCA_TEMP1 += UART3_TIMER; // Add 1 bit time to PCA_TEMP
PCA0CPL3 = PCA_TEMP1; // Restore PCA0CPL0 and PCA0CPH0
PCA0CPH3 = (PCA_TEMP1 >> 8); // with the updated value
SURXST1++; // Update RX state variable.
break;
case 9:
RDR1 = RXSHIFT1; // Move received data to receive register.
SRI1 = 1; // Set receive complete indicator.
PCA0CPM3 = 0x11; // Switch module 0 to negative capture
// mode; interrupt enabled for START detection.
SURXST1 = 0; // Reset RX state variable.
if (SES1){ // If user-level interrupt support enabled
EIE2 |= 0x20; // Enable IE7.
P3IF |= 0x80; // Trigger IE7.
}
break;
}
}
else if (CCF2){
CCF2 = 0; // Clear interrupt flag
switch (SUTXST1){
case 0:
SW_TX1 = 0; // Drop TX pin as START bit.
PCA_TEMP1 = PCA0L; // Read PCA counter value into
PCA_TEMP1 |= (PCA0H << 8); // PCA_TEMP.
PCA_TEMP1 += UART3_TIMER; // Add 1 bit time.
PCA0CPL2 = PCA_TEMP1; // Store updated match value into
PCA0CPH2 = (PCA_TEMP1 >> 8); // module 1 capture/compare registers.
PCA0CPM2 |= 0x48; // Enable module 1 software timer.
SUTXST1++; // Update TX state variable.
break;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
SW_TX1 = (TDR1 & 0x01); // Output LSB of TDR onto SW_TX pin.
TDR1 >>= 1; // Shift TDR right 1 bit.
TDR1 |= 0x80; // Shift '1' into MSB of TDR for
// STOP bit in State 9.
PCA_TEMP1 = (PCA0CPH2 << 8); // Read module 1 contents into
PCA_TEMP1 |= PCA0CPL2; // PCA_TEMP.
PCA_TEMP1 += UART3_TIMER; // Add 1 bit time to PCA_TEMP
PCA0CPL2 = PCA_TEMP1; // Restore PCA0CPL1 and PCA0CPH1
PCA0CPH2 = (PCA_TEMP1 >> 8); // with the updated value
SUTXST1++; // Update TX state variable.
break;
case 10:
STI1 = 1; // Indicate TX complete.
SUTXST1 = 0; // Reset TX state.
SW_TX1 = 1; // SW_TX should remain high.
PCA0CPM2 = 0x01; // Disable module 1 software timer; leave
// interrupt enabled for next transmit.
if (SES1){ // If user-level interrupt support enabled:
EIE2 |= 0x20; // Enable IE7.
P3IF |= 0x80; // Trigger IE7.
}
STXBSY1 = 0; // SW_UART TX free.
break;
}
}
}
//----------------------------------------------------------------------------------------
// USER_ISR: User SW_UART Interrupt Service Routine (IE7 ISR)
// If interrupt-mode test code is enabled, this ISR
// transmits 15 characters and receives 15 characters. This routine is triggered each
// time a SW_UART transmit or receive is completed.
// - Checks receive complete indicator, and services.
// - Checks transmit complete indicator, and services.
// - Checks for transmits or receives that completed during the ISR; if so, triggers the
// interrupt again.
//
void USER_ISR(void) interrupt 19 { // IE7 Interrupt Service Routine
P3IF &= ~(0x80); // Clear IE7 interrupt flag
if (SRI0)
{
SRI0 = 0;
CommRecBuffer2[CommRecBufferTail2]=RDR0;
CommRecBufferTail2++;
if (CommRecBufferTail2==DB_RECMAXSIZE2)
{
CommRecBufferTail2=0;
}
FlagRecComm2=1;
}
else
if (STI0)
{
STI0 = 0;
CommSendBufferHead2++;
if (CommSendBufferHead2==DB_SENDMAXSIZE2)
{
CommSendBufferHead2=0;
}
if (CommSendBufferHead2!=CommSendBufferTail2)
{
STXBSY0 = 1;
TDR0=CommSendBuffer2[CommSendBufferHead2];
CCF0 = 1;
SendItComm2=0;
}
else
{
SendItComm2=1;
}
}
if (SRI1)
{
SRI1 = 0;
CommRecBuffer3[CommRecBufferTail3]=RDR1;
CommRecBufferTail3++;
if (CommRecBufferTail3==DB_RECMAXSIZE3)
{
CommRecBufferTail3=0;
}
FlagRecComm3=1;
}
else
if (STI1)
{
STI1 = 0;
CommSendBufferHead3++;
if (CommSendBufferHead3==DB_SENDMAXSIZE3)
{
CommSendBufferHead3=0;
}
if (CommSendBufferHead3!=CommSendBufferTail3)
{
STXBSY1 = 1;
TDR1=CommSendBuffer2[CommSendBufferHead2];
CCF2 = 1;
SendItComm3=0;
}
else
{
SendItComm3=1;
}
}
if (STI0|SRI0) // If SRI or STI is set, re-trigger
P3IF |= 0x80; // interrupt to service.
if (STI1|SRI1) // If SRI or STI is set, re-trigger
P3IF |= 0x80; // interrupt to service.
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -