原创 89c51+sja1000+tja1040 (转)

2009-2-21 18:57 3096 1 1 分类: 通信

调试好的can程序,89c51+sja1000+tja1040
************************************程序功能***************************************************
//节点1向CAN节点2发送数据,数据的头两个字节分别是:节点1的ID和要求节点2回复的数据长度
//节点2收到节点1的信息后,立即按照节点1的要求回复数据
//************************************************************************************************
#i nclude <AT89X51.H>
#i nclude <SJA_nnyt.H>                           //SJA存储器定义头文件
#i nclude <SJA_nnyt.C>                           //SJA子程序文件
#i nclude <display_s.h>                              //显示头文件
#i nclude<string.h>         //字符串函数
//***************************头文件***************************************************//
void Init_Cpu(void);                                //初始化单片机
void Sja_1000_Init(void);                           //初始化SIA
//************************************************************************************
bit s;                                              //配置sja标志
bit flag_send;                                      //发送命令标志
unsigned char data a[5]={0x05,0x05,0x05,0x05,0x05}; //显示"5"
unsigned char b[5]={0x12,0x12,0x12,0x12,0x12};      //显示"p"
unsigned char c[5]={0x01,0x01,0x01,0x01,0x01};      //显示"1"
unsigned char data  send_data[10],rcv_data[10];     //发送和接收数组
unsigned char bdata flag_init;                      //保存中断寄存器值
unsigned int count_k;                               //延时记数用
sbit rcv_flag=flag_init^0;                          //接收中断标志
sbit err_flag=flag_init^2;                          //错误中断标志
//***********************************************************************************//
void main(void)
{  


    s="0";                                            //配置sja1000出现错误时,重新初始化
    do{
       Sja_1000_Init();
      }while(s!=0);                                   
    Init_Cpu();                                        //initialize mcu
    flag_init=0x00;                                 //保存中断寄存器值清零
    while(1)
    {
        if(rcv_flag)                                //if there is receive interrupt
        {
            rcv_flag=0;                             //接收标志位清零
            BCAN_DATA_RECEIVE(rcv_data);            //接收数据
            BCAN_CMD_PRG(RRB_CMD);                  //释放接收缓冲区
            flag_send=1;                            //发送命令置位
        }
        if(flag_send)                               
        {
            flag_send=0;                            //发送位清零
            send_data[0]=rcv_data[2];                //接收到的"发送方ID10~ID3"
            send_data[1]=rcv_data[3];               //接收到的"发送方ID2~ID0"和要求的数据长度
            send_data[2]=0x88;
            send_data[3]=0x89;
            BCAN_DATA_WRITE(send_data);             //发送数据
            BCAN_CMD_PRG(TR_CMD);                   //置位发送请求位
            for(count_k=0;count_k<200;count_k++)
            display(a);                             //延时显示"5"
        }
        if (err_flag)                               //错误中断
        {  
            for(count_k=0;count_k<280;count_k++)   
            display(c);                             //错误显示"1"
            err_flag=0;                             //错误标志位清零
            Sja_1000_Init();                        //初始化SJA
           
        }
        display(b);                                 //显示"p"
    }
}



void ex0_int(void) interrupt 0 using 1              //外部中断0
{
    SJA_BCANAdr=REG_INTERRUPT;                      //指针指向中断寄存器
    flag_init=*SJA_BCANAdr;                         //保持中断寄存器值
}



void Init_Cpu(void)                                 //单片机初始化,开放外部中断0
{
    PX0=1;
    EX0=1;
    EA="1";
}


void Sja_1000_Init(void)
{
    s="BCAN"_CREATE_COMMUNATION();  //SJA自测
    s="BCAN"_ENTER_RETMODEL();      //进入复位
    s="BCAN"_SET_BANDRATE(0x04);    //设置波特率100K/S
    s="BCAN"_SET_OBJECT(0xaa,0x00); //设置地址ID:550
    s="BCAN"_SET_OUTCLK(0xaa,0x48); //设置输出方式,禁止COLOCKOUT输出
    s="BCAN"_QUIT_RETMODEL();       //退出复位模式
    SJA_BCANAdr=REG_CONTROL;      //地址指针指向控制寄存器
    *SJA_BCANAdr|=0x1e;           //开放错误\接收\发送中断
}
 


 



 载入中...


