I2C EEPROM bit-banging: Viết tốt, nhưng chỉ khi bit đầu tiên không được đặt


9

Tôi hiện đang làm việc trên một dự án E2C EEPROM bằng cách sử dụng bit-banging để điều khiển các dòng SDA và SCL.

Hàm đọc của tôi hoạt động tốt nhưng bất cứ khi nào tôi viết bất kỳ byte nào có chữ "1" hàng đầu, tôi luôn đọc lại FF; ngay cả khi byte đã được lập trình với cái gì khác trước đó. Dẫn đầu "0" là hoàn hảo. Nó không phải là thói quen đọc của tôi; như tôi có thể thấy trên phạm vi nó trả về FF.

Tôi đang tìm kiếm gợi ý về lý do tại sao điều này có thể được. Có bất kỳ điều gì rõ ràng tôi có thể bỏ lỡ có thể gây ra vấn đề? [Tôi không thể đăng mã - công ty bảo mật ... :(]

Mỗi dạng sóng tôi nhìn vào đều đáp ứng chính xác thông số kỹ thuật. Tôi đang tách EEPROM. Pull up của tôi là 2.2k vì vậy trong spec. Tôi đang ở mức khoảng 500 Hz trong nguyên mẫu này. Con chip đang gửi ACK đến từng byte của tôi để nó nhận ra chúng. Nhưng nó không hoạt động ...

Tôi đang sử dụng Microchip 24LC256 .

Thuật toán viết đơn giản hóa cho một byte:

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

Thuật toán đọc đơn giản hóa cho một byte:

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
@Justin - Tôi nghĩ rằng anh ta nói rằng viết giá trị 0x7F cho bất kỳ địa chỉ nào hoạt động, nhưng viết 0x80 vào bất kỳ địa chỉ nào không hoạt động.
Rocketmagnet

1
Những thứ như thế này khiến tôi ghét I2C.
Rocketmagnet

1
Tôi đã có một linh cảm điên rồ. Trong mỗi mã bit của bạn, bạn có vô tình đăng nhập mở rộng với một thao tác đúng ca không? Nếu bạn là người dẫn đầu của bạn cuối cùng sẽ rời khỏi bạn với 0xFF sau 7 hoạt động thay đổi.
Abbeyatcu

3
Điều trớ trêu, ở đây, là mã "công ty bí mật". Nó có giá trị với họ. Mọi người khác ở đây chia sẻ mã hoạt động. Điều làm cho mã của công ty này khác với các mã khác là nó không hoạt động.
gbarry

2
Thật khó để tưởng tượng tại sao một công ty rất cần phải giữ bí mật một số mã đập I2C. Có rất nhiều trên mạng.
Rocketmagnet

Câu trả lời:


4

Bạn đang đọc dữ liệu sau khi đồng hồ thấp trở lại. Bạn sẽ phải làm điều đó giữa làm cho đồng hồ lên cao và làm cho nó thấp. Sau khi đồng hồ ở mức thấp, nô lệ được phép thay đổi dòng dữ liệu, không phải trong khi nó ở mức cao.

nhập mô tả hình ảnh ở đây

Vì vậy, đọc nên như thế này:

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

Đó là một điểm hay; Tôi sẽ sửa nó. Tuy nhiên, dữ liệu của tôi vẫn hiển thị dưới dạng tất cả (FF) trên phạm vi của tôi để việc đọc của tôi không thể là vấn đề ... :(
Thomas O

3

Vấn đề cuối cùng hóa ra là tôi đã vô tình gửi một điều kiện STOP trong một số điều kiện do thời gian bị sai lệch. Tôi đã từ bỏ việc sử dụng phạm vi và lấy ra bộ phân tích logic, và có thể khắc phục sự cố trong 15 phút vì nó làm nổi bật STOP không nên có ở đó. Tôi sẽ chọn người đưa tiền thưởng dựa trên câu trả lời hữu ích nhất. Cảm ơn bạn cho tất cả các giải pháp.


Vui mừng bạn đã giải quyết nó bằng cách "xác minh thời gian ghi"

3
Tôi nói với bạn rằng điều này sẽ được giải quyết bằng cách nhìn vào dạng sóng.
Rocketmagnet

@Rocketmagnet Tôi đã luôn nhìn vào dạng sóng, nhưng chưa bao giờ nhận thấy nó trước đây.
Thomas O

Có, nhưng bạn đã không cho chúng tôi xem dạng sóng, mặc dù chúng tôi liên tục yêu cầu bạn cho nó. Bạn có thể đã có vấn đề này giải quyết ngày trước.
Rocketmagnet

@Rocket - Tôi đồng ý. Tôi ước tôi có một máy ảnh có sẵn tại thời điểm đó. Tek DPO tôi đang sử dụng có ổ đĩa mềm nhưng không có đĩa mềm. Tôi sẽ đăng một bức ảnh nếu tôi có thể có.
Thomas O

2

OK phạm vi của bạn chứng minh byte thứ 1 đi vào PIC là xấu nên nó không phải là chức năng đọc PIC.

Bạn đã xác minh thời gian ghi là OK ở cuối nhận chưa?

Điều này có thất bại trong cả hai chế độ dưới đây?

- Byte mode sequential
- Page mode Sequential

Thông số kỹ thuật cho thấy "Bit đáng tin cậy nhất (MSB) 'b7' được gửi lần đầu tiên" Điều này cũng trùng khớp khi b7 = 1 rằng toàn bộ byte được đọc lại dưới dạng FF. Vì vậy, nó không được viết và chỉ bị xóa (điều kiện lỗi) khi b7 = 1 hoặc nó đọc ngược lại là FF bất kể nội dung trước đó. Vì mỗi lần ghi là một lần xóa rộng byte trước khi ghi, nên nó vẫn có thể là ghi xấu hoặc đọc sai hoặc thời gian của byte thứ 1 là khác nhau.

Đề xuất: Xác minh tín hiệu PTC trong khi ghi / đọc để đảm bảo hoạt động bình thường. nhập mô tả hình ảnh ở đây

Có một tùy chọn sử dụng đồng hồ bên ngoài để định thời lượng cho chu kỳ E / W bằng PTC. Bạn đã thử để bạn sử dụng này?

thời gian chu kỳ tE / W

  • bộ dao động nội bộ 7ms
  • đồng hồ ngoài 4 ~ 10 ms phút ~ tối đa

Liệu nó có vượt qua tiêu chí này?


1

Âm thanh như nó có thể là một vài điều:

  1. Có gì khác trên xe buýt? Có thể có một cuộc tranh chấp xe buýt với một thiết bị khác đang được thiết lập lại hoặc chưa được khởi tạo?
  2. Bạn có thay đổi chính xác hướng của pin I / O không? Nếu nó hoạt động tốt trong trường hợp đầu ra, bạn có thể đã vô tình quên thay đổi hướng của pin thành đầu vào và sẽ luôn luôn đọc 0xFF. Pin có thể được để lại như một đầu ra lái xe buýt trong khi bạn đọc từ nó.
  3. Bạn có kéo nội bộ trên pin và / hoặc trên các dòng I / O không? Vi điều khiển thường cung cấp một phạm vi kháng và không phải là một giá trị cố định. Bạn có thể muốn vô hiệu hóa pull-up trên micro và chỉ sử dụng những cái rời rạc trên xe buýt vì bạn có thể có được lực cản kéo chính xác hơn từ các thành phần rời rạc.
  4. Độ phân cực của đồng hồ - Bạn có chắc chắn rằng bạn đang đo ở cạnh / pha bên phải giữa đồng hồ / dữ liệu? Bạn có thể xem ra những gì có vẻ tốt cho bạn trên phạm vi, nhưng nếu giai đoạn không phù hợp, tất cả EEPROM của bạn sẽ thấy là 0xFFs (và rất có thể sẽ trả về giống như đó là một lệnh / điều kiện không hợp lệ).

1. Chỉ cần EEPROM và MCU. 2. Có, tôi tin là tôi, vì EEPROM có thể giữ SDA / SCL ở mức thấp. 3. Có 2,2k 5% pull up trên bảng liền kề với EEPROM.
Thomas O

đối với số 2, bạn có chắc chắn EEPROM là người giữ xe buýt ở mức thấp. EEPROM có bất kỳ điều kiện nào trong biểu dữ liệu mà nó sẽ trả về tất cả 0xFFs không? Xem các chỉnh sửa của tôi ở trên quá.
Joel B

#4. EEPROM là "ACK" trong các yêu cầu của tôi và hoạt động với một số từ, nhưng không phải tất cả.
Thomas O

0

Tôi đã gửi bài này như một nhận xét ở trên, nhưng sự tự tin của tôi về câu trả lời đã âm thầm tăng lên trong sự suy thoái sâu sắc trong tâm trí của tôi vì vậy tôi đang thúc đẩy nó để trả lời.

Tôi có một linh cảm điên rồ rằng đây gần như chắc chắn là một lỗi phần mềm cấp thấp liên quan đến sự ký kết của một số biến. Trong mỗi mã bit của bạn, bạn có vô tình đăng nhập mở rộng với một thao tác đúng ca không? Nếu bạn là người dẫn đầu của bạn cuối cùng sẽ rời khỏi bạn với 0xFF sau 7 hoạt động thay đổi.

Steven đã ám chỉ điều này trong một bình luận, nhưng bạn đã chứng kiến ​​sự tôn nghiêm của các thao tác viết của bạn trên một ống soi, hay bạn chỉ cho rằng chúng hoạt động dựa trên một nửa số đọc ngược có vẻ tốt? Nếu bạn chưa thử xem hoạt động ghi của giá trị 0xAA, đó có thể là một điều tốt để thử.

Nếu bạn có thể cung cấp mã thực tế của vòng lặp bên trong và khai báo biến liên quan, chúng tôi có thể phát hiện ra lỗi.


Bài viết của tôi rất hay; Tôi có thể thấy điều này trên phạm vi. Một điều kỳ lạ khác: Địa chỉ với MSB hàng đầu đều ổn. Chỉ có dữ liệu gây ra vấn đề! Tôi nghĩ về việc đăng mã sớm.
Thomas O

1
Để hỗ trợ cho câu trả lời này: nếu đây là mã C, hãy thay đổi tất cả các khai báo 'char' thành char unsign char 'và thử lại.
Wouter van Ooijen
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.