打印
[AVR单片机]

ATmega16A使用485进行通信,无**常收发数据,求帮助

[复制链接]
1555|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
chongchudb|  楼主 | 2015-9-19 11:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
来自 2楼
SD10A| | 2015-9-21 21:40 | 只看该作者
程序我写了,用ICCAVR6  编译通过  
你可以修改一下晶振频率和波特率试验一下




#include "iom16v.h"
#include "macros.h"
#define  uchar unsigned char
#define  uint  unsigned int
//波特率,晶振
#define BAUD 19200                                       
#define FXTAL 12000000UL

#define  RS485EN_DDR DDRD|=BIT(PD4)
#define  RS485_EN    PORTD|=BIT(PD4)
#define  RS485_UNEN  PORTD&=~BIT(PD4)

//*******************
//延时函数 用的8MHZ标准的
//
//*******************
void delay (uint ms)
                {
                uint i,j;
                for(i=0;i<ms;i++)
                 {
                 for(j=0;j<1141;j++);
                 }
                }

//串口初始化函数
//*******************
//串口初始化函数
//注意波特率和晶振在最先的定义上设置好
//1停止位 8数据位  无奇偶校验
//*******************
void USART_Init()
{        
        unsigned int Temp;
        RS485EN_DDR;//使能端口设置成输出       
                UCSRA=0x00;                                                                        //串口控制器A清零
                UCSRB=0x00;                                                                        //串口控制器B清零
                UCSRC|=BIT(URSEL)|BIT(UCSZ1)|BIT(UCSZ0);        //选择USCRC,异步操作,1个停止位,八位数据
                Temp=(FXTAL/BAUD/16)-1;                        //求出9600波特率的赋值
                UBRRH=((Temp>>8)&0x00ff);                //波特率寄存器高八位赋值
                UBRRL=(Temp&0x00ff);                        //波特率寄存器低八位赋值
       
                //UBRR=71;        //从手册中直接取得赋值,9600kbps
                UCSRB|=BIT(TXEN)|BIT(RXEN);        //发送使能,接收使能,
}

/**********发送函数***********/
void uart_sendB(uchar data)
{
RS485_EN;
while(!(UCSRA&(BIT(UDRE))));                //数据寄存器UDR是否为空?
UDR=data;                                                        //UDR赋值
while(!(UCSRA&(BIT(TXC))));                        //数据是否已经发送完毕?
UCSRA|=BIT(TXC);                    //清除发送完毕标志位
RS485_UNEN;                                       
}
/**********主函数**************/
void main()
{         
     uchar i = 4;
     uchar j = 'a';
     USART_Init();    // 初始化
         while(1)
         {    uart_sendB(i);  delay(10);                                      
                          uart_sendB(j);  delay(10);                           
              uart_sendB(i);  delay(10);                           
              uart_sendB(j);  delay(10);                           
        }
}

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
chongchudb + 1 谢谢啊,这个是对的,我的发送也终于改出来.
板凳
chongchudb|  楼主 | 2015-9-19 12:03 | 只看该作者

#include <iom16v.h>
#include <macros.h>
#define  uchar unsigned char
#define  uint  unsigned int
#define  XTAL   8                                                     

/********延时函数*******************/
void delay(uint ms)
{          uint i,j;
         while(i < ms)
         {
                    for(j = 1; j < (uint)(XTAL*143-2); j++);
                    i++;
         }
}       
/*************波特率设置***********************/
void uart_init(void)
{          UCSRB = 0x00;                                                                                                                                         
         UCSRA = 0x00;                               
         UCSRC = 0x00;                               
         UBRRH = 0x00;                                                                                                                        
         UBRRL = 0x33;                                                                                                                                                                                         
         UCSRB = 0x98;                                               
     SREG = BIT(7);                     
     DDRD |= 0X02;                   
}

void init_devices(void)
{
         CLI();
         uart_init();
         MCUCR = 0x00;
         GICR  = 0x00;
         TIMSK = 0x00;                              
         SEI();                                   
}


/**********发送函数***********/
void uart_sendB(uchar data)
{          while(!(UCSRA&(BIT(UDRE)))) ;                         
         UDR = data;                                                          
}


/**********主函数**************/
void main()
{          uchar i = 4;
         uchar j = 'a';
         init_devices();                              // 初始化

         PORTD = 0x03;                                 // PD端口初始化0000 0011
         DDRD = 0xFF;                                // 输出
                  
         while(1)
         {    uart_sendB(i); delay(10);                          
                             uart_sendB(j);  delay(10);                          
                  uart_sendB(i);        delay(10);                          
                             uart_sendB(j);   delay(10);                          
        }
}

使用特权

评论回复
地板
SD10A| | 2015-9-19 14:43 | 只看该作者
本帖最后由 SD10A 于 2015-9-19 14:58 编辑

  UCSRC = 0x86;

使用特权

评论回复
5
hebeijiang| | 2015-9-19 14:47 | 只看该作者
在主函数中将 PD端口初始化0000 0001 或 PD端口初始化0000 0010,试一下。
要学会将问题分解,485芯片有没输出,485芯片需要输入什么信号才会输出,单片机的对应管脚有没信号输出,哪个信号没有,...

使用特权

评论回复
6
SD10A| | 2015-9-20 10:42 | 只看该作者
还有个问题     485有个使能端   你这边怎么没有》?

使用特权

评论回复
7
chongchudb|  楼主 | 2015-9-20 16:43 | 只看该作者
SD10A 发表于 2015-9-20 10:42
还有个问题     485有个使能端   你这边怎么没有》?

对,之前没注意,我照你的UCSRC=0x86改了。
使能端是PD4,我现在改了,         PORTD = 0x12;        只不过还是不行。。。

使用特权

评论回复
8
SD10A| | 2015-9-20 19:31 | 只看该作者
chongchudb 发表于 2015-9-20 16:43
对,之前没注意,我照你的UCSRC=0x86改了。
使能端是PD4,我现在改了,         PORTD = 0x12;        只不过还是不行。 ...

还有对于这两个IO  是不需要专门的  设置成输入和输出的

使用特权

评论回复
9
chongchudb|  楼主 | 2015-9-20 20:30 | 只看该作者
SD10A 发表于 2015-9-20 19:31
还有对于这两个IO  是不需要专门的  设置成输入和输出的

我的PD1接的是TXD串口输出,PD0接的是RXD串口输入。还有使能端PD4接的是DE和RE反,所以,PORTD=0x12。(0001 0010)。不过数据依旧没有发送出来,不知道怎么搞的?:'(
如果程序没问题的话,我打算用示波器看看A、B口输出的波形,只不过知道输出什么样的波形才算是对的。。
可以帮我指点一二吗,谢谢了啊:'(

使用特权

评论回复
10
ningling_21| | 2015-9-21 18:19 | 只看该作者
485收发需要控制

使用特权

评论回复
11
SD10A| | 2015-9-21 21:49 | 只看该作者
如果波特率不是很正确的话 你可以用ICCAVR 的魔法棒自动计算下数值 直接写UBRRH  UBRRL

使用特权

评论回复
12
元方义城| | 2015-9-22 12:58 | 只看该作者
485发送与接收控制口,可以连接在一起用一个IO控制。这样直接确定,要么接收要么发送。就不乱了

使用特权

评论回复
13
chongchudb|  楼主 | 2015-9-22 18:27 | 只看该作者
元方义城 发表于 2015-9-22 12:58
485发送与接收控制口,可以连接在一起用一个IO控制。这样直接确定,要么接收要么发送。就不乱了 ...

嗯嗯,是PD4口,使能端,后来改了:P

使用特权

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

本版积分规则

3

主题

13

帖子

0

粉丝