调试好的can程序,89c51+sja1000+tja1040
************************************程序功能***************************************************
//节点1向CAN节点2发送数据,数据的头两个字节分别是:节点1的ID和要求节点2回复的数据长度
//节点2收到节点1的信息后,立即按照节点1的要求回复数据
//************************************************************************************************
#i nclude <AT89X51.H>
#i nclude <SJA_nnyt.H> //SJA存储器定义头文件
#i nclude <SJA_nnyt.C> //SJA子程序文件
#i nclude <display_s.h> //显示头文件
#i nclude<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; //开放错误\接收\发送中断
}
载入中...
他们彼此深信,是瞬间迸发的热情让他们相遇。这样的确定是美丽的,但变幻无常更为美丽
首页 相册 标签实验(4)资料(10)好文(6)源程序 C(102)源程序 汇编(3)my heart(2)<< < 2008 - 7 > >> 日 一 二 三 四 五 六
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
留言簿签写留言
~~~~~~~~~~~~~
公告载入中...
最新日志经典C源程序100例95
经典C源程序100例96
经典C源程序100例97
经典C源程序100例98
经典C源程序100例99
经典C源程序100例100
经典C源程序100例89
经典C源程序100例86
经典C源程序100例87
经典C源程序100例88
最新评论Re:一个人的奋斗历程(转)
Re:明天买板子咯~~~
Re:调试好的can程序,89c51
补充AUXR
Re:实验三.LED流水灯(C语言)
Re:明天买板子咯~~~
Re:实验一.从最简单的点亮一个灯做
Re:实验一.从最简单的点亮一个灯做
Re:明天买板子咯~~~
Re:初学者必看!(转)
搜索 日志标题 日志内容
登陆用户名:
密 码:
记住密码
用户注册 忘记密码
友情连接统计载入中...
2007-7-18 12:00:00
调试好的can程序,89c51+sja1000+tja1040
0
推荐******************以下为汇编程序*********************************************************************
系统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
BCAN_ENTER_RETMODEL:
MOV DPTR, #REG_CONTROL ;控制寄存器访问
MOVX A, @DPTR ;
ORL A, #01H ;置位复位请求
MOVX @DPTR, A ;
CLR F0
MOVX A, @DPTR ;验证复位是否写入
JB ACC.0, BCAN_ER_QUIT
SETB F0 ;复位不成功
BCAN_ER_QUIT:
RET
BCAN_QUIT_RETMODEL:
MOV DPTR, #REG_CONTROL ; 控制寄存器访问
MOVX A, @DPTR ;
ANL A, #0FEH ;清零复位请求,进入工作状态
MOVX @DPTR, A
CLR F0
MOVX A, @DPTR
JNB ACC.0, BCAN_QR_QUIT ;验证是否退出复位状态
SETB F0
BCAN_QR_QUIT:
RET
BCAN_DATA_WRITE:
MOV DPTR, #REG_STATUS ;读取状态寄存器
MOVX A, @DPTR ;判断上次发送是否完成
SETB F0
JNB ACC.3, BCAN_DW_QUIT ;正在发送退出
CLR F0
MOVX A, @DPTR ;判断发送缓冲区是否锁定,
SETB F0
JNB ACC.2, BCAN_DW_QUIT ;锁定则跳出
CLR F0
INC R0 ;
MOV A, @R0 ;ID号的低3位 \RTR位 \数据长度DLC
DEC R0 ;恢复指针指向发送数据的首地址
MOV DPTR, #REG_TxBuffer1;发送缓冲区首地址
JB ACC.4, BCAN_WYB ;远程帧
;数据帧
ANL A, #0FH ;计算发送数据的长度
ADD A, #02H
MOV R7, A
AJMP BCAN_WRTXBUF ;
BCAN_WYB:
MOV R7, #02 ;写入发送缓冲区数据长度为2
BCAN_WRTXBUF:
MOV A, @R0 ;开始写入
MOVX @DPTR, A
SETB F0
MOVX A, @DPTR ;校验写入的是否正确
XRL A, @R0
JNZ BCAN_DW_QUIT ;写入错误退出
CLR F0 ;正确写入继续
INC R0
INC DPTR
DJNZ R7, BCAN_WRTXBUF ;没有写完继续
BCAN_DW_QUIT:
RET
BCAN_DATA_RECEIVE:
MOV DPTR, #REG_STATUS
MOVX A, @DPTR
SETB F0
JNB ACC.0, BCAN_DR_QUIT ;判断报文是否有效
CLR F0
MOV DPTR, #REG_RxBuffer2 ;接收报文的ID号的低3位 \RTR位 \数据长度DLC
MOVX A, @DPTR
MOV DPTR, #REG_RxBuffer1 ;接收缓冲区的首地址
JB ACC.4, BCAN_RCVYB ;接收到的是远程帧
;数据帧
ANL A, #0FH ;计算接收到的数据长度
ADD A, #02H ;计算报文的长度
MOV R6, A
AJMP BCAN_RCVDATA
BCAN_RCVYB:
MOV R6, #02 ;远程帧
BCAN_RCVDATA: ;开始读取数据
MOVX A, @DPTR
MOV @R0, A
INC DPTR
INC R0
DJNZ R6, BCAN_RCVDATA
BCAN_DR_QUIT:
RET
BCAN_SET_BANDRATE:
MOV A, R7 ;判断波特率的值是否存在
CLR CY
SUBB A, #13 ;
SETB F0
JNC BCAN_SETBR_QUIT ;输入的值大于12则不正确
CLR F0
MOV A, R7
RL A
MOV DPTR, #BCAN_SETBR ;查表找出相应的预设第一个值
MOVC A, @A+DPTR
MOV R5, A ;将数据保存
MOV A, R7 ;找出第二个值
RL A
INC A
MOVC A, @A+DPTR
MOV R6, A ;保存值
MOV DPTR, #REG_BTR0 ;装入波特率预设值,同步跳转宽度
;位宽度
MOV A, R5
MOVX @DPTR, A
SETB F0
MOVX A, @DPTR
XRL A, R5 ;判断写入是否正确
JNZ BCAN_SETBR_QUIT ;不正确
CLR F0
INC DPTR
MOV A, R6
MOVX @DPTR, A
SETB F0
MOVX A, @DPTR
XRL A, R6 ;判断写入是否正确
JNZ BCAN_SETBR_QUIT
CLR F0
BCAN_SETBR_QUIT:
RET
BCAN_SETBR:
DB 053H, 02FH ;20KBPS的预设值
DB 087H, 0FFH ;40KBPS的预设值
DB 047H, 02FH ;50KBPS的预设值
DB 083H, 0FFH ;80KBPS的预设值
DB 043H, 02fH ;100KBPS的预设值
DB 03H, 01cH ;125KBPS的预设值
DB 081H, 0faH ;200KBPS的预设值
DB 01H, 01cH ;250KBPS的预设值
DB 080H, 0faH ;400KBPS的预设值
DB 00H, 01cH ;500KBPS的预设值
DB 080H, 0b6H ;666KBPS的预设值
DB 00H, 016H ;800KBPS的预设值
DB 00H, 014H ;1000KBPS的预设值
BCAN_SET_OBJECT:
MOV DPTR, #REG_ACR ;写ACR寄存器
MOV A, R7
MOVX @DPTR, A
MOVX A, @DPTR
SETB F0
XRL A, R7 ;检验写入是否正确
JNZ BCAN_SETO_QUIT
CLR F0
INC DPTR ;写AMR寄存器
MOV A, R6
MOVX @DPTR, A
MOVX A, @DPTR
SETB F0
XRL A, R6 ;检验写入是否正确
JNZ BCAN_SETO_QUIT
CLR F0
BCAN_SETO_QUIT:
RET
BCAN_SET_OUTCLK:
MOV DPTR, #REG_OCR ;写OCR寄存器
MOV A, R7
MOVX @DPTR, A
MOVX A, @DPTR
SETB F0
XRL A,R7
JNZ BCAN_OCR_QUIT ;检验写入是否正确
CLR F0
MOV DPTR, #REG_CDR ;写CDR寄存器
MOV A, R6
MOVX @DPTR, A
MOVX A, @DPTR
SETB F0
XRL A,R6
JNZ BCAN_OCR_QUIT &
文章评论(0条评论)
登录后参与讨论