⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 2_uart_sst.c

📁 sst芯片参考 增强UART功能
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -