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

📄 5_uart_sst.c

📁 C51 用PCA 模拟串口
💻 C
📖 第 1 页 / 共 3 页
字号:
//===========================SST MCU扩展的5个UART使用说明==============================
//	本例程是使用SST MCU(SST89E/V52RD,54RD,58RD,516RD)的特殊硬件功能做的,新增加2个扩展UART的功能.
//  扩展UART的特点:采用全双工方式,即:收发不用分时;采用半双工方式,可扩展5个新的UART
//  
//  1.发送和接收均采用中断方式,不占用标准8052的资源(定时器,硬件中断,RAM),
//    占用的资源均是SST MCU的特殊资源,因此这个例子只适合SST的单片机,不能用于其它非SST的MCU
//	2.发送采用UART4_SEND_OUT(data)函数,直接取要发送的数据即可.
//	3.接收采用中断方式接收,接收的数据放在自己定义的变量"UART4_SBUF"单元内.
//	4.使用本例程请参考MAIN.C函数.//
//		4.0	 加入本文件进行一些函数的声明和设置参数(晶振频率,通讯的波特率,缓冲区的大小,UART的I/O口定义)
//		4.2  对扩展UART进行初始化和打开:
//					UART4_INIT(); // 初始化UART4
//					UART4_RX_ENABLE(); // 允许UART4接收
//		4.3  接收首先查询UART通道的数据接收到标志--UART4_RI,若为1,说明已接收到数据,则从UART4_SBUF单元取出数据即可
//			  if (UART4_RI)				//已经接收到数据,将接收到的数据存入UART4_BUF的内存中
//					{	UART4_RI = 0;   // 清除接收标志,UART4_RI这个标志在接收到一个字节后会自动置1
//						UART4_BUF[] = UART4_SBUF; // 取出接收到的数据,送到缓冲区内
//					}
//	5. 本示例可用串口调试串口进行测试,上电开始即会发送--"12"2个字符到PC,
//		然后从PC端发送一串数据到UART,应在马上可收到返回的数据,从而验证了UART的收发结果.
//		然后再换成其余4个UART的I/O,应都能正常工作.
//  6.  在11.0592M晶振,双倍速模式下,波特率为9600,在单倍速模式下,波特率为4800,
//		对应的波特率和晶振的关系,在单倍速模式下:
//      4800--11.0592Mhz;     9600--18.432Mhz;    19200--40MHZ  
//===============================================================================================
//			香港弘微科技有限公司(SPAC)
//			技术支持:田伯运  0755-26010579    andy.tian@spacltd.com.cn
//===============================================================================================  
//#include <SST89x5xxRD2.H> // SFR声明
#include <5_UART_SST.h>

//--------------------------------------------------------------------
// 全局常量
//--------------------------------------------------------------------

//#define TIME_COUNT SYSCLK/BAUD_RATE/4 // 对应一个位时间的PCA计数值,(PCA 配置为对SYSCLK/4计数)
//#define TH_TIME_COUNT TIME_COUNT*3/2 // 3/2位时间用于接收到一个起始,
#define NEG_CAP_INT 	0x11 		//00010001 CAP ,ECCF//置为下降沿捕捉中断方式
#define POS_CAP_INT 	0x21		//置为上升沿捕捉中断方式		
#define TIME_INIT       0x49   		//置为软件定时器中断方式
#define DISABLE_MODE    0x0			//禁止PCA的操作

unsigned int TIME_COUNT;			//将定义改为变量,以便他人修改
//--------------------------------------------------------------------
//全局变量
//--------------------------------------------------------------------
//--------------UART0通道所用的变量-----------------------------------
bit UART0_RI; // 不能用字节变量,UART0接受完成标志
bit UART0_TI; // 不能用字节变量,UART0 发送完成标志
char UART0_SBUF; // UART0 发送和接收数据缓冲器
static  bit UART0_RX_FLAG; // 不能用字节变量,UART0的接收标志(UART0_RX_FLAG=1:表示处于UART0处于接收状态,UART0_RX_FLAG=0:表示处于UART0处于发送状态,)
static  char UART0_TX_STATE = 0; // UART0 TX状态变量,静态变量,不能为其它变量占用其单元
static  char UART0_RX_STATE = 0; // UART0 RX状态变量,静态变量,不能为其它变量占用其单元
static  unsigned char UART0_RX_SHIFT; // UART0 RX中间移位寄存器,静态变量,不能为其它变量占用其单元

