CAN总线SJA1000测试程序

来源:本站
导读:目前正在解读《CAN总线SJA1000测试程序》的相关信息,《CAN总线SJA1000测试程序》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《CAN总线SJA1000测试程序》的详细说明。
简介:本文为CAN总线SJA1000测试程序,下面一起来学习一下:

CAN总线SJA1000测试程序

//********************************************************************

//SJA1000测试程序

//在8位单片机P89LPC922上测试通过

//串口转CAN:内部时钟7.373MHz,串口115200,can口20k

//协议:1、8位数据为1帧,是数据转发,双向

// 2、DB,01,目的地址,XX,XX,XX,0D,0A 改目的地址

// 3、DB,02,验收码 ,XX,XX,XX,0D,0A 改验收码

// 4、DB,03,验收屏蔽,XX,XX,XX,0D,0A 改验收屏蔽

// 5、DB,04,BTR0,BTR1,XX,XX,0D,0A 改波特率

//编写日期:2010.06.18

//********************************************************************

#include<reg932.h> //单片机头文件

#include"sja.h"

unsigned char RBuf[8]; //接收区

unsigned char CBuf[8]; //发送区

unsigned char CL; //计数

unsigned char num; //

unsigned char Inp; //串口接收计数

unsigned char Num2; //串口延时计数

bit Fir=0; //数据头标志,1-头

unsigned char ACN=0x00; //验收码

unsigned char AMN=0x00; //验收屏蔽

unsigned char TBN=0x00; //目标地址

unsigned char BTR0N=0x4E; //波特率,20k

unsigned char BTR1N=0x2F;

//--------------------------------------------------------------------

//io_init:初始化IO子程序

//--------------------------------------------------------------------

void io_init(void)

{

P0M1=0x00; //P0准双向

P0M2=0x00;

P1M1=0x00; //P1准双向

P1M2=0x00;

P3M1=0x00; //P3准双向

P3M2=0x00;

}

//-------------------------------------------------------------------

//TIMER_init:初始化定时器

//-------------------------------------------------------------------

void TIMER_init(void)

{

TMOD=0x11; //定时器0和1配置为模式1

TAMOD=0x00;

// ET0=1; //允许定时器0中断

TH1=0xB7; //5ms,根据波特率和单片机计算出

TL1=0xFF;

ET1=1; //允许定时器1中断

TR1=1; //打开定时器1

}

//--------------------------------------------------

//UART_init:初始化UART

//--------------------------------------------------

void UART_init(void)

{

SCON=0x50; //串口模式1,接收使能

SSTAT=0x00; //组合中断使能,停止位产生中断

BRGCON=0x00; //关闭BRG

BRGR0=0x30; //设置波特率为115200

BRGR1=0x00;

BRGCON=0x03; //允许BRG

ES=1; //允许串口中断

}

//------------------------------------------------------------------

//main:主函数

//------------------------------------------------------------------

void main(void)

{

io_init(); //端口初始化

TIMER_init(); //定时器0初始化

UART_init();

SJA_init(ACN,AMN,BTR0N,BTR1N);

IT1=1; //外部中断1下降沿有效

EX1=1; //外部中断1有效

IP0H=0x16; //定时器0中断和外部中断1优先级设高3

IP0=0x0E; //通信中断优先级设高2

IP1H=0; //定时器1中断优先级设高1

IP1=0; //键盘中断优先级设高0

EA=1;

while(1); //

}

//-------------------------------------------------------------------

//Timer1Int:定时中断子程序,通信间隔判断,5ms

//-------------------------------------------------------------------

void Timer1Int(void) interrupt 3

{

TH1=0xB7; //5ms,根据波特率和单片机计算出

TL1=0xFF;

Num2++; //超时计数

if(Num2>4)Fir=0;

}

//-------------------------------------------------------------------

//ComInt:通信中断子程序,接收串口数据,发送到CAN口

//-------------------------------------------------------------------

void ComInt() interrupt 4

{

unsigned char IND; //临时量

unsigned char i; //循环量

if(RI) //有输入数据,执行以下程序,发送中断不响应

{

IND=SBUF; //读入数据

RI=0;

Num2=0;

if(!Fir)

{

Fir=1; //新数据

Inp=0; //清零

RBuf[Inp]=IND;

}

else

{ //数据

Inp++; //数据位置加1

RBuf[Inp]=IND; //保存数据

if(Inp==7)

{

Fir=0; //8位数据

if(RBuf[0]==0xDB&&RBuf[6]==0x0D&&RBuf[7]==0x0A) //命令处理

{

if(RBuf[1]==0x01) TBN=RBuf[2]; //改目的地址

if(RBuf[1]==0x02) ACN=RBuf[2]; //改验收码

if(RBuf[1]==0x03) AMN=RBuf[2]; //改验收屏蔽

if(RBuf[1]==0x04) //改波特率

{

BTR0N=RBuf[2];

BTR1N=RBuf[3];

}

SJA_init(ACN,AMN,BTR0N,BTR1N); //重新初始化

}

else //发送数据

{

SJA_write(TransBuffer1,TBN); //目的地址

SJA_write(TransBuffer2,0x08);

for(i=0;i<8;i++) //写发送缓冲区

{

SJA_write(TransBuffer3+i,RBuf[i]);

}

SJA_write(CMR,0x01); //发送

}

}

}

}

}

