📄 sr.lst
字号:
__start:
__text_start:
0018 E5CF LDI R28,0x5F
0019 E0D4 LDI R29,4
001A BFCD OUT 0x3D,R28
001B BFDE OUT 0x3E,R29
001C 51C0 SUBI R28,0x10
001D 40D0 SBCI R29,0
001E EA0A LDI R16,0xAA
001F 8308 STD Y+0,R16
0020 2400 CLR R0
0021 E6E9 LDI R30,0x69
0022 E0F0 LDI R31,0
0023 E010 LDI R17,0
0024 36E9 CPI R30,0x69
0025 07F1 CPC R31,R17
0026 F011 BEQ 0x0029
0027 9201 ST R0,Z+
0028 CFFB RJMP 0x0024
0029 8300 STD Z+0,R16
002A E2E6 LDI R30,0x26
002B E0F0 LDI R31,0
002C E6A0 LDI R26,0x60
002D E0B0 LDI R27,0
002E E010 LDI R17,0
002F 32EF CPI R30,0x2F
0030 07F1 CPC R31,R17
0031 F021 BEQ 0x0036
0032 95C8 LPM
0033 9631 ADIW R30,1
0034 920D ST R0,X+
0035 CFF9 RJMP 0x002F
0036 D0AD RCALL _main
_exit:
0037 CFFF RJMP _exit
FILE: E:\iccavr\无线+I2C\test1--sr\twi.c
(0001)
(0002) /*函数的使用说明:
(0003) 1.该twi模块包含四种工作模式,主发,主收,从收,从发,其中主发由
(0004) twiWriteByte(从机地址,要发送的数据)实现,主收由twiReadByte(从机地址)实现,从机
(0005) 的发送与接收均通过中断实现
(0006) 2.在从机模式下,需调用twi_init()来使能并初始化twi总线
(0007) 3.在主机模式下,调用twiWriteByte(从机地址,要发送的数据)向指定的从机写入数据,
(0008) 调用twiReadByte(从机地址)从指定的从机读取数据,然后可通过查询错误状态error_state
(0009) 的值决定下一步如何操作。
(0010) */
(0011)
(0012) //************************* 头文件 ******************************************
(0013) #include "twi.h"
(0014)
(0015) //TWI同程序的接口参数
(0016) //receive_data,error_state不用设置
(0017) extern char receive_data; // 接收到的数据
(0018) extern char error_state; // twi错误状态
(0019) //以下三个参数根据需求进行设置
(0020) extern char slave_address; // 设置从机地址,Bits 7..1:存放从机地址,Bit 0:最低位为广播识别使能位
(0021) extern char bit_race; // 设置主机模式的比特率,SCL=CPU频率/(16+2*(TWBR)*4TWPS),TWPS在4的指数位置
(0022) extern char send_data; // 从机发送模式下从机向主机发送的数据
(0023)
(0024) //*************************** twi错误状态说明*********************************
(0025) // 0:twi传送无错误
(0026) // 1:在主发模式下,SLA+W已发送,返回NOT ACK
(0027) // 2:在主发模式下,DATA已发送,返回NOT ACK
(0028) // 3:在主发模式下,SLA+W或者数据的仲裁失败
(0029) // 4:在主收模式下,SLA+R或者数据的仲裁失败
(0030) // 5:在主收模式下,SLA+R已发送,返回NOT ACK
(0031) // 6:在主发模式下,START信号发送不成功
(0032) // 7:在主收模式下,START信号发送不成功
(0033) // 8:在主收模式下,数据接受完成
(0034) // 9:在主收模式下,数据接受不成功
(0035) //*****************************************************************************
(0036)
(0037) //*************************** twi stop 信号延时时间 ****************************
(0038) //******************************************************************************
(0039) void StopDelay(void)
(0040) {
(0041) unsigned int i;
(0042) for(i = 0;i < 20;i ++);
_StopDelay:
i --> R16
0038 2700 CLR R16
0039 2711 CLR R17
003A C002 RJMP 0x003D
003B 5F0F SUBI R16,0xFF
003C 4F1F SBCI R17,0xFF
003D 3104 CPI R16,0x14
003E E0E0 LDI R30,0
003F 071E CPC R17,R30
0040 F3D0 BCS 0x003B
(0043) }
0041 9508 RET
(0044) //******************************* twi 启动总线*********************************
(0045) //******************************************************************************
(0046) void start(void)
(0047) {
(0048) TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); //发出start信号
_start:
0042 EA84 LDI R24,0xA4
0043 BF86 OUT 0x36,R24
(0049) _NOP();
0044 0000 NOP
(0050) _NOP();
0045 0000 NOP
(0051) }
0046 9508 RET
(0052) //************************** twi 释放总线************************************
(0053) //***************************************************************************
(0054) void stop(void)
(0055) {
(0056) TWCR = (1 << TWINT) |(1 << TWEN)|(1 << TWSTO); //发出stop信号
_stop:
0047 E984 LDI R24,0x94
0048 BF86 OUT 0x36,R24
(0057) StopDelay(); //等待总线恢复
0049 DFEE RCALL _StopDelay
(0058) TWCR= 0x45;
004A E485 LDI R24,0x45
004B BF86 OUT 0x36,R24
(0059) }
004C 9508 RET
(0060) //****************************** twi 初始化*************************************
(0061) // TWCR: 控制寄存器,用来控制TWI操作,说明如下:
(0062) // Bit 7-TWINT:中断标志位,Bit 6-TWEA:使能应答位,Bit 5-TWSTA:START状态位
(0063) // Bit 4-TWSTO:STOP状态位,Bit 3-TWWC: 写冲突标志,Bit 2-TWEN:TWI使能位
(0064) // Bit 1-RES:保留,Bit 0-TWIE:中断使能
(0065) // TWSR: 状态寄存器,Bits 7..3:表示了TWI总线的当前状态,读取时需屏蔽低三位的值,Bits 1..0-TWPS:TWI预分频位
(0066) // TWBR: 比特率寄存器,用来设置TWI的工作频率,计算公式为:SCL=CPU频率/(16+2*(TWBR)*4TWPS),TWPS在4的指数位置
(0067) // TWAR: 从机地址寄存器,Bits 7..1:存放从机地址,Bit 0:最低位为广播识别使能位
(0068) // TWDR: 数据寄存器,用来存放接收或要发送的地址和数据
(0069) //******************************************************************************
(0070) void twi_init(void)
(0071) {
(0072) TWCR= 0x00; //disable twi
_twi_init:
004D 2422 CLR R2
004E BE26 OUT 0x36,R2
(0073) TWBR= bit_race; //set bit rate
004F 90200063 LDS R2,0x63
0051 B820 OUT 0x00,R2
(0074) TWSR= 0x00; //set prescale为1
0052 2422 CLR R2
0053 B821 OUT 0x01,R2
(0075) TWAR= slave_address; //set slave address
0054 90200062 LDS R2,0x62
0056 B822 OUT 0x02,R2
(0076) TWCR= 0x45; //enable twi
0057 E485 LDI R24,0x45
0058 BF86 OUT 0x36,R24
(0077) }
0059 9508 RET
_twi_isr:
TWSR_state --> R16
005A 922A ST R2,-Y
005B 930A ST R16,-Y
005C 931A ST R17,-Y
005D 938A ST R24,-Y
005E 939A ST R25,-Y
005F 93EA ST R30,-Y
0060 B62F IN R2,0x3F
0061 922A ST R2,-Y
(0078) //************************** 检测发送时的状态码 ****************************
(0079) //**************************************************************************
(0080) /*void checkstate(void)
(0081) {
(0082) unsigned char TWSR_state;
(0083) TWSR_state = TWSR & 0xf8; //屏蔽第三位读取状态
(0084) switch(TWSR_state)
(0085) {
(0086) case 0x08:error_state=0;break; // START已发送
(0087) case 0x18:error_state=0;break; // SLA+W已发送,接收到ACK
(0088) case 0x20:error_state=1;break; // SLA+W已发送,接收到NOT ACK
(0089) case 0x28:error_state=0;break; // 数据已发送,接收到ACK
(0090) case 0x30:error_state=2;break; // 数据已发送,接收到NOT ACK
(0091) case 0x38:error_state=3;break; // SLA+W或数据的仲裁失败
(0092) default: break;
(0093) }
(0094) TWCR=0x45;
(0095) }
(0096) //********** twi主机发送,向地址为WriteAddress的从机发送1个字节数据************
(0097) // 入口参数1:WriteAddress:从机地址
(0098) // TWDR中存放的高七位为地址,最低位表示读写控制,0为写,1为读
(0099) // 入口参数2:data,向从机写的数据
(0100) //******************************************************************************
(0101) void twiWriteByte(unsigned char WriteAddress,char data)
(0102) {
(0103) unsigned char TWCR_state;
(0104) char i=0;
(0105) error_state=0;
(0106)
(0107) //初始化 twi
(0108) twi_init();
(0109)
(0110) //发送START信号
(0111) start();
(0112) TWCR_state = TWCR & 0x80;
(0113) while((TWCR_state == 0x00))
(0114) {
(0115) i++;
(0116) if(i>=10){error_state=6;break;}
(0117) TWCR_state = TWCR & 0x80; //轮循等待START信号发送完成
(0118) }
(0119)
(0120) //若START发送成功,发送从机地址
(0121) if(error_state==0)
(0122) {
(0123) TWDR = WriteAddress; //发地址
(0124) _NOP();
(0125) _NOP();
(0126)
(0127) TWCR = (1 << TWINT) | (1 << TWEN);
(0128) TWCR_state = TWCR & 0x80;
(0129) while(TWCR_state == 0x00)
(0130) {TWCR_state = TWCR & 0x80;} //轮循查询地址是否发送
(0131) checkstate();
(0132) }
(0133)
(0134) //若从机地址发送成功,向从机发送数据
(0135) if(error_state==0)
(0136) {
(0137) TWDR = data; //发数据
(0138) _NOP();
(0139) _NOP();
(0140) TWCR = (1 << TWINT) | (1 << TWEN);
(0141) TWCR_state = TWCR & 0x80;
(0142) while(TWCR_state == 0x00) TWCR_state = TWCR & 0x80; //轮循查询数据是否发送
(0143) checkstate();
(0144) }
(0145)
(0146) //发送STOP,退出总线控制
(0147) stop();
(0148) }
(0149) //************** twi主机接收,从地址为ReadAaddress的从机接收1个字节*************
(0150) // 入口参数1:ReadAaddress:从机地址
(0151) // TWDR中存放的高七位为地址,最低位表示读写控制,0为写,1为读
(0152) //******************************************************************************
(0153) void twiReadByte(unsigned char ReadAaddress)
(0154) {
(0155) unsigned char TWCR_state;
(0156) char i=0;
(0157) error_state=0;
(0158)
(0159) //初始化 twi
(0160) twi_init();
(0161)
(0162) //发送START信号
(0163) start();
(0164) TWCR_state = TWCR & 0x80;
(0165) while((TWCR_state == 0x00))
(0166) {
(0167) i++;
(0168) if(i>=10){error_state=7;break;}
(0169) TWCR_state = TWCR & 0x80; //轮循等待START信号发送完成
(0170) }
(0171)
(0172) //若START信号发送完成,发送读地址,并读取数据
(0173) if(error_state==0)
(0174) {
(0175) TWDR = ReadAaddress; //发地址
(0176) _NOP();
(0177) _NOP();
(0178) TWCR = (1 << TWINT) | (1 << TWEN)|( 1<<TWIE )|(1 << TWEA);
(0179) while(error_state==0)
(0180) {i++;if(i>150){error_state=9;break;}};
(0181) }
(0182)
(0183) //发送STOP,退出总线控制
(0184) stop();
(0185) }*/
(0186) //************** twi 中断例程,接收数据 ****************************************
(0187) //******************************************************************************
(0188) //twi中断服务程序
(0189) char twi_isr(void)
(0190) {
(0191) unsigned char TWSR_state;
(0192) TWSR_state = TWSR & 0xf8;
0062 B101 IN R16,0x01
0063 7F08 ANDI R16,0xF8
(0193) switch(TWSR_state)
0064 2711 CLR R17
0065 3800 CPI R16,0x80
0066 E0E0 LDI R30,0
0067 071E CPC R17,R30
0068 F139 BEQ 0x0090
0069 E880 LDI R24,0x80
006A E090 LDI R25,0
006B 1780 CP R24,R16
006C 0791 CPC R25,R17
006D F064 BLT 0x007A
006E 3000 CPI R16,0
006F 0701 CPC R16,R17
0070 F159 BEQ 0x009C
0071 3000 CPI R16,0
0072 E0E0 LDI R30,0
0073 071E CPC R17,R30
0074 F14C BLT 0x009E
0075 3600 CPI R16,0x60
0076 E0E0 LDI R30,0
0077 071E CPC R17,R30
0078 F0A1 BEQ 0x008D
0079 C024 RJMP 0x009E
007A 3A00 CPI R16,0xA0
007B E0E0 LDI R30,0
007C 071E CPC R17,R30
007D F0D9 BEQ 0x0099
007E EA80 LDI R24,0xA0
007F E090 LDI R25,0
0080 1780 CP R24,R16
0081 0791 CPC R25,R17
0082 F02C BLT 0x0088
0083 3808 CPI R16,0x88
0084 E0E0 LDI R30,0
0085 071E CPC R17,R30
0086 F079 BEQ 0x0096
0087 C016 RJMP 0x009E
0088 3F08 CPI R16,0xF8
0089 E0E0 LDI R30,0
008A 071E CPC R17,R30
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -