接(1)
//-------------------------------------------------------------------------------------
//中断服务程序
//--------------------------------------------------------------------------------------
void PCA_ISR(void) interrupt 9
{
static char SUTXST=0; //SW_UART TX状态变量
static char SURXST=0; //SW_UART RX状态变量
static unsigned char RXSHIFT; //SW_UART RX移位寄存器
static int PCA_TEMP; //临时储存变量,用于处理PCA模块的搞和低字节
//首先检查接受中断变量,如果CCF0置位则对其服务
if(CCF0){
CCF0=0; //清除中断标志
switch(SURXST){
//状态:0 收到起始位
//在该状态,是SW_TX上的负边沿触发中断,表示检测到起始位,同时PCA0CP0寄存器捕捉PCA0的值
//检查接受允许和起始位
//将PCA模块0切换到软件定时方式
//加3/2位时间到模块0捕捉寄存器以采样LSB
//TX状态变量加1
case 0:
if(SREN&~SW_RX){ //检查接收允许和起始位
PCA_TEMP=(PCA0CPH0<<8);//将模块0的内容读到PCA_TEMP
PCA_TEMP|=PCA0CPL0;
PCA_TEMP+=TH_TIME_COUNT;//加3/2位时间到PCA_TEMP
PCA0CPL0=PCA_TEMP; //更新PCA0CPL0和PCA0CPH0
PCA0CPH0=(PCA_TEMP>>8);
PCA0CPM0=0x49; //将模块0切换到软件定时器方式,允许中断
SURXST++; } //更新RX状态变量
break;
//状态1-8:收到数据位
//采样SW_RX引脚
//将新数据移入RXSHIFT
//加1个位时间变量到模块0捕捉寄存器
//RX状态变量加1
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
RXSHIFT=RXSHIFT >> 1; //右移一位
if(SW_RX) //如果SW_RX=1;将1移入RXSHIFT的MSB
RXSHIFT |= 0x80;
PCA_TEMP = (PCA0CPH0<<8);//将模块0内容读到PCA_TEMP
PCA_TEMP |= PCA0CPL0;
PCA_TEMP += TIME_COUNT;//加1个位时间到PCA_TEMP
PCA0CPL0 = PCA_TEMP; //更新PCA0CPL0和PCA0CPH0
PCA0CPH0 = (PCA_TEMP>>8);
SURXST++; //更新RX状态变量
break;
//状态9:已收到8个数据位,捕捉停止位
//将RXSHIFT传到RDR
//置位SRI(表示接收完成)
//设置模块0,为下一次传输做准备
//复位RX状态变量
case 9:
RDR = RXSHIFT;
SRI = 1;
PCA0CPM0 = 0x11;
SURXST = 0;
break;
}
}
//检查发送中断,如果CCF1置位则对其服务
else if(CCF1){
CCF1=0; //清除中断标志
switch(SUTXST){
//状态0:发送过程以启动
//在此,用户已将要发送的字节装入到TDR,强制模块1中断以启动发送
//发送起始位(使SW_TX变低电平)
//读PCA0,加一个位时间后存到模块1捕捉寄存器
//TX状态变量加1
case 0:
SW_TX=0;
PCA_TEMP=PCA0L;
PCA_TEMP|=(PCA0H<<8);
PCA_TEMP+=TIME_COUNT;
PCA0CPL1=PCA_TEMP;;
PCA0CPH1=(PCA_TEMP>>8);
PCA0CPM1|=0x48;
SUTXST++;
break;
//状态1-9:发送数据位
//将TDR的LSB输入到TX
//将TDR右移一位
//将一个1移入TDR的MSB作为状态9的停止位
//加一个时间到模块1捕捉寄存器
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
SW_TX=(TDR&0x01);
TDR>>=1;
TDR|=0x80;
PCA_TEMP=(PCA0H<<8);
PCA_TEMP|=PCA0L;
PCA_TEMP+=TIME_COUNT;
PCA0CPL1=PCA_TEMP;;
PCA0CPH1=(PCA_TEMP>>8);
SUTXST++;
break;
//状态10:最后一位数据已发送完。发送停止位并结束传输过程
//发送停止位
//置1发送结束标志,清除忙标志
//复位TX状态
//设置模块1,为下一次传输做准备
case 10:
STI=1;
SUTXST=0;
SW_TX=1;
PCA0CPM1=0x01;
break;
}
}
}
//==========================================================================================
//硬件UART中断服务程序
//发送字符1-15,并接收15个字符
//检查接收中断并服务
//检查发送中断并服务
void HW_UART_ISR(void) interrupt 4
{
static char i=0; //发送数据变量
static char j=0; //接收数据的下标
static idata char HW_BUF[20];//接收数据缓冲区
if(RI){ //如果接收完成
RI=0; //清除接收标志
HW_BUF[j++]=SBUF; //读接收缓冲区
if(j==15) //如果已收到15个字符禁止HW_UART接收器
REN=0;
}
else if(TI){ //如果发送完成
TI=0; //清除发送标志
if(i<15) //如果还有发送的字符变量+1
SBUF=i++;
else
HW_DONE=1; //如果15个字符发送完毕,指示HW_TX结束
}
}
//-------------------------------------------------------------------------------------
//中断服务程序
//--------------------------------------------------------------------------------------
void PCA_ISR(void) interrupt 9
{
static char SUTXST=0; //SW_UART TX状态变量
static char SURXST=0; //SW_UART RX状态变量
static unsigned char RXSHIFT; //SW_UART RX移位寄存器
static int PCA_TEMP; //临时储存变量,用于处理PCA模块的搞和低字节
//首先检查接受中断变量,如果CCF0置位则对其服务
if(CCF0){
CCF0=0; //清除中断标志
switch(SURXST){
//状态:0 收到起始位
//在该状态,是SW_TX上的负边沿触发中断,表示检测到起始位,同时PCA0CP0寄存器捕捉PCA0的值
//检查接受允许和起始位
//将PCA模块0切换到软件定时方式
//加3/2位时间到模块0捕捉寄存器以采样LSB
//TX状态变量加1
case 0:
if(SREN&~SW_RX){ //检查接收允许和起始位
PCA_TEMP=(PCA0CPH0<<8);//将模块0的内容读到PCA_TEMP
PCA_TEMP|=PCA0CPL0;
PCA_TEMP+=TH_TIME_COUNT;//加3/2位时间到PCA_TEMP
PCA0CPL0=PCA_TEMP; //更新PCA0CPL0和PCA0CPH0
PCA0CPH0=(PCA_TEMP>>8);
PCA0CPM0=0x49; //将模块0切换到软件定时器方式,允许中断
SURXST++; } //更新RX状态变量
break;
//状态1-8:收到数据位
//采样SW_RX引脚
//将新数据移入RXSHIFT
//加1个位时间变量到模块0捕捉寄存器
//RX状态变量加1
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
RXSHIFT=RXSHIFT >> 1; //右移一位
if(SW_RX) //如果SW_RX=1;将1移入RXSHIFT的MSB
RXSHIFT |= 0x80;
PCA_TEMP = (PCA0CPH0<<8);//将模块0内容读到PCA_TEMP
PCA_TEMP |= PCA0CPL0;
PCA_TEMP += TIME_COUNT;//加1个位时间到PCA_TEMP
PCA0CPL0 = PCA_TEMP; //更新PCA0CPL0和PCA0CPH0
PCA0CPH0 = (PCA_TEMP>>8);
SURXST++; //更新RX状态变量
break;
//状态9:已收到8个数据位,捕捉停止位
//将RXSHIFT传到RDR
//置位SRI(表示接收完成)
//设置模块0,为下一次传输做准备
//复位RX状态变量
case 9:
RDR = RXSHIFT;
SRI = 1;
PCA0CPM0 = 0x11;
SURXST = 0;
break;
}
}
//检查发送中断,如果CCF1置位则对其服务
else if(CCF1){
CCF1=0; //清除中断标志
switch(SUTXST){
//状态0:发送过程以启动
//在此,用户已将要发送的字节装入到TDR,强制模块1中断以启动发送
//发送起始位(使SW_TX变低电平)
//读PCA0,加一个位时间后存到模块1捕捉寄存器
//TX状态变量加1
case 0:
SW_TX=0;
PCA_TEMP=PCA0L;
PCA_TEMP|=(PCA0H<<8);
PCA_TEMP+=TIME_COUNT;
PCA0CPL1=PCA_TEMP;;
PCA0CPH1=(PCA_TEMP>>8);
PCA0CPM1|=0x48;
SUTXST++;
break;
//状态1-9:发送数据位
//将TDR的LSB输入到TX
//将TDR右移一位
//将一个1移入TDR的MSB作为状态9的停止位
//加一个时间到模块1捕捉寄存器
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
SW_TX=(TDR&0x01);
TDR>>=1;
TDR|=0x80;
PCA_TEMP=(PCA0H<<8);
PCA_TEMP|=PCA0L;
PCA_TEMP+=TIME_COUNT;
PCA0CPL1=PCA_TEMP;;
PCA0CPH1=(PCA_TEMP>>8);
SUTXST++;
break;
//状态10:最后一位数据已发送完。发送停止位并结束传输过程
//发送停止位
//置1发送结束标志,清除忙标志
//复位TX状态
//设置模块1,为下一次传输做准备
case 10:
STI=1;
SUTXST=0;
SW_TX=1;
PCA0CPM1=0x01;
break;
}
}
}
//==========================================================================================
//硬件UART中断服务程序
//发送字符1-15,并接收15个字符
//检查接收中断并服务
//检查发送中断并服务
void HW_UART_ISR(void) interrupt 4
{
static char i=0; //发送数据变量
static char j=0; //接收数据的下标
static idata char HW_BUF[20];//接收数据缓冲区
if(RI){ //如果接收完成
RI=0; //清除接收标志
HW_BUF[j++]=SBUF; //读接收缓冲区
if(j==15) //如果已收到15个字符禁止HW_UART接收器
REN=0;
}
else if(TI){ //如果发送完成
TI=0; //清除发送标志
if(i<15) //如果还有发送的字符变量+1
SBUF=i++;
else
HW_DONE=1; //如果15个字符发送完毕,指示HW_TX结束
}
}