//-------------------------------------------------------------------

//Int1Int:外部中断子程序,接收CAN总线数据并发送到串口

//-------------------------------------------------------------------

void Int1Int(void) interrupt 2

{

unsigned char tmp; //临时量

tmp=SJA_read(IR); //读中断寄存器

tmp&=0x01;

if(tmp==0x01) //判断是接收中断

{

for(tmp=0;tmp<8;tmp++)

{

CBuf[tmp]=SJA_read(RxBuffer3+tmp); //读缓冲器数据

SBUF = CBuf[tmp]; //发送数据到串口

while(TI==0);

TI = 0;

}

SJA_write(CMR,0x04); //清缓冲器,等下次数据来

}

}

/*CAN 总线SJA1000寄存器地址定义(用的是PeliCAN 模式,扩展帧EFF 模式)*/

#include<reg932.h> //单片机头文件

#include"sja.h" //

//-----------------------------------------------------------------

//SJA1000读

//参数:寄存器地址addr

//返回:读取到数据

//-----------------------------------------------------------------

unsigned char SJA_read(unsigned char addr)

{

unsigned char dat;

ALE=1;

P0=addr;

ALE=0;

P0=0xFF;

CS=0;

RD=0;

dat=P0;

RD=1;

CS=1;

return dat;

}

//-----------------------------------------------------------------

//SJA1000写

//参数:寄存器地址addr,待写入数据dat

//返回:无

//-----------------------------------------------------------------

void SJA_write(unsigned char addr,unsigned char dat)

{

ALE=1;

P0=addr;

ALE=0;

CS=0;

WR=0;

P0=dat;

WR=1;

CS=1;

}

//-----------------------------------------------------------------

//SJA1000初始化

//参数:验收代码AC,验收屏蔽AM,波特率参数BTOBT1

//返回:无

//-----------------------------------------------------------------

void SJA_init(unsigned char AC,unsigned char AM,unsigned char BT0,unsigned char BT1)

{

unsigned int i;

unsigned char c;

RESET=0;

ALE=0;

WR=1;

RD=1;

CS=1;

INT=1;

for(i=0;i<8000;i++);

RESET=1;

SJA_write(CDR,0x40); //时钟分频寄存器,默认0x40(BasicCAN) PeliCAN 模式0xC0

c=SJA_read(IR); //中断寄存器

SJA_write(CR,0x61); //进入复位模式

SJA_write(OCR,0xFA); //输出控制寄存器,默认0xfa

SJA_write(BTR0,BT0); //波特率设置 20kHz

SJA_write(BTR1,BT1); //BTRO=0x0E,SJW=1,BTR1=0x2F,SAM=0单倍

SJA_write(ACR,AC); //验收代码寄存器

SJA_write(AMR,AM); //验收屏蔽寄存器

SJA_write(CR,0x06); //进入工作模式,使能发送、接收中断

}

//SJA1000测试,BasicCAN模式

//模拟时序选intel模式

//sja.h

#ifndef __SJA_H__

#define __SJA_H__

#define CR 0x00 // 控制寄存器地址

#define CMR 0x01 // 命令寄存器地址

#define SR 0x02 // 状态寄存器地址

#define IR 0x03 // 中断寄存器地址

#define ACR 0x04 // 验收码寄存器地址

#define AMR 0x05 // 验收屏蔽寄存器地址

#define BTR0 0x06 // 总线定时寄存器0地址

#define BTR1 0x07 // 总线定时寄存器1地址

#define OCR 0x08 // 输出控制寄存器地址

#define TR 0x09 // 测试寄存器地址

#define TransBuffer1 0x0a // 发送缓冲器

#define TransBuffer2 0x0b

#define TransBuffer3 0x0c

#define TransBuffer4 0x0d

#define TransBuffer5 0x0e

#define TransBuffer6 0x0f

#define TransBuffer7 0x10

#define TransBuffer8 0x11

#define TransBuffer9 0x12

#define TransBuffer10 0x13

#define RxBuffer1 0x14 // 接收缓冲器

#define RxBuffer2 0x15

#define RxBuffer3 0x16

#define RxBuffer4 0x17

#define RxBuffer5 0x18

#define RxBuffer6 0x19

#define RxBuffer7 0x1a

#define RxBuffer8 0x1b

#define RxBuffer9 0x1c

#define RxBuffer10 0x1d

#define CDR 0x1f // 时钟频分寄存器

//管脚定义:PO数据

sbit RESET=P1^3; //复位

sbit INT=P1^4; //中断

sbit ALE=P3^0; //写地址使能

sbit RD=P1^6; //写数据

sbit WR=P1^7; //读数据

sbit CS=P3^1; //片选

unsigned char SJA_read(unsigned char addr); //SJA读

void SJA_write(unsigned char addr,unsigned char dat); //SJA写

void SJA_init(unsigned char AC,unsigned char AM,unsigned char BT0,unsigned char BT1); //SJA初始化

#endif

提醒:《CAN总线SJA1000测试程序》最后刷新时间 2024-03-14 00:55:28,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《CAN总线SJA1000测试程序》该内容的真实性请自行鉴别。