他们彼此深信,是瞬间迸发的热情让他们相遇。这样的确定是美丽的,但变幻无常更为美丽  
首页 相册 标签实验(4)资料(10)好文(6)源程序 C(102)源程序 汇编(3)my heart(2)<<  < 2008 - 7 >  >> 日 一 二 三 四 五 六
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31    


留言簿签写留言
~~~~~~~~~~~~~
公告载入中...
最新日志经典C源程序100例95
经典C源程序100例96
经典C源程序100例97
经典C源程序100例98
经典C源程序100例99
经典C源程序100例100
经典C源程序100例89
经典C源程序100例86
经典C源程序100例87
经典C源程序100例88
最新评论Re:一个人的奋斗历程(转)
Re:明天买板子咯~~~
Re:调试好的can程序,89c51
补充AUXR
Re:实验三.LED流水灯(C语言)
Re:明天买板子咯~~~
Re:实验一.从最简单的点亮一个灯做
Re:实验一.从最简单的点亮一个灯做
Re:明天买板子咯~~~
Re:初学者必看!(转)
搜索 日志标题 日志内容
 
登陆用户名: 
密 码: 
    记住密码 
 用户注册 忘记密码 


友情连接统计载入中...



2007-7-18 12:00:00
调试好的can程序,89c51+sja1000+tja1040
0
推荐******************以下为汇编程序*********************************************************************


系统can地址为550,用于can系统测试,应用T0定时器每隔1s向can总线发送一组数据:数据长度为8个字节,
首字节为05H,第二个字节为累加变量,每秒钟数值增加1,
*********************************************************************************************************
CONTROLLER_BASE   EQU   7E00H     ;SJA1000的片选地址


RCV_GOOD        BIT    0FH    ;成功的接收一帧标志
SEC_FLAG        BIT    010H    ;一秒到标志
ERR_FLAG        BIT    011H    ;监测到错误标志


SAVE_INT_INFO   DATA    032H    ;保存SJA1000中断寄存器的内容


SEND_DATA_BUF1    DATA     040H    ;发送缓冲区
SEND_DATA_BUF2    DATA    041H
SEND_DATA_BUF3    DATA    042H
SEND_DATA_BUF4    DATA    043H
SEND_DATA_BUF5    DATA    044H
SEND_DATA_BUF6    DATA    045H
SEND_DATA_BUF7    DATA    046H
SEND_DATA_BUF8    DATA    047H
SEND_DATA_BUF9    DATA    048H
SEND_DATA_BUF10   DATA    049H


RCV_DATA_BUF1     DATA    050H    ;接收缓冲区
RCV_DATA_BUF2     DATA    051H
RCV_DATA_BUF3     DATA    052H
RCV_DATA_BUF4     DATA    053H
RCV_DATA_BUF5     DATA    054H
RCV_DATA_BUF6     DATA    055H
RCV_DATA_BUF7     DATA    056H
RCV_DATA_BUF8     DATA    057H
RCV_DATA_BUF9     DATA    058H
RCV_DATA_BUF10    DATA    059H


ERROR_STATUS      DATA  07CH    ;错误状态表示
TEST_DATA         DATA    07FH    ;测试发送数据
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;程序开始
ORG         0000H
LJMP        MAIN         ;运行主程序


ORG        0003H             
LJMP        BCAN_INT0    ;中断方式访问SJA1000程序


ORG        000BH
LJMP        T0_INTERRUPT     ;定时器0中断


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


ORG               0100H   ;程序开始
MAIN:
    MOV        R0,#07fH
    CLR     A
    MOV     @R0,A
    DJNZ    R0,$-1
    MOV     @R0,A
    MOV     SP,#60H        ;设置SP
    CLR     P2.0                ;SJA1000退出硬件复位模式
   
    LCALL   SJA1000_INT0    ;初始化SJA1000
    LCALL   T0_INIT
    CLR     P3.4                ;点亮指示灯
    SETB    PX0
    SETB    IT0
    SETB    EX0
    SETB    ET0
    SETB    TR0
    SETB    EA


LOOPER:
        JNB        RCV_GOOD,LOOPER2    ;sja1000成功接收一帧,通知CPU处理
        CLR         RCV_GOOD
    LCALL       RCVDATA_PRG
LOOPER2:
    JNB        SEC_FLAG,LOOPER3    ;一秒时间到,每秒发送一次
        CLR         SEC_FLAG
    CLR         P3.5                ;点亮指示灯
    LCALL       SENDDATA_PRG
LOOPER3:
    JNB        ERR_FLAG,LOOPER4               ;错误标志,错误处理
        CLR         ERR_FLAG
    LCALL       ERR_PRG
LOOPER4:
    AJMP        LOOPER


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;初始化SJA1000;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   
   
SJA1000_INT0:  
    LCALL         BCAN_CREATE_COMMUNATION ;调用SJA1000接口测试函数
    MOV           R7,           #04
    LCALL         BCAN_SET_BANDRATE   ;设置波特率为100k         
    MOV           R7,         #0A8H  ;设置接收报文ID
    MOV           R6,         #0FFH
    LCALL         BCAN_SET_OBJECT
    MOV           R7,         #0AAH   ;设置输出控制、时钟分频;正常输出模式
    MOV           R6,         #048H   ;使能内部比较器、禁止CLKOUT
    LCALL         BCAN_SET_OUTCLK     ;
    LCALL         BCAN_QUIT_RETMODEL  ;退出复位状态
    MOV              DPTR,#REG_CONTROL   ;开放SJA1000内部功能中断
    MOV              A,#01EH          ;中断开放
    MOVX      @DPTR,A
    CLR           F0
    RET


;;;;;;;;;;;;;;;;;;;;;;错误信息处理;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ERR_PRG:
    LCALL     BCAN_ENTER_RETMODEL                 ;进入复位模式
    LCALL       SJA1000_INT0 ;
    MOV       ERROR_STATUS,#0FCH
    RET


;;;;;;;;;;;;;;;;;;;;;;;接收数据处理部分;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RCVDATA_PRG:
    MOV    R0,# RCV_DATA_BUF1     ;微处理器接收首地址
    LCALL    BCAN_DATA_RECEIVE              ;调用接收数据子程序
    MOV    R7,#04H                  ;释放接收缓冲区
    LCALL    BCAN_CMD_PRG        ;
        RET
;;;;;;;;;;;;;;;;;;控制SJA1000向CAN总线发送数据处理部分;;;;;;;;;;;;;;;
SENDDATA_PRG:
    MOV           R0,          #SEND_DATA_BUF1
    MOV           @R0,         #02H
    INC           R0
    MOV           @R0,         #08H
    INC           R0
    MOV           @R0,         #05H
    MOV              A,           TEST_DATA
    INC           R0
    MOV           @R0,         A
    MOV           R0,          #SEND_DATA_BUF1
    LCALL         BCAN_DATA_WRITE       ;将要发送的数据送入发送缓冲区
    MOV           R7,          #01
    LCALL         BCAN_CMD_PRG
    RET


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;定时器0初始化;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
T0_INIT:
    MOV     A,TMOD
    ANL     A,#0F0H
    ORL     A,#01H
    MOV        TMOD,A;T0工作在方式1
    MOV        TH0,#0FCH        ;定时周期1MS
    MOV        TL0,#066H
    MOV     3AH,#00H
    RET


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;外部中断0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
BCAN_INT0:
    push    DPH
    PUSH    DPL
    PUSH    PSW            ;PSW,ACC入栈
    PUSH    ACC
        USING    3            ;应用寄存器第3组 
    MOV    DPTR,#REG_INTERRUPT    ;读中断寄存器
    MOVX    A,@DPTR          ;
    MOV    SAVE_INT_INFO,A        ;保存中断寄存器的内容
    JNB     ACC.0,BCAN_INT1        ;接收中断
    SETB    RCV_GOOD        ;置位接收标志


BCAN_INT1:
    MOV    A,SAVE_INT_INFO          
    JNB    ACC.2,BCAN_INT2        ;错误中断
    SETB    ERR_FLAG        ;置位错误标志