//--------------UART1通道所用的变量-----------------------------------
bit UART1_RI; // UART1接受完成标志
bit UART1_TI; // UART1 发送完成标志
char UART1_SBUF; // UART1 发送和接收数据缓冲器
static  bit UART1_RX_FLAG; // UART1的接收标志(UART0_RX_FLAG=1:表示处于UART0处于接收状态,UART0_RX_FLAG=0:表示处于UART0处于发送状态,)
static  char UART1_TX_STATE = 0; // UART1 TX状态变量,静态变量,不能为其它变量占用其单元
static  char UART1_RX_STATE = 0; // UART1 RX状态变量,静态变量,不能为其它变量占用其单元
static  unsigned char UART1_RX_SHIFT; // UART1 RX中间移位寄存器,静态变量,不能为其它变量占用其单元

//--------------UART2通道所用的变量-----------------------------------
bit UART2_RI; // UART2接受完成标志
bit UART2_TI; // UART2 发送完成标志
char UART2_SBUF; // UART2 发送和接收数据缓冲器
static  bit UART2_RX_FLAG; // UART2的接收标志(UART0_RX_FLAG=1:表示处于UART0处于接收状态,UART0_RX_FLAG=0:表示处于UART0处于发送状态,)
static  char UART2_TX_STATE = 0; // UART2 TX状态变量,静态变量,不能为其它变量占用其单元
static  char UART2_RX_STATE = 0; // UART2 RX状态变量,静态变量,不能为其它变量占用其单元
static  unsigned char UART2_RX_SHIFT; // UART2 RX中间移位寄存器,静态变量,不能为其它变量占用其单元

//--------------UART3通道所用的变量-----------------------------------
bit UART3_RI; // UART3接受完成标志
bit UART3_TI; // UART3 发送完成标志
char UART3_SBUF; // UART3 发送和接收数据缓冲器
static  bit UART3_RX_FLAG; // UART3的接收标志(UART0_RX_FLAG=1:表示处于UART0处于接收状态,UART0_RX_FLAG=0:表示处于UART0处于发送状态,)
static  char UART3_TX_STATE = 0; // UART3 TX状态变量,静态变量,不能为其它变量占用其单元
static  char UART3_RX_STATE = 0; // UART3 RX状态变量,静态变量,不能为其它变量占用其单元
static  unsigned char UART3_RX_SHIFT; // UART3 RX中间移位寄存器,静态变量,不能为其它变量占用其单元

//--------------UART1通道所用的变量-----------------------------------
bit UART4_RI; // UART4接受完成标志
bit UART4_TI; // UART4 发送完成标志
char UART4_SBUF; // UART4 发送和接收数据缓冲器
static  bit UART4_RX_FLAG; // UART4的接收标志(UART0_RX_FLAG=1:表示处于UART0处于接收状态,UART0_RX_FLAG=0:表示处于UART0处于发送状态,)
static  char UART4_TX_STATE = 0; // UART4 TX状态变量,静态变量,不能为其它变量占用其单元
static  char UART4_RX_STATE = 0; // UART4 RX状态变量,静态变量,不能为其它变量占用其单元
static  unsigned char UART4_RX_SHIFT; // UART4 RX中间移位寄存器,静态变量,不能为其它变量占用其单元
//--------------------------------------------------------------------
// 函数原型
//--------------------------------------------------------------------
//--------------UART0通道所用的函数-----------------------------------
void UART0_INIT(); // UART0初始化程序
void UART0_RX_ENABLE(); // UART0接收允许程序
void UART0_SEND_OUT(unsigned char data_send); // UART0发送允许程序
//--------------UART1通道所用的函数-----------------------------------
void UART1_INIT(); // UART1初始化程序
void UART1_RX_ENABLE(); // UART1接收允许程序
void UART1_SEND_OUT(unsigned char data_send); // UART1发送允许程序
//--------------UART2通道所用的函数-----------------------------------
void UART2_INIT(); // UART2初始化程序
void UART2_RX_ENABLE(); // UART2接收允许程序
void UART2_SEND_OUT(unsigned char data_send); // UART2发送允许程序
//--------------UART3通道所用的函数-----------------------------------
void UART3_INIT(); // UART3初始化程序
void UART3_RX_ENABLE(); // UART3接收允许程序
void UART3_SEND_OUT(unsigned char data_send); // UART3发送允许程序
//--------------UART4通道所用的函数-----------------------------------
void UART4_INIT(); // UART4初始化程序
void UART4_RX_ENABLE(); // UART4接收允许程序
void UART4_SEND_OUT(unsigned char data_send); // UART4发送允许程序

void PCA_ISR(); // UART0 中断服务程序


//--------------------------------------------------------------------
// 函数
//--------------------------------------------------------------------



