📄 can232.lst
字号:
__start:
__text_start:
0038 E5CF LDI R28,0x5F
0039 E0D4 LDI R29,4
003A BFCD OUT 0x3D,R28
003B BFDE OUT 0x3E,R29
003C 51C0 SUBI R28,0x10
003D 40D0 SBCI R29,0
003E EA0A LDI R16,0xAA
003F 8308 STD Y+0,R16
0040 2400 CLR R0
0041 E7EB LDI R30,0x7B
0042 E0F0 LDI R31,0
0043 E010 LDI R17,0
0044 38E1 CPI R30,0x81
0045 07F1 CPC R31,R17
0046 F011 BEQ 0x0049
0047 9201 ST R0,Z+
0048 CFFB RJMP 0x0044
0049 8300 STD Z+0,R16
004A E5E4 LDI R30,0x54
004B E0F0 LDI R31,0
004C E6A0 LDI R26,0x60
004D E0B0 LDI R27,0
004E E010 LDI R17,0
004F 36EF CPI R30,0x6F
0050 07F1 CPC R31,R17
0051 F021 BEQ 0x0056
0052 95C8 LPM
0053 9631 ADIW R30,1
0054 920D ST R0,X+
0055 CFF9 RJMP 0x004F
0056 940E02C1 CALL _main
_exit:
0058 CFFF RJMP _exit
_delay:
i --> R20
k --> R16
0059 940E0348 CALL push_gset1
FILE: F:\小制作\can,usb,以太网学习板\232转CAN学习程序\main.c
(0001) /*##############################################################################
(0002) 功能:CAN与232相互转换
(0003) 作者:LHF
(0004) 时间:2007-01
(0005) 版本:V1.0
(0006) ################################################################################
(0007) 资源分配: PORTC.2~5:JTAG
(0008) ##############################################################################*/
(0009) //##############################################################################
(0010) #include <iom16v.h> //寄存器定义;
(0011) #include <macros.h> //宏定义;
(0012) #include "MCP2515.h" //2515寄存器定义
(0013) #define uchar unsigned char //数据类型定义
(0014) #define uint unsigned int //数据类型定义
(0015)
(0016) #pragma interrupt_handler INT1_17:3 //定义INT1的中断服务程序
(0017) #pragma interrupt_handler Timer0:10 //定义定时计数器0的中断服务程序
(0018) #pragma interrupt_handler Usart_receive:12 //定义接收中断服务程序
(0019) #define fosc 7372800 //晶振7.3728MHZ
(0020) uchar can_boud=0x07;//MCP2515在16M晶振情况,can_boud=0x00总线波特率为1M,0x01=500K,0x03=250K,0x07=125K;公式:16M/(16*(1+X))
(0021) uint bps=38400;//定义串口波特率
(0022)
(0023) uchar eflag=0;//是不是扩展帧,为1则表示接收到的是扩展帧,0表示标准帧
(0024) uchar Tdate[10]={0};//存放要发送标准帧的数据,最大10位,前2位是ID号,后8位是数据位
(0025) uchar TID[2]={0,0};//存放要发送标准帧的ID号
(0026)
(0027) uchar Rdate[8]={0};//存放接收到的数据
(0028) uchar RESID[4];//存放接收到的数据帧的ID号,标准帧只用到RESID[0],RESID[1],扩展帧全部用到
(0029)
(0030) uchar bytetime;//232与CAN透明转换时,根据不同的波特率确定所要延时的时间,
(0031) uint usart_number=0;//计数当前所接收的串行数据的那一组数据流的数据个数,串口传来的数据存放在Tdate中等待用CAN标准帧发送
(0032)
(0033) uchar state;//2515状态(包括发送接收中断标志位和各请求发送位),具体见数据手册
(0034) uchar DLC=8;//接收到数据的长度
(0035)
(0036) //****************************************************************************//
(0037) //********************************延时程序************************************//
(0038) void delay(uchar k)//
(0039) {uint i=0;
005B 2744 CLR R20
005C 2755 CLR R21
005D C009 RJMP 0x0067
(0040) while(k--){for(i=0;i<8000;i++);}
005E 2744 CLR R20
005F 2755 CLR R21
0060 C002 RJMP 0x0063
0061 5F4F SUBI R20,0xFF
0062 4F5F SBCI R21,0xFF
0063 3440 CPI R20,0x40
0064 E1EF LDI R30,0x1F
0065 075E CPC R21,R30
0066 F3D0 BCS 0x0061
0067 2E20 MOV R2,R16
0068 2433 CLR R3
0069 5001 SUBI R16,1
006A 2022 TST R2
006B F791 BNE 0x005E
006C 940E034B CALL pop_gset1
006E 9508 RET
(0041) }
(0042) //##############################################################################
(0043) void Set_CS(uchar level) //
(0044) {if(level) PORTB|=0x10; //
_Set_CS:
level --> R16
006F 2300 TST R16
0070 F011 BEQ 0x0073
0071 9AC4 SBI 0x18,4
0072 C003 RJMP 0x0076
(0045) else PORTB&=0xef; //
0073 B388 IN R24,0x18
0074 7E8F ANDI R24,0xEF
0075 BB88 OUT 0x18,R24
0076 9508 RET
_WriteSPI:
clear --> R20
order --> R20
0077 940E0348 CALL push_gset1
0079 2F40 MOV R20,R16
(0046) }
(0047) //##############################################################################
(0048) //********************************SPI对2515访问*******************************//
(0049) //****************WriteSPI()*******************//
(0050) void WriteSPI(uchar order)
(0051) { uchar clear;
(0052) Set_CS(0); //
007A 2700 CLR R16
007B DFF3 RCALL _Set_CS
(0053) SPDR=order; //2515读指令为0x03
007C B94F OUT 0x0F,R20
(0054) while(!(SPSR&0x80)); //等待SPIF置位,等数据发送完毕
007D 9B77 SBIS 0x0E,7
007E CFFE RJMP 0x007D
(0055) clear=SPSR;
007F B14E IN R20,0x0E
(0056) clear=SPDR;//
0080 B14F IN R20,0x0F
(0057) Set_CS(1); //
0081 E001 LDI R16,1
0082 DFEC RCALL _Set_CS
0083 940E034B CALL pop_gset1
0085 9508 RET
_Read_state:
clear --> R20
order --> R20
0086 940E0348 CALL push_gset1
0088 2F40 MOV R20,R16
(0058) }
(0059)
(0060) //****************Read_state()*******************//
(0061) uchar Read_state(uchar order)//读状态命令,order=0xa0,0xa1,
(0062) { uchar clear;
(0063) Set_CS(0); //
0089 2700 CLR R16
008A DFE4 RCALL _Set_CS
(0064) SPDR=order; //
008B B94F OUT 0x0F,R20
(0065) while(!(SPSR&0x80)); //等待SPIF置位,等数据发送完毕
008C 9B77 SBIS 0x0E,7
008D CFFE RJMP 0x008C
(0066) clear=SPSR;
008E B14E IN R20,0x0E
(0067) clear=SPDR;//
008F B14F IN R20,0x0F
(0068)
(0069) SPDR=0; //空数据
0090 2422 CLR R2
0091 B82F OUT 0x0F,R2
(0070) while(!(SPSR&0x80));//等待SPIF置位,等数据发送完毕
0092 9B77 SBIS 0x0E,7
0093 CFFE RJMP 0x0092
(0071) clear=SPSR;
0094 B14E IN R20,0x0E
(0072) clear=SPDR; //通过先读SPSR,紧接着访问SPDR来对SPIF清零
0095 B14F IN R20,0x0F
(0073)
(0074) Set_CS(1); //
0096 E001 LDI R16,1
0097 DFD7 RCALL _Set_CS
(0075) return clear;
0098 2F04 MOV R16,R20
0099 940E034B CALL pop_gset1
009B 9508 RET
_Read_Byte:
date --> R20
clear --> R22
Address --> R10
009C 940E0344 CALL push_gset3
009E 2EA0 MOV R10,R16
(0076) }
(0077) //**从2515指定地址Address读取一个字节数据Data**//
(0078) uchar Read_Byte(uchar Address)
(0079) {uchar clear;
(0080) uchar date;
(0081) Set_CS(0); //使能SPI器件
009F 2700 CLR R16
00A0 DFCE RCALL _Set_CS
(0082)
(0083) SPDR=0x03; //送2515读指令为0x03
00A1 E083 LDI R24,3
00A2 B98F OUT 0x0F,R24
(0084) while(!(SPSR&0x80)); //等待SPIF置位,等数据发送完毕
00A3 9B77 SBIS 0x0E,7
00A4 CFFE RJMP 0x00A3
(0085) clear=SPSR;
00A5 B16E IN R22,0x0E
(0086) clear=SPDR; //通过先读SPSR,紧接着访问SPDR来对SPIF清零
00A6 B16F IN R22,0x0F
(0087)
(0088) SPDR=Address; //送地址
00A7 B8AF OUT 0x0F,R10
(0089) while(!(SPSR&0x80));
00A8 9B77 SBIS 0x0E,7
00A9 CFFE RJMP 0x00A8
(0090) clear=SPSR;
00AA B16E IN R22,0x0E
(0091) clear=SPDR;
00AB B16F IN R22,0x0F
(0092)
(0093) SPDR=0x00; //发空数据,启动数据发送以接收数据
00AC 2422 CLR R2
00AD B82F OUT 0x0F,R2
(0094) while(!(SPSR&0x80));
00AE 9B77 SBIS 0x0E,7
00AF CFFE RJMP 0x00AE
(0095) clear=SPSR;
00B0 B16E IN R22,0x0E
(0096) clear=SPDR;
00B1 B16F IN R22,0x0F
(0097)
(0098) date=SPDR; //接收数据
00B2 B14F IN R20,0x0F
(0099) Set_CS(1); //关SPI器件DS1722
00B3 E001 LDI R16,1
00B4 DFBA RCALL _Set_CS
(0100) return date;
00B5 2F04 MOV R16,R20
00B6 940E033A CALL pop_gset3
00B8 9508 RET
_Write_Byte:
clear --> R20
Data --> R22
Address --> R10
00B9 940E0344 CALL push_gset3
00BB 2F62 MOV R22,R18
00BC 2EA0 MOV R10,R16
(0101) }
(0102) //**向2515指定地址Address写一个字节数据Data**//
(0103) void Write_Byte(uchar Address,uchar Data)
(0104) {uchar clear;
(0105) Set_CS(0); //使能SPI器件2515
00BD 2700 CLR R16
00BE DFB0 RCALL _Set_CS
(0106)
(0107) SPDR=0x02; //送2515写命令为0x02
00BF E082 LDI R24,2
00C0 B98F OUT 0x0F,R24
(0108) while(!(SPSR&0x80));//等待SPIF置位,等数据发送完毕
00C1 9B77 SBIS 0x0E,7
00C2 CFFE RJMP 0x00C1
(0109) clear=SPSR;
00C3 B14E IN R20,0x0E
(0110) clear=SPDR;
00C4 B14F IN R20,0x0F
(0111)
(0112) SPDR=Address; //送地址,启动SPI时钟
00C5 B8AF OUT 0x0F,R10
(0113) while(!(SPSR&0x80));//等待SPIF置位,等数据发送完毕
00C6 9B77 SBIS 0x0E,7
00C7 CFFE RJMP 0x00C6
(0114) clear=SPSR;
00C8 B14E IN R20,0x0E
(0115) clear=SPDR; //通过先读SPSR,紧接着访问SPDR来对SPIF清零
00C9 B14F IN R20,0x0F
(0116)
(0117) SPDR=Data;
00CA B96F OUT 0x0F,R22
(0118) while(!(SPSR&0x80));
00CB 9B77 SBIS 0x0E,7
00CC CFFE RJMP 0x00CB
(0119) clear=SPSR;
00CD B14E IN R20,0x0E
(0120) clear=SPDR;
00CE B14F IN R20,0x0F
(0121) Set_CS(1); //关SPI器件
00CF E001 LDI R16,1
00D0 DF9E RCALL _Set_CS
00D1 940E033A CALL pop_gset3
00D3 9508 RET
_load_Standard_ID_dates:
TIDL --> R12
TIDH --> R14
j --> R20
T0 --> R22
i --> R10
num --> Y+10
00D4 931A ST R17,-Y
00D5 930A ST R16,-Y
00D6 940E0340 CALL push_gset5
(0122) }
(0123) //****************************************************************************//
(0124) //###########################对CAN的一些操作####################################
(0125) //***************************要发送的数据包***********************************//
(0126) void load_Standard_ID_dates(uchar num)//给标准帧装载ID和数据
(0127) //选用发送缓冲器0,num:要发送的个数(最大8个)
(0128) {
(0129) uchar i,j,T0=0x36;
00D8 E366 LDI R22,0x36
(0130) uchar TIDH,TIDL;
(0131) i=TID[1]>>3;j=TID[0]<<5;j=j+i;i=TID[1]<<5;
00D9 90A0006F LDS R10,TID+1
00DB 94A6 LSR R10
00DC 94A6 LSR R10
00DD 94A6 LSR R10
00DE 9140006E LDS R20,TID
00E0 0F44 LSL R20
00E1 0F44 LSL R20
00E2 0F44 LSL R20
00E3 0F44 LSL R20
00E4 0F44 LSL R20
00E5 0D4A ADD R20,R10
00E6 90A0006F LDS R10,TID+1
00E8 0CAA LSL R10
00E9 0CAA LSL R10
00EA 0CAA LSL R10
00EB 0CAA LSL R10
00EC 0CAA LSL R10
(0132) TIDL=i;TIDH=j;//将数组TID中的值转化为TIDH,TIDL以便给TXB0SIDH,TXB0SIDL附值
00ED 2CCA MOV R12,R10
00EE 2EE4 MOV R14,R20
(0133) Write_Byte(CANCTRL,0x80);//CAN工作在配置模式
00EF E820 LDI R18,0x80
00F0 E00F LDI R16,0xF
00F1 DFC7 RCALL _Write_Byte
(0134) Write_Byte(CNF1,can_boud);
00F2 91200060 LDS R18,can_boud
00F4 E20A LDI R16,0x2A
00F5 DFC3 RCALL _Write_Byte
(0135) Write_Byte(TXB0SIDH,TIDH);
00F6 2D2E MOV R18,R14
00F7 E301 LDI R16,0x31
00F8 DFC0 RCALL _Write_Byte
(0136) Write_Byte(TXB0SIDL,TIDL);
00F9 2D2C MOV R18,R12
00FA E302 LDI R16,0x32
00FB DFBD RCALL _Write_Byte
(0137) Write_Byte(TXB0DLC,num);//
00FC 852A LDD R18,Y+10
00FD E305 LDI R16,0x35
00FE DFBA RCALL _Write_Byte
(0138) for(i=2;i<num+2;i++,T0++)Write_Byte(T0,Tdate[i]);
00FF E082 LDI R24,2
0100 2EA8 MOV R10,R24
0101 C00B RJMP 0x010D
0102 E684 LDI R24,0x64
0103 E090 LDI R25,0
0104 2DEA MOV R30,R10
0105 27FF CLR R31
0106 0FE8 ADD R30,R24
0107 1FF9 ADC R31,R25
0108 8120 LDD R18,Z+0
0109 2F06 MOV R16,R22
010A DFAE RCALL _Write_Byte
010B 94A3 INC R10
010C 9563 INC R22
010D 858A LDD R24,Y+10
010E 5F8E SUBI R24,0xFE
010F 16A8 CP R10,R24
0110 F388 BCS 0x0102
0111 940E033D CALL pop_gset5
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -