找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3010|回复: 8
打印 上一主题 下一主题
收起左侧

求助,STC单片机TTL端口可以主从通讯,用了485芯片就不能通讯了,求大佬指点迷津啊!

[复制链接]
跳转到指定楼层
楼主
主机代码:
#include <STC15.h>
#include <INTRINS.H>
#define uint unsigned int   //宏命令,声明uint替代unsignde int
#define uchar unsigned char        //宏命令,声明uchar替代unsigned char

sbit a=P1^0;
sbit b=P1^1;
sbit c=P1^2;
sbit d=P1^3;
sbit e=P1^4;
sbit f1=P1^5;
sbit ss=P1^6;
sbit xx=P1^7;
sbit rs485=P5^5; //485方向控制脚
sbit s1=P2^0;
sbit s2=P2^0;
sbit s3=P2^0;
sbit s4=P2^0;
sbit s5=P2^0;
sbit s6=P2^0;
sbit s7=P2^0;
sbit s8=P2^0;
sbit s9=P2^0;
sbit s10=P2^0;

uchar shuxian,run,as1,as2,as3,as4,as5,as6,as7,as8,as9,as10,ast,ads;//数显及按键指令
uchar sdat[4];   //串口接收到的数组
uchar fdat[4];         //串口要发送的数组
uchar fadd,sadd,add;                      //广播地址码,接收地址码,主机地址码。
uchar key,cnt;                                               //握手信号,送数计量。
uint clt;                                 //定时变量最大值65536即65秒。

void ysms(uint xms)
{
uint i,j,k;
  for(i=xms;i>0;i--)
        for(j=50;j>0;j--)
        for(k=1;k>0;k--);  
}

/* 串口配置函数,baud-通信波特率 */
void ConfigUART()
{
    SCON = 0x50;                //8位数据,可变波特率
        AUXR |= 0x01;                //串口1选择定时器2为波特率发生器
        AUXR |= 0x04;                //定时器2时钟为Fosc,即1T
        T2L = 0xE0;                //设定定时初值
        T2H = 0xFE;                //设定定时初值
        AUXR |= 0x10;                //启动定时器2
        TH0 = 0xfc;    // 设置定时器0高8位初值         11.0592Mhz主频下该参数溢出一次约0.001秒
    TL0 = 0x66;     //设置定时器0低8位
    TR1 = 1;       //启动T1
        ET0=1;                   //关闭T1中断使能
        EA=1;                   //总中断开关
    ES=1;       //使能串口1中断
}

void main()
{
    P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x00;
    P1M1 = 0x00;
    P2M0 = 0x00;
    P2M1 = 0x00;
    P3M0 = 0x00;
    P3M1 = 0x00;
    P4M0 = 0x00;
    P4M1 = 0x00;
    P5M0 = 0x00;
    P5M1 = 0x00;
    P6M0 = 0x00;
    P6M1 = 0x00;
    P7M0 = 0x00;
    P7M1 = 0x00;                                                          
        key=1;                                                                                  //初始允许广播握手
        cnt=0;
    ConfigUART();  //配置波特率为9600
        TI=0;RI=0;
        shuxian = 11;
        run     = 12;
        fadd    = 1;
    cnt=0;
    while (1)
    {
       
        fdat[0]=fadd;                         //发送数组0字节为读取fadd变量
        fdat[1]=255;
        fdat[2]=255;
        fdat[3]=255;

          
          if(key==1)
          {
            rs485=1;         //设置485为发送方向
                ET0=0;                 //
                TR0=0;
                clt=0;
                REN=0;
                for(cnt=0;cnt<4;cnt++)        //FOR循环送4个字节
                {
                 SBUF=fdat[cnt];
                 while(!TI);
                 TI=0;                                  //清零发送完毕标记
                }
                rs485=0;                         //设置485为接收方向
                TR0=1;
                ET0=1;
                clt=0;
                fadd++;                                 //广播地址值+1
                if(fadd>=8){fadd=1;}  //如果广播地址超过或等于8.则重新置为1;
                key=0;                                  //握手信号清零
                }
    }
}
/* T0中断服务函数,完成LED扫描 */
void InterruptTimer0() interrupt 1
{
    TH0 = 0xfc;  //重新加载重载值
    TL0 = 0x66;
        clt++;
        if(clt>=500){key=1;clt=0;}           //定时超过0.5秒后,重新发起握手信号
}
/* UART中断服务函数 */
void InterruptUART() interrupt 4
{
        if(RI)                                                   //此主机暂不接收任何数据这部分不用理会
        {
        sdat[cnt] = SBUF;
        cnt++;
        RI=0;
        }
       
}



从机代码
#include <stc15.h>
#define uint unsigned int   //宏命令,声明uint替代unsignde int
#define uchar unsigned char        //宏命令,声明uchar替代unsigned char