//==================UART0通道的函数======================================
//--------------------------------------------------------------------
// UART0_INIT: UART0初始化子程序
// 初始化UART0
// - 配置PCA: 模块0为负沿捕捉方式模块1为软件定时器方式
// PCA时基= SYSCLK/4禁止PCA中断禁止PCA计数器
// - 清除被挂起的PCA模块0和模块1中断
// - 复位TX和RX状态变量
//
void UART0_INIT(void)
{
 	CMOD   = 0x03 ; 					//CIDL=0,WDTE=0,CPS1 CPS0=01 Fosc/12 ,/ECF=1  
										//TBY20060223:改为PCA采用4分频的时钟,以提高波特率为4800*3=11400
 	CCON= 0X0;
 	CL = 0X0;							//PCA计数器初设为00
 	CH = 0X0;
	//----------UART0通道变量的初始化------------------------------------------
 	CCAPM0 = DISABLE_MODE ;			//禁止PCA0的操作
	CCF0 = 0; // 清除被挂起的PCA模块0和模块1 
	UART0_RI = 0; // 清除接收完成标志
	UART0_TI = 1; // 置发送完成标志,初始认为已经没有数据向外发了,这样有利于发前查询上次发送的标志,节省等待时间
	UART0_TX = 1; // TX线初始化为高电平
	UART0_RX_FLAG = 1;	//初始置UART0置于接收状态,只有发送时才置为发送状态
	UART0_TX_STATE = 0; // UART0 TX状态变量
	UART0_RX_STATE = 0; // UART0 RX状态变量
	UART0_RX_SHIFT=8; 			// UART0 RX移位寄存器

	CR = 1; 							// 启动PCA计数器
 	PPC = 1;							//置PCA中断为最高级
 	IPH |= 0x40;//highest PRI			//置PCA中断为最高级
 	EC = 1;							//PCA中断允许
	EA = 1; // 全局中断允许

}
//--------------------------------------------------------------------
// UART0_ENABLE: UART0接收允许子程序
// 允许UART0
// - 允许PCA模块0中断
// - 允许PCA模块1中断
// - 启动PCA计数器
//--------------------------------------------------------------------
void UART0_RX_ENABLE(void)
{
	CCAPM0=NEG_CAP_INT;				//置为下降沿捕捉中断方式
	UART0_RX_FLAG = 1;				//置接收标志

}
//--------------------------------------------------------------------
// UART0_ENABLE: UART0发送允许子程序
// 允许UART0
// - 允许PCA模块0中断
// - 允许PCA模块1中断
// - 启动PCA计数器
//--------------------------------------------------------------------
void UART0_SEND_OUT(unsigned char data_send)
{
	while (~UART0_TI);			//上次的数据已经发送完毕
	UART0_TI = 0; 		//如果发送完成,清除发送标志,UART0_TI这个标志在发送完一个字节后会自动置1
	UART0_SBUF =data_send;	//将发送的数据放入UART0发送寄存器中
	CCAPM0=TIME_INIT;				//01001001	//置为软件定时器中断方式
	UART0_RX_FLAG = 0;				//置发送标志
}

