📄 2_uart_sst.c
字号:
#include <2_UART_SST.h>
#define NEG_CAP_INT 0x11 //00010001 CAP ,ECCF//置为下降沿捕捉中断方式
#define POS_CAP_INT 0x21 //置为上升沿捕捉中断方式
#define DISABLED_MODE 0x0 //禁止PCA的操作
#define TIME_INIT 0x49 //置为软件定时器中断方式
#define DISABLE_MODE 0x0
//TBY20060223:采用双倍速方式,改为PCA采用4分频的时钟,以提高波特率为4800*3=11400
#define FULL_SPEEDL SYSCLK/2/BAUDRATE1%0x100 //接收的一个位的时间常数的低8位
#define FULL_SPEEDH SYSCLK/2/BAUDRATE1/0x100 //接收的一个位的时间常数的高8位
#define HALF_SPEEDL FULL_SPEEDL/2 //接收的半个位的时间常数的低8位
#define HALF_SPEEDH FULL_SPEEDH/2 //接收的半个位的时间常数的高8位
#define TX_START_BIT 0x0 //发送的状态
#define TX_DATA_BIT 0x1
#define TX_STOP_BIT 0x2
#define TX_STOP_END 0x3
#define RX_START_EDGE 0 //接收的状态
#define RX_START_BIT 1
#define RX_DATA_BIT 2
#define RX_STOP_BIT 3
xdata struct uart1_tx_strut
{
uchar tx_state ; //发送的状态
uint tx_bitcont ; //发送的一个数据的位数(常用的为8位宽度)
uint count ; //已发送的数据个数(序号)
uint len ; //总的发送的数据包长度
uchar buff[MAX_SIZE_BUF] ; //发送缓冲区大小
} uart2_tx,uart1_tx ; //原来的BUFFER设为256,由于SST89E516的XRAM为300H,如果分配4个256的BUFFER,SST MCU内部的XRAM便不够,
//因此出现第2个UART不能接收或发送的现象.
xdata struct uart1_rx_strut
{
uchar no_data_count ; //接收缓冲区无数据的时间计数,接收到数据,将置为0,没有数据时,20ms加一(在定时中断内加一)
uchar rx_state ; //接收的状态
uchar rx_bitcont ; //接收的一个数据的位数(常用的为8位宽度)
uchar buff[MAX_SIZE_BUF] ; //接收缓冲区大小
uint count ; //已经接收的数据个数,也可根据接收的数目,来判断有无新数据,在取出数据后,将这个数目清零
} uart2_rx,uart1_rx ; //原来的BUFFER设为256,由于SST89E516的XRAM为300H,如果分配4个256的BUFFER,SST MCU内部的XRAM便不够,
//因此出现第2个UART不能接收或发送的现象.
//----------------------------------------
void PCA_ISR (void) interrupt 6 using 1
{
uchar temp ;
uint temp_ccap ;
CF = 0 ;
//============================= UART1的接收过程====================================
if (CCF1) //是PCA1的捕捉响应标志,说明PCA1管脚上有下降沿或上升沿出现,
{ //第一次是属于外部捕捉的下降沿中断,以后便是软件定时器的采集定时中断(在每位的中间时刻进行采集数据)
CCF1=0; //清接收的PCA1中断标志
switch (uart1_rx.rx_state)
{
case RX_START_EDGE: //是接收的起始边沿
{
temp_ccap = CCAP1H *0x100 + CCAP1L + HALF_SPEEDL; //???为何要多加一个位的低8位时间?--由于高8位进位的问题捕捉当前的时间,再加上半位的时间为何要多加一个位的低8位时间?,
CCAP1H = temp_ccap/0x100 +HALF_SPEEDH ; //重置捕捉的高8位数据,再加半位时间 //就是下一个起始位的中间采集时刻
CCAP1L += HALF_SPEEDL; //实际上,CCAP0L并没有多加一次FULL_SPEEDL,加也只是加在了temp_ccap上重置捕捉的低8位数据,再加半位时间
CCAPM1=TIME_INIT; //置为软件定时器中断方式,计算下一位的采集时间
uart1_rx.rx_state=RX_START_BIT; //置下一个状态为:接收起始位
}break;
case RX_START_BIT: //是接收起始位
{
temp_ccap = CCAP1H *0x100 + CCAP1L + FULL_SPEEDL; //???:为何要多加一个位的低8位时间??--由于高8位进位的问题
CCAP1L += FULL_SPEEDL; //实际上,CCAP0L并没有多加一次FULL_SPEEDL,加也只是加在了temp_ccap上
CCAP1H = temp_ccap/0x100 +FULL_SPEEDH ; //置下一个位的采集时间,就是本次的时间加上一个位的时间
if (RXD1)
{
uart1_rx.rx_state=RX_START_EDGE; //如果RXD1=1,说明不是起始位,起始位应为0
CCAPM1=NEG_CAP_INT; //置为下降沿捕捉中断方式
}
else
{
uart1_rx.rx_state=RX_DATA_BIT; //RXD1=0,为接收的起始位,置下一状态为数据接收
uart1_rx.rx_bitcont=8; //接收8位的数据
}
}break;
case RX_DATA_BIT: //是接收数据位的状态
{
temp_ccap = CCAP1H *0x100 + CCAP1L + FULL_SPEEDL; //???为何要多加一个位的低8位时间?
CCAP1L += FULL_SPEEDL;
CCAP1H = temp_ccap/0x100 +FULL_SPEEDH ; //置下一个位的采集时间
uart1_rx.buff[uart1_rx.count]=uart1_rx.buff[uart1_rx.count]>>1; //接收的内容右移一位
if(RXD1)
uart1_rx.buff[uart1_rx.count]|=0x80; //I/O是1,置D7位为1
uart1_rx.rx_bitcont--; //位数减一(共需移8位)
if(uart1_rx.rx_bitcont==0)
{
uart1_rx.rx_state=RX_STOP_BIT; //8位接收完,准备接收停止位.
}
}break;
case RX_STOP_BIT: //为接收的停止位,重置下降沿的起始位
{
CCAPM1=NEG_CAP_INT; //置为下降沿捕捉中断方式
if(RXD1) //停止位应是1,如果是零,非正确数据,丢弃
{
uart1_rx.count++ ; //是正确数据,接收的数据个数加一
uart1_rx.no_data_count = 0 ; //置有接收到的数据标志
}
uart1_rx.rx_state=RX_START_EDGE;
}break;
default :break;
}
}
//============================= UART1的发送过程====================================
if (CCF0) //当软件定时器到下一位发送的时间时,就产生此发送中断
{ //TX operation
CCF0 = 0 ; //清PCA0的中断标志
temp_ccap = CCAP0H *0x100 + CCAP0L + FULL_SPEEDL; //???为何要多加一个位的低8位时间?--由于高8位进位的问题
CCAP0L +=FULL_SPEEDL; //实际上,CCAP0L并没有多加一次FULL_SPEEDL,加也只是加在了temp_ccap上
CCAP0H = temp_ccap/0x100 +FULL_SPEEDH ; //PCA0的下一位的定时时间为本次捕捉到的计数加上一个位的时间
//就是串行发送下一位的时刻,每位相隔的时间就是一个位的时间
//attention: must counteract the time of interrupt response;
switch(uart1_tx.tx_state)
{
case TX_START_BIT:
{ //sent start bit //是发送的起始位状态,就发送起始位--0
TXD1=0;
uart1_tx.tx_state=TX_DATA_BIT; //将起始位状态改为数据位状态,说明下次发送的是数据位
uart1_tx.tx_bitcont=0x8; //发送的位数置为8位
}break ;
case TX_DATA_BIT:
{ //sent a bit of data //是发送的数据位状态,就发送数据位
temp = uart1_tx.buff[uart1_tx.count]; //从发送缓冲区取出一个将要发送的数据
temp=temp>>1;
if(CY)
TXD1=0x1; //移位发送到TXD1管脚上
else
TXD1=0x0;
uart1_tx.buff[uart1_tx.count]=temp; //将移位后的数据重新放回到取数的单元
uart1_tx.tx_bitcont--; //发送的位数减一
if(uart1_tx.tx_bitcont==0)
uart1_tx.tx_state=TX_STOP_BIT; //8位的数据发送完毕,将状态改为发送停止位
}break ;
case TX_STOP_BIT:
{ //sent stop bit //是发送的停止位状态,发送停止位,
TXD1=1;
uart1_tx.tx_state=TX_STOP_END; //置发送状态置为发送结束标志
}break ;
case TX_STOP_END:
{ //a byte data was sent finished //是发送结束标志,重置为发送起始位状态
uart1_tx.tx_state=TX_START_BIT;
uart1_tx.count++; //发送的数据个数加一
if(uart1_tx.len==uart1_tx.count) //判断是否缓冲区的数据全部发送完?
{
CCAPM0=DISABLED_MODE; //发送的数据长度等于发送的数据个数,禁止PCA的操作
uart1_tx.tx_state=0xff; //置禁止发送
}
}break ;
default : CCAPM0=DISABLED_MODE; break ; //其它状态,统统禁止发送
}
}
//=================================================================================
//============================= UART2的接收过程====================================
if (CCF2) //当软件定时器到下一位发送的时间时,就产生此发送中断
{ //TX operation
CCF2 = 0 ; //清PCA0的中断标志
temp_ccap = CCAP2H *0x100 + CCAP2L + FULL_SPEEDL; //???为何要多加一个位的低8位时间?--由于高8位进位的问题
CCAP2L +=FULL_SPEEDL; //实际上,CCAP0L并没有多加一次FULL_SPEEDL,加也只是加在了temp_ccap上
CCAP2H = temp_ccap/0x100 +FULL_SPEEDH ; //PCA0的下一位的定时时间为本次捕捉到的计数加上一个位的时间
//就是串行发送下一位的时刻,每位相隔的时间就是一个位的时间
//attention: must counteract the time of interrupt response;
switch(uart2_tx.tx_state)
{
case TX_START_BIT:
{ //sent start bit //是发送的起始位状态,就发送起始位--0
TXD2=0;
uart2_tx.tx_state=TX_DATA_BIT; //将起始位状态改为数据位状态,说明下次发送的是数据位
uart2_tx.tx_bitcont=0x8; //发送的位数置为8位
}break ;
case TX_DATA_BIT:
{ //sent a bit of data //是发送的数据位状态,就发送数据位
temp = uart2_tx.buff[uart2_tx.count]; //从发送缓冲区取出一个将要发送的数据
temp=temp>>1;
if(CY)
TXD2=0x1; //移位发送到TXD2管脚上
else
TXD2=0x0;
uart2_tx.buff[uart2_tx.count]=temp; //将移位后的数据重新放回到取数的单元
uart2_tx.tx_bitcont--; //发送的位数减一
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -