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

📄 microsystem.c

📁 SP2339驱动
💻 C
字号:
/**********************************************************************************
 Microsystem.c source file SP2338 serial communication example for MCS-51 MCU
 Author: Chen Wei, 2003-03-06
***********************************************************************************/
#include <reg52.h>
#define uchar unsigned char

uchar idata uart0_t_buf[8]; 		// you can modify the buffer size of sub-serial port 0
uchar idata uart1_t_buf[8]; 		// you can modify the buffer size of sub-serial port 1
uchar idata uart2_t_buf[8]; 		// you can modify the buffer size of sub-serial port 2
uchar idata send_buf   [8];		// you can modify the buffer size of temporary data package

uchar idata uart0_r_buf,uart1_r_buf,uart2_r_buf;
uchar idata uart0_send_num,uart1_send_num,uart2_send_num;
uchar idata uart_port_num,send_byte_num,uart_pointer,i;

bit bdata write_success,uart_busy;
bit bdata uart0_receive,uart1_receive,uart2_receive;

sbit 	ADRI_0=P2^0;	/* connect to pin ADRO0 of SP2328/SP2338 */
sbit	ADRI_1=P2^1;	/* connect to pin ADRO1 of SP2328/SP2338 */
sbit	ADRO_0=P2^2;	/* connect to pin ADRI0 of SP2328/SP2338 */
sbit	ADRO_1=P2^3;	/* connect to pin ADRI0 of SP2328/SP2338 */


#define _DEBUG_SUB_MODULE				// Be used to test sub-serial port 0~sub-serial port 0


/*****************************************************************************************************
 serial port ISR.
*****************************************************************************************************/
serial () interrupt 4 using 0 {
	if(RI){								// 判断母串口是发送中断还是接收中断?
		RI=0;							// 母串口接收中断
		switch(P2&0x03){					// 判断接收到的数据来自哪个子串口?
			case 0:{					// 接收到的一个字节数据来自串口0
				uart0_r_buf=SBUF;			// 清空"SBUF"以便接收其他子串口的数据
				uart0_receive=1;			// 置串口0收到数据标志,主程序采用查询该
				break;					// 标志的方式处理收到的数据,主程序处理
			}						// 完刚收到的数据后软件必须将该标志"清零"
			case 1:{					// 接收到的一个字节数据来自串口1
				uart1_r_buf=SBUF;
				uart1_receive=1;
				break;
			}
			case 2:{					// 接收到的一个字节数据来自串口2
				uart2_r_buf=SBUF;
				uart2_receive=1;
				break;
			}
			case 3:{					// 防止程序跑飞(正常情况下不会执行该语句)
				break;
			}
		}
	}

	else{								// 母串口发送中断
		TI=0;
		switch(uart_pointer){					// 判断轮到该哪个子串口发送数据
			case 0:{					// 轮到串口0发送数据
				uart_pointer++;				// 串口数据发送指针加"1",下一次中断判断串口1有无数据发送
				if(uart0_send_num){			// 判断串口0缓冲区的数据是否已经完全发送
					ADRO_0=0;			// 串口0缓冲区的数据没有发送完
					ADRO_1=0;			// 注意:写数据到"SBUF"前必须先置欲发送子串口的地址!!!
					uart0_send_num--;		// 下一次发送数据包中的下一个字节数据
					SBUF=uart0_t_buf[uart0_send_num];	// 从缓冲区发送一个字节到指定的子串口
					uart_busy=1;			// 置母串口忙(正在发送数据)标志
					break;
				}
				else if(uart1_send_num|uart2_send_num){	// 串口0的数据已经发送完,继续判断串口1和串口2
					ADRO_0=1;			// 的数据是否也已经发送完,如果还没有发送完,则需
					ADRO_1=1;			// 要发送"0x00"用于延时一个字节时间长度
					SBUF=0;				// 注意:发送"0x00"前必须先设置串口地址!!!
					uart_busy=1;			// 置母串口忙(正在发送数据)标志
					break;
				}					// 如果串口0~串口2的数据包都已经发送完,置母串口"空闲"标志
				else {uart_busy=0;break;}		// 主程序通过该标志判断是否需要以"TI=1"启动子串口数据发送
			}						// 注:如所有子串口的数据发送都已经完,则不会再产生发送中断

			case 1:{					// 轮到串口1发送数据
				uart_pointer++;
				if(uart1_send_num){
					ADRO_0=1;
					ADRO_1=0;
					uart1_send_num--;
					SBUF=uart1_t_buf[uart1_send_num];
					uart_busy=1;
					break;
				}
				else if(uart0_send_num|uart2_send_num){
					ADRO_0=1;
					ADRO_1=1;
					SBUF=0;
					uart_busy=1;
					break;
				}
				else {uart_busy=0;break;}
			}

			case 2:{					// 轮到串口2发送数据
				uart_pointer++;
				if(uart2_send_num){
					ADRO_0=0;
					ADRO_1=1;
					uart2_send_num--;
					SBUF=uart2_t_buf[uart2_send_num];
					uart_busy=1;
					break;
				}
				else if(uart0_send_num|uart1_send_num){
					ADRO_0=1;
					ADRO_1=1;
					SBUF=0;
					uart_busy=1;
					break;
				}
				else {uart_busy=0;break;}
			}

			case 3:{					// 发送"0x00"用于延时一个字节时间长度
				uart_pointer++;
				ADRO_0=1;
				ADRO_1=1;
				SBUF=0;
				uart_busy=1;
				break;
			}

			case 4:{					// 发送"0x00"用于延时一个字节时间长度
				uart_pointer=0;
				ADRO_0=1;
				ADRO_1=1;
				SBUF=0;
				uart_busy=1;
				break;
			}
		}
	}
}

/****************************************************************************************
 function:           void uart_send(uchar uart_port_num,uchar send_byte_num)
 input:              uchar uart_port_num - index of sub-serial port
                     uchar send_byte_num - data number will be sent
                     write_success=0 (Call the function must before "write_success=0" first )
 output:             write_success (If data is sent success,then "write_success==1" else "write_success==0")
****************************************************************************************/
void uart_send (uchar uart_port_num,uchar send_byte_num){
	switch(uart_port_num){
		case 0:{					// 上位机需要向串口0发送数据
			if(uart0_send_num==0){			// 判断串口0的上一包数据是否已经发送完
				for(i=0;i<send_byte_num;i++){	// 上一包数据发送已经结束,则将临时缓冲区的数据
				uart0_t_buf[i]=send_buf[i];	// 转移到串口0的发送缓冲区中
				}
				write_success=1;		// 置串口0数据"发送成功"标志
				uart0_send_num=send_byte_num;
				if(uart_busy==0){		// 判断母串口发送中断是否已经启动
					uart_pointer=0;
					TI=1;			// 母串口一直没有发送数据,需要启动发送中断
					break;
				}
				else {break;}			// 母串口正在发送其他子串口的数据,不需要再次
			}					// 启动发送中断
			else {break;}				// 如果串口0的上一包数据没有发送完,则该次数据包
		}						// 发送不成功(数据标志为:"write_success==0")
		case 1:{
			if(uart1_send_num==0){
				for(i=0;i<send_byte_num;i++){
				uart1_t_buf[i]=send_buf[i];
				}
				write_success=1;
				uart1_send_num=send_byte_num;
				if(uart_busy==0){
					uart_pointer=1;
					TI=1;
					break;
				}
				else {break;}
			}
			else {break;}
		}
		case 2:{
			if(uart2_send_num==0){
				for(i=0;i<send_byte_num;i++){
				uart2_t_buf[i]=send_buf[i];
				}
				write_success=1;
				uart2_send_num=send_byte_num;
				if(uart_busy==0){
					uart_pointer=2;
					TI=1;
					break;
				}
				else {break;}
			}
			else {break;}
		}
	}
}

uart_receive (void){			//用户自己编写的母串口接收函数
	;
}

void init_serialcomm(void){
	SCON   = 0x50; 			//SCON: serail mode 1, 8-bit UART, enable ucvr
	T2CON |= 0x34; 			//TMOD: timer 2, mode 2, 16-bit reload,timer 2 run
	RCAP2H = 0xFF; 			//Baud:38400  fosc=11.0592MHz
	RCAP2L = 0xF7;			//Baud:38400  fosc=11.0592MHz
	IE    |= 0x90; 			//Enable Serial Interrupt
}


#ifdef _DEBUG_SUB_MODULE

main(){

	init_serialcomm();

	while(1){
		send_buf[0]=0x31;
		send_buf[1]=0x32;
		send_buf[2]=0x33;
		write_success=0;		// 调用函数"void uart_send (uchar uart_port_num,uchar send_byte_num)"
		while(!write_success){		// 前必须先将"write_success"标志清"0"
			uart_send(0,3);		// 向串口0发送3个字节数据(按照先后顺序分别为:"0x33"、"0x32"、"0x31")
		}
		send_buf[0]=0x41;
		send_buf[1]=0x42;
		send_buf[2]=0x43;
		send_buf[3]=0x44;
		send_buf[4]=0x45;
		send_buf[5]=0x46;
		write_success=0;
		while(!write_success){		// 向串口1发送6个字节数据(按照先后顺序分别为:"0x46"、"0x45"、"0x44"、
			uart_send(1,6);		// "0x43"、"0x42"、"0x41")
		}
		send_buf[0]=0x51;
		send_buf[1]=0x52;
		send_buf[2]=0x53;
		send_buf[3]=0x54;
		send_buf[4]=0x55;
		send_buf[5]=0x56;
		send_buf[6]=0x57;
		send_buf[7]=0x58;
		write_success=0;
		while(!write_success){		// 向串口2发送8个字节数据(按照先后顺序分别为:"0x58"、"0x57"、"0x56"... ...
			uart_send(2,8);
		}
	}
}

#endif // _DEBUG_SUB_MODULE


⌨️ 快捷键说明

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