📄 microsystem.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 + -