I2C EEPROM 비트 뱅잉 : 첫 번째 비트가 설정되지 않은 경우에만 잘 씁니다.


9

현재 비트 뱅킹을 사용하여 SDA 및 SCL 라인을 구동하는 I2C EEPROM 프로젝트를 진행하고 있습니다.

내 읽기 기능은 제대로 작동하지만 선행 "1"로 바이트를 쓸 때마다 항상 FF를 다시 읽습니다. 바이트가 이전에 다른 것으로 프로그래밍 된 경우에도 마찬가지입니다. 선행 "0"은 완벽합니다. 내 읽기 루틴이 아닙니다. 범위에서 볼 수 있듯이 FF를 반환합니다.

이것이 왜 그런지에 대한 제안을 찾고 있습니다. 내가 놓칠 수있는 명백한 문제가 있습니까? [코드를 게시 할 수 없습니다-회사 기밀 정보 ... :(]

내가 보는 모든 파형은 사양을 정확하게 충족시킵니다. EEPROM을 분리하고 있습니다. 내 풀업은 2.2k이므로 사양 내에 있습니다. 이 프로토 타입에서 약 500Hz로 클럭킹하고 있습니다. 칩이 각 바이트에 ACK를 보내서 인식합니다. 그러나 그것은 작동하지 않습니다 ...

Microchip 24LC256을 사용하고 있습니다.

1 바이트에 대한 단순화 된 쓰기 알고리즘 :

wait
SDA low
SCL low
wait
for each bit
    if bit is set:   SDA high
    if bit is unset: SDA low
    wait
    SCL high
    wait
    wait
    SCL low
    wait
wait
SDA high 
SCL high
wait
wait
check ACK status
SDA low
SCL low
wait
return ACK status

1 바이트에 대한 단순화 된 판독 알고리즘 :

wait
SCL low
SDA high
for each bit (8 bits)
    SCL high
    wait
    wait
    SCL low
    wait
    check and store received bit
    wait
do a NACK or ACK depending on if it is the last byte

1
@ 저스틴- 어떤 주소에 0x7F 값을 쓰면 작동하지만 모든 주소에 0x80을 쓰면 작동 하지 않는다고 생각합니다.
Rocketmagnet

1
I2C를 싫어하게 만드는 것은 이런 것들입니다.
Rocketmagnet

1
나는 미친 직감이 있습니다. 각 비트 코드마다 실수로 시프트 연산을 사용하여 실수로 부호 확장합니까? 당신이 그렇다면 당신의 최고의 사람은 결국 7 교대 작업 후 0xFF로 당신을 떠날 것입니다.
vicatcu

3
아이러니는 여기서 "회사 기밀"코드입니다. 그들에게 가치가 있습니다. 다른 모든 사람들은 작동하는 코드를 공유합니다. 이 회사의 코드를 다른 회사와 차별화시키는 것은 작동하지 않는다는 것입니다.
gbarry

2
회사가 왜 I2C 비트 뱅킹 코드를 기밀로 유지해야 하는지를 상상하기가 어렵습니다. 인터넷에는 많은 것들이 있습니다.
Rocketmagnet

답변:


4

시계가 다시 낮아지면 데이터를 읽습니다. 시계를 높이는 것과 낮게 만드는 것 사이에 그렇게해야합니다. 클럭이 낮 으면 슬레이브는 데이터 라인이 높을 때가 아니라 데이터 라인을 변경할 수 있습니다.

여기에 이미지 설명을 입력하십시오

따라서 독서는 다음과 같아야합니다.

wait
SCL low
SDA high
for each bit (8 bits)
    SCL high                      <--------
    wait
    check and store received bit  <--------
    wait
    SCL low                       <--------
    wait
    wait
do a NACK or ACK depending on if it is the last byte

그건 좋은 지적이야; 내가 고칠 게 그러나 내 데이터는 여전히 내 범위에서 올인원 (FF)으로 표시되므로 내 읽기는 문제가 될 수 없습니다 ... :(
Thomas O

3

결국 문제는 맹 글링 된 타이밍으로 인해 일부 조건에서 실수로 STOP 조건을 보내고 있다는 것이 밝혀졌습니다. 나는 스코프 사용을 포기하고 로직 애널라이저를 꺼내서 15 분 안에 문제를 해결할 수 있었지만 중지해서는 안되는 STOP을 강조 표시했습니다. 가장 유용한 답변을 바탕으로 현상금을 줄 사람을 선택합니다. 모든 솔루션에 감사드립니다.


"쓰기 타이밍 확인"을 통해 문제를 해결하게되어

3
나는 이것이 파형을 보면서 해결 될 것이라고 말했습니다.
Rocketmagnet

@Rocketmagnet 저는 항상 파형을보고 있었지만 전에는 눈치 채지 못했습니다.
Thomas O

네,하지만 당신은 나타나지 않았다 우리에게 우리가 반복적으로 당신을 요구에도 불구하고, 파형을. 며칠 전에이 문제가 해결되었을 수 있습니다.
Rocketmagnet

@Rocket-동의합니다. 당시 카메라를 사용할 수 있었으면 좋겠다. 내가 사용한 Tek DPO에는 플로피 드라이브가 있지만 플로피는 없습니다. 내가 할 수 있다면 나는 그림을 게시했다.
Thomas O

2

스코프가 PIC에 들어오는 첫 번째 바이트가 불량하다는 것을 증명하므로 PIC 읽기 기능이 아닙니다.

수신 측에서 쓰기 타이밍이 정상인지 확인 했습니까?

아래 두 모드에서 모두 실패합니까?

- Byte mode sequential
- Page mode Sequential

스펙은 "가장 중요한 비트 (MSB) 'b7'가 먼저 전송 됨"을 표시합니다. 이는 또한 전체 바이트가 FF로 다시 읽혀지는 b7 = 1 일 때도 일치합니다. 따라서 b7 = 1 일 때 쓰지 않고 지워지거나 (고장 상태) 또는 이전 내용에 관계없이 FF로 잘못 읽습니다. 모든 쓰기는 쓰기 전에 바이트 폭 지우기이므로 여전히 쓰기가 잘못되었거나 읽기가 잘못되었거나 첫 번째 바이트의 타이밍이 다를 수 있습니다.

제안 : 정상적인 작동을 위해 쓰기 / 읽기 중에 PTC 신호를 확인하십시오. 여기에 이미지 설명을 입력하십시오

PTC를 사용하여 E / W 사이클의 길이를 타이밍하기 위해 외부 클록을 사용하는 옵션이 있습니다. 이것을 사용해 보셨습니까?

tE / W 사이클 시간

  • 내부 발진기 7ms typ
  • 외부 클럭 4 ~ 10 ms min ~ max

이 기준을 통과합니까?


1

몇 가지 일 수 있습니다.

  1. 버스에 무엇이 더 있습니까? 재설정 또는 초기화되지 않은 다른 장치와의 버스 경합이있을 수 있습니까?
  2. I / O 핀의 방향을 올바르게 바꾸고 있습니까? 출력 케이스에서 제대로 작동하면 실수로 핀 방향을 입력으로 변경하는 것을 잊었을 수 있으며 항상 읽습니다 0xFF. 핀은 버스를 읽는 동안 버스를 구동하는 출력으로 남을 수 있습니다.
  3. 핀 자체 및 / 또는 I / O 라인에 내부 풀업이 있습니까? 마이크로 컨트롤러는 일반적으로 고정 된 값이 아니라 다양한 저항을 제공합니다. 개별 부품에서보다 정확한 풀업 저항을 얻을 수 있으므로 마이크로에서 풀업을 비활성화하고 버스에서 개별 풀업을 사용하면됩니다.
  4. 클럭 극성-클럭 / 데이터 사이의 오른쪽 가장자리 / 위상을 측정하고 있습니까? 당신은 스코프에서 당신에게 잘 보이는 것을 시계로 찍을 수 있지만, 단계가 라인을 벗어나면 모든 EEPROM은 0xFFs 를 볼 것입니다 (그리고 아마도 아마도 잘못된 명령 / 조건과 같은 것을 반환 할 것입니다).

1. EEPROM과 MCU 만 있습니다. 2. 그렇습니다. EEPROM이 SDA / SCL을 낮게 유지할 수 있기 때문입니다. 3. EEPROM에 인접한 보드에는 2.2k 5 % 풀업이 있습니다.
Thomas O

# 2의 경우, EEPROM이 버스를 낮게 유지하는 것이 확실합니까? EEPROM에 데이터 시트에 모든 0xFFs 가 반환되는 조건이 있습니까? 위의 편집 내용도 참조하십시오.
Joel B

# 4. EEPROM이 내 요청을 "ACK"하고 일부 단어와 함께 작동하지만 전부는 아닙니다.
Thomas O

0

나는 이것을 위의 의견으로 제출했지만 대답에 대한 자신감은 마음 깊은 곳에서 조용히 커져서 대답으로 홍보하고 있습니다.

나는 이것이 확실히 일부 변수의 부호와 관련하여 저수준 소프트웨어 버그라는 미친 직감을 가지고 있습니다. 각 비트 코드마다 실수로 시프트 연산을 사용하여 실수로 부호 확장합니까? 당신이 그렇다면 당신의 주요한 사람은 결국 7 교대 작업 후 0xFF로 당신을 떠날 것입니다.

스티븐은이를 언급하면서 언급했지만 오실로스코프에서 쓰기 작업의 신성함을 목격 했습니까? 아니면 읽기 백의 절반만으로도 잘 작동한다고 가정하십니까? 0xAA 값의 쓰기 작업을 보지 않았다면 시도해 보는 것이 좋습니다.

내부 루프의 실제 코드와 관련 변수 선언을 제공 할 수 있다면 버그를 발견 할 수 있습니다.


내 글은 좋다; 범위에서 이것을 볼 수 있습니다. 또 다른 이상 : MSB를 선도하는 주소는 괜찮습니다. 데이터 만 문제를 일으킨다! 코드를 곧 게시 할 생각입니다.
Thomas O

1
이 답변을 지원하기 위해 : 이것이 C 코드 인 경우 모든 'char'선언을 'unsigned char'로 변경하고 다시 시도하십시오.
Wouter van Ooijen
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.