⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 light.lst

📁 详细介绍M8两版间通讯
💻 LST
📖 第 1 页 / 共 3 页
字号:
    010B 99E1      SBIC	0x1C,1
    010C CFFE      RJMP	_rom_write
(0006) 	EEAR=Address;
    010D BB1F      OUT	0x1F,R17
    010E BB0E      OUT	0x1E,R16
(0007) 	EEDR=Data;
    010F BB2D      OUT	0x1D,R18
(0008) 	EECR|=(1<<EEMWE);
    0110 9AE2      SBI	0x1C,2
(0009) 	EECR|=(1<<EEWE);
    0111 9AE1      SBI	0x1C,1
    0112 9508      RET
(0010)  }
(0011) unsigned char rom_read(unsigned int Address)
(0012)  {
(0013)  	CLI();
_rom_read:
  Address              --> R16
    0113 94F8      BCLR	7
(0014) 	while(EECR&(1<<EEWE));
    0114 99E1      SBIC	0x1C,1
    0115 CFFE      RJMP	0x0114
(0015) 	EEAR=Address;
    0116 BB1F      OUT	0x1F,R17
    0117 BB0E      OUT	0x1E,R16
(0016) 	EECR|=(1<<EERE);
    0118 9AE0      SBI	0x1C,0
(0017) 	SEI();
    0119 9478      BSET	7
(0018) 	return EEDR;
    011A B30D      IN	R16,0x1D
    011B 9508      RET
FILE: G:\Mega8程序\TCXO评估板\LedShow\I2C.c
(0001) /*******************************************************
(0002) 本部分为TWI总线的被控器部分程序,可以完成被控接收、被控发送数据
(0003) 其工作方式与At240×系列的EEPROM的字节读写相同
(0004) 目前问题是EEPROM的读写速度太慢,无法跟上TWI总线速度。
(0005) *///////////////////////////////////////////////////////
(0006) 
(0007) #include<iom8v.h>
(0008) #include <macros.h>
(0009) /*     AT2402C地址
(0010) 1	0	1	0		A2 A1 A0 R/W
(0011) 前4位为AT240X系列的特征字
(0012) 后3位为可编程位
(0013) 最后一位为读写位
(0014) */
(0015) #define rd_device_add 0xa1 //读地址:0b10100001
(0016) #define wr_device_add 0xa0 //写地址:0b10100000
(0017) 
(0018) /*TWI状态定义----MT 主方式传输  MR 主方式接收*/
(0019) #define START								0x08
(0020) #define RE_START						0x10
(0021) 
(0022) #define MT_SLA_ACK					0x18
(0023) #define MT_SLA_NOACK				0x20
(0024) #define MT_DATA_ACK					0x28
(0025) #define MT_DATA_NOACK				0x30
(0026) 
(0027) #define MR_SLA_ACK					0x40
(0028) #define MR_SLA_NOACK				0x48
(0029) #define MR_DATA_ACK					0x50
(0030) #define MR_DATA_NOACK				0x58
(0031) 
(0032) //SR-从机方式接收  ST-从机方式传输  ALL-广播 NOCTRL-主机丢失控制权
(0033) #define SR_SLA_ACK					0x60
(0034) #define SR_SLA_ACK_NOCTRL		0x68
(0035) #define SR_ALL_ACK					0x70
(0036) #define SR_ALL_ACK_NOCTRL		0x78
(0037) #define SR_DATA_ACK					0X80
(0038) #define SR_DATA_NOACK				0X88
(0039) #define SR_ALL_DATA_ACK			0x90
(0040) #define SR_ALL_DATA_NOACK		0x98
(0041) #define SR_STOP_RESTART			0xa0
(0042) 
(0043) #define ST_SLA_ACK					0xa8
(0044) #define ST_SLA_ACK_NOCTRL		0xb0
(0045) #define ST_DATA_ACK					0xb8
(0046) #define ST_DATA_NOACK				0xc0
(0047) #define ST_LAST_DATA_ACK		0xc8
(0048) 
(0049) ///////////////////////////////////////////////////////////
(0050) #define EE_READ							0xf0
(0051) #define EE_READ_OK					0x50
(0052) #define EE_WRITE						0x0f
(0053) #define EE_WRITE_OK					0x05
(0054) #define EE_WRITE_OVER				0xa5
(0055) 
(0056) #define TestAck() (TWSR&0xf8)
(0057) //TWSR--I2C状态寄存器,检查TWI状态,应该将预分频位屏蔽(第三位是保留位)
(0058) 
(0059) #define Start()						(TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE))
(0060) //清除中断标志位,在总线上发出起始信号,激活TWI功能,开放TWI中断
(0061) #define Stop()						(TWCR=((1<<TWINT)|(1<<TWSTO)|(1<<TWEN))&(~(1<<TWIE)))
(0062) //清除中断标志位,在总线上发出终止信号,激活TWI功能,关闭TWI中断
(0063) #define MT_NACK						(TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWIE))
(0064) //清除中断标志位,使能TWI功能,开放TWI中断,在主控接收状态下不对SDA线作应答
(0065) #define MT_ACK						(TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWIE)|(1<<TWEA))
(0066) //清除中断标志位,使能TWI功能,开放TWI中断,在主控接收状态下对SDA线作应答
(0067) #define TWItransmit(x)		{TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWIE);}
(0068) //写入8位数据到数据寄存器中,同时清除中断标志位,使能TWI功能,开放TWI中断
(0069) 
(0070) extern char cDataBuff[];
(0071) extern void rom_write(unsigned int Address,unsigned  char Data);
(0072) extern unsigned char rom_read(unsigned int Address);
(0073) 
(0074) unsigned char charData;//TWI中断中,传送的数据
(0075) unsigned char charAddr;//TWI中断中,数据所处的EEPROM地址
(0076) unsigned char charState;//TWI中断中,中断所处的状态
(0077) 
(0078) void TWI_init(void)
(0079)  {
(0080) 	DDRC&=0b11001111;//设置PC4、PC5为输入
_TWI_init:
    011C B384      IN	R24,0x14
    011D 7C8F      ANDI	R24,0xCF
    011E BB84      OUT	0x14,R24
(0081) 	PORTC|=0b00110000;//将SDA、SCL线拉高(内置上拉电阻)
    011F B385      IN	R24,0x15
    0120 6380      ORI	R24,0x30
    0121 BB85      OUT	0x15,R24
(0082) 	charState=EE_READ;
    0122 EF80      LDI	R24,0xF0
    0123 9380008C  STS	charState,R24
(0083) 	TWBR=0x00;//波特率寄存器,主机正常情况下应不小于10
    0125 2422      CLR	R2
    0126 B820      OUT	0x00,R2
(0084) 	TWSR=0x00;//TWI状态寄存器,时钟分频值1
    0127 B821      OUT	0x01,R2
(0085) 	TWAR=0xa0;/*被控器地址寄存器。0xa0为AT2402的地址,可以用ATMEGA8来模拟AT2402。
    0128 EA80      LDI	R24,0xA0
    0129 B982      OUT	0x02,R24
(0086) 	 						作为从机,应该将被控器的地址写入。注意不要和其他器件相同*/
(0087) 	TWCR=(TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWIE)|(1<<TWEA));//清除中断标志位,使能TWI功能,开放TWI中断
    012A EC85      LDI	R24,0xC5
    012B BF86      OUT	0x36,R24
    012C BF86      OUT	0x36,R24
    012D 9508      RET
_TWI_Ready:
  charTemp             --> R20
  TWI_STATE            --> R22
    012E 922A      ST	R2,-Y
    012F 923A      ST	R3,-Y
    0130 930A      ST	R16,-Y
    0131 931A      ST	R17,-Y
    0132 938A      ST	R24,-Y
    0133 939A      ST	R25,-Y
    0134 93EA      ST	R30,-Y
    0135 93FA      ST	R31,-Y
    0136 B62F      IN	R2,0x3F
    0137 922A      ST	R2,-Y
    0138 D1C2      RCALL	push_gset2
(0088)  }
(0089) #pragma interrupt_handler TWI_Ready:iv_TWI//TWI中断处理
(0090) void TWI_Ready(void)
(0091)  {
(0092)  	static unsigned char charIndex=0;
(0093)  	unsigned char charTemp;
(0094)  	unsigned char TWI_STATE;
(0095) 	TWI_STATE=TestAck();
    0139 B161      IN	R22,0x01
    013A 7F68      ANDI	R22,0xF8
(0096) 	switch (TWI_STATE)//检查状态标志字
    013B 2F46      MOV	R20,R22
    013C 2755      CLR	R21
    013D 3A40      CPI	R20,0xA0
    013E E0E0      LDI	R30,0
    013F 075E      CPC	R21,R30
    0140 F409      BNE	0x0142
    0141 C103      RJMP	0x0245
    0142 EA80      LDI	R24,0xA0
    0143 E090      LDI	R25,0
    0144 1784      CP	R24,R20
    0145 0795      CPC	R25,R21
    0146 F074      BLT	0x0155
    0147 3640      CPI	R20,0x60
    0148 E0E0      LDI	R30,0
    0149 075E      CPC	R21,R30
    014A F101      BEQ	0x016B
    014B 3640      CPI	R20,0x60
    014C E0E0      LDI	R30,0
    014D 075E      CPC	R21,R30
    014E F40C      BGE	0x0150
    014F C111      RJMP	0x0261
    0150 3840      CPI	R20,0x80
    0151 E0E0      LDI	R30,0
    0152 075E      CPC	R21,R30
    0153 F0D1      BEQ	0x016E
    0154 C10C      RJMP	0x0261
    0155 3B48      CPI	R20,0xB8
    0156 E0E0      LDI	R30,0
    0157 075E      CPC	R21,R30
    0158 F409      BNE	0x015A
    0159 C0F3      RJMP	0x024D
    015A EB88      LDI	R24,0xB8
    015B E090      LDI	R25,0
    015C 1784      CP	R24,R20
    015D 0795      CPC	R25,R21
    015E F034      BLT	0x0165
    015F 3A48      CPI	R20,0xA8
    0160 E0E0      LDI	R30,0
    0161 075E      CPC	R21,R30
    0162 F409      BNE	0x0164
    0163 C0E4      RJMP	0x0248
    0164 C0FC      RJMP	0x0261
    0165 3C40      CPI	R20,0xC0
    0166 E0E0      LDI	R30,0
    0167 075E      CPC	R21,R30
    0168 F409      BNE	0x016A
    0169 C0F4      RJMP	0x025E
    016A C0F6      RJMP	0x0261
(0097) 	 {
(0098) 	 	case SR_SLA_ACK:
(0099) 	 	 {
(0100) 	 	 	MT_ACK;
    016B EC85      LDI	R24,0xC5
    016C BF86      OUT	0x36,R24
(0101) 	 	 }
(0102) 	 	break;
    016D C150      RJMP	0x02BE
(0103) 	 	case SR_DATA_ACK:
(0104) 	 	 {
(0105) 	 	 	switch (charState)
    016E 9140008C  LDS	R20,charState
    0170 2755      CLR	R21
    0171 3540      CPI	R20,0x50
    0172 E0E0      LDI	R30,0
    0173 075E      CPC	R21,R30
    0174 F0B9      BEQ	0x018C
    0175 3540      CPI	R20,0x50
    0176 E0E0      LDI	R30,0
    0177 075E      CPC	R21,R30
    0178 F40C      BGE	0x017A
    0179 C144      RJMP	0x02BE
    017A 3F40      CPI	R20,0xF0
    017B E0E0      LDI	R30,0
    017C 075E      CPC	R21,R30
    017D F009      BEQ	0x017F
    017E C13F      RJMP	0x02BE
(0106) 	 	 	 {
(0107) 	 	 	 	case EE_READ://进入开始读取数据状态,此处即将读取的数据为ROM的Index
(0108) 	 	 	 	 {
(0109) 	 	 	 	 	PORTC^=(0b00001000);//闪亮LED
    017F E088      LDI	R24,0x8
    0180 B225      IN	R2,0x15
    0181 2628      EOR	R2,R24
    0182 BA25      OUT	0x15,R2
(0110) 	 	 	 	 	charAddr=TWDR;
    0183 B023      IN	R2,0x03
    0184 9220008D  STS	charAddr,R2
(0111) 	 	 	 	 	MT_ACK;
    0186 EC85      LDI	R24,0xC5
    0187 BF86      OUT	0x36,R24
(0112) 	 	 	 	 	charState=EE_READ_OK;
    0188 E580      LDI	R24,0x50
    0189 9380008C  STS	charState,R24
(0113) 	 	 	 	 }
(0114) 	 	 	 	break;
    018B C132      RJMP	0x02BE
(0115) 	 	 	 	case EE_READ_OK://进入读取数据完成状态此处即将读取的数据为ROM->Index的数据
(0116) 	 	 	 	 {
(0117) 	 	 	 	 	charData=TWDR;
    018C B023      IN	R2,0x03
    018D 9220008E  STS	charData,R2
(0118) 	 	 	 	 	MT_ACK;
    018F EC85      LDI	R24,0xC5
    0190 BF86      OUT	0x36,R24
(0119) 					//rom_write((unsigned char)charAddr,charData);
(0120) 	 	 	 	 	charState=EE_READ;
    0191 EF80      LDI	R24,0xF0
    0192 9380008C  STS	charState,R24
(0121) 	 	 	 	 	charIndex+=3;
    0194 9180008B  LDS	R24,charIndex
    0196 5F8D      SUBI	R24,0xFD
    0197 9380008B  STS	charIndex,R24
(0122) 	 	 	 	 	charIndex&=0b00011111;//检查charIndex,防止数据超出0~31范围
    0199 718F      ANDI	R24,0x1F
    019A 9380008B  STS	charIndex,R24
(0123) 	 	 	 	 	cDataBuff[charIndex--]=0x0a;//间隔空格符
    019C 2E28      MOV	R2,R24
    019D 2433      CLR	R3
    019E 5081      SUBI	R24,1
    019F 9380008B  STS	charIndex,R24
    01A1 E681      LDI	R24,0x61
    01A2 E090      LDI	R25,0
    01A3 2DE2      MOV	R30,R2
    01A4 27FF      CLR	R31
    01A5 0FE8      ADD	R30,R24
    01A6 1FF9      ADC	R31,R25
    01A7 E08A      LDI	R24,0xA
    01A8 8380      STD	Z+0,R24
(0124) 	 	 	 	 	charTemp=charAddr%10;
    01A9 E01A      LDI	R17,0xA
    01AA 9100008D  LDS	R16,charAddr
    01AC D11D      RCALL	mod8u
    01AD 2F40      MOV	R20,R16
(0125) 	 	 	 	 	charIndex&=0b00011111;//检查charIndex,防止数据超出0~31范围
    01AE 9180008B  LDS	R24,charIndex
    01B0 718F      ANDI	R24,0x1F
    01B1 9380008B  STS	charIndex,R24
(0126) 	 	 	 	 	cDataBuff[charIndex--]=charTemp;
    01B3 2E28      MOV	R2,R24
    01B4 2433      CLR	R3
    01B5 5081      SUBI	R24,1
    01B6 9380008B  STS	charIndex,R24
    01B8 E681      LDI	R24,0x61
    01B9 E090      LDI	R25,0
    01BA 2DE2      MOV	R30,R2
    01BB 27FF      CLR	R31
    01BC 0FE8      ADD	R30,R24
    01BD 1FF9      ADC	R31,R25
    01BE 8340      STD	Z+0,R20
(0127) 	 	 	 	 	charAddr/=10;
    01BF E01A      LDI	R17,0xA
    01C0 9100008D  LDS	R16,charAddr
    01C2 D109      RCALL	div8u
    01C3 9300008D  STS	charAddr,R16
(0128) 	 	 	 	 	charTemp=charAddr%10;
    01C5 E01A      LDI	R17,0xA
    01C6 D103      RCALL	mod8u
    01C7 2F40      MOV	R20,R16
(0129) 	 	 	 	 	charIndex&=0b00011111;//检查charIndex,防止数据超出0~31范围
    01C8 9180008B  LDS	R24,charIndex
    01CA 718F      ANDI	R24,0x1F
    01CB 9380008B  STS	charIndex,R24
(0130) 	 	 	 	 	cDataBuff[charIndex--]=charTemp;
    01CD 2E28      MOV	R2,R24
    01CE 2433      CLR	R3
    01CF 5081      SUBI	R24,1
    01D0 9380008B  STS	charIndex,R24
    01D2 E681      LDI	R24,0x61
    01D3 E090      LDI	R25,0
    01D4 2DE2      MOV	R30,R2
    01D5 27FF      CLR	R31
    01D6 0FE8      ADD	R30,R24
    01D7 1FF9      ADC	R31,R25
    01D8 8340      STD	Z+0,R20
(0131) 	 	 	 	 	charAddr/=10;
    01D9 E01A      LDI	R17,0xA
    01DA 9100008D  LDS	R16,charAddr
    01DC D0EF      RCALL	div8u
    01DD 9300008D  STS	charAddr,R16
(0132) 	 	 	 	 	cDataBuff[charIndex]=charAddr;
    01DF E681      LDI	R24,0x61
    01E0 E090      LDI	R25,0
    01E1 91E0008B  LDS	R30,charIndex
    01E3 27FF      CLR	R31
    01E4 0FE8      ADD	R30,R24
    01E5 1FF9      ADC	R31,R25
    01E6 2E20      MOV	R2,R16
    01E7 8220      STD	Z+0,R2
(0133) 	 	 	 	 	charIndex+=4;//指向末尾空位
    01E8 9180008B  LDS	R24,charIndex
    01EA 5F8C      SUBI	R24,0xFC
    01EB 9380008B  STS	charIndex,R24
(0134) 	 	 	 	 	charIndex+=3;
    01ED 5F8D      SUBI	R24,0xFD
    01EE 9380008B  STS	charIndex,R24
(0135) 	 	 	 	 	charIndex&=0b00011111;//检查charIndex,防止数据超出0~31范围

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -