如上图电路原理图
功能实现串口转485,能同时对485进行收发,或者对在485网络上的收到的数据进行转发.
2天完成。
三个串口
1.P3.0,P3.1 使能 P1.4 对应485 U3
2.P1.0,P1.1 使能 P0.7 对应 485 U4
3.P0.0,P0.1 使能 P4.6 对应 485 U5
按老规矩找stcai_isp上找到相应的范例程序,思路是把串口对应的485一个一个调通。然后全部进行整合。
注意请选择intel的8058芯片进行编译这句话
选择下图中的即可
新建项目,添加包括经常用的一些函数头文件,C文件加入到项目中来。
#define MAIN_Fosc 11059200L //定义主时钟
#include "..\..\STC8Gxxx.h"
#include "public.h"
/************* 本地常量声明 **************/
#define RX1_Length 128 /* 接收缓冲长度 */
#define RX2_Length 128 /* 接收缓冲长度 */
#define RX3_Length 128 /* 接收缓冲长度 */
/************* 本地变量声明 **************/
u8 xdata RX1_Buffer[RX1_Length]; //接收缓冲
u8 xdata RX2_Buffer[RX2_Length]; //接收缓冲
u8 xdata RX3_Buffer[RX3_Length]; //接收缓冲
//u8 TX1_read,RX1_write; //读写索引(指针).
//u8 TX2_read,RX2_write; //读写索引(指针).
///u8 TX3_read,RX3_write; //读写索引(指针).
u8 RX1_Cou,RX2_Cou,RX3_Cou;
bit B_TX1_Busy,B_TX2_Busy,B_TX3_Busy,B_TX4_Busy; // 发送忙标志
bit ri_1,ri_2,ri_3;
/************* 本地函数声明 **************/
void UART1_config(u32 brt, u8 timer, u8 io); // brt: 通信波特率, timer=2: 波特率使用定时器2, 其它值: 使用Timer1做波特率. io=0: 串口1切换到P3.0 P3.1, =1: 切换到P3.6 P3.7, =2: 切换到P1.6 P1.7, =3: 切换到P4.3 P4.4.
void UART2_config(u32 brt, u8 timer, u8 io); // brt: 通信波特率, timer=2: 波特率使用定时器2, 其它值: 使用Timer2做波特率. io=0: 串口2切换到P1.0 P1.1, =1: 切换到P4.6 P4.7.
void UART3_config(u32 brt, u8 timer, u8 io); // brt: 通信波特率, timer=2: 波特率使用定时器2, 其它值: 使用Timer3做波特率. io=0: 串口3切换到P0.0 P0.1, =1: 切换到P5.0 P5.1.
void PrintString1(u8 *puts);
void PrintString2(u8 *puts);
void PrintString3(u8 *puts);
//========================================================================
// 函数: void main(void)
// 描述: 主函数
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2024-6-27
// 备注:
//========================================================================
void main(void)
{
u8 i;
EAXRAM();
UART1_config( 4800UL, 1, 0); // brt: 通信波特率, timer=2: 波特率使用定时器2, 其它值: 使用Timer1做波特率. io=0: 串口1切换到P3.0 P3.1, =1: 切换到P3.6 P3.7, =2: 切换到P1.6 P1.7, =3: 切换到P4.3 P4.4.
UART2_config( 4800UL, 2, 0); // brt: 通信波特率, timer=2: 波特率使用定时器2, 其它值: 使用Timer2做波特率. io=0: 串口2切换到P1.0 P1.1, =1: 切换到P4.6 P4.7.
UART3_config( 4800UL, 2, 0); // brt: 通信波特率, timer=2: 波特率使用定时器2, 其它值: 使用Timer3做波特率. io=0: 串口3切换到P0.0 P0.1, =1: 切换到P5.0 P5.1.
EA = 1;
ri_1=0;
ri_2=0;
ri_3=0;
RX1_Cou=0;
RX2_Cou=0;
RX3_Cou=0;
for(i=0; i<RX1_Length; i++) RX1_Buffer[i] = 0;
B_TX1_Busy = 0;
for(i=0; i<RX2_Length; i++) RX2_Buffer[i] = 0;
B_TX2_Busy = 0;
for(i=0; i<RX3_Length; i++) RX3_Buffer[i] = 0;
B_TX3_Busy = 0;
P14=0;P07=0;P46=0;
while (1)
{
/*P14=1; //U3
delay_ms(50);
PrintString1("12345");
delay_ms(500);
SBUF=ri_1;
delay_ms(500);
//PrintString1(ri_1);
//delay_ms(1000);
P14=0;*/
/*P07=1; //U4 vdr
delay_ms(50);
PrintString2("2");
delay_ms(1000);
P07=0;
P46=1; //U5
delay_ms(50);
PrintString3("3");
delay_ms(1000);
P46=0;*/
if(ri_1) //1,3 收 2发
{
P14=1; //发送置1 串口助手发一串数据给mcu,但mcu只返回一个字节回来,问题出在 数组长度定义是,加大RX1_Length即可
P07=1;
delay_ms(1);
PrintString2(RX1_Buffer);
ri_1=0;
RX1_Buffer[0]=0;
RX1_Buffer[RX1_Cou]=0;
RX1_Cou=0;
P14=0; //接收置0
}
/*if(ri_2==1) //1,3 收 2发
{
P07=1; //发送置1
delay_ms(1);
PrintString2(RX2_Buffer);
ri_2=0;
RX2_Buffer[0]=0;
RX2_Buffer[RX2_Cou]=0;
RX2_Cou=0;
P07=0; //接收置0
}*/
if(ri_3==1)
{
P46=1; //置发送 P07=1; //发送置1
P07=1;
delay_ms(1);
PrintString2(RX3_Buffer);
RX3_Buffer[0]=0;
RX3_Buffer[RX3_Cou]=0;
ri_3=0;
RX3_Cou=0;
P46=0; //置接收
}
}
}
在编程过程中出现几个问题
1.网上下载资料中(还是专家大神)com2端口不能用即 P1.0,P1.1没有任何反应,经过对比调试,发现此4行代码必须加上,即解决问题。
2.电脑发送数据给485只返回一个byte,或者和自己发送的无关返回,3个方面解决,一是485接收发送时加一个1ms延时,如main中处理,2是如下图所示。
3是如图所示 不勾选使用快速下载模式.
3.在中断处理中不能加任何延时,因为中断会来得很快,造成数据流失。中断中尽量精简,不能写代码,控制在8行以内。