shaw 发表于 2024-3-12 11:48:09

关于IIC数据连续读取的问题

//-------------------------------------------------------------------------------------------------
void        ee_start( void)
{
        ee_scl = 1 ;
        ee_sda = 1 ;
        delay(10) ;
        ee_sda = 0 ;
        delay(10) ;
        ee_scl = 0 ;
        delay(10) ;
                }
//-------------------------------------------------------------------------------------------------
void        ee_stop( void)
{
        ee_scl = 0 ;
        ee_sda = 0 ;
        delay(10) ;
        ee_scl = 1 ;
        delay(10) ;
        ee_sda = 1 ;
        delay(10) ;
                }
//-------------------------------------------------------------------------------------------------
unsigned        char        r_ack(void)
{
unsigned        char        ack = 0x55 ;
        delay(5)         ;
        ee_scl = 1         ;
        delay(5)         ;
        if(ee_sda == 0 )        ack = 0xaa ;
        ee_scl = 0         ;
        return        ack ;
                                        }       
//-------------------------------------------------------------------------------------------------
//55输出0aa输出1
void        w_ack(unsigned        char ack)
{
        if ( ack == 0x55 )                ee_sda = 0 ;
        else if ( ack == 0xaa )                ee_sda = 1 ;
        delay(5)         ;
        ee_scl = 1         ;
        delay(5)         ;
        ee_scl = 0         ;
                                        }       
//---------------------------------------------------------------------------------------------
//        ee.ack == 0xaa表示正确
void        ee_send_byte(unsigned        char        i)
{
unsigned        char                n=0 ;       
        while ( n<8 )
        {
                if (( i & 0x80 ) == 0x00 )
                {        ee_sda = 0 ;        }
                else               
                {        ee_sda = 1 ;        }
                delay(5)         ;
                ee_scl = 1         ;
                delay(5)         ;
                ee_scl = 0         ;
                i = i << 1         ;                       
                n = n + 1         ;
                                }
//-------------------------------------
//                读取 ACK 位
//                ack = r_ack( ) ;
                        }
//---------------------------------------------------------------------------------------------
//        ee.ack == 0xaa表示正确
unsigned        char        ee_read_byte( )
{
unsigned        char                i   ;       
unsigned        char                n=0 ;       
        while ( n<8 )
        {        ee_scl = 1 ;
                delay(5) ;
                i = ( i << 1 ) & 0xfe ;
                if ( ee_sda == 1 )                {        i = i + 1 ;        }
                ee_scl = 0         ;
                delay(5) ;
                n = n + 1 ;                }
//---------------------------------------------------
        return                i        ;
                        }
//----------------------------------------------------------------------------------------------
//                2408         address = 0 -- 3ff
void        ee_write( unsigned char address,unsigned char dat)
{       
        ee_start() ;
        ee_send_byte( 0xa0 ) ;       
        ack = r_ack( ) ;
        ee_send_byte( address ) ;       
        ack = r_ack( ) ;
        ee_send_byte( dat ) ;       
        ack = r_ack( ) ;
        ee_stop() ;
//------------------------------------------
                delay_ms(5) ;
//读 ACK 约使用 4ms
//        delay_ms(10);
        do
        {        ee_start() ;
                ee_send_byte( 0xa0 ) ;       
                ack = r_ack( ) ;
                        }        while ( ack == 0x55 ) ;       
        ee_stop() ;
                }               
//----------------------------------------------------------------------------------------------
//        读 1 BYTE约需要 1 ms
//                2408         address = 0 -- 3ff
unsigned        char        ee_read( unsigned char address )
{
unsigned        char                i;
        ee_start() ;
        ee_send_byte( 0xa0 ) ;       
        ack = r_ack( ) ;
        ee_send_byte( address ) ;       
        ack = r_ack( ) ;
        ee_start() ;
        ee_send_byte( 0xa1) ;       
        ack = r_ack( ) ;
        i =        ee_read_byte( ) ;
        w_ack(0xaa) ;
        ee_stop() ;
        return        i ;
                }               
//----------------------------------------------------------------------------------------------
void        ee_read_p( unsigned char address )
{
        ee_start() ;
        ee_send_byte( 0xa0 ) ;       
        ack = r_ack( ) ;
        ee_send_byte( address ) ;       
        ack = r_ack( ) ;
        ee_start() ;
        ee_send_byte( 0xa1) ;       
        ack = r_ack( ) ;
//--------------------------------
        a =        ee_read_byte( ) ;
        w_ack(0x55) ;
        //--------------------------------
        a =        ee_read_byte( ) ;
        w_ack(0x55) ;
        //--------------------------------
        a =        ee_read_byte( ) ;
        w_ack(0x55) ;
//--------------------------------
        a =        ee_read_byte( ) ;
        w_ack(0x55) ;
//--------------------------------
        a =        ee_read_byte( ) ;
        w_ack(0x55) ;
//--------------------------------
        a =        ee_read_byte( ) ;
        w_ack(0x55) ;
//--------------------------------
        a =        ee_read_byte( ) ;
        w_ack(0x55) ;
//--------------------------------
        a =        ee_read_byte( ) ;
        w_ack(0xaa) ;
        ee_stop() ;
                }               


