A simple example of twi multi-host communication is also provided, and IIC I2C is tested for anti-interference.

Source: Internet
Author: User

The following is a simple example:
Only one host is set on the bus, and the host uses query read/write
Multiple slave machines are allowed on the bus, and the slave machine uses the hardware interruption function.
*****************
I started to use the interrupt function for both the host and slave, but I found that the host is vulnerable to line interference and "Twi Crashes" (using one end of the wire to ground, the other end keeps rubbing and transient the twi communication line). When the machine crashes, the twi twint will no longer set the interrupt mark, causing the program to be interrupted to run, twint cannot be set even if the communication line is physically truncated (the host is retained and the pull-up resistor is retained. At this time, your interrupted code will no longer work, and you will not be able to judge the success or failure of the arbitration after the interruption. That is to say, this AVR (atmega48) Hardware Twi may be a problem, of course, it does not rule out my food.
To prevent interference, I use this method. Every time the Host reads and writes data, it exits the twi function. The slave has not found a dead host. However, we recommend that the slave continuously check whether the bus is occupied. Once the occupied bus times out, it also exits Twi once and then enters the STANDBY state.


/*************************************** **************

Codewizardavr v1.25.9 professional
Chip type: atmega48
Clock frequency: 8.000000 MHz
Memory Model: Small
External SRAM size: 0
Data stack size: 128
**************************************** *************/
// Twcr register description
// Bit 7-twint: Twi interrupt flag
// Bit 6-twea: enables Twi to respond
// Bit 5-twsta: Twi start status bit
// Bit 4-twsto: Twi stop status bit
// Bit 3-twwc: Mark of twi write conflict
// Bit 2-twen: Twi enabling
// Bit 1-res: Reserved
// Bit 0-twie: Twi interrupt enabling

# Include <000048.h>
# Include <delay. h>
# Include <nokia3310.h>

# Define iic_time 65535 // determines whether the host runs normally within the unit time
# Define iic_init twcr = 0b11000101; // standby
# Define iic_start_run twcr = 0b10100100; // The host sends a start signal.
# Define iic_byte_run twcr = 0b0000100; // clear the stop. stop mark/start host data receiving or sending
# Define iic_byte_run_ack twcr = 0b11000100; // clear the interrupt. Stop mark/start host data receiving/sending/responding to enable
# Define iic_stop_run twcr = 0b10010100; // host stop/release bus/Twi ready
# Define iic_off twcr = 0b0000000; // force exit Twi, applicable to host usage when the bus is disturbed
# Define iic_stop_no twcr & 16 // whether to send stop
# Define iic_int_ OK twcr> 127 // sets the interrupt mark
# Define iic_status twsr // Twi running status
# Define iic_datas twdr

Unsigned char iic_news [10]; // data volume
Unsigned int iic_n; // Communication Data Count

Interrupt [Twi] void twi_isr (void) // The slave Twi interrupt program/process read and write data in the relevant location
{
LCD _puthex (twsr); // LCD monitoring

Switch (iic_status)
{
Case 0x60: // your SLA + W has been received. Ack has been returned.
{
Iic_n = 0;
Iic_init;
Break;
}

Case 0x70: // The broadcast address ack has been returned.
{
Iic_n = 0;
Iic_init;
Break;
}

Case 0x80: // previously it was addressed with its own SLA + W. Data has been received and ACK has returned
{
Iic_news [iic_n] = iic_datas;
Iic_n ++;
Iic_init;
Break;
}

Case 0xa0: // receives the stop or repeated start when the slave is working.
{
Iic_init;
Break;
}

Case 0xa8: // your SLA + R has been received. Ack has been returned.
{
Iic_n = 0;
Iic_datas = iic_news [iic_n];
Iic_init;
Break;
}

Case 0xb8: // The data has been sent to receive ACK
{
Iic_n ++;
Iic_datas = iic_news [iic_n];
Iic_init;
Break;
}

Case 0xc0: // The data has been sent to receive the not_ack
{
Iic_init;
Break;
}

Case 0x90: // previously addressed in broadcast mode, data has been received ack has returned
{
Iic_news [iic_n] = iic_datas;
Iic_init;
Iic_n ++;
Break;
}

Default:
{
Iic_off;
Iic_init;
Break;
}
}
}

/*/Slave host *********************************** **********************************

Void main (void)
{
Unsigned int N;
LCD _init ();
LCD _cls ();
Twbr = 32; // 8 MHz/(16 + 2*32) = 100 kHz
TWAR = 2 + 1; // set your own address and enable broadcast receiving
Iic_init;
# ASM ("Sei") // enable global interrupt
While (1)
{
If (pinc.5 = 0 | pinc.4 = 0) if (n <65535) n ++; // checks whether the line is used for a long time/prevents Twi from crashing
If (pinc.5 = 1 & pinc.4 = 1) n = 0;
If (n = 65535) {iic_off; iic_init ;}
}
}

//************************************** ***********************************/

// Host write (excluding stop signal)/query method/parameter: slave address. quantity. Array

Unsigned char iic_write (unsigned char address, unsigned char N, unsigned char * P)
{
Unsigned char I;
Unsigned int;
If (address % 2 | n <1) Return (4); // If the parameter is not set, 4 is returned.
Iic_start_run; // send start
For (A = 0; A <iic_time; A ++) if (iic_int_ OK) break; // a simple time-limited wait
If (iic_status! = 0x08 & iic_status! = 0x10) Return (1); // If (repeated) Start fails, 1 is returned.
Iic_datas = address; iic_byte_run; // send address SLA + W
For (A = 0; A <iic_time; A ++) if (iic_int_ OK) break;
If (iic_status! = 0x18) Return (2); // SLA + W if the sending fails, 2 is returned.
For (I = 0; I <n; I ++) // send data
{
Iic_datas = P [I];
Iic_byte_run;
For (A = 0; A <iic_time; A ++) if (iic_int_ OK) break;
If (iic_status! = 0x28) Return (3); // 3 is returned if data transmission fails.
}
Return (0); // 0 is returned if the request is successful.
}

// Host read (excluding stop signal)/query method/parameter: slave address. quantity. Array

Unsigned char iic_read (unsigned char address, unsigned char N, unsigned char * P)
{
Unsigned char I;
Unsigned int;
If (address % 2 | n <1) Return (4); // If the parameter is not set, 4 is returned.
Iic_start_run; // send start
For (A = 0; A <iic_time; A ++) if (iic_int_ OK) break; // a simple time-limited wait
If (iic_status! = 0x08 & iic_status! = 0x10) Return (1); // If (repeated) Start fails, 1 is returned.
Iic_datas = address + 1; iic_byte_run; // send address SLA + R
For (A = 0; A <iic_time; A ++) if (iic_int_ OK) break;
If (iic_status! = 0x40) Return (2); // SLA + R returns 2 If the sending fails.
For (I = 0; I <n; I ++) // read data
{
If (I + 1 <n) iic_byte_run_ack; else iic_byte_run;
For (A = 0; A <iic_time; A ++) if (iic_int_ OK) break;
If (iic_status! = 0x50 & iic_status! = 0x58) Return (3); // 3 is returned if Data Reading fails.
P [I] = iic_datas;
}
Return (0); // 0 is returned if the request is successful.
}

Void iic_stop (void) // host sends stop
{
Unsigned int;
Iic_stop_run;
For (A = 0; A <iic_time; A ++) if (iic_stop_no); else break;
}

// Host ************************************* ********************************

Void main (void)
{
Unsigned char iic_ OK;
Iic_news [0] = 0xaa; iic_news [1] = 0xbb; iic_news [2] = 0xcc; iic_news [3] = 0xdd;
LCD _init ();
LCD _cls ();
Twbr = 32; // 8 MHz/(16 + 2*32) = 100 kHz
While (1)
{
LCD _gotoxy (0, 0 );
// Update the data to be written.
Iic_ OK = iic_write (, iic_news); // success returns 0/(address, data volume, array)
LCD _puthex (iic_ OK );
// Update the data to be written.
Iic_ OK = iic_write (2, 4, iic_news );
LCD _puthex (iic_ OK );

Iic_ OK = iic_read (2, 4, iic_news );
LCD _puthex (iic_ OK );
// Save the read data
Ddrd = 255; portd = portd ^ 255; // led observation/When the LED flashes fast but not visible/When the LED flashes slowly

Iic_stop ();
Iic_off; // disable. Reset Twi to prevent the line from being disturbed and unable to set the interruption mark.

}
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.