搜索
bottom↓
回复: 38

M128不能操作sja1000实现can通信!!!

[复制链接]

出0入0汤圆

发表于 2008-7-29 09:32:41 | 显示全部楼层 |阅读模式
我用的是ATmage128+sja1000做的can总县通信,我的sja1000的片选接在PD7口,
下面是SJA1000的初始化程序:
#define REG_CONTROL (*(volatile unsigned char *)0x0100)
#define REG_COMMAND (*(volatile unsigned char *)0x0101)
#define REG_STATUS (*(volatile unsigned char *)0x0102)
#define REG_IR (*(volatile unsigned char *)0x0103)
#define REG_ACR (*(volatile unsigned char *)0x0104)
#define REG_AMR (*(volatile unsigned char *)0x0105)
#define REG_BTR0 (*(volatile unsigned char *)0x0106)
#define REG_BTR1 (*(volatile unsigned char *)0x0107)
#define REG_OCR (*(volatile unsigned char *)0x0108)  

#define REG_CDR (*(volatile unsigned char *)0x011F)



void sja_init()
{
    REG_CONTROL=0x01;
        while((REG_CONTROL&0x01)==0)
        {
           REG_CONTROL=0x01;
        }
        REG_CDR=0x48;
    REG_ACR=0x11;
    REG_AMR=0x00;
    REG_OCR=0xaa;
    REG_BTR0=0x00;
    REG_BTR1=0x1c; //500kbps
    REG_CONTROL=0x1E;  //进入操作模式
        while((REG_CONTROL&0x01)==1)
        {
           REG_CONTROL=0x1E;
        }
}

请教各位高手,我的问题是数据没有写入进去,也没有读取到寄存器里面的值(通过LED显示实现),请问这个问题怎么解决啊,谢谢!!
难道是我的sja1000的CS必须接在PC7(A15)口吗???

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2008-7-29 17:04:28 | 显示全部楼层
我做过CAN总线的程序
你的CAN的片选是连在PC7吧?
你开了外部存储区使能了么?
MCUCR |= 0x80;

出0入0汤圆

 楼主| 发表于 2008-7-29 18:19:54 | 显示全部楼层
我是连在PD7,我开了外部存储区使能啊
另外在ICCAVR中编译时,在project-》option中需要选择存储区吗?还是默认的internal SRAM呢

出0入0汤圆

发表于 2008-7-30 06:42:10 | 显示全部楼层
瞎说,我一直在用!哪个口线都接过,搞开发要有耐心。

出0入0汤圆

发表于 2008-7-30 08:22:26 | 显示全部楼层
标题党

出0入0汤圆

发表于 2008-7-30 09:14:41 | 显示全部楼层
你的地址线怎么连接的,为什么CAN的地址都是100起始的呢?建议你把部分相关的图传上来。这样 也好让大家帮忙分析呀

出0入0汤圆

 楼主| 发表于 2008-7-30 10:26:26 | 显示全部楼层
我是把sja1000的AD0~AD7连接到M128的PA口,片选连在PD7口,用的是上电自动复位,ALE、RD、WR分别连接在相应的IO口

出0入0汤圆

发表于 2008-7-30 14:32:22 | 显示全部楼层
这样似乎不可以吧?
如果按你的接法,CAN的地址不该是0x100开始,该是0x0000开始的
而M128的存储器的0~4K+256部分是分配给内部SRAM,所以尽管你的程序看来是在访问CAN的存储器,实际上是在访问内部的RAM。建议是把CAN的片选接在PC口的高位。至少在PC5。

你试试吧,有进展了说一声呀

出0入0汤圆

发表于 2008-7-30 15:19:13 | 显示全部楼层
我用M16加SJA1000也很好用.

出0入0汤圆

发表于 2008-7-30 15:33:15 | 显示全部楼层
呵呵,不在于用什么驱动SJA1000.M16也好,128也好,道理是一样的,楼主的存储区设置的有些问题

出0入0汤圆

 楼主| 发表于 2008-7-30 21:31:07 | 显示全部楼层
8楼的哥们  你M16通拉  不是要模拟时序吗?
我也弄过,也没搞通。
但是M128中,SJA1000的片选不一定要接在PC口啊

出0入0汤圆

 楼主| 发表于 2008-7-30 21:33:22 | 显示全部楼层
各位大侠  能不能给小弟点代码参考一下呢,急啊。
hm-xiao@live.cn

谢谢!

出0入0汤圆

发表于 2008-7-31 08:48:37 | 显示全部楼层
不是你的代码有问题
你的问题在硬件上。跟你说过了,你的接法CAN地址是0x0000起始的,访问时实际上是访问的SRAM。
外设的片选是不一定在C口,但是你应该注意到CAN的地址是0x0000起始的,跟单片机的SRAM重叠了。
你看看M128的手册,只看存储器那章,看完你就明白了

出0入0汤圆

发表于 2008-7-31 08:57:30 | 显示全部楼层
【10楼】 xhming
是模拟的,感觉速度还可以,

出0入0汤圆

发表于 2008-7-31 09:08:37 | 显示全部楼层

(原文件名:DSCF2021.JPG)

出0入0汤圆

发表于 2008-7-31 09:10:20 | 显示全部楼层
osoun
你的板子真漂亮~~~!!

出0入0汤圆

发表于 2008-7-31 09:18:30 | 显示全部楼层
void caninit()
{ uchar tx_number=0,ca;
  asm("cli");    //禁用所有中断,
   clr_can_rst;
   delay(10);
   set_can_rst;  //复位SJA1000
   
   while(read_data(con_reg)&0x01==0) //请求复位,
{ write_data(con_reg,0x01);
    tx_number++;
    if(tx_number==250)
    {   tx_number=0;
      rssend('c');
      rssend('i');
        rssend('e');
     printf("can rest erro\n");
            goto erro; }         
                        }
//-----------------复位成功设置参数----------------------//
   write_data(tm0_reg,0x09);
   write_data(tm1_reg,0x14);
   // rssend(read_data(tm0_reg));////
   write_data(out_reg,0x1e);
   write_data(clk_reg,0x14);
   write_data(acr_reg,0x60);
   write_data(amr_reg,0xdf);
   ca=read_data(con_reg);
   write_data(con_reg,(ca|0x0a));
  // rssend('m');
   rssend(read_data(con_reg));
//---------------------退出复位模式--------------------//
                 tx_number=0;
          do{   ca=read_data(con_reg);
              write_data(con_reg,(ca&0xfe));
                  tx_number++;
                if(tx_number==250)
                {
                      tx_number=0;
                    printf("can rest erro\n");
                        // rssend('k');
                     goto erro;
                                  }
                                  }
    while(read_data(con_reg)&0x01!=0);
//---------------------成功退出发送串口提示-------------------------  
    //  printf("sja1000 init over\n");
         // rssend('o');
  
   
erro: asm("sei"); //   不成功,提示.
                 }
//============================================================================//

出0入0汤圆

 楼主| 发表于 2008-7-31 10:55:47 | 显示全部楼层
mingyuexin1981

你说我的硬件有问题(是我的接线有问题?)?还是我定义地址的时候有问题呢
能不能说详细点啊   谢谢

出0入0汤圆

发表于 2008-7-31 11:14:03 | 显示全部楼层
你看我在7楼的回复吧

出0入0汤圆

 楼主| 发表于 2008-7-31 15:13:51 | 显示全部楼层
osoun   你的M16和sja1000的接法是怎么样的啊
sja1000的复位脚你接在什么地方呢

出0入0汤圆

发表于 2008-7-31 16:14:31 | 显示全部楼层
//============================================================================//
//       AD0-AD7  ----------  PORTC
//           ALE  ----------  PD7
//            WR  ----------  PD5
//            RD  ----------  PD6      
//        CAN RST ----------  PD4
//        CAN INT ----------  PD3
//           LED1 ----------  PD2
//============================================================================//
//
//
//============================================================================//
#include <stdio.h>
#include <ioavr.h>
#include <intrinsics.h>

#define uchar unsigned char
#define uint  unsigned int

#define set_ale  PORTD|=0X80
#define clr_ale  PORTD&=0X7F
#define set_wr   PORTD|=0X20
#define clr_wr   PORTD&=0XdF
#define set_rd   PORTD|=0X40
#define clr_rd   PORTD&=0XbF

#define  ledon  PORTD&=0XFB
#define  ledoff  PORTD|=0X04
  
#define clr_can_rst   PORTD&=0XEF
#define set_can_rst   PORTD|=0X10

//---------------BAsic CAN BUS------------------//
#define  con_reg    0x00
#define  com_reg    0x01
#define  sta_reg    0x02
#define  int_reg    0x03
#define  acr_reg    0x04
#define  amr_reg    0x05
#define  tm0_reg    0x06
#define  tm1_reg    0x07
#define  out_reg    0x08
#define  tex_reg    0x09
#define  txid1      0x0a
#define  txid2      0x0b
#define  txdata1    0x0c
#define  txdata2    0x0d
#define  txdata3    0x0e
#define  txdata4    0x0f
#define  txdata5    0x10
#define  txdata6    0x11
#define  txdata7    0x12
#define  txdata8    0x13
#define  rxid1      0x14
#define  rxid2      0x15
#define  rxdata1    0x16
#define  rxdata2    0x17
#define  rxdata3    0x18
#define  rxdata4    0x19
#define  rxdata5    0x1a
#define  rxdata6    0x1b
#define  rxdata7    0x1c
#define  rxdata8    0x1d
#define  clk_reg    0x1e

//................................................//

出0入0汤圆

发表于 2008-7-31 16:23:44 | 显示全部楼层
因为要装到一个小外壳里, 所以只好用手头上有的M16(是贴片的),如果有M128的话,还是尽量挂总线上吧,那样速度快些.
      我的CS接到地,M16,SAJ1000各用一个晶体,

出0入0汤圆

 楼主| 发表于 2008-7-31 16:49:21 | 显示全部楼层
真的很奇怪啊  我的CS接在PC7,复位接在PC6, AD0~AD7接在PA口。ALE、WR、RD分别接在PD7~PD5,PC0~PC5接LED,可是怎么也不对
#include "iom16v.h"
#include "stdio.h"
#include "macros.h"

#define uint unsigned int
#define uchar unsigned char

#define REG_CONTROL 0x00
#define REG_COMMAND 0x01
#define REG_STATUS 0x02
#define REG_IR 0x03
#define REG_ACR 0x04
#define REG_AMR 0x05
#define REG_BTR0 0x06
#define REG_BTR1 0x07
#define REG_OCR 0x08

#define REG_TxBuffer1 0x0A
#define REG_TxBuffer2 0x0B
#define REG_TxBuffer3 0x0C
#define REG_TxBuffer4 0x0D
#define REG_TxBuffer5 0x0E
#define REG_TxBuffer6 0x0F
#define REG_TxBuffer7 0x10
#define REG_TxBuffer8 0x11
#define REG_TxBuffer9 0x12
#define REG_TxBuffer10 0x13

#define REG_RxBuffer1 0x14
#define REG_RxBuffer2 0x15
#define REG_RxBuffer3 0x16
#define REG_RxBuffer4 0x17
#define REG_RxBuffer5 0x18
#define REG_RxBuffer6 0x19
#define REG_RxBuffer7 0x1A
#define REG_RxBuffer8 0x1B
#define REG_RxBuffer9 0x1C
#define REG_RxBuffer10 0x1D

#define REG_CDR 0x1F

uchar RcvBuf[20];
uchar SendBuf[20];
uchar kaiguaninfo[8]={0x55,0x00,0x55,0x00,0x55,0x00,0x55,0x00};
void delay(int j)
{
        unsigned int i;
        while(j>0)
        {
                for(i=1000;i>0;i--)
                {}
                j--;
        }
}

void port_init(void)
{  
   DDRB=0x00;
   PORTB=0x00;
   DDRC=0xFF;
   PORTC=0x7f;
   DDRD=0xf0;
   PORTD=0xff;      
}

void init_MCU(void)
{
  UBRRH=0;
  UBRRL=47;//设置波特率9600  7.783M晶振
  UCSRB=0xd8;
  UCSRC=0x86;
  
  MCUCR|= 0x0c;//INT0使能,低电平触发中断
                //INT1使能,上升沿触发中断
  MCUCSR|= 0x00;
  GICR=0xc0;//开启外部中断0和1
  //SEI();
}

//以address为地址,从sja1000中读取一个字节
uchar read(uchar address)
{
   uchar mid,i;
   PORTC&=~BIT(7);  //片选信号有效
   PORTD|=BIT(7);   //置ALE为1
   DDRA=0xff;       //设置A口为输出
   PORTA=address;   //A口输出地址
   PORTD&=~BIT(7);  //置ALE为0
   DDRA=0x00;       //设置A口为输入
   PORTD&=~BIT(5);  //读信号有效
   PORTD|=BIT(5);   //读信号置1
   PORTC|=BIT(7);   //片选信号置1
   return mid;
}

//以address为地址,向sja1000中写一个字节
void write(uchar address,uchar x)
{  
   uchar i;
   PORTC&=~BIT(7); //片选信号有效
   PORTD|=BIT(7);  //置ALE为1
   DDRA=0xff;     //设置A口为输出
   PORTA=address; //A口输出地址
   PORTD&=~BIT(7); //置ALE为0
   PORTD&=~BIT(6); //写信号有效
   PORTA=x;      //A口输出数据  
   PORTD|=BIT(6);  //写信号置1
   PORTC|=BIT(7);  //片选信号置1  
}

void CAN_RESET(void)
{
   PORTC&=~BIT(6);
   delay(10);
   PORTC|=BIT(6);   
   CLI();
   while((read(REG_CONTROL)&0x01))
   PORTC&=~0x01;(LED)
   write(REG_CONTROL,0x01);
   write(REG_CDR,0x48);
   write(REG_ACR,0x01);
   write(REG_AMR,0x00);
   write(REG_OCR,0xaa);
   write(REG_BTR0,0x01);
   write(REG_BTR1,0x1c);
   write(REG_CONTROL,0x1E);
   while(((read(REG_CONTROL))&0x01)==1)
   {  
      write(REG_CONTROL,0x1E);
      PORTC&=~0x02;//(LED)
   }
   SEI();
}
//读取can寄存器数据
uchar CAN_ReadRegister(uchar RegIndex)
{
   return(read(RegIndex));
}

void SendData(void)
{
    uchar datalong;
        uint i;
        if((CAN_ReadRegister(REG_CONTROL)&0x01)==0)
        {
          SendBuf[0] = 0x11;
          SendBuf[1] = 0x28;
          for (i=0; i<8; i++)
              SendBuf[i+2]=kaiguaninfo;                                       
          if((CAN_ReadRegister(REG_STATUS)&0x10)!=0)
          {          
                if((CAN_ReadRegister(REG_STATUS)&0x08)==0x08)
                {
                  if((CAN_ReadRegister(REG_STATUS)&0x04)==0x04)
                  {       
                        write(REG_TxBuffer1,SendBuf[0]);
                        write(REG_TxBuffer2,SendBuf[1]);
                        write(REG_TxBuffer3,SendBuf[2]);
                        write(REG_TxBuffer4,SendBuf[3]);
                        write(REG_TxBuffer5,SendBuf[4]);
                        write(REG_TxBuffer6,SendBuf[5]);
                        write(REG_TxBuffer7,SendBuf[6]);
                        write(REG_TxBuffer8,SendBuf[7]);
                        write(REG_TxBuffer9,SendBuf[8]);
                        write(REG_TxBuffer10,SendBuf[9]);
                  }
                       write(REG_COMMAND,0x01);
                    PORTC&=~0x04;        //(LED)                 
                }
          }                 
        }
        else
        {
                printf("SJA1000 is working as Reset Mode!\n");
                CAN_RESET();
        }
}
可是怎么也不对啊,sja1000的初始化里面寄存器写值就不对,帮我看下是怎么回事,谢谢!

