📄 mcp2510.lst
字号:
__text_start:
__start:
002D E5CF LDI R28,0x5F
002E E0D4 LDI R29,4
002F BFCD OUT 0x3D,R28
0030 BFDE OUT 0x3E,R29
0031 51C0 SUBI R28,0x10
0032 40D0 SBCI R29,0
0033 EA0A LDI R16,0xAA
0034 8308 STD Y+0,R16
0035 2400 CLR R0
0036 E6E6 LDI R30,0x66
0037 E0F0 LDI R31,0
0038 E010 LDI R17,0
0039 37E4 CPI R30,0x74
003A 07F1 CPC R31,R17
003B F011 BEQ 0x003E
003C 9201 ST R0,Z+
003D CFFB RJMP 0x0039
003E 8300 STD Z+0,R16
003F E5E4 LDI R30,0x54
0040 E0F0 LDI R31,0
0041 E6A0 LDI R26,0x60
0042 E0B0 LDI R27,0
0043 E010 LDI R17,0
0044 35EA CPI R30,0x5A
0045 07F1 CPC R31,R17
0046 F021 BEQ 0x004B
0047 95C8 LPM
0048 9631 ADIW R30,1
0049 920D ST R0,X+
004A CFF9 RJMP 0x0044
004B 940E0341 CALL _main
_exit:
004D CFFF RJMP _exit
FILE: F:\多运动体协调控制程序\通信程序1\mcp2510.c
(0001) //ICC-AVR application builder : 2007-10-17 16:47:59
(0002) // Target : M16
(0003) // Crystal: 16.000Mhz
(0004)
(0005) #include <iom16v.h>
(0006) #include <macros.h>
(0007) #define READ 0x03 // 读MCP2510指令代码
(0008) #define WRITE 0x02 // 写MCP2510指令代码
(0009) #define RESET 0xC0 // 复位MCP2510指令代码
(0010) #define RTS 0x80 // MCP2510请求发送指令代码
(0011) #define STA2510 0xA0 // 读MCP2510状态指令代码
(0012) #define BITMOD 0x05 // MCP2510位修改指令代码
(0013) int timecount;
(0014) int a[]; // SPI发送或接收数据寄存器
(0015) int b[]; // 发送或接收的数据
(0016) int c[]; // 发送或接收的数据
(0017) int i; // 临时变量
(0018) int count; // 发送接收计数器
(0019) int count1=0; // for test
(0020) int RecID_H=0;
(0021) int RecID_L=0;
(0022) int DLC;
(0023)
(0024) void port_init(void)
(0025) {
(0026) PORTA = 0xFF;
_port_init:
004E EF8F LDI R24,0xFF
004F BB8B OUT 0x1B,R24
(0027) DDRA = 0x00;
0050 2422 CLR R2
0051 BA2A OUT 0x1A,R2
(0028) PORTB = 0xFF;
0052 BB88 OUT 0x18,R24
(0029) DDRB = 0x00;
0053 BA27 OUT 0x17,R2
(0030) PORTC = 0xFF; //m103 output only
0054 BB85 OUT 0x15,R24
(0031) DDRC = 0x00;
0055 BA24 OUT 0x14,R2
(0032) PORTD = 0xFF;
0056 BB82 OUT 0x12,R24
(0033) DDRD = 0x00;
0057 BA21 OUT 0x11,R2
0058 9508 RET
(0034) }
(0035)
(0036) //TIMER0 initialize - prescale:1
(0037) // WGM: Normal
(0038) // desired value: 100KHz
(0039) // actual value: 100.000KHz (0.0%)
(0040) void timer0_init(void)
(0041) {
(0042) TCCR0 = 0x00; //stop
_timer0_init:
0059 2422 CLR R2
005A BE23 OUT 0x33,R2
(0043) TCNT0 = 0x60; //set count
005B E680 LDI R24,0x60
005C BF82 OUT 0x32,R24
(0044) OCR0 = 0xA0; //set compare
005D EA80 LDI R24,0xA0
005E BF8C OUT 0x3C,R24
(0045) TCCR0 = 0x01; //start timer
005F E081 LDI R24,1
0060 BF83 OUT 0x33,R24
0061 9508 RET
(0046) }
(0047)
(0048) #pragma interrupt_handler timer0_comp_isr:20
(0049) void timer0_comp_isr(void)
(0050) {/*int i=0;
(0051) timecount=0;
(0052) timecount++;
(0053) if (timecount>=1000) timecount=0;
(0054) SPDR=READ;
(0055) SPDR=0x66;
(0056) b[i]=SPDR;
(0057) b[i++]=SPDR;
(0058) while(!(SPSR & (1<<SPIF)))*/
(0059) ;
_timer0_comp_isr:
0062 9518 RETI
(0060) //compare occured TCNT0=OCR0
(0061) }
(0062)
(0063) //TIMER1 initialize - prescale:1
(0064) // WGM: 0) Normal, TOP=0xFFFF
(0065) // desired value: 100KHz
(0066) // actual value: 100.000KHz (0.0%)
(0067) void timer1_init(void)
(0068) {
(0069) TCCR1B = 0x00; //stop
_timer1_init:
0063 2422 CLR R2
0064 BC2E OUT 0x2E,R2
(0070) TCNT1H = 0xFF; //setup
0065 EF8F LDI R24,0xFF
0066 BD8D OUT 0x2D,R24
(0071) TCNT1L = 0x60;
0067 E680 LDI R24,0x60
0068 BD8C OUT 0x2C,R24
(0072) OCR1AH = 0x00;
0069 BC2B OUT 0x2B,R2
(0073) OCR1AL = 0xA0;
006A EA80 LDI R24,0xA0
006B BD8A OUT 0x2A,R24
(0074) OCR1BH = 0x00;
006C BC29 OUT 0x29,R2
(0075) OCR1BL = 0xA0;
006D BD88 OUT 0x28,R24
(0076) //OCR1CH = $OCR1CH$;
(0077) //OCR1CL = $OCR1CL$;
(0078) ICR1H = 0x00;
006E BC27 OUT 0x27,R2
(0079) ICR1L = 0xA0;
006F BD86 OUT 0x26,R24
(0080) TCCR1A = 0x50;
0070 E580 LDI R24,0x50
0071 BD8F OUT 0x2F,R24
(0081) TCCR1B = 0x01; //start Timer
0072 E081 LDI R24,1
0073 BD8E OUT 0x2E,R24
0074 9508 RET
(0082) }
(0083)
(0084) //TIMER2 initialize - prescale:1
(0085) // WGM: Normal
(0086) // desired value: 100KHz
(0087) // actual value: 100.000KHz (0.0%)
(0088) void timer2_init(void)
(0089) {
(0090) TCCR2 = 0x00; //stop
_timer2_init:
0075 2422 CLR R2
0076 BC25 OUT 0x25,R2
(0091) ASSR = 0x00; //set async mode
0077 BC22 OUT 0x22,R2
(0092) TCNT2 = 0x60; //setup
0078 E680 LDI R24,0x60
0079 BD84 OUT 0x24,R24
(0093) OCR2 = 0xA0;
007A EA80 LDI R24,0xA0
007B BD83 OUT 0x23,R24
(0094) TCCR2 = 0x11; //start
007C E181 LDI R24,0x11
007D BD85 OUT 0x25,R24
007E 9508 RET
(0095) }
(0096)
(0097) //SPI initialize
(0098) // clock rate: 4000000hz
(0099) void spi_init(void)
(0100) {
(0101) SPCR = 0x50; //setup SPI
_spi_init:
007F E580 LDI R24,0x50
0080 B98D OUT 0x0D,R24
(0102) SPSR = 0x00; //setup SPI
0081 2422 CLR R2
0082 B82E OUT 0x0E,R2
0083 9508 RET
(0103) }
(0104)
(0105) //ADC initialize
(0106) // Conversion time: 3uS
(0107) void adc_init(void)
(0108) {
(0109) ADCSR = 0x00; //disable adc
_adc_init:
0084 2422 CLR R2
0085 B826 OUT 0x06,R2
(0110) ADMUX = 0x00; //select adc input 0
0086 B827 OUT 0x07,R2
(0111) ACSR = 0x80;
0087 E880 LDI R24,0x80
0088 B988 OUT 0x08,R24
(0112) ADCSR = 0xE2;
0089 EE82 LDI R24,0xE2
008A B986 OUT 0x06,R24
008B 9508 RET
(0113) }
(0114)
(0115) //call this routine to initialize all peripherals
(0116) void init_devices(void)
(0117) {
(0118) //stop errant interrupts until set up
(0119) CLI(); //disable all interrupts
_init_devices:
008C 94F8 BCLR 7
(0120) port_init();
008D DFC0 RCALL _port_init
(0121) timer0_init();
008E DFCA RCALL _timer0_init
(0122) timer1_init();
008F DFD3 RCALL _timer1_init
(0123) timer2_init();
0090 DFE4 RCALL _timer2_init
(0124) spi_init();
0091 DFED RCALL _spi_init
(0125) adc_init();
0092 DFF1 RCALL _adc_init
(0126)
(0127) MCUCR = 0x00;
0093 2422 CLR R2
0094 BE25 OUT 0x35,R2
(0128) GICR = 0x00;
0095 BE2B OUT 0x3B,R2
(0129) TIMSK = 0x02; //timer interrupt sources
0096 E082 LDI R24,2
0097 BF89 OUT 0x39,R24
(0130) SEI(); //re-enable interrupts
0098 9478 BSET 7
0099 9508 RET
(0131) //all peripherals are now initialized
(0132) }
(0133)
(0134)
(0135) void SPIINT()// SPI中断服务子程序
(0136) {
(0137) SPSR=0x00;
_SPIINT:
009A 2422 CLR R2
009B B82E OUT 0x0E,R2
(0138) a[i++]=SPDR; // 数据暂存a[]中
009C 9020006A LDS R2,i
009E 9030006B LDS R3,i+1
00A0 01C1 MOVW R24,R2
00A1 9601 ADIW R24,1
00A2 9390006B STS i+1,R25
00A4 9380006A STS i,R24
00A6 E002 LDI R16,2
00A7 E010 LDI R17,0
00A8 0191 MOVW R18,R2
00A9 940E0349 CALL empy16s
00AB 01F8 MOVW R30,R16
00AC E780 LDI R24,0x70
00AD E090 LDI R25,0
00AE 0FE8 ADD R30,R24
00AF 1FF9 ADC R31,R25
00B0 B02F IN R2,0x0F
00B1 2433 CLR R3
00B2 8231 STD Z+1,R3
00B3 8220 STD Z+0,R2
(0139) count-=1;
00B4 91800068 LDS R24,count
00B6 91900069 LDS R25,count+1
00B8 9701 SBIW R24,1
00B9 93900069 STS count+1,R25
00BB 93800068 STS count,R24
(0140) if(count>0) SPDR=a[i];// 未发送完,继续
00BD 2422 CLR R2
00BE 1628 CP R2,R24
00BF 0639 CPC R3,R25
00C0 F48C BGE 0x00D2
00C1 9120006A LDS R18,i
00C3 9130006B LDS R19,i+1
00C5 E002 LDI R16,2
00C6 E010 LDI R17,0
00C7 940E0349 CALL empy16s
00C9 01F8 MOVW R30,R16
00CA E780 LDI R24,0x70
00CB E090 LDI R25,0
00CC 0FE8 ADD R30,R24
00CD 1FF9 ADC R31,R25
00CE 8020 LDD R2,Z+0
00CF 8031 LDD R3,Z+1
00D0 B82F OUT 0x0F,R2
00D1 C001 RJMP 0x00D3
(0141) else PORTB|=BIT(PB4);//否则,片选信号置高电平
00D2 9AC4 SBI 0x18,4
(0142) return;
00D3 9508 RET
_SPIEXCHANGE:
count --> R20
00D4 940E0364 CALL push_gset1
00D6 01A8 MOVW R20,R16
(0143) }
(0144)
(0145)
(0146) void SPIEXCHANGE(count)// 启动SPI传送
(0147) int count;
(0148) {
(0149) if(count>0) { // 有数据可送?
00D7 2422 CLR R2
00D8 2433 CLR R3
00D9 1624 CP R2,R20
00DA 0635 CPC R3,R21
00DB F4E4 BGE 0x00F8
(0150) i=0,i=i++;
00DC 9230006B STS i+1,R3
00DE 9220006A STS i,R2
00E0 01C1 MOVW R24,R2
00E1 9601 ADIW R24,1
00E2 9390006B STS i+1,R25
00E4 9380006A STS i,R24
00E6 9230006B STS i+1,R3
00E8 9220006A STS i,R2
(0151) PORTB&=~BIT(PB4); // 片选位置低电平
00EA 98C4 CBI 0x18,4
(0152) SPDR=a[i]; // 送数
00EB 0191 MOVW R18,R2
00EC E002 LDI R16,2
00ED E010 LDI R17,0
00EE 940E0349 CALL empy16s
00F0 01F8 MOVW R30,R16
00F1 E780 LDI R24,0x70
00F2 E090 LDI R25,0
00F3 0FE8 ADD R30,R24
00F4 1FF9 ADC R31,R25
00F5 8020 LDD R2,Z+0
00F6 8031 LDD R3,Z+1
00F7 B82F OUT 0x0F,R2
(0153) }
(0154) else
(0155) ; // 否则,空操作,并返回
(0156) return;
00F8 940E0367 CALL pop_gset1
00FA 9508 RET
(0157) }
(0158)
(0159) void WAIT_SPI()// 等待SPI传送完成
(0160) {
(0161) do{
(0162) ;
(0163) }while(count>0); // 当count!=0时,等待 to add "CLRWDT"
_WAIT_SPI:
00FB 2422 CLR R2
00FC 2433 CLR R3
00FD 90400068 LDS R4,count
00FF 90500069 LDS R5,count+1
0101 1424 CP R2,R4
0102 0435 CPC R3,R5
0103 F3BC BLT 0x00FB
(0164) return;
0104 9508 RET
(0165) }
(0166)
(0167) void RESET2510()//对MCP2510芯片进行复位
(0168) {
(0169) a[0]=RESET;
_RESET2510:
0105 EC80 LDI R24,0xC0
0106 E090 LDI R25,0
0107 93900071 STS a+1,R25
0109 93800070 STS a,R24
(0170) count=1;
010B E081 LDI R24,1
010C 93900069 STS count+1,R25
010E 93800068 STS count,R24
(0171) SPIEXCHANGE(count); // 送复位指令
0110 018C MOVW R16,R24
0111 DFC2 RCALL _SPIEXCHANGE
(0172) WAIT_SPI();
0112 DFE8 RCALL _WAIT_SPI
(0173) return;
0113 9508 RET
_RD2510:
j --> R20
n --> R22
adress --> R20
0114 940E0362 CALL push_gset2
0116 01B9 MOVW R22,R18
0117 01A8 MOVW R20,R16
(0174) }
(0175)
(0176) void RD2510(adress,n)//从地址
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -