nnyt

    1. / 2006-10-03
      调试好的can(汇编及C语言)程序,与大家分享! //************************************程序功能***************************************************//节点1向CAN节点2发送数据,数据的头两个字节分别是:节点1的ID和要求节点2回复的数据长度//节点2收到节点1的信息后,立即按照节点1的要求回复数据//************************************************************************************************#include <AT89X51.H>#include <SJA_nnyt.H>                           //SJA存储器定义头文件#include <SJA_nnyt.C>                           //SJA子程序文件#include <display_s.h>                              //显示头文件#include<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;           //开放错误\接收\发送中断}******************以下为汇编程序*********************************************************************系统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    042HSEND_DATA_BUF4    DATA    043H SEND_DATA_BUF5    DATA    044HSEND_DATA_BUF6    DATA    045H SEND_DATA_BUF7    DATA    046HSEND_DATA_BUF8    DATA    047H SEND_DATA_BUF9    DATA    048HSEND_DATA_BUF10   DATA    049H RCV_DATA_BUF1     DATA    050H    ;接收缓冲区RCV_DATA_BUF2     DATA    051H RCV_DATA_BUF3     DATA    052HRCV_DATA_BUF4     DATA    053H RCV_DATA_BUF5     DATA    054HRCV_DATA_BUF6     DATA    055H RCV_DATA_BUF7     DATA    056HRCV_DATA_BUF8     DATA    057H RCV_DATA_BUF9     DATA    058HRCV_DATA_BUF10    DATA    059H ERROR_STATUS      DATA  07CH    ;错误状态表示TEST_DATA         DATA    07FH    ;测试发送数据;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;程序开始ORG         0000HLJMP        MAIN         ;运行主程序ORG        0003H              LJMP        BCAN_INT0    ;中断方式访问SJA1000程序ORG        000BHLJMP        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    EALOOPER:        JNB        RCV_GOOD,LOOPER2    ;sja1000成功接收一帧,通知CPU处理        CLR         RCV_GOOD    LCALL       RCVDATA_PRGLOOPER2:    JNB        SEC_FLAG,LOOPER3    ;一秒时间到,每秒发送一次        CLR         SEC_FLAG    CLR         P3.5                ;点亮指示灯    LCALL       SENDDATA_PRGLOOPER3:    JNB        ERR_FLAG,LOOPER4               ;错误标志,错误处理        CLR         ERR_FLAG    LCALL       ERR_PRGLOOPER4:    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本人同时提供can实验开发板给初学者1   CAN控制器为SJA1000,驱动器为TJA1050,电源隔离;2   提供详尽的源程序,可根据用户需求编写程序联系我:13671387011(短信联系,QQ详谈)       QQ: 531706356
    2. 基于CAN总线的分布式控制网络设计 2/12015 汽车电子 2006-10-03
      调试好的can(汇编及C语言)程序,与大家分享! //************************************程序功能*************************************************** //节点1向CAN节点2发送数据,数据的头两个字节分别是:节点1的ID和要求节点2回复的数据长度 //节点2收到节点1的信息后,立即按照节点1的要求回复数据 //************************************************************************************************ #include #include                            //SJA存储器定义头文件 #include                            //SJA子程序文件 #include                               //显示头文件 #include         //字符串函数 //***************************头文件***************************************************// 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

最近访客

< 1/1 >

统计信息

已有63人来访过

  • 芯积分:--
  • 好友:--
  • 主题:1
  • 回复:2

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言