📄 uart_to_twi.lst
字号:
0225 4050 SBCI R21,0
0226 3040 CPI R20,0
0227 0745 CPC R20,R21
0228 F7C1 BNE 0x0221
0229 D146 RCALL pop_gset1
022A 9508 RET
FILE: H:\程序库\twi_master_polling.c
(0001) #include <iom8v.h>
(0002) #include <macros.h>
(0003) #include "delay.h"
(0004) #include "twi_master_polling.h"
(0005)
(0006) unsigned char Write_Succsee_Flag;
(0007) unsigned char Read_Succsee_Flag;
(0008)
(0009) void twi_init(void)
(0010) {
(0011) Write_Succsee_Flag = false;
_twi_init:
022B 2422 CLR R2
022C 9220008C STS Write_Succsee_Flag,R2
(0012) Read_Succsee_Flag = false;
022E 9220008B STS Read_Succsee_Flag,R2
(0013)
(0014) TWCR= 0X00; //disable twi
0230 BE26 OUT 0x36,R2
(0015) TWBR= 0x20; //set bit rate
0231 E280 LDI R24,0x20
0232 B980 OUT 0x00,R24
(0016) TWSR= 0x00; //set prescale
0233 B821 OUT 0x01,R2
(0017) //TWAR= DEVICE_ADR; //set slave address 本身作为主控
(0018) TWCR= 0x44; //enable twi 置位TWEA,TWEN TWIE
0234 E484 LDI R24,0x44
0235 BF86 OUT 0x36,R24
0236 9508 RET
_twi_write_byte:
Wdata --> Y+4
RamAddress --> R20
device_adr --> R22
0237 D133 RCALL push_gset2
0238 2F42 MOV R20,R18
0239 2F60 MOV R22,R16
(0019) }
(0020) /******************************************
(0021) I2C总线写一个字节
(0022) 返回0: 写成功
(0023) 返回错误状态字:写失败
(0024) *******************************************/
(0025) unsigned char twi_write_byte(unsigned char device_adr,unsigned char RamAddress,unsigned char Wdata)
(0026) {
(0027) //I2C启动
(0028) Start(); Wait(); //等TWINT置位
023A EA84 LDI R24,0xA4
023B BF86 OUT 0x36,R24
023C B626 IN R2,0x36
023D FE27 SBRS R2,7
023E CFFD RJMP 0x023C
(0029) if(TestAck()!=START) {Write_Succsee_Flag = false;Stop();return TestAck();}//ACK
023F B181 IN R24,0x01
0240 7F88 ANDI R24,0xF8
0241 3088 CPI R24,0x8
0242 F041 BEQ 0x024B
0243 2422 CLR R2
0244 9220008C STS Write_Succsee_Flag,R2
0246 E984 LDI R24,0x94
0247 BF86 OUT 0x36,R24
0248 B101 IN R16,0x01
0249 7F08 ANDI R16,0xF8
024A C040 RJMP 0x028B
(0030) //写I2C从器件地址和写方式
(0031) Write8Bit(device_adr); Wait();
024B B963 OUT 0x03,R22
024C E884 LDI R24,0x84
024D BF86 OUT 0x36,R24
024E B626 IN R2,0x36
024F FE27 SBRS R2,7
0250 CFFD RJMP 0x024E
(0032) if(TestAck()!=MT_SLA_ACK) {Write_Succsee_Flag = false;Stop();return TestAck();}//ACK
0251 B181 IN R24,0x01
0252 7F88 ANDI R24,0xF8
0253 3188 CPI R24,0x18
0254 F041 BEQ 0x025D
0255 2422 CLR R2
0256 9220008C STS Write_Succsee_Flag,R2
0258 E984 LDI R24,0x94
0259 BF86 OUT 0x36,R24
025A B101 IN R16,0x01
025B 7F08 ANDI R16,0xF8
025C C02E RJMP 0x028B
(0033) //写RAM地址
(0034) Write8Bit(RamAddress); Wait();
025D B943 OUT 0x03,R20
025E E884 LDI R24,0x84
025F BF86 OUT 0x36,R24
0260 B626 IN R2,0x36
0261 FE27 SBRS R2,7
0262 CFFD RJMP 0x0260
(0035) if(TestAck()!=MT_DATA_ACK) {Write_Succsee_Flag = false;Stop();return TestAck();}//ACK
0263 B181 IN R24,0x01
0264 7F88 ANDI R24,0xF8
0265 3288 CPI R24,0x28
0266 F041 BEQ 0x026F
0267 2422 CLR R2
0268 9220008C STS Write_Succsee_Flag,R2
026A E984 LDI R24,0x94
026B BF86 OUT 0x36,R24
026C B101 IN R16,0x01
026D 7F08 ANDI R16,0xF8
026E C01C RJMP 0x028B
(0036) //写数据
(0037) Write8Bit(Wdata); Wait();
026F 800C LDD R0,Y+4
0270 B803 OUT 0x03,R0
0271 E884 LDI R24,0x84
0272 BF86 OUT 0x36,R24
0273 B626 IN R2,0x36
0274 FE27 SBRS R2,7
0275 CFFD RJMP 0x0273
(0038) if(TestAck()!=MT_DATA_ACK) {Write_Succsee_Flag = false;Stop();return TestAck();}//ACK
0276 B181 IN R24,0x01
0277 7F88 ANDI R24,0xF8
0278 3288 CPI R24,0x28
0279 F041 BEQ 0x0282
027A 2422 CLR R2
027B 9220008C STS Write_Succsee_Flag,R2
027D E984 LDI R24,0x94
027E BF86 OUT 0x36,R24
027F B101 IN R16,0x01
0280 7F08 ANDI R16,0xF8
0281 C009 RJMP 0x028B
(0039) //I2C停止
(0040) Stop();
0282 E984 LDI R24,0x94
0283 BF86 OUT 0x36,R24
(0041) delay_ms(10);//延时等写完
0284 E00A LDI R16,0xA
0285 E010 LDI R17,0
0286 DF97 RCALL _delay_ms
(0042) Write_Succsee_Flag = true;
0287 E081 LDI R24,1
0288 9380008C STS Write_Succsee_Flag,R24
(0043) return Write_Succsee_Flag;
028A 2F08 MOV R16,R24
028B D0D7 RCALL pop_gset2
028C 9508 RET
_twi_read_byte:
temp --> R20
RamAddress --> R18
device_adr --> R16
028D D0DF RCALL push_gset1
(0044) }
(0045) /******************************************
(0046) I2C总线读一个字节
(0047) 如果读失败也返回0
(0048) *******************************************/
(0049) unsigned char twi_read_byte(unsigned char device_adr,unsigned char RamAddress)
(0050) {
(0051) unsigned char temp;
(0052)
(0053) //I2C启动
(0054) Start(); Wait();
028E EA84 LDI R24,0xA4
028F BF86 OUT 0x36,R24
0290 B626 IN R2,0x36
0291 FE27 SBRS R2,7
0292 CFFD RJMP 0x0290
(0055) if (TestAck()!=START) {Read_Succsee_Flag = false;Stop();return TestAck();}//ACK
0293 B181 IN R24,0x01
0294 7F88 ANDI R24,0xF8
0295 3088 CPI R24,0x8
0296 F041 BEQ 0x029F
0297 2422 CLR R2
0298 9220008B STS Read_Succsee_Flag,R2
029A E984 LDI R24,0x94
029B BF86 OUT 0x36,R24
029C B101 IN R16,0x01
029D 7F08 ANDI R16,0xF8
029E C061 RJMP 0x0300
(0056) //写I2C从器件地址和写方式
(0057) Write8Bit(device_adr); Wait();
029F B903 OUT 0x03,R16
02A0 E884 LDI R24,0x84
02A1 BF86 OUT 0x36,R24
02A2 B626 IN R2,0x36
02A3 FE27 SBRS R2,7
02A4 CFFD RJMP 0x02A2
(0058) if (TestAck()!=MT_SLA_ACK) {Read_Succsee_Flag = false;Stop();return TestAck();}//ACK
02A5 B181 IN R24,0x01
02A6 7F88 ANDI R24,0xF8
02A7 3188 CPI R24,0x18
02A8 F041 BEQ 0x02B1
02A9 2422 CLR R2
02AA 9220008B STS Read_Succsee_Flag,R2
02AC E984 LDI R24,0x94
02AD BF86 OUT 0x36,R24
02AE B101 IN R16,0x01
02AF 7F08 ANDI R16,0xF8
02B0 C04F RJMP 0x0300
(0059) //写RAM地址
(0060) Write8Bit(RamAddress); Wait();
02B1 B923 OUT 0x03,R18
02B2 E884 LDI R24,0x84
02B3 BF86 OUT 0x36,R24
02B4 B626 IN R2,0x36
02B5 FE27 SBRS R2,7
02B6 CFFD RJMP 0x02B4
(0061) if (TestAck()!=MT_DATA_ACK) {Read_Succsee_Flag = false;Stop();return TestAck();}
02B7 B181 IN R24,0x01
02B8 7F88 ANDI R24,0xF8
02B9 3288 CPI R24,0x28
02BA F041 BEQ 0x02C3
02BB 2422 CLR R2
02BC 9220008B STS Read_Succsee_Flag,R2
02BE E984 LDI R24,0x94
02BF BF86 OUT 0x36,R24
02C0 B101 IN R16,0x01
02C1 7F08 ANDI R16,0xF8
02C2 C03D RJMP 0x0300
(0062) //I2C重新启动
(0063) Start(); Wait();
02C3 EA84 LDI R24,0xA4
02C4 BF86 OUT 0x36,R24
02C5 B626 IN R2,0x36
02C6 FE27 SBRS R2,7
02C7 CFFD RJMP 0x02C5
(0064) if (TestAck()!=RE_START) {Read_Succsee_Flag = false;Stop();return TestAck();}
02C8 B181 IN R24,0x01
02C9 7F88 ANDI R24,0xF8
02CA 3180 CPI R24,0x10
02CB F041 BEQ 0x02D4
02CC 2422 CLR R2
02CD 9220008B STS Read_Succsee_Flag,R2
02CF E984 LDI R24,0x94
02D0 BF86 OUT 0x36,R24
02D1 B101 IN R16,0x01
02D2 7F08 ANDI R16,0xF8
02D3 C02C RJMP 0x0300
(0065) //写I2C从器件地址和读方式
(0066) Write8Bit(device_adr+1); Wait();
02D4 2F80 MOV R24,R16
02D5 5F8F SUBI R24,0xFF
02D6 B983 OUT 0x03,R24
02D7 E884 LDI R24,0x84
02D8 BF86 OUT 0x36,R24
02D9 B626 IN R2,0x36
02DA FE27 SBRS R2,7
02DB CFFD RJMP 0x02D9
(0067) if(TestAck()!=MR_SLA_ACK) {Read_Succsee_Flag = false;Stop();return TestAck();}//ACK
02DC B181 IN R24,0x01
02DD 7F88 ANDI R24,0xF8
02DE 3480 CPI R24,0x40
02DF F041 BEQ 0x02E8
02E0 2422 CLR R2
02E1 9220008B STS Read_Succsee_Flag,R2
02E3 E984 LDI R24,0x94
02E4 BF86 OUT 0x36,R24
02E5 B101 IN R16,0x01
02E6 7F08 ANDI R16,0xF8
02E7 C018 RJMP 0x0300
(0068) //启动主I2C读方式,且设为准备响应
(0069) Twi(); Wait();
02E8 EC84 LDI R24,0xC4
02E9 BF86 OUT 0x36,R24
02EA B626 IN R2,0x36
02EB FE27 SBRS R2,7
02EC CFFD RJMP 0x02EA
(0070) if(TestAck()!=MR_DATA_ACK) {Read_Succsee_Flag = false;Stop();return TestAck();}//ACK
02ED B181 IN R24,0x01
02EE 7F88 ANDI R24,0xF8
02EF 3580 CPI R24,0x50
02F0 F041 BEQ 0x02F9
02F1 2422 CLR R2
02F2 9220008B STS Read_Succsee_Flag,R2
02F4 E984 LDI R24,0x94
02F5 BF86 OUT 0x36,R24
02F6 B101 IN R16,0x01
02F7 7F08 ANDI R16,0xF8
02F8 C007 RJMP 0x0300
(0071) //读取I2C接收数据
(0072) temp=TWDR;
02F9 B143 IN R20,0x03
(0073) Read_Succsee_Flag = true;
02FA E081 LDI R24,1
02FB 9380008B STS Read_Succsee_Flag,R24
(0074) //I2C停止
(0075) Stop();
02FD E984 LDI R24,0x94
02FE BF86 OUT 0x36,R24
(0076) return temp;
02FF 2F04 MOV R16,R20
0300 D06F RCALL pop_gset1
0301 9508 RET
_uart0_rx_isr:
0302 922A ST R2,-Y
0303 938A ST R24,-Y
0304 939A ST R25,-Y
0305 93EA ST R30,-Y
0306 93FA ST R31,-Y
0307 B62F IN R2,0x3F
0308 922A ST R2,-Y
FILE: H:\程序库\usart_m8.c
(0001) /*****************************************************************
(0002) //ICC-AVR application builder : 2005-8-19 14:40:53
(0003) // Target : M8
(0004) // Crystal: 7.3728Mhz
(0005) // Crystal: 4.6080Mhz
(0006)
(0007) 实验:做usart串行通讯实验
(0008) 目的:了解及会使用usart串口
(0009) CPU:atmega8L
(0010) 相关的5个寄存器:UCSRA,UCSRB,UCSRC,UDR,UBRR(UBRRH,UBRRL)
(0011) 其中:UBRRH和UCSRC共用一个地址
(0012) ******************************************************************/
(0013) /*配置:CKOPT=0,CKSEL3..0=1111,SUT1..0=11(65ms慢速上升电源)*/
(0014) #include "usart_m8.h"
(0015)
(0016) unsigned char UART_RX_buff[UART_RX_BUFFER_SIZE];
(0017) unsigned char UART_TX_buff[UART_TX_BUFFER_SIZE];
(0018) unsigned char Rx_Flag;
(0019) unsigned char Rx_Temp,Rx_Count;
(0020) unsigned char Rx_Start_Pack_Flag,Rx_Over_Pack_Flag;
(0021)
(0022) unsigned char Write_Error[6] = {'x','w','4','0','x',0};//后面这个零是一定要加的,表示字符串结束
(0023) unsigned char Read_Error[6] = {'x','w','8','0','x',0};//或者"\0"
(0024) unsigned char aa[5] = {'o','p'};
(0025)
(0026) #pragma interrupt_handler uart0_rx_isr:12
(0027) void uart0_rx_isr(void)
(0028) {
(0029) //uart has received a character in UDR
(0030)
(0031) UART_RX_buff[Rx_Count] = UDR;
0309 EB80 LDI R24,0xB0
030A E090 LDI R25,0
030B 91E0008D LDS R30,Rx_Count
030D 27FF CLR R31
030E 0FE8 ADD R30,R24
030F 1FF9 ADC R31,R25
0310 B02C IN R2,0x0C
0311 8220 STD Z+0,R2
(0032) Rx_Count = Rx_Count+1;
0312 9180008D LDS R24,Rx_Count
0314 5F8F SUBI R24,0xFF
0315 9380008D STS Rx_Count,R24
(0033) if(Rx_Count == 9)
0317 3089 CPI R24,0x9
0318 F431 BNE 0x031F
(0034) {
(0035) Rx_Flag = true;
0319 E081 LDI R24,1
031A 9380008F STS Rx_Flag,R24
(0036) //USART_TransmitByte((Rx_Count+0x30));
(0037) Rx_Count = 0;
031C 2422 CLR R2
031D 9220008D STS Rx_Count,R2
(0038) //上位机在这时候要停一会儿,才能发第二串数据
(0039) }
031F 9029 LD R2,Y+
0320 BE2F OUT 0x3F,R2
0321 91F9 LD R31,Y+
0322 91E9 LD R30,Y+
0323 9199 LD R25,Y+
0324 9189 LD R24,Y+
0325 9029 LD R2,Y+
0326 9518 RETI
(0040) //USART_TransmitByte((Rx_Count+0x30));
(0041) }
(0042)
(0043) //UART0 initialize
(0044) // desired baud rate: 9600
(0045) // actual: baud rate:9600 (0.0%)
(0046) // char size: 8 bit
(0047) // parity: Disabled
(0048) void uart0_init(void)
(0049) {
(0050) Rx_Count = 0;
_uart0_init:
0327 2422 CLR R2
0328 9220008D STS Rx_Count,R2
(0051) Rx_Flag = false;
032A 9220008F STS Rx_Flag,R2
(0052) Rx_Start_Pack_Flag = false;
032C 922000D1 STS Rx_Start_Pack_Flag,R2
(0053) Rx_Over_Pack_Flag = false;
032E 922000D0 STS Rx_Over_Pack_Flag,R2
(0054) //本身的uart的初始化
(0055) UCSRB = 0x00; //disable while setting baud rate
0330 B82A OUT 0x0A,R2
(0056) //UCSRB[RXCIE,TXCIE,UDRIE,RXEN,TXEN,UCSZ2,RXB8,TXB8]
(0057) //Bit 7 – RXCIE: RX Complete Interrupt Enable
(0058)
(0059) UCSRA = 0x00;
0331 B82B OUT 0x0B,R2
(0060) //UCSRA[RXC,TXC,UDRE,FE,DOR,PE,U2X,MPCM]
(0061)
(0062) UCSRC = (BIT(URSEL)|BIT(UCSZ1)|BIT(UCSZ0));//设置成8位
0332 E886 LDI R24,0x86
0333 BD80 OUT 0x20,R24
(0063) //UCSRC[URSEL,UMSEL,UPM1,UPM0,USBS,UCSZ1,UCSZ0,UCPOL]
(0064) //位URSEL:寄存器选择("1"为UCSRC或"0"为UBRRH)
(0065) //位UMSEL:工作模式选择(0为异步,1为同步)
(0066) //位UPM1..0:为校验方式,硬件支持校验
(0067) //位USBS:停止位选择(0为一位,1为两位)
(0068) //位UCSZ0..2:发送位数选择(如果是8位:011)
(0069) //位UCPOL:时钟极性(只在同步模式使用,异步应置为"0")
(0070)
(0071) UBRRL = 0x77;//baudrate; //set baud rate lo
0334 E787 LDI R24,0x77
0335 B989 OUT 0x09,R24
(0072) UBRRH = 0x00; //set baud rate hi(设置波特率只用低四位,加起来一共12位)
0336 BC20 OUT 0x20,R2
(0073) //UBRR = baudrate; /* set the baud rate */
(0074)
(0075) UCSRB = ((1<<RXCIE)|(1<<RXEN)|(1<<TXEN));
0337 E988 LDI R24,0x98
0338 B98A OUT 0x0A,R24
0339 9508 RET
(0076) }
(0077) /************************************************************************
(0078) 接收时采用中断方式,,,以"包"为单位接收(9个字符)
(0079) *************************************************************************/
(0080) void UART_Receive(void)
(0081) {
(0082) if(Rx_Flag == true)
_UART_Receive:
033A 9180008F LDS R24,Rx_Flag
033C 3081 CPI R24,1
033D F471 BNE 0x034C
(0083) {
(0084) Rx_Flag = false;
033E 2422 CLR R2
033F 9220008F STS Rx_Flag,R2
(0085)
(0086) if((UART_RX_buff[0] == 0x58)&&(UART_RX_buff[8] == 0x58))//0x58 = 'w'
0341 918000B0 LDS R24,UART_RX_buff
0343 3588 CPI R24,0x58
0344 F439 BNE 0x034C
0345 918000B8 LDS R24,0xB8
0347 3588 CPI R24,0x58
0348 F419 BNE 0x034C
(0087) {
(0088) Rx_Over_Pack_Flag = true; //这个标志,可以让主函数去查
0349 E081 LDI R24,1
034A 938000D0 STS Rx_Over_Pack_Flag,R24
(0089) //Rx_Count = 0;//接收计数器清零
(0090) }
(0091) //USART_TransmitByte('p');//接收一包完,就发一个信号叫上机暂停发
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -