关于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
那么,问题是啥,“不说了,问题都在代码里”?
是这样的,我的程序在MICROCHIP芯片中运行是成功的,
拿到STC32上发现I2C连续 读 只能读第一个BYTE成功,
第二个就不对了。尤其是我需要 LM75A 和 HDC1080 的读取全错了
【新提醒】OLED12864, DMA-I2C 驱动,STC32G12K128演示 - OLED12864-GUI/U8g2-科学计算器 - 国芯论坛-STC全球32位8051爱好者互助交流社区 - STC全球32位8051爱好者互助交流社区 (stcaimcu.com)
shaw 发表于 2024-3-12 22:24
是这样的,我的程序在MICROCHIP芯片中运行是成功的,
拿到STC32上发现I2C连续 读 只能读第一个BYTE成功,
...
既然有对比,直接逻辑分析仪对比分析下应该比较容易发现问题。大概率还是时序方面问题 shaw 发表于 2024-3-12 22:24
是这样的,我的程序在MICROCHIP芯片中运行是成功的,
拿到STC32上发现I2C连续 读 只能读第一个BYTE成功,
...
读完一个字节要给器件发ACK的,直到不想继续读了,发个NACK,这是协议要求的,必须严格遵循。 晓飛飛 发表于 2024-3-19 21:03
读完一个字节要给器件发ACK的,直到不想继续读了,发个NACK,这是协议要求的,必须严格遵循。 ...
肯定遵守协议了,不然在MICROCHIP单片机上就不会成功
页:
[1]