您现在所在的是:

单片机论坛

回帖:0个,阅读:917 [上一页] [1] [下一页]
* 帖子主题:

CAN总线SJA1000测试

1922
周长锁
文章数:312
年度积分:53
历史总积分:1922
注册时间:2006/4/29
发站内信
08年优秀博客奖
发表于: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
欢迎光临我的BLOG

关于我们 | 联系我们 | 广告服务 | 本站动态 | 友情链接 | 法律声明 | 非法和不良信息举报

工控网客服热线:0755-86369299
版权所有 工控网 Copyright©2024 Gkong.com, All Rights Reserved

46.8003