//--------------------------------------------------------------------
// 中断服务程序
//--------------------------------------------------------------------
//
// PCA_ISR: PCA中断服务程序
// 该ISR由发送和接收函数触发每个发送和接收位都触发
// - 检查模块0中断标志(CCF0)如果置位服务接收状态
// - 检查模块1中断标志(CCF1)如果置位服务发送状态
//--------------------------------------------------------------------
void PCA_ISR (void) interrupt 6 using 1
{
	unsigned int PCA_TEMP; // 临时存储变量
							// 用于处理PCA模快高和低字节
							// 首先检查接收中断变量如果CCF0置位则对其服务

	//===========UART0通道的数据接收和发送的处理=============================
	if (CCF0)
	{
		CCF0 = 0; // 清除中断标志
		if (UART0_RX_FLAG)
		{
			switch (UART0_RX_STATE)
				{
					// 状态0:收到起始位
					// 在该状态是UART0_TX上的负边沿触发的中断表示检测到起始位
					// 同时PCA0CP0寄存器捕捉到PCA0的值
					// - 检查接收允许和起始位是否正确
					// - 将PCA模块0切换到软件定时器方式
					// - 加3/2位时间到模块0捕捉寄存器以采样LSB
					// - RX状态变量加1
					case 0:
						if (~UART0_RX)
							{ //检查接收允许和起始位是否正确
								PCA_TEMP = (CCAP0H * 0x100)+CCAP0L+TIME_COUNT*3/2; // 将模块0内容读到
								CCAP0L = PCA_TEMP; // 用新值恢复CCAP0L和CCAP0H
								CCAP0H = (PCA_TEMP/ 0x100);
								CCAPM0 = TIME_INIT ; // 将模块0切换到软件定时器方式
													// 允许中断
								UART0_RX_STATE++; // 更新RX状态变量
							}
							break;
							// 状态1-8: 收到数据位
							// - 采样UART0_RX引脚
							// - 将新数据位移入UART0_RX_SHIFT
							// - 加1个位时间到模块0捕捉寄存器
							// - RX状态变量增1
					case 1:
					case 2:
					case 3:
					case 4:
					case 5:
					case 6:
					case 7:
					case 8:
						UART0_RX_SHIFT = UART0_RX_SHIFT >> 1; // 右移一位
						if (UART0_RX) // If UART0_RX=1
							UART0_RX_SHIFT |= 0x80; // 将'1'移入UART0_RX_SHIFT的msb
						PCA_TEMP = ( CCAP0H* 0x100)+CCAP0L+TIME_COUNT;// 将模块0内容读到PCA_TEMP
						CCAP0L = PCA_TEMP; // 用新值恢复CCAP0L和CCAP0H
						CCAP0H = (PCA_TEMP / 0x100);
						UART0_RX_STATE++; // 更新RX状态变量
						break;
							// 状态9: 已收到8个数据位捕捉停止位
							// - 将UART0_RX_SHIFT传送到UART0_SBUF
							// - 置位UART0_RI (表示接收完成)
							// - 为下一次传输准备模块0
							// - 复位RX状态变量
							// - 触发IE7如果用户级中断支持被允许
					case 9:
						UART0_SBUF = UART0_RX_SHIFT; // 将接收到的数据传送到接收寄存器
						UART0_RI = 1; // 置1接收完成标志
						CCAPM0 = NEG_CAP_INT;		//置为下降沿捕捉中断方式0x11; // 切换模块0到负沿捕捉方式
											// 允许中断以检测起始位
						UART0_RX_STATE = 0; // 复位RX状态变量
						break;
					}
				}
	//======================UART0发送===================================
	//================================检查发送中断如果CCF1置位则对其服务
				else 		//否则,UART0_RX_FLAG=0,为发送状态
				{
						switch (UART0_TX_STATE)
						{
									// 状态0: 发送过程已启动
									// 在此用户已将发送字节装入到UART0_SBUF强制模块1中断以启动发送
									// - 发送起始位(使UART0_TX变低)
									// - 读PCA0为第一位加一个位时间存到模块1捕捉寄存器
									// - TX状态变量增1
							case 0:
								UART0_TX = 0; // 使TX引脚变低作为起始位
								PCA_TEMP = (CH* 0x100)+CL+TIME_COUNT; // 将PCA计数器的值读到PCA_TEMP
								CCAP0L = PCA_TEMP; // 将更新后的匹配值存到
								CCAP0H = (PCA_TEMP/ 0x100);// 模块1捕捉比较寄存器
								CCAPM0 = TIME_INIT;	//0x48; // 允许模块1软件定时器
								UART0_TX_STATE++; // 更新TX状态变量
								break;
										// 状态1-9: 发送位
										// - 将UART0_SBUF的LSB输出到TX
										// - 将UART0_SBUF右移一位
										// - 将一个'1'移入UART0_SBUF的MSB作为状态9的停止位
										// - 加一个位时间到模块1捕捉寄存器
							case 1:
							case 2:
							case 3:
							case 4:
							case 5:
							case 6:
							case 7:
							case 8:
							case 9:
								UART0_TX = (UART0_SBUF & 0x01); // 将UART0_SBUF的LSB输出到UART0_TX引脚
								UART0_SBUF >>= 1; // UART0_SBUF右移一位
								UART0_SBUF |= 0x80; // 将一个'1'移入UART0_SBUF的MSB
											// 作为状态9的停止位
								PCA_TEMP = (CCAP0H * 0x100)+CCAP0L+TIME_COUNT;// 将模块1内容读到PCA_TEMP
								CCAP0L = PCA_TEMP; // 用新值恢复CCAP1L
								CCAP0H = (PCA_TEMP / 0x100);// 和CCAP1H
								UART0_TX_STATE++; // 更新TX状态变量
								break;
								// 状态10: 最后一位已发送完发送停止位并结束传输过程
								// - 发送停止位
								// - 置1发送结束标志清除忙标志
								// - 复位TX状态
								// - 为下一次传输准备模块1
								// - 触发IE7如果用户级中断支持被允许
						case 10:
							UART0_TI = 1; // 表示发送完成

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -