No.95389 作者:nnyt 邮件:nnyt@tom.com ID:56467 登陆:2次 文章数:2篇 最后登陆IP:219.239.34.4 最后登陆:2007/5/6 10:50:27 注册:2006/7/6 11:00:26 财富:116 发帖时间:2006/7/6 11:02:26 发贴者IP:219.239.34.6 标题:nnyt:调试好的can(汇编及C语言)程序,与大家分享! 摘要:No.95389调试好的can(汇编及C语言)程序,与大家分享! //************************************程序功能*************************************************** //节点1向CAN节点2发送数据,数据的头两个字节分别是:节点1的ID和要求节点2回复的数据长度 //节点2收到节点1的信息后,立即按照节点1的要求回复数据 //************************************************************************************************ #include <AT89X51.H> #include <SJA_BCANCONF.H> //SJA存储器定义头文件 #include <SJA_BCANFUNC.C> //SJA子程序文件 #include <display_s.h> //显示头文件 #include <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; //开放错误\接收\发送中断 } ******************以下为汇编程序********************************************************************* 系统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 ......
>>返回讨论的主题
|