搜索
bottom↓
回复: 1

求救M128与sja1000的自收发程序问题

[复制链接]

出0入0汤圆

发表于 2014-3-6 20:31:11 | 显示全部楼层 |阅读模式
#include <mega128.h>  
#define uchar unsigned char
#define uint unsigned int
#define clk   16000000  
#define  sja_baseaddr 0x4000  
#define  MODE       0x00
#define  CMR       0x01
#define  SR        0x02
#define  IR        0x03
#define  IER       0x04
#define  BTR0      0x06
#define  BTR1      0x07
#define  OCR       0x08
#define  RXERR     0x0E      //接收错误计数器
#define  TXERR     0x0F      //发送错误计数器
#define  ACR0      0x10
#define  ACR1      0x11
#define  ACR2      0x12
#define  ACR3      0x13
#define  AMR0      0x14
#define  AMR1      0x15
#define  AMR2      0x16
#define  AMR3      0x17
#define  RMC       0x1D          //RX报文计数器
#define  RBSA      0x1E          //接收缓冲区起始地址
#define  CDR       0x1F  
//发送缓冲器      
#define TXbuffer0     0x10
#define TXbuffer1     0x11
#define TXbuffer2     0x12
#define TXbuffer3     0x13
#define TXbuffer4     0x14
#define TXbuffer5     0x15
#define TXbuffer6     0x16
#define TXbuffer7     0x17
#define TXbuffer8     0x18
#define TXbuffer9     0x19
#define TXbuffer10    0x1A
#define TXbuffer11    0x1B
#define TXbuffer12    0x1C
   
  // 接收缓冲器                                                                                                               
#define Rxbuffer0        0x10                                                                                                      
#define Rxbuffer1        0x11
#define Rxbuffer2        0x12
#define Rxbuffer3        0x13
#define Rxbuffer4        0x14
#define Rxbuffer5        0x15
#define Rxbuffer6        0x16
#define Rxbuffer7        0x17
#define Rxbuffer8        0x18
#define Rxbuffer9        0x19
#define Rxbuffer10       0x1A
#define Rxbuffer11       0x1B               
#define Rxbuffer12       0x1C  
  void uart_send(uchar data);  
  uchar *sja_address;
  uchar read_sja( uchar addr)                  //读SJA1000状态寄存器子程序
  {
        sja_address=(uchar *)sja_baseaddr;
        sja_address=sja_address+addr;
        return (*sja_address);                    
  }

void write_sja(uchar addr,uchar val)            //写SJA1000寄存器子程序
{   
      
       sja_address=(uchar *)sja_baseaddr;
       sja_address=sja_address+addr;
       *sja_address=val;
}
                                   
                                                     
void delay(uint x)
{
   uint i,j;
   for(i=x;i>0;i--)
   {
     for (j=1000;j>0;j--);
   }
}   
   
   void  can_read()
   {  
     uchar a[13];
     int i;
       a[0]=read_sja(Rxbuffer0);
       a[1]=read_sja(Rxbuffer1);
       a[2]=read_sja(Rxbuffer2);
       a[3]=read_sja(Rxbuffer3);
       a[4]=read_sja(Rxbuffer4);
       a[5]=read_sja(Rxbuffer5);
       a[6]=read_sja(Rxbuffer6);
       a[7]=read_sja(Rxbuffer7);
       a[8]=read_sja(Rxbuffer8);
       a[9]=read_sja(Rxbuffer9);
       a[10]=read_sja(Rxbuffer10);
       a[11]=read_sja(Rxbuffer11);
       a[12]=read_sja(Rxbuffer12);  
       write_sja(CMR,0X04);            //release RXbuffer   
      
        for(i=0;i<13;i++)
        {
         uart_send(a[i]);
        }
    }   
  
/*interrupt [2]  void ex0()
{   
   if(IR&0x01==0x01)      //产生了接收中断  
    can_read();
}    */

void uart_send(uchar data)
{
  while (!UCSR0A.5 );     //判断发送缓冲器是否准备好接收新数据                                                  
  UDR0 = data;            //发送数据      
}      

void mcu_init()
{
  UBRR0H=((clk/16/9600)-1)/256;            //波特率设置                              
  UBRR0L=((clk/16/9600)-1)%256;
  UCSR0B=0x18;         //接收和发送使能
  UCSR0C=0x06;         //数据帧位数   
  MCUCR=0x80;          //允许外部并行扩展接口
  SREG=0x00;           //关总中断
  EIMSK=0x01;       //外部中断0使能
  EICRA=0x02;          //INT0下降沿产生中断请求
  
}      
                     
/*
***** **************************************
函数功能:初始化sja1000
内容:复位、波特率设置、开放中断等等
*******************************************
*/
                                          
void sja1000_init()
{  
   write_sja(MODE,0x01);                //进入复位模式
   while(!(read_sja(MODE)&0x01))        //检测SJA1000是否达到复位模式
        {
           write_sja(MODE,0x01);                //进入复位模式
        }   
        delay(500);
   write_sja(CMR,0x12);                 //自收自发  
   write_sja(MODE,0x08);                //单滤波器
   write_sja(IER,0x01);                 // 接收中断使能
   write_sja(RBSA,0x00);                        //缓存器起始地址寄存器设置为0
   write_sja(RXERR,0x00);                       
   write_sja(TXERR,0x00);
   write_sja(IR,0x00);
   write_sja(ACR0,0x00);                 //acceptcode buffer
   write_sja(ACR1,0x00);
   write_sja(ACR2,0x00);
   write_sja(ACR3,0x00);         
   write_sja(AMR0,0xff);                  //验收屏蔽寄存器,接收任何标识符的数据包
   write_sja(AMR1,0xff);
   write_sja(AMR2,0xff);
   write_sja(AMR3,0xff);                                             
   write_sja(BTR0,0x00);             //设置1M的波特率通信
   write_sja(BTR1,0x14);  
   write_sja(OCR,0x1a);              //配置输出管脚,TX1 悬空,TX0推挽输出
   write_sja(CDR,0xc8);              // 关闭时钟,工作于pelican模式  
   write_sja(MODE,0x00);             //进入工作模式
}   
      
void CAN_Tx()
{  
    uchar state;
  state=read_sja(SR);
  
  while(!(state & 0x04));              //检查发送缓冲器是否被锁定  

  write_sja(TXbuffer0,0x88);                 //扩展帧,数据帧,长度为8字节   
  
  write_sja(TXbuffer1,0x22);                  //节点IP
  write_sja(TXbuffer2,0x00);           
  write_sja(TXbuffer3,0x0F);
  write_sja(TXbuffer4,0x30);  
                                                            
  write_sja(TXbuffer5,0x05);                 
  write_sja(TXbuffer6,0x06);
  write_sja(TXbuffer7,0x06);
  write_sja(TXbuffer8,0x07);                        
  write_sja(TXbuffer9,0x07);                  
  write_sja(TXbuffer10,0x08);
  write_sja(TXbuffer11,0x0b);
  write_sja(TXbuffer12,0x0c);           
  write_sja(CMR,0x01);                    //启动发送   
   
   while(read_sja(SR)&0x08) ;         // 检测发送是否完成   
     SREG=0x80;           //开总中断
           
}                                       

/*
****************************
函数说明:主函数
****************************
*/
void  main()
{   
   mcu_init();
   sja1000_init();
   DDRC=0xff;      
   PORTC=0x40;        //choose the sja1000   
     
     while(1)
     {CAN_Tx();  
      
can_read();
      }

   
                     
                                                                                                                             
}           
大家帮帮忙 我的自收发程序 总是搞不通  哪里有问题  谢了                     

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

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

出0入0汤圆

发表于 2015-2-1 12:36:40 | 显示全部楼层

最近也在调SJA1000,我的硬件应该没问题(见下面的测试过程),不知道哪里出了问题

你搞定了吗?搞定的话能不能发个demo啊

测试过程:
1、在正常模式下(地址0寄存器写入0)读写测试寄存器(地址0x09)正常;写入55读回55,写入aa读回aa;
2、在上述写完测试寄存器后立刻切入测试模式(地址0寄存器写入1)写时钟分频寄存器(地址0x1f),连续写C8/C4/C0(关闭clockout、clock=Fosc/2、clock=Fosc/10),用仿真器单步跟踪可以看到clockout频率分别为0(无输出)、8MHz、1.6MHz(注:Fosc=16MHz)。
从上述两点应该看可否得出结论:1、MCU和SJA1000硬件连接正常;2、SJA1000正常工作;

现在的我调试时发现:初始化(PeriCAN模式,初始化代码不能确定是否正确)完毕后(实际上是写完时钟分频寄存器后)状态寄存器(偏址0x02)是0X3C,也即收、发状态都是1(忙),无法进一步操作

以上测试已经断开TJA1050与SJA1000的TX/RX。)。

#include <REG52.H>                /* special function register declarations   */
                                  /* for the intended 8051 derivative         */

#include <stdio.h>                /* prototype declarations for I/O functions */
#include <absacc.h>                                  /* 主要是用于寻址外部存储器*/
#include "sja1000_reg.h"                    /* sja1000T的寄存器定义文件*/
#include "sja1000.h"

sbit SJARst = P1^0; //复位控制                                    

#define XtalFreq        (12000000)                /* main crystal frequency        */
#define CntrFreq        (XtalFreq/12)   /* main counter frequency        */
#define BaudRate        (4800)                        /* baud rate        */

#define UARTOPEN


void main (void)
{

        unsigned char tmp;

#ifdef UARTOPEN
        SCON        = 0x50;        /* SCON: mode 1, 8-bit UART, enable rcvr */
        TMOD        = 0x21;         
        /* TMOD: timer 1, mode 2, 8-bit reload  */
        /* TMOD: timer 0, mode 1, 16-bit        */

        PCON |= 0x80;   /* SMOD = 1 Double Baud Rate for TH1 load */
        TH0=TL0 = 0;
//        TH1=TL1 = (unsigned int)(256 - ( (XtalFreq / BaudRate) / 192));
        TH1=TL1 = (unsigned int)(256 - ( XtalFreq  / BaudRate / ((PCON&0x80)?1:2) ) / 192) ;
       
        TR1        = 1;        /* TR1:  timer 1 run        */
       
        TI        = 1;        /* TI:   set TI to send first char of UART  */
//    SCON  = 0x50;                        /* SCON: mode 1, 8-bit UART, enable rcvr      */
//    TMOD |= 0x20;               /* TMOD: timer 1, mode 2, 8-bit reload        */
//    TH1   = 0xFD;                /* TH1:  reload value for 9600 baud @ 11.0595MHZ   */
//    TR1   = 1;                  /* TR1:  timer 1 run                          */
//    TI    = 1;                  /* TI:   set TI to send first char of UART    */
#endif
        PX0=1;                                          //外部中断0高优先级
        IT0=1;                                          //设置INT0为下降沿中断
        IE0=0;  /* 清中断标志 */
        EX0=1;                                          //使能INT0中断
/*------------------------------------------------
Note that an embedded program never exits (because
there is no operating system to return to).  It
must loop and execute forever.
------------------------------------------------*/

   
    printf ("Hello World\n");   /* Print "Hello World" */
        SJA_Init();//主要是使芯片复位
        tmp = SJA_Test();
       
        /* Enter the reset Mode        */
        REG_MODE = 0x01;
        while((REG_MODE&0x01)!= 0x01);        //确定进入复位模式
        printf("1.Enter the Reset Mode,REG_MODE=0x%.4x\n",REG_MODE);

        REG_CDR = 0xc0;//设置时钟分频寄存器。CDR.7 = 1,PeliCAN模式;CDR.6(RX0激活,关闭RX1)  fCLKOUT = fOSC/2, CDR.3(CLKOUT ON)
        REG_CDR = 0xc4;//设置时钟分频寄存器。CDR.7 = 1,PeliCAN模式;CDR.6(RX0激活,关闭RX1)  fCLKOUT = fOSC/10, CDR.3(CLKOUT ON)
        REG_CDR = 0xc8;//设置时钟分频寄存器。CDR.7 = 1,PeliCAN模式;CDR.6(RX0激活,关闭RX1)  fCLKOUT = fOSC/2, CDR.3(CLKOUT off)
        REG_RBSA = 0x00;//RX缓冲器起始地址   
                  
        /*Configure acceptance code and mask register*/                                                            
        REG_ACR0 = 0xff;//验收码寄存器                       
    REG_ACR1 = 0xff;                           
        REG_ACR2 = 0xff;                           
        REG_ACR3 = 0xff;                           
                                                            
        REG_AMR0 = 0xff;//验收屏蔽寄存器,接收任何标识符的数据包         
        REG_AMR1 = 0xff;                           
        REG_AMR2 = 0xff;                           
        REG_AMR3 = 0xff;   
                               

        /*configure bus timing registers*/
        REG_BTR0 = 0x49;//0x00;                           
        REG_BTR1 = 0x14;//0x14; //100k@12MHz
                                           
        REG_IR_ABLE = 0x01;//Peli模式中断使能,接收中断使能,发送中断禁止                  
        REG_IR_ABLE = 0xff;//Peli模式中断使能,接收中断使能,发送中断禁止                  
   
        REG_OCR = 0x1a;//设置输出模式:正常输出,从TX0口输出;TX1悬空
                                              
        REG_MODE = 0x0c; //进入自接收模式.CDR.3(选择单个验收滤波器),CDR.2 (此模式可以检测所有节点)

        do
        {
                tmp = REG_MODE;
        }while(tmp != 0x0c);//确定进入自接收模式下
        printf("2.Enter the self-test Mode\n",REG_MODE);

        printf("REG_SR=0x%.4x\n",REG_SR);
       
        SJA1000_TxData();//发送数据
        printf("\n\n");
        //SJA1000_Rx_Display();//接收数据展示
        EA = 1;//使能全局中断
        while(1);
}


void SJA1000_TxData(void)
{
        while(REG_SR & 0x10) /*printf("REG_SR=0x%.4x\n", REG_SR)*/;//当SJA1000不处于接收状态时才可继续执行,SR.4==0x1,正在接收,等待
    while(!(REG_SR & 0x08))printf("REG_SR=0x%.4x\n", REG_SR); //SR.3=0,发送请求未处理完,等待直到SR.3=1
    while(!(REG_SR & 0x04))printf("REG_SR=0x%.4x\n", REG_SR); //SR.2=0,发送缓冲器被锁。等待直到SR.2=1   
       
        REG_TxBuffer0 = 0x08;//帧信息,标准帧,数据帧,8字节        
                                                                   
        REG_TxBuffer1 = 0xFF;//标识符1                             
        REG_TxBuffer2 = 0xFF;//标识符2                     
                                                         
        REG_TxBuffer3 = 0x11;//发送数据位:1                       
        REG_TxBuffer4 = 0x22;//发送数据位:2                       
        REG_TxBuffer5 = 0x33;                                      
        REG_TxBuffer6 = 0x44;                                      
        REG_TxBuffer7 = 0x55;                                      
        REG_TxBuffer8 = 0x66;                                      
        REG_TxBuffer9 = 0x77;                                      
        REG_TxBuffer10 = 0x88;//here Over                          
                             
        SJA1000_Tx_Display();
        REG_CMD = 0x10;//自接收
        while(!(REG_SR & 0x08));//检测发送完毕       
}

void SJA1000_Tx_Display(void)
{
        printf( " TBSR3 = 0x%.4x \n", REG_TxBuffer3 );  
        printf( " TBSR4 = 0x%.4x \n", REG_TxBuffer4 );  
        printf( " TBSR5 = 0x%.4x \n", REG_TxBuffer5 );  
        printf( " TBSR6 = 0x%.4x \n", REG_TxBuffer6 );  
        printf( " TBSR7 = 0x%.4x \n", REG_TxBuffer7 );  
        printf( " TBSR8 = 0x%.4x \n", REG_TxBuffer8 );  
        printf( " TBSR9 = 0x%.4x \n", REG_TxBuffer9 );  
        printf( " TBSR10 = 0x%.4x \n",REG_TxBuffer10);  
}

void SJA_Init(void)                          
{   
        //SJA1000复位                                       
         unsigned char i;                           
         for(i = 0;i < 125;i++);           
         SJARst = 0;                                 
         for(i = 0;i < 125;i++);//给RST引脚一个低脉冲
         SJARst = 1;                                 
         for(i = 0;i < 125;i++);                     
}

unsigned char SJA_Test(void)
{
        unsigned char tmp;
        REG_MODE = 0;
        tmp = 0;
        tmp = REG_TEST;
        tmp = 255;
        do
        {
                REG_TEST = tmp;
                if(REG_TEST != tmp) return tmp;
        } while(tmp--);
        return 0;       
}

/************************************************************
                函数:ex0_int
                说明:中断服务程序
                入口:无
                返回:无

***********************************************************/
void handle_int(void) interrupt 0 using 1
{
        if(REG_IR & 0x01)      //产生了接收中断
  {
           #pragma disable
         printf( " Received message.\n");
         printf( " RBSR3 = %x \n", REG_RxBuffer3 );
         printf( " RBSR4 = %x \n", REG_RxBuffer4 );
         printf( " RBSR5 = %x \n", REG_RxBuffer5 );     
         printf( " RBSR6 = %x \n", REG_RxBuffer6 );     
         printf( " RBSR7 = %x \n", REG_RxBuffer7 );     
         printf( " RBSR8 = %x \n", REG_RxBuffer8 );     
         printf( " RBSR9 = %x \n", REG_RxBuffer9 );     
         printf( " RBSR10 = %x \n",REG_RxBuffer10);   

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

本版积分规则

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

GMT+8, 2024-7-23 12:30

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

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