#define S1_S0 0x40              //P_SW1.6
#define S1_S1 0x80              //P_SW1.7

sbit xxd=P1^0;
sbit ssd=P1^1;
sbit a=P1^2;
sbit b=P1^3;
sbit c=P1^4;
sbit rs485=P1^5;
sbit jxd=P1^6;
sbit fd=P1^7;
sbit wha=P5^4;
sbit ds=P5^5;

uchar shuxian = 0;
uchar as,jt,ss,xx,addr,cnt,fadd,key;
uchar sdat[4];  //串口接收到的数组
uchar fdat[4];         //串口发送的数组
uchar t;
uint clt;

void ysms(uint xms)
{
uint i,j,k;
  for(i=xms;i>0;i--)
        for(j=50;j>0;j--)
        for(k=1;k>0;k--);  
}

/* 串口配置函数,baud-通信波特率 */
void ConfigUART()
{
    SCON = 0x50;                //8位数据,可变波特率
        AUXR |= 0x01;                //串口1选择定时器2为波特率发生器
        AUXR |= 0x04;                //定时器2时钟为Fosc,即1T
        T2L = 0xE0;                //设定定时初值
        T2H = 0xFE;                //设定定时初值
        AUXR |= 0x10;                //启动定时器2
        EA=1;                   //总中断开关
    ES=1;       //使能串口1中断
}

void main()
{       

        P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x00;
    P1M1 = 0x00;
    P2M0 = 0x00;
    P2M1 = 0x00;
    P3M0 = 0x00;
    P3M1 = 0x00;
    P4M0 = 0x00;
    P4M1 = 0x00;
    P5M0 = 0x00;
    P5M1 = 0x00;
    P6M0 = 0x00;
    P6M1 = 0x00;
    P7M0 = 0x00;
    P7M1 = 0x00;

           a=0;b=0;c=0;ssd=0;xxd=0;jxd=0;fd=0;
        cnt=0;
           ConfigUART();
        TI=0;RI=0;
        shuxian=1;
    while (1)
    {           
           rs485=0;
           shuxian=sdat[0];
          switch(shuxian)                                //数组0字节显示函数
          {
          case 1 : a=1;b=0;c=0; break;
          case 2 : a=0;b=1;c=0; break;
          case 3 : a=1;b=1;c=0; break;
          case 4 : a=0;b=0;c=1; break;
          case 5 : a=1;b=0;c=1; break;
          case 6 : a=0;b=1;c=1; break;
          case 7 : a=1;b=1;c=1; break;
          }   
            
    }
}

/* UART中断服务函数 */
void InterruptUART() interrupt 4
{
          

       RI = 0;            
           sdat[cnt] = SBUF;
           cnt++;
           if(cnt>=4){cnt=0;}
}




分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:718536 发表于 2021-1-8 19:56 | 只看该作者
现在直接用单片机脚TTL电平是可以主从通讯的。就是经过485芯片后完全没反应....
回复

使用道具 举报

板凳
ID:390416 发表于 2021-1-8 20:41 | 只看该作者

可以使用490芯片 代替485芯片
回复

使用道具 举报

地板
ID:235200 发表于 2021-1-8 21:11 | 只看该作者
是一端用了485还是两端用了485,如果是前者肯定不能通信
回复

使用道具 举报

5#
ID:718536 发表于 2021-1-8 22:05 | 只看该作者
csmyldl 发表于 2021-1-8 21:11
是一端用了485还是两端用了485,如果是前者肯定不能通信

两头都是用485芯片呀。
回复

使用道具 举报

6#
ID:863432 发表于 2021-1-9 11:41 | 只看该作者
RS485芯片是有使能控制引脚的,该引脚决定接收和发送,所以RS485通信是半双工,UART是全双工,一定注意。
回复

使用道具 举报

7#
ID:752974 发表于 2021-1-9 13:08 | 只看该作者
6楼说的很明白了,485通信是主从结构,一主多从,从机平时一定是接收状态,根据主机的命令再确定自己的收发状态。切记!!!!
回复

使用道具 举报

8#
ID:718536 发表于 2021-1-9 14:24 | 只看该作者
munuc_w 发表于 2021-1-9 13:08
6楼说的很明白了,485通信是主从结构,一主多从,从机平时一定是接收状态,根据主机的命令再确定自己的收发 ...

是的啊,我从机485方向RE.DE一直是拉低的。就是一直通讯不能。
回复

使用道具 举报

9#
ID:718536 发表于 2021-1-9 21:11 | 只看该作者
已经解决了,原来是因为485芯片不支持热拔插,烧毁了,  换了个芯片就可以正常通讯了。还有485芯片貌似是CMOS工艺,如果单片机上电瞬间是高阻状态的话,建议485芯片引脚还是加上上拉电阻之类的,不然 造成引脚悬空容易烧毁,AB脚1K上下拉,AB脚间120欧。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表