打印
[51单片机]

初始485芯片带来的烦恼,求大神指点指点

[复制链接]
1051|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
baochen123456|  楼主 | 2017-4-28 09:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
如果用全双工的通讯芯片就可以进行通讯,但用485就不能实现通讯了 。下面是小弟的代码。求大神指点指点小弟。串口通讯  :0F 00 0F
                   0F 01 0E
                   0F 02 0D
                   0F 04 0B
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar recive[3],rec_num;        //定义数组大小
sbit RS485_DIR = P3^3;          //定义485管脚
void send();                         //声明发送函数
void delay(uint t) //延时函数
{
        uint i;
        for(t;t>0;t--)
        for(i = 110;i>0;i--);

}
void UsartInit()                //串口初始化
{
       
        SCON=0X50;                //设置为工作方式1
        TMOD=0X20;                //设置计数器工作方式2       
        PCON=0X80;                //波特率加倍
        TH1=0XF3;                //波特率4800
        TL1=0XF3;
        ES=1;                        //打开接收中断               
        EA=1;                        //打开总中断                       
        TR1=1;                        //打开计数器
       
}
void main()
{

        delay(20);
        RS485_DIR =0;
        delay(100);
        UsartInit();
        while(1);
       
}

void Usart() interrupt 4
{
        uchar checkXOR;
        RS485_DIR=0;
        if(RI)
        {
                RI = 0;
                recive[rec_num] = SBUF ;
                rec_num++;
                if((rec_num ==3)&&(recive[0] == 0x0f))//判断第一个数组
                {
                        checkXOR = recive[0]^recive[1];///异或一二数组
                        if(checkXOR == recive[2])    //与数组三比较
                        {
                                switch(recive[1])
                                {
                                                case  0x00:   
                                                  send();                                                                               
                                                rec_num = 0;
                                                break;
                                       
                                                case 0x01:
                                                send();                                               
                                                rec_num = 0;
                                                 break;
                                               
                                                case 0x02:
                                                send();
                                                rec_num = 0;
                                                break;
                               
                                                case  0x04:
                                                send();
                                                rec_num = 0;
                                                break;       
                                               
                                }       
                        }
                }
                if(TI)
                        {
                                TI = 0;
                        }
                }
}
void send()//发送函数
{
        uchar i;
        RS485_DIR=1;
        for(i=0;i<3;i++)                        //把数组给SBUF
        {
                SBUF = recive[i];
                delay(100);
        }
        RS485_DIR=0;
}



相关帖子

沙发
ningling_21| | 2017-4-28 11:38 | 只看该作者
delay(100);  这个延时时间够不够?

使用特权

评论回复
板凳
JerryWu75| | 2017-4-28 12:21 | 只看该作者
在你的send函数中,循环中deley(100)来发送下一个字节,这是MCU的硬件可能还没有把上一个字节发送完,你需要判断发送缓冲区是否已经空,发送是否已经完成,才能发送下一个字节。

同理,在send发送结束后,同样需要判断发送是否已经结束后,才能将RS485_DIR拉低。转入接收状态。

使用特权

评论回复
地板
ningling_21| | 2017-4-28 15:32 | 只看该作者
可换成不需控制收发的485芯片

使用特权

评论回复
5
baochen123456|  楼主 | 2017-4-28 16:30 | 只看该作者
JerryWu75 发表于 2017-4-28 12:21
在你的send函数中,循环中deley(100)来发送下一个字节,这是MCU的硬件可能还没有把上一个字节发送完,你 ...

谢谢您的解答,我把程序中的RS_485   0和1换了下,结果发送0F 01 0E 缓冲区变成了78 7F3C 这是怎么回事?

使用特权

评论回复
6
Lbsonggz| | 2017-4-28 23:07 | 只看该作者
接收中断处理的东西太多了,处理移入主函数,中断仅用于接收才符合MCU中断的含义和要求

使用特权

评论回复
7
前功尽弃| | 2017-4-30 10:19 | 只看该作者
void send()//发送函数
{
        uchar i;
        RS485_DIR=1;
        for(i=0;i<3;i++)                        //把数组给SBUF
        {
                SBUF = recive[i];
                delay(100);
        }
        RS485_DIR=0;
}
你把delay(100);这个延时放到循环外面试试

使用特权

评论回复
8
JerryWu75| | 2017-5-3 17:30 | 只看该作者
baochen123456 发表于 2017-4-28 16:30
谢谢您的解答,我把程序中的RS_485   0和1换了下,结果发送0F 01 0E 缓冲区变成了78 7F3C 这是怎么回事? ...

void send()//发送函数
{
        uchar i;
        RS485_DIR=1;
        for(i=0;i<3;i++)                        //把数组给SBUF
        {
                SBUF = recive;
                delay(100);
        }
        while(发送没有完成); //这这里加上判断发送是否已经结束
        RS485_DIR=0;
}

需要注意的是,发送结束应该是你的单片机内部UART的TX结束,不是你的软件发送结束。
另外在发送时,接收中断中不要接收数据。

使用特权

评论回复
9
baochen123456|  楼主 | 2017-5-12 19:04 | 只看该作者
Lbsonggz 发表于 2017-4-28 23:07
接收中断处理的东西太多了,处理移入主函数,中断仅用于接收才符合MCU中断的含义和要求 ...

谢谢,小弟,这几天出去搬砖了,没有及时表示感谢实在抱歉。谢谢了。

使用特权

评论回复
10
baochen123456|  楼主 | 2017-5-12 19:05 | 只看该作者
JerryWu75 发表于 2017-5-3 17:30
void send()//发送函数
{
        uchar i;

谢谢,小弟,这几天出去搬砖了,没有及时表示感谢实在抱歉。谢谢了。

使用特权

评论回复
11
baochen123456|  楼主 | 2017-5-12 19:05 | 只看该作者
前功尽弃 发表于 2017-4-30 10:19
void send()//发送函数
{
        uchar i;

谢谢,小弟,这几天出去搬砖了,没有及时表示感谢实在抱歉。谢谢了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

11

帖子

0

粉丝