出0入0汤圆

发表于 2008-7-31 17:00:18 | 显示全部楼层
你的熔丝都设的对吗,JTAG功能关了吗.

出0入0汤圆

 楼主| 发表于 2008-7-31 20:01:41 | 显示全部楼层
JTAG关拉  容丝位没问题啊

你能否把你的原理图和程序给我参考下呢

出0入0汤圆

发表于 2008-7-31 20:19:15 | 显示全部楼层
最好采用硬复位

出0入0汤圆

 楼主| 发表于 2008-7-31 20:21:58 | 显示全部楼层
你是说上电自动复位吗?

出0入0汤圆

发表于 2008-8-1 08:45:04 | 显示全部楼层
你为什么不用外部总线的方式
你开始的时候怎么不说是模拟外部总线的方式阿
我之前的话都是白说了

出0入0汤圆

 楼主| 发表于 2008-8-1 12:56:19 | 显示全部楼层
楼上的兄弟  我上面的是M16的

M128的我是用外部总线的

出0入0汤圆

发表于 2008-8-1 15:01:28 | 显示全部楼层
你用外部总线了
pc7连CAN片选
Pc6连CAN复位
你读写CAN寄存器的时候会不会把CAN复位了
我去年做过M128的CAN驱动,也调通了
有时间发个图和程序给你吧

出0入0汤圆

 楼主| 发表于 2008-8-1 15:11:03 | 显示全部楼层
好的  非常感谢你,我的油箱是hm-xiao@live.cn

出0入0汤圆

发表于 2008-8-1 15:19:14 | 显示全部楼层
可以同事发给我看看吗?我也正在学习CAN通讯。谢谢了!whuctx@163.com

出0入0汤圆

 楼主| 发表于 2008-8-2 12:54:21 | 显示全部楼层
mingyuexin1981  你好
有时间发给我一份你的原理图和程序,谢谢!
我的油箱是:hm-xiao@live.cn

出0入0汤圆

 楼主| 发表于 2008-8-4 17:40:27 | 显示全部楼层
mingyuexin1981  你好
有时间发给我一份你的原理图和程序,谢谢!
我的油箱是:hm-xiao@live.cn

出0入0汤圆

发表于 2008-8-29 17:10:48 | 显示全部楼层
很无私的人嘛!我先自己试一下,不行再找你!哈哈!

出0入0汤圆

发表于 2009-4-25 20:47:29 | 显示全部楼层
大侠们,谁要M64+sja1000调好的程序呀,能不能给小弟发一份参考一下,谢谢了!
邮箱:hpuzw@qq.com

出0入0汤圆

发表于 2011-9-27 17:16:57 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-11-15 19:55:03 | 显示全部楼层
回复【29楼】mingyuexin1981  
-----------------------------------------------------------------------

你好  我想问问你还有mega128的程序吗   can通讯的呀 谢谢呀  269880390@qq.com

出0入0汤圆

发表于 2013-12-3 14:46:51 | 显示全部楼层
osoun 高人 能否可以把你的原程序发上来呀,让大家看看好吧 
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 22:19

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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