📄 hard_i2c.lst
字号:
__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 + -