BCAN_INT2:
    POP    ACC
    POP    PSW
    POP     DPL
    POP     DPH
    RETI
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;定时器0中断;;;;;;;;;;;;;;;;
T0_INTERRUPT:
    push    DPH
    PUSH    DPL
    PUSH    PSW             ;PSW、ACC入栈
    PUSH    ACC
    USING   2
        MOV    TH0,#80H         ;设置定时周期0.3S
    MOV    TL0,#26H
        INC     3AH
    MOV     A,3AH
    CJNE    A,#23H,T0_QUIT       ;判断1秒时间是否到
    MOV     3AH,#00H
    INC    TEST_DATA            ;测试发送的数据,每1秒加1
        SETB    SEC_FLAG             ;置位1秒到标志
T0_QUIT:
    POP    ACC
    POP    PSW
    POP     DPL
    POP     DPH
    RETI


 


 


BCAN_ENTER_RETMODEL:
      MOV            DPTR,   #REG_CONTROL       ;控制寄存器访问 
      MOVX           A,      @DPTR              ;
      ORL            A,      #01H               ;置位复位请求
      MOVX           @DPTR,  A                              ;
      CLR            F0
      MOVX           A,      @DPTR              ;验证复位是否写入
      JB             ACC.0,  BCAN_ER_QUIT
      SETB           F0                         ;复位不成功
BCAN_ER_QUIT:
      RET


 


BCAN_QUIT_RETMODEL:
      MOV            DPTR,   #REG_CONTROL   ; 控制寄存器访问 
      MOVX           A,      @DPTR          ;
      ANL            A,      #0FEH          ;清零复位请求,进入工作状态
      MOVX           @DPTR,  A
      CLR            F0
      MOVX           A,      @DPTR          
      JNB            ACC.0,  BCAN_QR_QUIT   ;验证是否退出复位状态
      SETB           F0
BCAN_QR_QUIT:
      RET


 


 



BCAN_DATA_WRITE:
      MOV            DPTR,   #REG_STATUS  ;读取状态寄存器
      MOVX           A,      @DPTR        ;判断上次发送是否完成
      SETB           F0
      JNB            ACC.3,  BCAN_DW_QUIT ;正在发送退出
      CLR            F0              
      MOVX           A,      @DPTR        ;判断发送缓冲区是否锁定,
      SETB           F0
      JNB            ACC.2,  BCAN_DW_QUIT ;锁定则跳出                    
      CLR            F0    
          
      INC            R0                   ;
      MOV            A,      @R0          ;ID号的低3位 \RTR位 \数据长度DLC
      DEC            R0                   ;恢复指针指向发送数据的首地址
      MOV            DPTR,   #REG_TxBuffer1;发送缓冲区首地址


      JB             ACC.4,  BCAN_WYB     ;远程帧
      ;数据帧
      ANL            A,      #0FH         ;计算发送数据的长度
      ADD            A,      #02H
      MOV            R7,     A
      AJMP           BCAN_WRTXBUF         ;


BCAN_WYB:
      MOV            R7,     #02          ;写入发送缓冲区数据长度为2


BCAN_WRTXBUF:     
      MOV            A,      @R0          ;开始写入
      MOVX           @DPTR,  A
      SETB           F0
      MOVX           A,      @DPTR        ;校验写入的是否正确
      XRL            A,      @R0
      JNZ            BCAN_DW_QUIT         ;写入错误退出
      CLR            F0                   ;正确写入继续
      INC            R0
      INC            DPTR
      DJNZ           R7,     BCAN_WRTXBUF ;没有写完继续
       
BCAN_DW_QUIT:     
      RET


 


BCAN_DATA_RECEIVE:
     MOV           DPTR,   #REG_STATUS
     MOVX          A,      @DPTR
     SETB          F0
     JNB           ACC.0,  BCAN_DR_QUIT   ;判断报文是否有效
     CLR           F0 


     MOV           DPTR,   #REG_RxBuffer2 ;接收报文的ID号的低3位 \RTR位 \数据长度DLC
     MOVX          A,      @DPTR
     MOV           DPTR,   #REG_RxBuffer1 ;接收缓冲区的首地址
     JB            ACC.4,  BCAN_RCVYB     ;接收到的是远程帧
     ;数据帧
     ANL           A,      #0FH           ;计算接收到的数据长度
     ADD           A,      #02H           ;计算报文的长度
     MOV           R6,     A
     AJMP          BCAN_RCVDATA


BCAN_RCVYB:
     MOV           R6,     #02            ;远程帧


BCAN_RCVDATA:                             ;开始读取数据
     MOVX          A,      @DPTR
     MOV           @R0,    A
     INC           DPTR
     INC           R0
     DJNZ          R6,     BCAN_RCVDATA


BCAN_DR_QUIT:
      
     RET


BCAN_SET_BANDRATE:
    MOV      A,             R7          ;判断波特率的值是否存在
    CLR      CY
    SUBB     A,             #13        ;
    SETB     F0
    JNC      BCAN_SETBR_QUIT            ;输入的值大于12则不正确
    CLR      F0
    MOV      A,             R7
    RL       A
    MOV      DPTR,          #BCAN_SETBR ;查表找出相应的预设第一个值
    MOVC     A,             @A+DPTR
    MOV      R5,            A           ;将数据保存
    MOV      A,             R7          ;找出第二个值
    RL       A
    INC      A
    MOVC     A,             @A+DPTR
    MOV      R6,            A           ;保存值


    MOV      DPTR,          #REG_BTR0   ;装入波特率预设值,同步跳转宽度
                                        ;位宽度
    MOV      A,             R5           
    MOVX     @DPTR,         A
    SETB     F0
    MOVX     A,             @DPTR       
    XRL      A,             R5          ;判断写入是否正确
    JNZ      BCAN_SETBR_QUIT            ;不正确
    CLR      F0
    INC      DPTR
    MOV      A,             R6
    MOVX     @DPTR,         A
    SETB     F0
    MOVX     A,             @DPTR
    XRL      A,             R6          ;判断写入是否正确
    JNZ      BCAN_SETBR_QUIT
    CLR      F0
BCAN_SETBR_QUIT:
    RET



BCAN_SETBR:
    DB 053H,     02FH                     ;20KBPS的预设值
    DB 087H,     0FFH                     ;40KBPS的预设值
    DB 047H,     02FH                     ;50KBPS的预设值
    DB 083H,     0FFH                     ;80KBPS的预设值
    DB 043H,     02fH                     ;100KBPS的预设值
    DB 03H,      01cH                     ;125KBPS的预设值
    DB 081H,     0faH                     ;200KBPS的预设值
    DB 01H,      01cH                     ;250KBPS的预设值
    DB 080H,     0faH                     ;400KBPS的预设值
    DB 00H,      01cH                     ;500KBPS的预设值
    DB 080H,     0b6H                     ;666KBPS的预设值
    DB 00H,      016H                     ;800KBPS的预设值
    DB 00H,      014H                     ;1000KBPS的预设值
  


BCAN_SET_OBJECT:
    MOV      DPTR,      #REG_ACR      ;写ACR寄存器
    MOV      A,         R7
    MOVX     @DPTR,     A
    MOVX     A,         @DPTR
    SETB     F0
    XRL      A,         R7            ;检验写入是否正确
    JNZ      BCAN_SETO_QUIT
    CLR      F0
    INC      DPTR                     ;写AMR寄存器
    MOV      A,         R6
    MOVX     @DPTR,     A
    MOVX     A,         @DPTR
    SETB     F0
    XRL      A,         R6            ;检验写入是否正确
    JNZ      BCAN_SETO_QUIT
    CLR      F0
BCAN_SETO_QUIT:
    RET   


 


BCAN_SET_OUTCLK:
    MOV      DPTR,      #REG_OCR            ;写OCR寄存器
    MOV      A,         R7
    MOVX     @DPTR,     A
    MOVX     A,         @DPTR
    SETB     F0
    XRL      A,R7
    JNZ      BCAN_OCR_QUIT                ;检验写入是否正确
    CLR      F0
    MOV      DPTR,      #REG_CDR            ;写CDR寄存器
    MOV      A,         R6
    MOVX     @DPTR,     A
    MOVX     A,         @DPTR
    SETB     F0
    XRL      A,R6
    JNZ      BCAN_OCR_QUIT &
 


 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
1
关闭 站长推荐上一条 /1 下一条