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

📄 iic接口读写.lst

📁 atmage8中的I2C口读写程序
💻 LST
字号:
__text_start:
__start:
      13 E5CF      LDI	R28,0x5F
      14 E0D4      LDI	R29,4
      15 BFCD      OUT	0x3D,R28
      16 BFDE      OUT	0x3E,R29
      17 51CE      SUBI	R28,0x1E
      18 40D0      SBCI	R29,0
      19 EA0A      LDI	R16,0xAA
      1A 8308      STD	Y+0,R16
      1B 2400      CLR	R0
      1C E6E0      LDI	R30,0x60
      1D E0F0      LDI	R31,0
      1E E010      LDI	R17,0
      1F 36E0      CPI	R30,0x60
      20 07F1      CPC	R31,R17
      21 F011      BEQ	0x0024
      22 9201      ST	R0,Z+
      23 CFFB      RJMP	0x001F
      24 8300      STD	Z+0,R16
      25 E2E6      LDI	R30,0x26
      26 E0F0      LDI	R31,0
      27 E6A0      LDI	R26,0x60
      28 E0B0      LDI	R27,0
      29 E010      LDI	R17,0
      2A E000      LDI	R16,0
      2B BF0B      OUT	0x3B,R16
      2C 32E6      CPI	R30,0x26
      2D 07F1      CPC	R31,R17
      2E F021      BEQ	0x0033
      2F 95C8      LPM
      30 9631      ADIW	R30,1
      31 920D      ST	R0,X+
      32 CFF9      RJMP	0x002C
      33 D0BE      RCALL	_main
_exit:
      34 CFFF      RJMP	_exit
FILE: E:\xiaozhiyong2009\设计资料\项目设计\ICCAVR_mega8_C\ICCAVR_mega8_IIC接口读写\IIC接口读写.c
(0001) //ICC-AVR application builder : 2009-3-12 17:05:04
(0002) // Target : M8
(0003) // Crystal: 8.0000Mhz
(0004) 
(0005) #include <iom8v.h>
(0006) #include <macros.h>
(0007) 
(0008) void port_init(void)
(0009) {
(0010)  PORTB = 0x00;
_port_init:
      35 2422      CLR	R2
      36 BA28      OUT	0x18,R2
(0011)  DDRB  = 0x00;
      37 BA27      OUT	0x17,R2
(0012)  PORTC = 0x00; //m103 output only
      38 BA25      OUT	0x15,R2
(0013)  DDRC  = 0x00;
      39 BA24      OUT	0x14,R2
(0014)  PORTD = 0x00;
      3A BA22      OUT	0x12,R2
(0015)  DDRD  = 0x00;
      3B BA21      OUT	0x11,R2
      3C 9508      RET
(0016) }
(0017) 
(0018) //call this routine to initialize all peripherals
(0019) void init_devices(void)
(0020) {
(0021)  //stop errant interrupts until set up
(0022)  CLI(); //disable all interrupts
_init_devices:
      3D 94F8      BCLR	7
(0023)  port_init();
      3E DFF6      RCALL	_port_init
(0024) 
(0025)  MCUCR = 0x00;
      3F 2422      CLR	R2
      40 BE25      OUT	0x35,R2
(0026)  GICR  = 0x00;
      41 BE2B      OUT	0x3B,R2
(0027)  TIMSK = 0x00; //timer interrupt sources
      42 BE29      OUT	0x39,R2
(0028)  SEI(); //re-enable interrupts
      43 9478      BSET	7
      44 9508      RET
_delay_ms:
  i                    --> R20
  time                 --> R16
      45 934A      ST	R20,-Y
      46 935A      ST	R21,-Y
(0029)  //all peripherals are now initialized
(0030) }
(0031) 
(0032) /*************************************************************************
(0033) 用    途:iic发送接收
(0034) Taget   :mega8
(0035) crystal :8M
(0036) 介    绍:PC4-SDA
(0037)          PC5-SCK/SCL
(0038) //***********************************************************************
(0039)  I2C 状态定义
(0040)  MT 主方式传输 MR 主方式接受
(0041) ***************************/
(0042) #define START			0x08
(0043) #define RE_START		0x10
(0044) #define MT_SLA_ACK		0x18
(0045) #define MT_SLA_NOACK 	0x20
(0046) #define MT_DATA_ACK		0x28
(0047) #define MT_DATA_NOACK	0x30
(0048) 
(0049) #define MR_SLA_ACK		0x40
(0050) #define MR_SLA_NOACK	0x48
(0051) #define MR_DATA_ACK		0x50
(0052) #define MR_DATA_NOACK	0x58
(0053) 
(0054) #define RD_DEVICE_ADDR 0xA1  //前4位器件固定,后三位看连线,最后1位是读写指令位
(0055) #define WD_DEVICE_ADDR 0xA0
(0056) #define Start()		 (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN))		//启动I2C
(0057) #define Stop()		 (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN))		//停止I2C
(0058) #define Wait()		 {while(!(TWCR&(1<<TWINT)));}				//等待中断发生
(0059) #define TestAck()	 (TWSR&0xf8)								//观察返回状态
(0060) #define SetAck		 (TWCR|=(1<<TWEA))							//做出ACK应答
(0061) #define SetNoAck	 (TWCR&=~(1<<TWEA))							//做出Not Ack应答
(0062) #define Twi()		 (TWCR=(1<<TWINT)|(1<<TWEN))				//启动I2C
(0063) #define Write8Bit(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);}		//写数据到TWDR
(0064) /*延时子程序*/
(0065) void delay_ms(int time)
(0066) {
(0067)  int i;
(0068)  for(;time>0;time--)
      47 C00A      RJMP	0x0052
(0069)   for(i=0;i<1000;i++);
      48 2744      CLR	R20
      49 2755      CLR	R21
      4A 5F4F      SUBI	R20,0xFF
      4B 4F5F      SBCI	R21,0xFF
      4C 3E48      CPI	R20,0xE8
      4D E0E3      LDI	R30,3
      4E 075E      CPC	R21,R30
      4F F3D4      BLT	0x004A
      50 5001      SUBI	R16,1
      51 4010      SBCI	R17,0
      52 2422      CLR	R2
      53 2433      CLR	R3
      54 1620      CP	R2,R16
      55 0631      CPC	R3,R17
      56 F38C      BLT	0x0048
      57 9159      LD	R21,Y+
      58 9149      LD	R20,Y+
      59 9508      RET
(0070) }
(0071) //初始化
(0072) void iic_init()
(0073) {
(0074)  TWBR= 0x20; //设置波特率
_iic_init:
      5A E280      LDI	R24,0x20
      5B B980      OUT	0x00,R24
(0075)  TWSR= 0x00; //设置预分频比
      5C 2422      CLR	R2
      5D B821      OUT	0x01,R2
(0076)  TWCR= 0x44; //使能应答,使能TWI
      5E E484      LDI	R24,0x44
      5F BF86      OUT	0x36,R24
(0077)  DDRC|=(1<<PC4)|(1<<PC5);
      60 B384      IN	R24,0x14
      61 6380      ORI	R24,0x30
      62 BB84      OUT	0x14,R24
(0078)  PORTC|=(1<<PC4)|(1<<PC5);
      63 B385      IN	R24,0x15
      64 6380      ORI	R24,0x30
      65 BB85      OUT	0x15,R24
      66 9508      RET
_iic_write:
  RegAddress           --> R12
  Wdata                --> R10
      67 92AA      ST	R10,-Y
      68 92CA      ST	R12,-Y
      69 2EC2      MOV	R12,R18
      6A 2EA0      MOV	R10,R16
(0079) }
(0080) /*********************************************
(0081) I2C总线写一个字节
(0082) 返回0:写成功
(0083) 返回1:写失败
(0084) **********************************************/
(0085) unsigned char iic_write(unsigned char Wdata,unsigned char RegAddress)
(0086) {
(0087)    Start();						//I2C启动
      6B EA84      LDI	R24,0xA4
      6C BF86      OUT	0x36,R24
(0088)    Wait();
      6D B626      IN	R2,0x36
      6E FE27      SBRS	R2,7
      6F CFFD      RJMP	0x006D
(0089)    if(TestAck()!=START) 
      70 B181      IN	R24,0x01
      71 7F88      ANDI	R24,0xF8
      72 3088      CPI	R24,0x8
      73 F011      BEQ	0x0076
(0090) 	  return 1;					//ACK
      74 E001      LDI	R16,1
      75 C02B      RJMP	0x00A1
(0091) 	  
(0092)    Write8Bit(WD_DEVICE_ADDR);	//写I2C从器件地址和写方式
      76 EA80      LDI	R24,0xA0
      77 B983      OUT	0x03,R24
      78 E884      LDI	R24,0x84
      79 BF86      OUT	0x36,R24
(0093)    Wait();
      7A B626      IN	R2,0x36
      7B FE27      SBRS	R2,7
      7C CFFD      RJMP	0x007A
(0094)    if(TestAck()!=MT_SLA_ACK) 
      7D B181      IN	R24,0x01
      7E 7F88      ANDI	R24,0xF8
      7F 3188      CPI	R24,0x18
      80 F011      BEQ	0x0083
(0095) 	  return 1;		            //ACK
      81 E001      LDI	R16,1
      82 C01E      RJMP	0x00A1
(0096) 	  			
(0097)    Write8Bit(RegAddress);		//写器件相应寄存器地址
      83 B8C3      OUT	0x03,R12
      84 E884      LDI	R24,0x84
      85 BF86      OUT	0x36,R24
(0098)    Wait();
      86 B626      IN	R2,0x36
      87 FE27      SBRS	R2,7
      88 CFFD      RJMP	0x0086
(0099)    if(TestAck()!=MT_DATA_ACK) 
      89 B181      IN	R24,0x01
      8A 7F88      ANDI	R24,0xF8
      8B 3288      CPI	R24,0x28
      8C F011      BEQ	0x008F
(0100) 	 return 1;				    //ACK
      8D E001      LDI	R16,1
      8E C012      RJMP	0x00A1
(0101) 	 
(0102)    Write8Bit(Wdata);			 	//写数据到器件相应寄存器
      8F B8A3      OUT	0x03,R10
      90 E884      LDI	R24,0x84
      91 BF86      OUT	0x36,R24
(0103)    Wait();
      92 B626      IN	R2,0x36
      93 FE27      SBRS	R2,7
      94 CFFD      RJMP	0x0092
(0104)    if(TestAck()!=MT_DATA_ACK) 
      95 B181      IN	R24,0x01
      96 7F88      ANDI	R24,0xF8
      97 3288      CPI	R24,0x28
      98 F011      BEQ	0x009B
(0105) 	  return 1;				    //ACK	
      99 E001      LDI	R16,1
      9A C006      RJMP	0x00A1
(0106) 	  
(0107)    Stop();  						//I2C停止
      9B E984      LDI	R24,0x94
      9C BF86      OUT	0x36,R24
(0108)    delay_ms(100);				//延时
      9D E604      LDI	R16,0x64
      9E E010      LDI	R17,0
      9F DFA5      RCALL	_delay_ms
(0109)    return 0;
      A0 2700      CLR	R16
      A1 90C9      LD	R12,Y+
      A2 90A9      LD	R10,Y+
      A3 9508      RET
_iic_read:
  temp                 --> R10
  RegAddress           --> R16
      A4 92AA      ST	R10,-Y
(0110) }  
(0111) 
(0112) /*********************************************
(0113) I2C总线读一个字节
(0114) 返回非0:读成功
(0115) 返回0:读失败
(0116) **********************************************/
(0117) unsigned char iic_read(unsigned RegAddress)
(0118) {
(0119)    unsigned char temp;
(0120)    Start();//I2C启动
      A5 EA84      LDI	R24,0xA4
      A6 BF86      OUT	0x36,R24
(0121)    Wait();
      A7 B626      IN	R2,0x36
      A8 FE27      SBRS	R2,7
      A9 CFFD      RJMP	0x00A7
(0122)    if (TestAck()!=START) 
      AA B181      IN	R24,0x01
      AB 7F88      ANDI	R24,0xF8
      AC 3088      CPI	R24,0x8
      AD F011      BEQ	0x00B0
(0123) 	   return 1;			 		//ACK	   
      AE E001      LDI	R16,1
      AF C040      RJMP	0x00F0
(0124) 	   
(0125)    Write8Bit(WD_DEVICE_ADDR);	//写I2C从器件地址和写方式
      B0 EA80      LDI	R24,0xA0
      B1 B983      OUT	0x03,R24
      B2 E884      LDI	R24,0x84
      B3 BF86      OUT	0x36,R24
(0126)    Wait(); 
      B4 B626      IN	R2,0x36
      B5 FE27      SBRS	R2,7
      B6 CFFD      RJMP	0x00B4
(0127)    if (TestAck()!=MT_SLA_ACK) 
      B7 B181      IN	R24,0x01
      B8 7F88      ANDI	R24,0xF8
      B9 3188      CPI	R24,0x18
      BA F011      BEQ	0x00BD
(0128) 	   return 1;				    //ACK
      BB E001      LDI	R16,1
      BC C033      RJMP	0x00F0
(0129) 	   
(0130)    Write8Bit(RegAddress);		//写器件相应寄存器地址
      BD B903      OUT	0x03,R16
      BE E884      LDI	R24,0x84
      BF BF86      OUT	0x36,R24
(0131)    Wait();
      C0 B626      IN	R2,0x36
      C1 FE27      SBRS	R2,7
      C2 CFFD      RJMP	0x00C0
(0132)    if (TestAck()!=MT_DATA_ACK) 
      C3 B181      IN	R24,0x01
      C4 7F88      ANDI	R24,0xF8
      C5 3288      CPI	R24,0x28
      C6 F011      BEQ	0x00C9
(0133) 	   return 1;
      C7 E001      LDI	R16,1
      C8 C027      RJMP	0x00F0
(0134) 	   
(0135)    Start();	   				   	//I2C重新启动
      C9 EA84      LDI	R24,0xA4
      CA BF86      OUT	0x36,R24
(0136)    Wait();
      CB B626      IN	R2,0x36
      CC FE27      SBRS	R2,7
      CD CFFD      RJMP	0x00CB
(0137)    if (TestAck()!=RE_START)  
      CE B181      IN	R24,0x01
      CF 7F88      ANDI	R24,0xF8
      D0 3180      CPI	R24,0x10
      D1 F011      BEQ	0x00D4
(0138) 	   return 1;
      D2 E001      LDI	R16,1
      D3 C01C      RJMP	0x00F0
(0139) 	   
(0140)    Write8Bit(RD_DEVICE_ADDR);	//写I2C从器件地址和读方式
      D4 EA81      LDI	R24,0xA1
      D5 B983      OUT	0x03,R24
      D6 E884      LDI	R24,0x84
      D7 BF86      OUT	0x36,R24
(0141)    Wait();
      D8 B626      IN	R2,0x36
      D9 FE27      SBRS	R2,7
      DA CFFD      RJMP	0x00D8
(0142)    if(TestAck()!=MR_SLA_ACK)  
      DB B181      IN	R24,0x01
      DC 7F88      ANDI	R24,0xF8
      DD 3480      CPI	R24,0x40
      DE F011      BEQ	0x00E1
(0143) 	   return 1;				   //ACK
      DF E001      LDI	R16,1
      E0 C00F      RJMP	0x00F0
(0144) 	   
(0145)    Twi();	 				   //启动主I2C读方式
      E1 E884      LDI	R24,0x84
      E2 BF86      OUT	0x36,R24
(0146)    Wait();
      E3 B626      IN	R2,0x36
      E4 FE27      SBRS	R2,7
      E5 CFFD      RJMP	0x00E3
(0147)    if(TestAck()!=MR_DATA_NOACK) 
      E6 B181      IN	R24,0x01
      E7 7F88      ANDI	R24,0xF8
      E8 3588      CPI	R24,0x58
      E9 F011      BEQ	0x00EC
(0148) 	   return 1;					//ACK	
      EA E001      LDI	R16,1
      EB C004      RJMP	0x00F0
(0149) 	   
(0150)    temp=TWDR;        //读取I2C接收数据
      EC B0A3      IN	R10,0x03
(0151)    Stop();          //I2C停止
      ED E984      LDI	R24,0x94
      EE BF86      OUT	0x36,R24
(0152)    return temp;
      EF 2D0A      MOV	R16,R10
      F0 90A9      LD	R10,Y+
      F1 9508      RET
(0153) }
(0154) //****************************************************************************
(0155) void main()
(0156) {
(0157)  unsigned char i,j;
(0158)  port_init();
_main:
  i                    --> R20
  j                    --> R20
      F2 DF42      RCALL	_port_init
(0159)  init_devices();
      F3 DF49      RCALL	_init_devices
(0160)  
(0161)  iic_init();
      F4 DF65      RCALL	_iic_init
(0162)  
(0163)  i=iic_write(0xaa,0X10);//在0X10地址写入数据0XAA
      F5 E120      LDI	R18,0x10
      F6 EA0A      LDI	R16,0xAA
      F7 DF6F      RCALL	_iic_write
      F8 2F40      MOV	R20,R16
(0164)  if (i==1)
      F9 3001      CPI	R16,1
      FA F419      BNE	0x00FE
(0165)  	PORTB=0x1;//若写入失败(i=1),B口0x01;若写入成功,B口输出0X02
      FB E081      LDI	R24,1
      FC BB88      OUT	0x18,R24
      FD C002      RJMP	0x0100
(0166)  else
(0167)  	PORTB=0x2;
      FE E082      LDI	R24,2
      FF BB88      OUT	0x18,R24
(0168)  j=iic_read(0X10);//读出0x10地址的数据
     100 E100      LDI	R16,0x10
     101 E010      LDI	R17,0
     102 DFA1      RCALL	_iic_read
     103 2F40      MOV	R20,R16
(0169)  if(j==1)
     104 3001      CPI	R16,1
     105 F419      BNE	0x0109
(0170) 	PORTD=0xff;	//若读出失败(j=1),D口全灭;若读出成功,D口输出0XAA
     106 EF8F      LDI	R24,0xFF
     107 BB82      OUT	0x12,R24
     108 C001      RJMP	0x010A
(0171)  else
(0172) 	PORTD=j;
     109 BB42      OUT	0x12,R20
(0173)  while(1)
FILE: <library>
     10A CFFF      RJMP	0x010A
     10B 9508      RET

⌨️ 快捷键说明

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