📄 main.lst
字号:
__text_start:
__start:
002A E5CF LDI R28,0x5F
002B E0D4 LDI R29,4
002C BFCD OUT 0x3D,R28
002D BFDE OUT 0x3E,R29
002E 51C0 SUBI R28,0x10
002F 40D0 SBCI R29,0
0030 EA0A LDI R16,0xAA
0031 8308 STD Y+0,R16
0032 2400 CLR R0
0033 E6E0 LDI R30,0x60
0034 E0F0 LDI R31,0
0035 E010 LDI R17,0
0036 36E0 CPI R30,0x60
0037 07F1 CPC R31,R17
0038 F011 BEQ 0x003B
0039 9201 ST R0,Z+
003A CFFB RJMP 0x0036
003B 8300 STD Z+0,R16
003C E5E4 LDI R30,0x54
003D E0F0 LDI R31,0
003E E6A0 LDI R26,0x60
003F E0B0 LDI R27,0
0040 E010 LDI R17,0
0041 35E4 CPI R30,0x54
0042 07F1 CPC R31,R17
0043 F021 BEQ 0x0048
0044 95C8 LPM
0045 9631 ADIW R30,1
0046 920D ST R0,X+
0047 CFF9 RJMP 0x0041
0048 940E00B0 CALL _main
_exit:
004A CFFF RJMP _exit
FILE: F:\2007电子设计\古欣\twitest\twi_test\twi.c
(0001)
(0002) #include "config.h"
(0003)
(0004) //TWI master initialize
(0005) // bit rate:100
(0006) void twi_master_init(void)
(0007) {
(0008) TWCR= 0x00; //disable twi
_twi_master_init:
004B 2422 CLR R2
004C BE26 OUT 0x36,R2
(0009) TWBR= 0x64; //set bit rate
004D E684 LDI R24,0x64
004E B980 OUT 0x00,R24
(0010) TWSR= 0x00; //set prescale
004F B821 OUT 0x01,R2
(0011) TWAR= 0x00; //set slave address
0050 B822 OUT 0x02,R2
(0012) TWCR= 0x04; //enable twi
0051 E084 LDI R24,4
0052 BF86 OUT 0x36,R24
0053 9508 RET
(0013) }
(0014)
(0015) //TWI slave initialize
(0016) // bit rate:100
(0017) void twi_slave_init(uint8 add)
(0018) {
(0019) TWCR= 0x00; //disable twi
_twi_slave_init:
add --> R16
0054 2422 CLR R2
0055 BE26 OUT 0x36,R2
(0020) TWBR= 0x64; //set bit rate
0056 E684 LDI R24,0x64
0057 B980 OUT 0x00,R24
(0021) TWSR= 0x00; //set prescale
0058 B821 OUT 0x01,R2
(0022) TWAR= (add<<1); //set slave address 从机地址为 0x01
0059 2E20 MOV R2,R16
005A 0C22 LSL R2
005B B822 OUT 0x02,R2
(0023) TWCR= (1<<TWEN)|(1<<TWEA)|(1<<TWIE); //enable twi
005C E485 LDI R24,0x45
005D BF86 OUT 0x36,R24
005E 9508 RET
(0024) //TWEN必须置位以使能TWI接口。TWEA也要置位以使主机寻址到自己(从机地址或广播) 时返回确认信息ACK
(0025) }
(0026)
(0027) //总线上起动开始条件
(0028) void i2c_start(void)
(0029) {
(0030) TWCR= (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
_i2c_start:
005F EA84 LDI R24,0xA4
0060 BF86 OUT 0x36,R24
(0031) while (!(TWCR & (1<<TWINT))); //等待START 信号成功发送
0061 B626 IN R2,0x36
0062 FE27 SBRS R2,7
0063 CFFD RJMP 0x0061
0064 9508 RET
(0032) }
(0033)
(0034) //把一个字节数据输入器件, 返回TWI状态
(0035) //发送地址,r_w:1为读,0为写
(0036) uint8 i2c_write_addr(uint8 addr,uint8 r_w)
(0037) {
(0038) if(r_w)
_i2c_write_addr:
r_w --> R18
addr --> R16
0065 2322 TST R18
0066 F021 BEQ 0x006B
(0039) {
(0040) TWDR = addr|r_w; //RW 为1:读操作
0067 2E20 MOV R2,R16
0068 2A22 OR R2,R18
0069 B823 OUT 0x03,R2
(0041) }
006A C003 RJMP 0x006E
(0042) else
(0043) {
(0044) TWDR = addr & 0xFE; // RW 为0: 写操作
006B 2F80 MOV R24,R16
006C 7F8E ANDI R24,0xFE
006D B983 OUT 0x03,R24
(0045) }
(0046)
(0047) TWCR = (1<<TWINT)|(1<<TWEN);
006E E884 LDI R24,0x84
006F BF86 OUT 0x36,R24
(0048) while (!(TWCR & (1<<TWINT)));
0070 B626 IN R2,0x36
0071 FE27 SBRS R2,7
0072 CFFD RJMP 0x0070
(0049) _NOP();
0073 0000 NOP
(0050) return(TWSR&0b11111000); //TWSR高五位为I2C工作状态。
0074 B101 IN R16,0x01
0075 7F08 ANDI R16,0xF8
0076 9508 RET
(0051) }
(0052)
(0053) //把一个字节数据输入器件, 返回TWI状态
(0054) //发送数据
(0055) uint8 i2c_write_data(uint8 data)
(0056) {
(0057) TWDR = data;
_i2c_write_data:
data --> R16
0077 B903 OUT 0x03,R16
(0058) TWCR = (1<<TWINT)|(1<<TWEN);
0078 E884 LDI R24,0x84
0079 BF86 OUT 0x36,R24
(0059) while (!(TWCR & (1<<TWINT)));
007A B626 IN R2,0x36
007B FE27 SBRS R2,7
007C CFFD RJMP 0x007A
(0060) _NOP();
007D 0000 NOP
(0061) return(TWSR&0b11111000); //TWSR高五位为I2C工作状态。
007E B101 IN R16,0x01
007F 7F08 ANDI R16,0xF8
0080 9508 RET
(0062) }
(0063)
(0064)
(0065) //从器件读出一个字节
(0066) uint8 i2c_read(void)
(0067) {
(0068) TWCR = (1<<TWINT)|(1<<TWEN);
_i2c_read:
0081 E884 LDI R24,0x84
0082 BF86 OUT 0x36,R24
(0069) Twi_NoAcK();
0083 B786 IN R24,0x36
0084 708F ANDI R24,0xF
0085 6880 ORI R24,0x80
0086 BF86 OUT 0x36,R24
(0070) while (!(TWCR & (1<<TWINT)));
0087 B626 IN R2,0x36
0088 FE27 SBRS R2,7
0089 CFFD RJMP 0x0087
(0071) return(TWDR);
008A B103 IN R16,0x03
008B 9508 RET
(0072) }
(0073)
(0074) //总线上起动停止条件
(0075) void i2c_stop(void)
(0076) {
(0077) TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
_i2c_stop:
008C E984 LDI R24,0x94
008D BF86 OUT 0x36,R24
008E 9508 RET
_i2c_maste_transt:
data --> R20
addr --> R22
008F 940E0153 CALL push_gset2
0091 2F42 MOV R20,R18
0092 2F60 MOV R22,R16
(0078) }
(0079)
(0080) //操作步骤: 启动,发送地址,发送数据,关闭总线
(0081) void i2c_maste_transt(uint8 addr, uint8 data)
(0082) {
(0083) i2c_start();
0093 DFCB RCALL _i2c_start
(0084)
(0085) if(i2c_write_addr(addr, 0)==TW_MT_SLA_ACK) //发送地址成功并收到ACK
0094 2722 CLR R18
0095 2F06 MOV R16,R22
0096 DFCE RCALL _i2c_write_addr
0097 3108 CPI R16,0x18
0098 F411 BNE 0x009B
(0086) {
(0087) i2c_write_data(data);
0099 2F04 MOV R16,R20
009A DFDC RCALL _i2c_write_data
(0088) }
(0089) i2c_stop();
009B DFF0 RCALL _i2c_stop
009C 940E014A CALL pop_gset2
009E 9508 RET
_i2c_maste_read:
tmp --> R20
addr --> R22
009F 940E0153 CALL push_gset2
00A1 2F60 MOV R22,R16
(0090) }
(0091) //操作步骤,启动,发送地址,读数据,关闭总线
(0092) uint8 i2c_maste_read(uint8 addr)
(0093) {
(0094) uint8 tmp=0;
00A2 2744 CLR R20
(0095) i2c_start();
00A3 DFBB RCALL _i2c_start
(0096) if(i2c_write_addr(addr, 1)==TW_MR_SLA_ACK) //发送地址成功并收到ACK
00A4 E021 LDI R18,1
00A5 2F06 MOV R16,R22
00A6 DFBE RCALL _i2c_write_addr
00A7 3400 CPI R16,0x40
00A8 F411 BNE 0x00AB
(0097) {
(0098) tmp=i2c_read();
00A9 DFD7 RCALL _i2c_read
00AA 2F40 MOV R20,R16
(0099) }
(0100) i2c_stop();
00AB DFE0 RCALL _i2c_stop
(0101) return tmp;
00AC 2F04 MOV R16,R20
00AD 940E014A CALL pop_gset2
00AF 9508 RET
FILE: F:\2007电子设计\古欣\twitest\twi_test\main_master.c
(0001) //ICC-AVR application builder : 2007-7-19 9:50:03
(0002) // Target : M16
(0003) // Crystal: 7.3728Mhz
(0004) //主机从1到255发一个数,收一个数。从机接收到任何数都返回。
(0005) //当主机收到的数为0x10时,从零开始发送。
(0006) #include "config.h"
(0007)
(0008) void main(void)
(0009) {
(0010) uint8 i=0,tmp=0;
_main:
tmp --> R20
i --> R22
00B0 2766 CLR R22
00B1 2744 CLR R20
(0011) //re-enable interrupts
(0012) DDRC=0X00;
00B2 2422 CLR R2
00B3 BA24 OUT 0x14,R2
(0013) PORTC=0x03; //使能内部上拉电阻
00B4 E083 LDI R24,3
00B5 BB85 OUT 0x15,R24
(0014) twi_master_init();
00B6 940E004B CALL _twi_master_init
00B8 C00E RJMP 0x00C7
(0015)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -