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

📄 hard_i2c.lst

📁 meg16 的所有功能实例
💻 LST
📖 第 1 页 / 共 2 页
字号:
__text_start:
__start:
    0033 E5CF      LDI	R28,0x5F
    0034 E0D4      LDI	R29,4
    0035 BFCD      OUT	0x3D,R28
    0036 BFDE      OUT	0x3E,R29
    0037 51C0      SUBI	R28,0x10
    0038 40D0      SBCI	R29,0
    0039 EA0A      LDI	R16,0xAA
    003A 8308      STD	Y+0,R16
    003B 2400      CLR	R0
    003C E7E2      LDI	R30,0x72
    003D E0F0      LDI	R31,0
    003E E010      LDI	R17,0
    003F 37E5      CPI	R30,0x75
    0040 07F1      CPC	R31,R17
    0041 F011      BEQ	0x0044
    0042 9201      ST	R0,Z+
    0043 CFFB      RJMP	0x003F
    0044 8300      STD	Z+0,R16
    0045 E5E4      LDI	R30,0x54
    0046 E0F0      LDI	R31,0
    0047 E6A0      LDI	R26,0x60
    0048 E0B0      LDI	R27,0
    0049 E010      LDI	R17,0
    004A 36E6      CPI	R30,0x66
    004B 07F1      CPC	R31,R17
    004C F021      BEQ	0x0051
    004D 95C8      LPM
    004E 9631      ADIW	R30,1
    004F 920D      ST	R0,X+
    0050 CFF9      RJMP	0x004A
    0051 940E00BD  CALL	_main
_exit:
    0053 CFFF      RJMP	_exit
FILE: E:\MYWORK~1\开发设计\EasyAVR\程序范例\Mega16例程\HARD_I~1\Hard_I2C.c
(0001) /****************************************Copyright (c)**************************************************
(0002) **                               ADEmbed Development Co.,LTD.                                    
(0003) **                                 http://www.adembed.com
(0004) **--------------File Info-------------------------------------------------------------------------------
(0005) ** File name:			Hard_I2C.c
(0006) ** Last modified Date:  2008-12-13
(0007) ** Last Version:		1.0
(0008) ** Descriptions:		Hard_I2C Test.
(0009) ** 
(0010) **------------------------------------------------------------------------------------------------------
(0011) ** Created by:			junbolu
(0012) ** Created date:		2008-12-13
(0013) ** Version:				1.0
(0014) ** Descriptions:		
(0015) **
(0016) **------------------------------------------------------------------------------------------------------
(0017) ** Modified by:
(0018) ** Modified date:
(0019) ** Version:
(0020) ** Descriptions:
(0021) **
(0022) **------------------------------------------------------------------------------------------------------
(0023) **ICC-AVR application builder : 2008-12-13
(0024) **Target : M16
(0025) **Crystal: 7.3728Mhz
(0026) **PC0--->SCL		PC1--->SDA			  PD6--->Write_EN
(0027) **
(0028) **描述:按键K0被按下一次,数码管的最低位会加一,并存储在24C02中,下一次系统启动时,会读取此数据并显示。
(0029) **      此程序采用的硬件I2C方式完成的24C02的读写。
(0030) **
(0031) **涉及知识点:
(0032) **           硬件I2C
(0033) **           
(0034) **			
(0035) *******************************************************************************************************/
(0036) 
(0037) #include<iom16v.h>
(0038) #include<macros.h>
(0039) #include"Define.h"
(0040) 
(0041) #define		fose	                        7372800
(0042) 
(0043) #define     SCL                                 0
(0044) #define     SDA                                 1
(0045)  
(0046) #define 	i2c_ddr                         DDRC
(0047) #define 	i2c_port                        PORTC
(0048) #define 	i2c_pin                         PINC      
(0049) 
(0050) #define 	AT24C02_ADDR					0xA0  //EEPROM设备地址
(0051) //定义I2C的延迟参数
(0052) #define    DelayX	100			//7.3M=>1;	8.4M=>2.建议5,因为将来的ClockCPU可以是16M
(0053) 
(0054) 
(0055) #define    SCL_1    {i2c_port|=1<<SCL;Delay_us(DelayX);}
(0056) #define    SCL_0    {i2c_port&=~(1<<SCL);Delay_us(DelayX);}
(0057) #define    SDA_1    {i2c_port|=1<<SDA;Delay_us(DelayX);}
(0058) #define    SDA_0    {i2c_port&=~(1<<SDA);Delay_us(DelayX);}
(0059) 
(0060) #define	   Write_EN_DO        DDRD |= (1<<6);
(0061) #define	   Write_EN_1         PORTD|= (1<<6);
(0062) #define	   Write_EN_0         PORTD&=~(1<<6);
(0063) 
(0064) #define rd_device_add                  0xa1
(0065) #define wr_device_add                  0xa0
(0066) 
(0067) //TWI状态定义
(0068) //MT 主方式传输  MR 主方式接收 
(0069) #define START 0x08  
(0070) #define RE_START 0x10
(0071) #define MT_SLA_ACK 0x18
(0072) #define MT_SLA_NOACK 0x20
(0073) #define MT_DATA_ACK  0x28
(0074) #define MT_DATA_NOACK 0x30
(0075) #define MR_SLA_ACK  0x40
(0076) #define MR_SLA_NOACK 0x48
(0077) #define MR_DATA_ACK 0x50
(0078) #define MR_DATA_NOACK 0x58
(0079) //常用TWI操作(主模式写和主模式读)
(0080) #define Start()    	  (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN))
(0081) #define Stop()     	  (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN))
(0082) #define Wait()	   	  {while(!(TWCR&(1<<TWINT)));}     
(0083) #define TestAck() 	  (TWSR&0xf8)
(0084) #define SetAck()	  (TWCR|=(1<<TWEA))
(0085) #define SetNoAck()    (TWCR&=~(1<<TWEA))
(0086) #define Twi()	  	  (TWCR=(1<<TWINT)|(1<<TWEN))
(0087) #define Write8Bit(x)  {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);} 
(0088) unsigned char DISP_NUM;							//显示的位数
(0089) unsigned char BitTab[]={0xFE,0xFD,0xFB,0xF7};	//三位位选码
(0090) unsigned char DispTab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //LED字形码
(0091) unsigned char DISP_DATA[4]={0,0,0,0};		    //显示的数字
(0092) 
(0093) void I2C_Ini(void);
(0094) unsigned char i2c_Write(unsigned char RomAddress,unsigned char Wdata);
(0095) unsigned char i2c_Read(unsigned char RomAddress);
(0096) 
(0097) 
(0098) void Delay_us(unsigned int time)
(0099) {
(0100) while(time--);
_Delay_us:
  time                 --> R16
    0054 0118      MOVW	R2,R16
    0055 5001      SUBI	R16,1
    0056 4010      SBCI	R17,0
    0057 2022      TST	R2
    0058 F7D9      BNE	0x0054
    0059 2033      TST	R3
    005A F7C9      BNE	0x0054
    005B 9508      RET
_Delay_ms:
  time                 --> R20
    005C 940E0185  CALL	push_gset1
    005E 01A8      MOVW	R20,R16
(0101) }
(0102) 
(0103) void Delay_ms(unsigned int time)
(0104) {
    005F C003      RJMP	0x0063
(0105) while(time--)
(0106) 	{
(0107) 	Delay_us(1000);
    0060 EE08      LDI	R16,0xE8
    0061 E013      LDI	R17,3
    0062 DFF1      RCALL	_Delay_us
    0063 011A      MOVW	R2,R20
    0064 5041      SUBI	R20,1
    0065 4050      SBCI	R21,0
    0066 2022      TST	R2
    0067 F7C1      BNE	0x0060
    0068 2033      TST	R3
    0069 F7B1      BNE	0x0060
    006A 940E0188  CALL	pop_gset1
    006C 9508      RET
(0108) 	}
(0109) }
(0110) void INT0_Init()
(0111) {
(0112)  GIFR |=0X40;              //清楚标志位
_INT0_Init:
    006D B78A      IN	R24,0x3A
    006E 6480      ORI	R24,0x40
    006F BF8A      OUT	0x3A,R24
(0113)  //MCUCR|=0X03; 			   //上升沿触发中断	
(0114)  MCUCR|=0X02;MCUCR&=~0X01; //下降沿触发中断	
    0070 B785      IN	R24,0x35
    0071 6082      ORI	R24,2
    0072 BF85      OUT	0x35,R24
    0073 B785      IN	R24,0x35
    0074 7F8E      ANDI	R24,0xFE
    0075 BF85      OUT	0x35,R24
(0115)  GICR |=0X40;  			   //使能外部中断0
    0076 B78B      IN	R24,0x3B
    0077 6480      ORI	R24,0x40
    0078 BF8B      OUT	0x3B,R24
    0079 9508      RET
_int0_isr:
    007A 940E019C  CALL	push_lset
(0116) }
(0117) 
(0118) #pragma interrupt_handler int0_isr:2
(0119) void int0_isr(void)
(0120) {
(0121)  DISP_DATA[3]++;
    007C 91800071  LDS	R24,DISP_DATA+3
    007E 5F8F      SUBI	R24,0xFF
    007F 93800071  STS	DISP_DATA+3,R24
(0122)  if(DISP_DATA[3]>9)
    0081 E089      LDI	R24,0x9
    0082 90200071  LDS	R2,DISP_DATA+3
    0084 1582      CP	R24,R2
    0085 F418      BCC	0x0089
(0123)      {
(0124) 	 DISP_DATA[3]=0;
    0086 2422      CLR	R2
    0087 92200071  STS	DISP_DATA+3,R2
(0125) 	 }
(0126)  Write_EN_0;
    0089 9896      CBI	0x12,6
(0127)  i2c_Write(0x02,DISP_DATA[3]);
    008A 91200071  LDS	R18,DISP_DATA+3
    008C E002      LDI	R16,2
    008D D053      RCALL	_i2c_Write
(0128)  Write_EN_1;
    008E 9A96      SBI	0x12,6
    008F 940E01B3  CALL	pop_lset
    0091 9518      RETI
(0129) }
(0130) //显示函数,DISP_NUM决定显示哪个LED
(0131) //采用共阴LED动态显示方法,定时中断函数里面调用
(0132) void Display(void)		
(0133) {
(0134)  PORTA=0x00;					   			//清除显示再位选
_Display:
    0092 2422      CLR	R2
    0093 BA2B      OUT	0x1B,R2
(0135)  PORTB=BitTab[DISP_NUM];					//PB口接位选
    0094 E680      LDI	R24,0x60
    0095 E090      LDI	R25,0
    0096 91E00072  LDS	R30,DISP_NUM
    0098 27FF      CLR	R31
    0099 0FE8      ADD	R30,R24
    009A 1FF9      ADC	R31,R25
    009B 8020      LDD	R2,Z+0
    009C BA28      OUT	0x18,R2
(0136)  PORTA=DispTab[DISP_DATA[DISP_NUM]];		//PA口接LED的段码
    009D E68E      LDI	R24,0x6E
    009E E090      LDI	R25,0
    009F 91E00072  LDS	R30,DISP_NUM
    00A1 27FF      CLR	R31
    00A2 0FE8      ADD	R30,R24
    00A3 1FF9      ADC	R31,R25
    00A4 81E0      LDD	R30,Z+0
    00A5 27FF      CLR	R31
    00A6 E684      LDI	R24,0x64
    00A7 E090      LDI	R25,0
    00A8 0FE8      ADD	R30,R24
    00A9 1FF9      ADC	R31,R25
    00AA 8020      LDD	R2,Z+0
    00AB BA2B      OUT	0x1B,R2
(0137) 
(0138)  
(0139)  DISP_NUM++;			//先显示高位,再显示低位
    00AC 91800072  LDS	R24,DISP_NUM
    00AE 5F8F      SUBI	R24,0xFF
    00AF 93800072  STS	DISP_NUM,R24
(0140)  if(DISP_NUM==4)
    00B1 3084      CPI	R24,4
    00B2 F419      BNE	0x00B6
(0141)     DISP_NUM=0;
    00B3 2422      CLR	R2
    00B4 92200072  STS	DISP_NUM,R2
    00B6 9508      RET
_timer0comp:
    00B7 940E019C  CALL	push_lset
(0142) }
(0143) 
(0144) #pragma interrupt_handler timer0comp:20
(0145) void timer0comp (void)
(0146) {
(0147)  Display();
    00B9 DFD8      RCALL	_Display
    00BA 940E01B3  CALL	pop_lset
    00BC 9518      RETI
(0148) } 
(0149) 
(0150) void main(void)
(0151) {
(0152)  
(0153)  DDRA=0XFF;
_main:
    00BD EF8F      LDI	R24,0xFF
    00BE BB8A      OUT	0x1A,R24
(0154)  PORTA=0X00;
    00BF 2422      CLR	R2
    00C0 BA2B      OUT	0x1B,R2
(0155)  DDRB=0X0F;
    00C1 E08F      LDI	R24,0xF
    00C2 BB87      OUT	0x17,R24
(0156)  PORTB=0X00;
    00C3 BA28      OUT	0x18,R2
(0157)  
(0158)  //按键0端口初始化
(0159)  DDRD &=~0x04;	   	//设置PD2为输入   	   						
    00C4 988A      CBI	0x11,2
(0160)  PORTD|=0x04;		//设置PD2为上拉
    00C5 9A92      SBI	0x12,2
(0161)  
(0162)  INT0_Init();                 //TART初始化
    00C6 DFA6      RCALL	_INT0_Init
(0163)  
(0164)  //t/c0初始化(10ms)
(0165)  TCCR0=0X0d;
    00C7 E08D      LDI	R24,0xD
    00C8 BF83      OUT	0x33,R24
(0166)  TCNT0=0X00;
    00C9 2422      CLR	R2
    00CA BE22      OUT	0x32,R2
(0167)  OCR0=0X48;
    00CB E488      LDI	R24,0x48
    00CC BF8C      OUT	0x3C,R24
(0168)  TIMSK=0X02;
    00CD E082      LDI	R24,2
    00CE BF89      OUT	0x39,R24
(0169) 
(0170)  //asm("sei");
(0171)  SEI();                       //全局中断使能
    00CF 9478      BSET	7
(0172)  
(0173)  //I2C_Ini();
(0174)  TWSR = 0X03;							/* TWI clock prescaler (TWPS) value = 0 */	
    00D0 E083      LDI	R24,3
    00D1 B981      OUT	0x01,R24
(0175)  TWBR = 0X10;	
    00D2 E180      LDI	R24,0x10
    00D3 B980      OUT	0x00,R24
(0176) 
(0177)  TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
    00D4 EA84      LDI	R24,0xA4
    00D5 BF86      OUT	0x36,R24
(0178)  
(0179)  Write_EN_DO;
    00D6 9A8E      SBI	0x11,6
(0180)  Write_EN_1;
    00D7 9A96      SBI	0x12,6
(0181)  DISP_DATA[3]=i2c_Read(0x02);
    00D8 E002      LDI	R16,2
    00D9 D04A      RCALL	_i2c_Read
    00DA 93000071  STS	DISP_DATA+3,R16
(0182) 
(0183)  for(;;)
    00DC CFFF      RJMP	0x00DC
    00DD 9508      RET
(0184) 	{ 
(0185) 	
(0186) 	}
(0187) }
(0188) 
(0189) 
(0190) //=======================================================================
(0191) //初始化端口
(0192) void I2C_Ini(void)

⌨️ 快捷键说明

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