打印
[AVR单片机]

AT90CAN128开发问题

[复制链接]
11550|27
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
胖兔子|  楼主 | 2007-4-5 22:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
shenshi| | 2007-4-6 12:15 | 只看该作者

给你一个例程参考下吧,这是我做的CAN测试程序

#include <avr/io.h>
#include <avr/signal.h>
#include <util/delay.h>

unsigned char can_transdata[8]={1,2,3,4,5,6,7,8};
unsigned char can_receivedata[8]={8,7,6,5,4,3,2,1};
unsigned char CanReceiveEndFlag;
InitCAN()
{
// CAN控制器 0# ,3# 信箱中断接收 ,1#、2#、4# 信箱发送数据 
  CANGCON |= (1<<SWRES);                                                        //CAN控制器软复位 
  CANBT1 = 0x0a;                                                                //设置波特率分频因子16MHz,16TQ,250k,=4=3+1,3 
  CANBT2 = 0x0c;                                                                //同步段为1“0x0n”传播段=7=6+1 
  CANBT3 = 0x37;                                                                //相位缓冲PH2=4=3+1,PH1=4=3+1 
  CANTCON = 0xff; 
//--------------can_MOB INITIAL------------------- 
//MOB0=RX[CMD]    接收上位机发来的指令       格式:3,0,0,177,239,33 
  CANPAGE  = 0x00;                                                              //MOB0,自动增量,初值为0 
  CANSTMOB = 0; 
  CANCDMOB = 0x18;                                                              //can2B,DLC=8 
  CANIDT4 = 0x30;                                                               // 00001 0xx 
  CANIDT3 = 0x00;                                                               // 01111 001              33 
  CANIDT2 = 0x41;                                                               // 10001 111             239 
  CANIDT1 = 0x00;                                                              // 01100 101             177 
  CANIDM4  = 0x00;                                                              //                             11111 100 
  CANIDM3  = 0x00;                                                              //                             11111 111 
  CANIDM2  = 0x00;                                                              //                             11111 111 
  CANIDM1  = 0x00; 
                                                               //CANIDM4-1数据校验屏蔽寄存器  00000 111 
  //MOB1=TX[STA1]  向上位机报告状态组1          6,0,0,178,239,33 
  CANPAGE = 0x10; 
  CANSTMOB = (1<<TXOK); 
  CANCDMOB = 0x18; 
  CANIDT4 = 0x30;                                                               // 00001 000 
  CANIDT3 = 0x80;                                                               // 01111 001              33 
  CANIDT2 = 0x00;                                                               // 10010 111             239 
  CANIDT1 = 0x20;                                                               // 11000 101             178 
                                                           
  CANGIE |= ((1<<ENIT) + (1<<ENRX));                                            //开全局中断 和 接收中断 
  CANIE2 |= 0x09;                                                               //开MOB3 & MOB0信箱接收中断(接收邮箱) 
  CANPAGE  = 0x00; 
  CANCDMOB |= 0x80;                                                             //MOB0接收使能                                                              //MOB3接收使能 
  CANGCON |= 0x02;                                                              //CAN控制器启动 
}
//中断函数     接收CAN数据帧 并 存入数据单元组 
//********************************************************** 
SIGNAL( CANIT_vect ) 

    unsigned char num_i;
    CANGIE &= ~(1<<ENRX);                  //关接收中断**** 
    CANPAGE = 0x00;                        //
    for(num_i = 0; num_i < 8; num_i++) 
    { 
      can_receivedata[num_i]=CANMSG;           //取得8个字节的数据 
    } 
 
    CANPAGE = 0x00; 
    CANSTMOB &= ~(1<<RXOK);                //清中断标志**** 
    CANCDMOB = 0x98;                       //接收使能 
                         //接收使能 
    CANGIE |= (1<<ENRX);                   //开中断 
    CanReceiveEndFlag=1;

//CAN数据帧发送 

void MOB_send (void) 

 // CANGIE &= ~(1<<ENRX); 
  unsigned int i; 

  CANPAGE = 0x10;                        //MOB1, auto increment, index 0 
  if (CANSTMOB & (1<<TXOK)) 
  { 
 // CANCDMOB= 0x18; 
  CANSTMOB &= ~(1<<TXOK); 
  for(i = 0; i < 8; i++)
  {
   CANMSG = can_transdata
  }
  CANCDMOB = 0x58;                               //帧发送 
  CANGIE |=(1<<ENRX); 
  } 


int main( void )
{
    InitCAN();
    PORTD    = 0xff;
    DDRD    = 0xa9;
//    MOB_send();
    sei();
    CANGIE |= 1<<ENRX;
    while(1)
    {
     if(CanReceiveEndFlag==1)
     {
        _delay_ms(1);
             MOB_send(); 
             CanReceiveEndFlag=0;
        }
     }
}

使用特权

评论回复
板凳
胖兔子|  楼主 | 2007-4-6 12:45 | 只看该作者

谢谢

谢谢绅士兄。这就看看

使用特权

评论回复
地板
胖兔子|  楼主 | 2007-4-6 13:14 | 只看该作者

AT90CAN128

绅士兄:
     我试了一下,但是不行。
     你给的例子 
CANBT1 = 0x0a;  //设置波特率分频因子16MHz,16TQ,250k,=4=3+1,3 
这句是0x0a是如何计算出来的?
我用的是外部晶振频率是11.0592,那么,在CAN中是如何设置的?
请赐教。

使用特权

评论回复
5
shenshi| | 2007-4-6 16:00 | 只看该作者

answer

我的注释中有些错误,我的CAN的波特率是125K的,我用的晶振是12M的,BT1、BT2、BT3的设置你要参考Datasheet中给的数值。11.0592的晶振可能会不可以。你不妨先用12M的测试一下,我这个程序在我的板子上没有问题,我两块板子可以互相收发。

使用特权

评论回复
6
胖兔子|  楼主 | 2007-4-6 16:19 | 只看该作者

只能参考Datasheet吗

BT1、BT2、BT3的设置只能参考Datasheet中给的数值吗?不能计算吗?


在串口中,开始我也是参考Datasheet中给的数值,后来我找了一个计算公式来计算波特率。方便了很多。
下面给出源码看大家能不能给出更好的思路。
在AT90CAN128中,我按照资料中说的来计算,怎么也算不出来。
再次谢谢大家。
#define fosc 11059200 //晶振 11.0592
/*******************************************************************************
*函数名:uart0_init                                                            *
*功  能:初始化串口1                                                              *
*参  数:baud                                                                  *
*支  持:300,600,1200,2400,4800,9600,19200,38400,56000,115200                  *
*******************************************************************************/
void uart0_init(long baud)
{

 UCSR0B = 0x00;  //设置波特率时关闭发送和接收
 UCSR0A = 0x00;
 UCSR0C = 0x06; //8位数据+1位STOP位
 UBRR0L=(fosc/16/(baud+1))%256;
 UBRR0H=(fosc/16/(baud+1))/256;//设置波特率
 UCSR0B =(1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0);//允许发送和接收,允许中断
}

使用特权

评论回复
7
shenshi| | 2007-4-6 16:29 | 只看该作者

answer

如果你的系统中既要用到CAN 又要用到串口的话,我建议你还是把晶振的频率改为12M吧。CAN对晶振的要求要比串口高很多。你给出的双龙的初始化串口的例程对于CAN来说没有意义。我觉得你还是将就一下CAN吧。我们就是这样做的

使用特权

评论回复
8
胖兔子|  楼主 | 2007-4-6 16:49 | 只看该作者

12晶振问题

绅士兄:
     如果我用12Mhz的晶振,串口通讯就会出现一系列问题,因为我的串口要与其它的设备通讯,必须保证误差等于0%,如果用整数倍的晶振,与其它设备的通讯就不能正常工作。
     刚才我重新配置了熔丝位,使用了内部8Mhz的晶振,按照DataSheet中给出的数值编译后,还是无法进行通讯。(手头没有12Mhz的晶振)

使用特权

评论回复
9
shenshi| | 2007-4-6 17:03 | 只看该作者

回答:

你用内部8M晶振的话,你要把BT1、BT2、BT3的设置要改下,DATASHEET中提供了06、DC、37你可以去看下。另外12M晶振的话,串口通信虽然有些误差,但是它是异步的,一个字节就调整的。我按照你的方法在我的板子上测试下,一会再回答你。

使用特权

评论回复
10
shenshi| | 2007-4-6 17:18 | 只看该作者

回答

说明下:8M晶振的设置BT1、BT2、BT3 的设置DATASHEET中是06、0C、37。
我测试了下这个程序在12M很正常,在8M的情况下,就是不停的在发。
你先把测试程序改动下,把收中断标志屏蔽下,先让板子处于一直发送的状态,你再看看发送引脚是否有波形。

使用特权

评论回复
11
zsmbj| | 2007-4-7 08:42 | 只看该作者

如用can和串口,建议用12M晶体吧。

CAN对时钟要求比较高,一般要选择晶振,不能用内部RC。晶振一般是16,12,8M等。如果要兼顾串口。12M是最好的选择,115200,57600,38400,28800,19200,14400,9600,4800,2400等误差只有0.2%,通讯完全没有问题。  8M也不错。不过57600和115200误差太大,不能使用。

串口误差不要大于2%,实际不大于0.5%完全没有问题。可以放心使用。

使用特权

评论回复
12
胖兔子|  楼主 | 2007-4-7 17:22 | 只看该作者

谢谢

我去买个12Mhz的晶振

使用特权

评论回复
13
胖兔子|  楼主 | 2007-4-10 16:45 | 只看该作者

CAN还是不通

绅士兄:
12Mhz晶振装上了。还是不行。为什么????????????

另外:我用来测试的CAN板是市场上买回来的。它与其它CAN设备通讯是正常的。

//     格式:3,0,0,177,239,33 
在你给的例子中,上面这句话的意思是什么??

网络主机地址
网络从机地址与回复主机地址又是如何设置的?


 

使用特权

评论回复
14
shenshi| | 2007-4-11 10:30 | 只看该作者

回复

绅士兄:
12Mhz晶振装上了。还是不行。为什么????????????

另外:我用来测试的CAN板是市场上买回来的。它与其它CAN设备通讯是正常的。

//     格式:3,0,0,177,239,33 
在你给的例子中,上面这句话的意思是什么??

网络主机地址
网络从机地址与回复主机地址又是如何设置的?


回答: //     格式:3,0,0,177,239,33 这个数据是没有意义的,主要是设置29位标识符的,对测试来说没有意义,MOB0中的屏蔽CANIDM都已经设置成了0,所以对方发来的数据不会屏蔽的.至于你说的网络的主机地址和从机地址,那应该是协议的问题,应该是设置CANIDT来完成的.

不通的话,你先查查硬件上数据是否到了单片机的接收引脚,每位时间是否是8us,有的时候因为线路上器件的延时,高电平的时间可能会小于8us,如果硬件上没问题,那就用仿真器跑下,看看是否进中断以及看下CAN寄存器的值时候正常

另外你可以先看发送程序是否能运行,

使用特权

评论回复
15
胖兔子|  楼主 | 2007-4-17 10:03 | 只看该作者

提问

绅士兄:
    前几天身体不适,一直没有上网。今天看见你给的回答了。


    你给我的例子在仿真器中运行的正常。


    在AT90CAN128的输出脚上有信号。但到了PCA82C250的CANH、CANL,没有变化了。
    这个电路我是按SJA1000的做的。不知对不对。

使用特权

评论回复
16
胖兔子|  楼主 | 2007-4-27 12:31 | 只看该作者

哈哈

自己顶

使用特权

评论回复
17
migzan| | 2007-5-20 21:10 | 只看该作者

请教shenshi

绅士兄:你的程序我试验下,也是不行,和楼主的情况一样

我也搞了好多天了,没头绪

希望能指点下

使用特权

评论回复
18
simon21ic| | 2007-5-21 11:09 | 只看该作者

建议参考一下Atmel提供的代码

RT

使用特权

评论回复
19
胖兔子|  楼主 | 2007-5-28 13:26 | 只看该作者

CAN的问题出哪了

休整N天,今天重新整CAN


在网上看了多位大大的例子与绅士兄给的差不多。

所以我觉得是我的电路图出了问题,但不但在哪。

我把我的图发上来,大家帮着看看。

使用特权

评论回复
20
shenshi| | 2007-6-11 17:19 | 只看该作者

huifu

8脚上的斜率电阻我们一般选择的是20K,当正常时,8脚的电压为0.4VCC到0.6VCC, 如果8脚的电压是5v的话,则进入待机模式,输出被关闭。你好好量下上面的电压。

使用特权

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

本版积分规则

1

主题

10

帖子

2

粉丝