sja1000 c语言,调试好的can(汇编及C语言)程序,sja1000+tja1040

调试好的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<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    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

*********************************************************************

本人同时提供can实验开发板给初学者

1   CAN控制器为SJA1000,驱动器为TJA1050,电源隔离;

2   提供详尽的源程序,可根据用户需求编写程序

联系我:13671387011(短信联系,QQ详谈)

QQ: 531706356

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值