The I/O port of the microcontroller simulates the I2C data bus transmission mode

Publisher:chenxiaohong68Latest update time:2016-09-26 Source: eefocusKeywords:MCU Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
The work that needs to be done is summarized as follows:

1. MCU's I2C is implemented by IO port simulation;

2. MCU establishes communication with timing chip RX-8025SA as I2C master device;

3. Realize the functions of timed alarm, timed wake-up and sleep;

Debugging process:

1. The code for IO port simulation I2C can be found on the Internet. However, in specific projects, due to the difference in clock timing control, it needs to be debugged again.

When debugging I2C in a specific project, you need to pay attention to the following points:

1) The address of an I2C device can be described using 7 bits or 8 bits.

Note that as long as the code is consistent with the actual device address, it is fine. The usage of the 7-bit address is nothing more than describing the upper 7 bits of the 8-bit address, because the last bit is fixed. (It is 1 when reading and 0 when writing).

2) The I2C communication protocol itself does not specify the number of bytes transmitted during the communication process. However, some devices may only allow the transmission of 1 byte, or 2 bytes, or bytes within a fixed number of bits. The specific rules should be determined by the device specification.

3) Some I2C devices can only be written but not read, so this is also something you need to pay attention to.

4) The communication rate of the 2C slave device, that is, the data transmission speed, may vary between different devices, so compatibility issues must be considered.

5) Some devices may have a 10-bit address. When writing the address, you need to send the device address twice.

6) The device programming should be as standardized as possible. When the bus is to be released, it is best to set the I/O to the input port. Some programming practices set the I/O to high when the bus is released, which is not good.

7) Timing control must comply with the requirements of the equipment specification:

Using MCU's IO port to simulate I2C communication to achieve timing function - Allang - Lemon is red

If you have an oscilloscope, here is a more applicable and efficient debugging method. Use the two-way probe of the oscilloscope to directly connect to the data line SDA and clock line SCL of I2C, obtain the two-way waveform after power-on, and then read the communication data according to the I2C communication protocol, so that you can see where the timing problem is.

2. If I2C communication is OK, you need to implement the timing function required by the project according to the RX-8025SA specification.

Take the alarm clock function as an example: (Please refer to the specification of RX-8025SA)

1. There is an alarm D function in the 8025 chip:

The alarm D function is a function that can obtain the [hour + minute] interrupt signal from the /INTA pin.

That is, when the current time (week+hour+minute) is consistent with the time set by Alarm_D, /INTA is set to L.

DALE position 1.

2. Connect /INTA to the RA5 pin of the MCU. The MCU determines the L or H of the RA5 pin.

And whether the current device is in the shutdown state. When RA5 = L and the device is in the power-on state,

The MCU notifies the device, and the device then determines whether to issue an alarm based on relevant settings.

3. The method for setting the alarm D time is as follows:

1) Set this DALE bit to 0 to disable Alarm_D;

Note: This is to avoid outputting /INTA=L when the current time in the alarm setting coincides with the alarm time.

2) Next, set the DAFG bit for the day of the week and the hour and minute;

3) Finally, set DALE to 1 to enable the alarm D function;

4. Power-on initialization: Set DAFG and WAFG to 0; make alarm W/alarm D invalid at the moment of power-on.

3. Attach the code for simulating I2C communication (search it online):

void IIC_str ( void )

{

IIC_SCL=0;

IIC_SDA=1;

_nop_();

_nop_();

IIC_SCL=1;

nops();

IIC_SDA=0;  // Start

nops();

IIC_SCL=0;

return;

}

void IIC_stop ( void )

{

IIC_SCL=0;

IIC_SDA=0;

_nop_();

_nop_();

IIC_SCL=1;

nops();

IIC_SDA=1;  // End

nops();

return;

}

void IIC_ack ( bit ack )

{

IIC_SCL=0;

_nop_();

_nop_();

if ( ack )

IIC_SDA=0;  //Response

else

IIC_SDA=1;  //No response

nops();

IIC_SCL=1;

nops();

IIC_SCL=0;

}

bit IIC_send_byte ( uchar c )

{

flying  outtime;

flying bitnum;

outtime=0;

for ( bitnum=0; bitnum<8; bitnum++ )

{

IIC_SCL=0;

if ( ( c<// Send a word

IIC_SDA=1;

else

IIC_SDA=0;

_nop_();

IIC_SCL=1;

nops();

nops();

IIC_SCL=0;

}

IIC_SDA=0;

IIC_SDA=1;  // Prepare to receive response signal

_nop_(); _nop_(); _nop_(); _nop_();

IIC_SCL=1;  // Start receiving response signal

while ( IIC_SDA )  // Timeout judgment

{

if ( ( outtime++ )>250 )  // Unable to receive response signal, stop IIC communication, return 0 value and report error

{

outtime=0;

IIC_stop();

return ( 0 ) ;

}

}

outtime=0;

IIC_SCL=0;

return ( 1 );  // Sending completed, return 1 value, communication successful

}

uchar IIC_read_byte ( bit ack )

{

flying retc;

flying bitnum;

retc=0;  //receive storage clear 0

IIC_SCL=0;

nops();

IIC_SDA=1;

for ( bitnum=0; bitnum<8; bitnum++ )

{

_nop_();

IIC_SCL=0;

IIC_SDA=1;  //Ready to receive

nops();

IIC_SCL=1;  //Receive

nops();

retc<<=1;

if ( IIC_SDA )  //Receive data bit judgment

retc+=1;

}

IIC_SCL=0;

_nop_();

_nop_();

_nop_();

IIC_SDA=1;

IIC_ack( ack );  //Response signal

return retc;

}

void IIC_send_noadder ( uchar adder, uchar ddata )

{

bit ack;

IIC_str ();

ack=IIC_send_byte ( adder );  //sending address

if ( !ack )

alarm=0;

return ; }

nops();

ack=IIC_send_byte(ddata);  //send data

if ( !ack )

{ alarm=0;

return ; }

IIC_stop ();

return ;

}

void IIC_read_noadder ( uchar adder, uchar *buf, uchar num )

{

bit ack;

flying i;

IIC_str ();

ack=IIC_send_byte ( adder );  //sending address

if ( !ack )

{ alarm=0;

return ; }

nops();

for ( i=0; i

{

*( buf++ )=IIC_read_byte ( 1 );  //Receive data  and store it in *buf

}

IIC_stop ();

return ;

}

void IIC_send_adder ( uchar adder , uchar sub , uchar ddata )

{

bit ack;

IIC_str();

ack=IIC_send_byte ( adder );  //Send slave address

if ( !ack )

{

alarm=0;

return ; }

ack=IIC_send_byte ( sub );  //Send slave address

if ( !ack )

{ alarm=0;

return ; }

ack=IIC_send_byte(ddata);  //send data

if ( !ack )

{ alarm=0;

return ; }

IIC_stop ();

return ;

}

void IIC_read_adder ( uchar adder, uchar sub, uchar *buf, uchar num )

{

bit ack;

flying i;

IIC_str ();

ack=IIC_send_byte ( adder );  //Send slave address

if ( !ack )

{ alarm=0;

return ; }

ack=IIC_send_byte ( sub );  //Send slave address

if ( !ack )

{ alarm=0;

return ; }

for ( i=0; i

{

*( buf++ )=IIC_read_byte ( 1 );  //Receive data  and store it in *buf

}

IIC_stop ();

return ;

}

Keywords:MCU Reference address:The I/O port of the microcontroller simulates the I2C data bus transmission mode

Previous article:GPRS module sends information code
Next article:51 single chip microcomputer control of relay

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号