发表于:2010/6/20 16:24:40
#0楼
//********************************************************************
//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 //单片机头文件
#includesja.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
}
//-------------------------------------------------------------------
//int1int:外部中断子程序,接收can总线数据并发送到串口
//-------------------------------------------------------------------
void int1int(void) interrupt 2
{
unsigned char tmp; //临时量
tmp=sja_read(ir); //读中断寄存器
tmp&=0x01;
if(tmp==0x01) //判断是接收中断
{
for(tmp=0;tmp
/*can 总线sja1000寄存器地址定义(用的是pelican 模式,扩展帧eff 模式)*/
#include //单片机头文件
#includesja.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,波特率参数bto\bt1
//返回:无
//-----------------------------------------------------------------
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
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
----------------------------------------------
此篇文章从博客转发
原文地址: Http://blog.gkong.com/more.asp?id=117598&Name=zhouchs
//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 //单片机头文件
#includesja.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
}
//-------------------------------------------------------------------
//int1int:外部中断子程序,接收can总线数据并发送到串口
//-------------------------------------------------------------------
void int1int(void) interrupt 2
{
unsigned char tmp; //临时量
tmp=sja_read(ir); //读中断寄存器
tmp&=0x01;
if(tmp==0x01) //判断是接收中断
{
for(tmp=0;tmp
/*can 总线sja1000寄存器地址定义(用的是pelican 模式,扩展帧eff 模式)*/
#include //单片机头文件
#includesja.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,波特率参数bto\bt1
//返回:无
//-----------------------------------------------------------------
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
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
----------------------------------------------
此篇文章从博客转发
原文地址: Http://blog.gkong.com/more.asp?id=117598&Name=zhouchs
欢迎光临我的BLOG