#include <STC32G.H>
#include "stdio.h"
#include "intrins.h"
#include         "config.h"
#include "base.c"
#include "2402.c"
//==============================================================================================================
void main()
{
    WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1; //扩展寄存器(XFR)访问使能
    CKCON = 0; //提高访问XRAM速度

    P0M1 = 0;   P0M0 = 0;   //设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
    P1M1 = 0;   P1M0 = 0;   //设置P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V)
    P2M1 = 0;   P2M0 = 0;   //设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V)
    P3M1 = 0;   P3M0 = 0;   //设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
    P4M1 = 0;   P4M0 = 0;   //设置P4.2~P4.5为漏极开路(实验箱加了上拉电阻到3.3V)
        P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
//-----------------------------------------------------------
                P1M0 = 0x02; P1M1 = 0x00;
//                P2M0 = 0xc0; P2M1 = 0xc0;
    P0M0 = 0x0c; P0M1 = 0x0c;

//-----------------------------------------------------------
                rs232_ini( );
                EA = 1;   //打开总中断
//--------------------------------------------------------       
//问题:单独一个BYTE读写都是对的,连续读就不正确,此时只有第一个BYTE正确
        while(1)
        {
                                delay_ms(1000);
                                led=~led ;
                                ee_read_p(0) ;                               
                                rs2_tx( 0xaa );                               
                                rs2_tx( 0xaa );                               
                                rs2_tx( 0xaa );                               
                                rs2_tx( 0xaa );
                                rs2_tx( ack );
                                rs2_tx( ack );
                                rs2_tx( ack );
                                rs2_tx(a);                               
                                rs2_tx(a);                               
                                rs2_tx(a);                               
                                rs2_tx(a);                               
                                rs2_tx(a);                               
                                rs2_tx(a);                               
                                rs2_tx(a);                               
                                rs2_tx(a);                               

                                delay_ms(1000);
                                led=~led ;
                                rs2_tx( 0xaa );                               
                                rs2_tx( 0xaa );                               
                                rs2_tx( 0xaa );                               
                                rs2_tx( 0xaa );
                                ee_read_p(0x10) ;                               
                                rs2_tx( ack );
                                rs2_tx( ack );
                                rs2_tx( ack );
                                rs2_tx(a);                               
                                rs2_tx(a);                               
                                rs2_tx(a);                               
                                rs2_tx(a);                               
                                rs2_tx(a);                               
                                rs2_tx(a);                               
                                rs2_tx(a);                               
                                rs2_tx(a);                               

                                delay_ms(1000);
                                led=~led ;
                                rs2_tx( 0xaa );                               
                                rs2_tx( 0xaa );                               
                                rs2_tx( 0xaa );                               
                                rs2_tx( 0xaa );
                                ee_read_p(0x20) ;                               
                                rs2_tx( ack );
                                rs2_tx( ack );
                                rs2_tx( ack );
                                rs2_tx(a);                               
                                rs2_tx(a);                               
                                rs2_tx(a);                               
                                rs2_tx(a);                               
                                rs2_tx(a);                               
                                rs2_tx(a);                               
                                rs2_tx(a);                               
                                rs2_tx(a);                               
                                        }
                        }




                       
                       
                       
                       
                       
                       

晓飛飛 发表于 2024-3-12 20:09:56

那么,问题是啥,“不说了,问题都在代码里”?

shaw 发表于 2024-3-12 22:24:32

晓飛飛 发表于 2024-3-12 20:09
那么,问题是啥,“不说了,问题都在代码里”?
是这样的,我的程序在MICROCHIP芯片中运行是成功的,
拿到STC32上发现I2C连续 读 只能读第一个BYTE成功,
第二个就不对了。尤其是我需要 LM75A 和 HDC1080 的读取全错了

神农鼎 发表于 2024-3-12 22:34:22



【新提醒】OLED12864, DMA-I2C 驱动,STC32G12K128演示 - OLED12864-GUI/U8g2-科学计算器 - 国芯论坛-STC全球32位8051爱好者互助交流社区 - STC全球32位8051爱好者互助交流社区 (stcaimcu.com)

21cnsound 发表于 2024-3-12 23:39:50

shaw 发表于 2024-3-12 22:24
是这样的,我的程序在MICROCHIP芯片中运行是成功的,
拿到STC32上发现I2C连续 读 只能读第一个BYTE成功,
...

既然有对比,直接逻辑分析仪对比分析下应该比较容易发现问题。大概率还是时序方面问题

晓飛飛 发表于 2024-3-19 21:03:32

shaw 发表于 2024-3-12 22:24
是这样的,我的程序在MICROCHIP芯片中运行是成功的,
拿到STC32上发现I2C连续 读 只能读第一个BYTE成功,
...

读完一个字节要给器件发ACK的,直到不想继续读了,发个NACK,这是协议要求的,必须严格遵循。

shaw 发表于 2024-3-26 11:06:14

晓飛飛 发表于 2024-3-19 21:03
读完一个字节要给器件发ACK的,直到不想继续读了,发个NACK,这是协议要求的,必须严格遵循。 ...

肯定遵守协议了,不然在MICROCHIP单片机上就不会成功
页: [1]
查看完整版本: 关于IIC数据连续读取的问题