After all the nonsense, let's get down to business. This time it's about the use of hardware IIC (not used to saying TWI yet) under the ATMega16 platform. In the ATMega16 datasheet we can see very powerful functions, and there are many master-slave settings. This article only talks about the most commonly used method, which is "ATMega16 hardware TWI scan send and scan read".
First of all, we need to clarify the process of sending and receiving TWI:
send:
1. Set the data transmission baud rate
2. Send START signal and wait for response ==》 <== Response signal
3. Send chip address and wait for response ==》 《==Response signal
4. Send the absolute address of the data and wait for the response ==》 ==Response signal
5. Send the data to be written and wait for the response ==》 《==Response signal
6. Send STOP signal to release the bus ==》 Data is written successfully
take over:
1. Set the data transmission baud rate
2. Send START signal and wait for response ==》 <== Response signal
3. Send chip address and wait for response ==》 《==Response signal
4. Send the absolute address of the data and wait for the response ==》 ==Response signal
5. Send RESTART signal and wait for response ==》 <==Response signal
6. Send the chip address and indicate the read operation, and wait for the response ==》 == response signal
7. Read data and wait for response ==》 《==Response signal
8. Send STOP signal to release the bus ==》 Data read operation is successful
Application chip: ATMega 16 Crystal: 7.3728
Code file: Project
|___TWI.C
| |_____ IAR_DELAY.H
|___UART.C
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IAR_DELAY.H
#ifndef __IAR_DELAY_H
#define __IAR_DELAY_H
#include
#define XTAL 7.3728 // can be defined as the crystal frequency you use (unit: MHz)
#define delay_us(x) __delay_cycles ( (unsigned long)(x * XTAL) )
#define delay_ms(x) __delay_cycles ( (unsigned long)(x * XTAL*1000) )
#define delay_s(x) __delay_cycles ( (unsigned long) (x * XTAL*1000000) )
#endif
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
UART.C
#include
#define uchar unsigned char
#define uint unsigned int
//############################################################## UBRRH=0x00; //Set the baud rate register low byte DDRD_Bit1=1; //Configure TX as output (very important) @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include void Uart_Init(void); #define IIC_Start() TWCR =(1< #define IIC_Wait() while(!(TWCR&(1< //################################################################################ /*stop stop*/ unsigned char Receive_Byte ;
/*Serial port initialization function*/
void Uart_Init(void)
{
UCSRB = (1<
UBRRL=47; //9600 //Set the baud rate register high byte
}
//##############################################################
/*Send one character data, query mode*/
void Uart_Transmit(uchar data)
{
while(!(UCSRA&(1<
UDR = data; /* Send data*/
}
#include "IAR_DELAY.H"
#define uchar unsigned char
#define uint unsigned int
void Uart_Transmit(uchar data);
//Variable declaration
#define EEPROM_BUS_ADDRESS 0xA0 //Device address
/*######################################################################################*/
/*Slave address bit definition:______________________________________-------------*/
/* AT24C02 | 1 | 0 | 1 | 0 | A2 | A1 | A0 | R/~W |------------*/
/* ---------------------------------------------------*/
/*# ...
//Subsequent actions of each status word in host sending mode
#define TW_START 0x08 //Start signal has been issued
#define TW_REP_START 0x10 //Repeat start signal has been issued
#define TW_MT_SLA_ACK 0x18 //Write byte has been issued and received ACK signal
#define TW_MT_SLA_NACK 0x20 //Write byte has been issued and received NACK signal
#define TW_MT_DATA_ACK 0x28 //Data has been issued and received ACK signal
#define TW_MT_DATA_NACK 0x30 //Data has been issued and received NACK signal
#define TW_MT_ARB_LOST 0x38 //Lost bus control right
//Subsequent actions of each status word in host receiving mode
#define TW_MR_ARB_LOST 0x38 //Lost bus control right, no response signal received
#define TW_MR_SLA_ACK 0x40 //Read command has been issued and received ACK
#define TW_MR_SLA_NACK 0x48 //Read command sent and received NACK
#define TW_MR_DATA_ACK 0x50 //Data received, ACK sent
#define TW_MR_DATA_NACK 0x58 //Data received, NACK sent
// The TWEN bit enables the TWI function and switches the PC0 and PC1 pins to the second function. If cleared, it interrupts the transmission of TWI.
#define IIC_Stop() TWCR =(1<
/*I2C bus single byte write*/
unsigned char twi_write(unsigned char addr, unsigned char dd)
{
TWBR = 10; //Set baud rate
/*start start*/
IIC_Start(); //Hardware sends START signal, and clears TWINT bit, enables hardware TWI, and makes TWI start working
IIC_Wait(); //Wait for sending START to complete TWINT bit
if ((TWSR & 0xF8) != 0x08) return 0; //Detect TWINT bit is in position, compare the status in TWSR register, if correct, transmit data downward, error returns 0
/*SLA_W Chip address*/
TWDR = EEPROM_BUS_ADDRESS ; //Chip address 0xA0, assign to data register TWDR, wait for sending
TWCR = (1 << TWINT) | (1 << TWEN); //Write 1 to clear the TWINT bit of the control register TWCR, then enable the TWI hardware interface, let TWI work, and send the data in the TWDR register
IIC_Wait(); //Wait for data to be sent and TWINT to be reset
if ((TWSR & 0xF8) != 0x18) return 0; //Detect that the TWINT bit is in position, compare the state in the TWSR register, if correct, transfer data downward, otherwise return 0
/*addr operation address*/
TWDR = addr; //Assign the absolute address of the write data to the data register TWDR, wait for sending
TWCR = (1 << TWINT) | (1 << TWEN); //TWINT of the control register TWCR Write 1 to clear the TWDR bit by software, then enable the TWI hardware interface, let TWI work, and send the data in the TWDR register
IIC_Wait(); //Wait for data to be sent and TWINT to be reset
if ((TWSR & 0xF8) != 0x28) return 0; //Detect the TWINT bit, compare the state in the TWSR register, if correct, transfer data downward, and return 0 if error occurs
/*dd write data*/
TWDR = dd; //Assign the data to be written to the data register TWDR and wait for it to be sent
TWCR = (1 << TWINT) | (1 << TWEN); //Write 1 to clear the TWINT bit of the control register TWCR by software, then enable the TWI hardware interface, let TWI work, and send the data in the TWDR register
IIC_Wait(); //Wait for data to be sent and TWINT to be reset
if ((TWSR & 0xF8) != 0x28) return 0; // Detect the TWINT bit, compare the status in the TWSR register, if it is correct, transfer data downward, otherwise return 0
IIC_Stop(); //Data transmission is completed, send STOP signal, release control of the busreturn
1; //Write data successfully, return 1 to judge whether the data is written successfully
}
//#########################################################################################
/*I2C bus single byte read*/
unsigned char twi_read(unsigned char addr)
{
TWBR = 2; //Set baud rate
/*start*/
IIC_Start(); //Hardware sends START signal and clears TWINT bit to enable hardware TWI and start TWI working
IIC_Wait(); //Wait for sending START to complete TWINT bit
if ((TWSR & 0xF8) != 0x08) return 0; //Detect TWINT bit, compare the state in TWSR register, if correct, transfer data downward, otherwise return 0
/*SLA_W chip address*/
TWDR = EEPROM_BUS_ADDRESS; //Chip address 0xA0, assign value to data register TWDR, wait for sending
TWCR = (1 << TWINT) | (1 << TWEN); //TWINT of control register TWCR Write 1 to clear the bit by software, then enable the TWI hardware interface, let TWI work, and send the data in the TWDR register
IIC_Wait(); //Wait for the data to be sent and TWINT to be reset
if ((TWSR & 0xF8) != 0x18) return 0; //Detect the TWINT bit, compare the state in the TWSR register, if correct, transfer the data downward, and return 0 if wrong
/*addr operation address*/
TWDR = addr; //Assign the absolute address of the write data to the data register TWDR and wait for sending
TWCR = (1 << TWINT) | (1 << TWEN); //Write 1 to clear the TWINT bit of the control register TWCR by software, then enable the TWI hardware interface, let TWI work, and send the data in the TWDR register
IIC_Wait(); //Wait for the data to be sent and TWINT to be reset
if ((TWSR & 0xF8) != 0x28) return 0; //Detect TWINT bit is in position, compare the state in TWSR register, if correct, transfer data downward, return 0 if error
/*restart restart*/
IIC_Start(); //Hardware sends RESTART signal, clears TWINT bit, enables hardware TWI, and starts TWI working
IIC_Wait(); //Wait for data to be sent and TWINT to be reset
if ((TWSR & 0xF8) != 0x10) return 0; //Detect TWINT bit is in position, compare the state in TWSR register, if correct, transfer data downward, return 0 if error
/*SLA_R chip address*/
TWDR = 0xA1; //Chip address 0xA0 and indicate that it is a read operation (the last bit is 1), assign value to data register TWDR, wait for sending
TWCR = (1 << TWINT) | (1 << TWEN); //TWINT of control register TWCR The software writes 1 to clear the TWINT bit of the control register TWCR, then enables the TWI hardware interface, allows TWI to work, and sends the data in the TWDR register
IIC_Wait(); //Wait for data to be sent and TWINT to be reset
if ((TWSR & 0xF8) != 0x40) return 0; //Detect that the TWINT bit is in position, compare the state in the TWSR register, If correct, transfer data downward, and return 0 if error
/*Read data*/
TWCR = (1 << TWINT) | (1 << TWEN); //Write 1 to clear the TWINT bit of the control register TWCR, then enable the TWI hardware interface, allow TWI to work, and send the data in the TWDR register
IIC_Wait(); //Wait for data to be sent and TWINT to be reset
if ((TWSR & 0xF8) != 0x58) return 0; //Detect that the TWINT bit is in position, compare the state in the TWSR register, If correct, transfer data downward, and return 0 if error
Receive_Byte = TWDR; //Put the read data into the local variable
/*stop*/
IIC_Stop(); //Data transmission completed, send STOP signal, release control of the bus
return Receive_Byte; //Use the read data as the output of the function
}
//################################################################################
/*Main function*/
void main(void)
{
uchar c,d;
Uart_Init(); //Serial port initialization
delay_us(20);
Uart_Transmit(0x55); //Test serial port
c = twi_write(0x51,0xf8); //Write data 0x22 at address 0x51
Uart_Transmit(c); //Send the return value to the serial port to test whether the write is successful
delay_ms(2);
d = twi_read(0x51); //Read the data at address 0x51
Uart_Transmit(d); //Send the read data to the serial port
while(1);
}
Previous article:AVR IO port characteristics and applications
Next article:IAR For AVR Serial Port Interrupt Receive
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Huawei's Strategic Department Director Gai Gang: The cumulative installed base of open source Euler operating system exceeds 10 million sets
- Download from the Internet--ARM Getting Started Notes
- Learn ARM development(22)
- Learn ARM development(21)
- Learn ARM development(20)
- Learn ARM development(19)
- Learn ARM development(14)
- Learn ARM development(15)
- Analysis of the application of several common contact parts in high-voltage connectors of new energy vehicles
- Wiring harness durability test and contact voltage drop test method
- Domestic MCU
- The RC steps down the voltage to 5V to power the microcontroller. The microcontroller IO directly controls the thyristor through the resistor. Is there a small probability that the IO will be damaged?
- About the memory FRAM of msp430fr2000!!
- [NXP Rapid IoT Review] + (I) Factory Program Usage
- Introduction to the application of decoupling capacitors in single chip microcomputer circuits
- CC2640之ADC功能实现和供电电压的採集
- 18 CC3200-LAUNCHXL development board user evaluation reports are out, participate in the vote to win prizes!
- [Synopsys IP Resources] Fast, accurate, and ruthless, Verdi automatically solves debugging problems and unleashes chip productivity
- A Brief Discussion on Synchronization of Multiple Asynchronous Clock Design
- SG3824 is a push-pull switching power supply without dual PWM output. Can you help me?