EEPROM đọc / ghi lỗi trên DSPIC


8

Tôi đang chạy một Microchip dsPIC30F6012a. Tôi có con chip này trên một số PCB, tất cả đều chạy cùng một phần mềm và quan sát cùng một vấn đề trên tất cả chúng. Điều này ngụ ý một vấn đề mang tính hệ thống, không phải là vấn đề sản xuất một lần. Vấn đề cũng có thể tái tạo, ngụ ý tôi sẽ có thể giết nó nếu tôi biết nơi để tìm. Nhưng tôi vẫn gặp khó khăn đáng ngạc nhiên khi gỡ lỗi ứng dụng.

Bảng thử nghiệm chấp nhận 24V, được giảm xuống 5V thông qua V7805. Con chip này chạy trên bộ dao động bên trong của nó, với PLL 16x, cho tốc độ hoạt động ~ 29,5 MIPS. Mã có liên quan trên bảng này về cơ bản là rất đơn giản: thức dậy, đọc dữ liệu từ EEPROM, sau đó nhập một vòng lặp vô hạn. Ngắt mỗi mili giây, quan sát một số dữ liệu môi trường và viết giá trị cập nhật vào EEPROM. Có những thứ khác đang diễn ra, nhưng vấn đề vẫn xảy ra ngay cả khi mã không liên quan được nhận xét, vì vậy tôi có thể chắc chắn rằng nó không liên quan đến vấn đề trong tay.

Trong sử dụng chung, 95% thời gian bảng thức dậy với giá trị chính xác trong bộ nhớ và tiếp tục công việc của mình. 5% còn lại, tuy nhiên, nó thức dậy với một giá trị không chính xác. Cụ thể, nó thức dậy với một phiên bản lật ngược của dữ liệu mà nó phải có. Đó là một ký tự dài bốn byte mà tôi đang xem và từ trên hoặc dưới của từ dài có thể bị lật. Ví dụ: 10 trở thành 2 ^ 16-10, sau này trở thành 2 ^ 32-10. Tôi có thể tái tạo trục trặc bằng cách đạp xe bằng tay vài chục lần, nhưng điều đó không nhất quán và ngón tay chuyển đổi của tôi bị mòn.

Để tái tạo vấn đề theo cách có kiểm soát, tôi đã xây dựng một bảng thứ hai điều khiển nguồn cung cấp 24V cho bảng đang được thử nghiệm. (Một DSPIC khác điều khiển bộ ghép quang darlington.) Bảng thử nghiệm tắt 24 V trong 1,5 giây (đủ lâu để đường ray 5V giảm xuống 0 và giữ nguyên trong một giây), sau đó bật 24 V trong một khoảng thời gian có thể định cấu hình . Với thời gian hoạt động khoảng 520 mS, tôi có thể tái tạo trục trặc EEPROM này trong vòng năm chu kỳ năng lượng, mọi lúc.

Đường ray 5V đang hoạt động hợp lý. Nó ổn định ở mức 5V trong vòng 1 mS khi bật, có lẽ là 4V quá mức, giả sử tôi có thể tin tưởng vào phạm vi của mình. Khi tắt, nó phân rã thành 0V theo cấp số nhân, đạt 1V trong vòng 50 mS. Tôi không có cảnh báo xây dựng nào có vẻ phù hợp, chỉ là các biến không được sử dụng và thiếu dòng mới ở cuối tệp.

Tôi đã thử một vài thứ:

  • Kích hoạt / vô hiệu hóa MCLR
  • Kích hoạt / vô hiệu hóa WDT
  • Kích hoạt / vô hiệu hóa bảo vệ mã
  • Kích hoạt / vô hiệu hóa / thay đổi điện áp phát hiện mất điện
  • Kích hoạt / vô hiệu hóa / thay đổi bộ hẹn giờ bật nguồn
  • Các cài đặt PLL khác nhau trên bộ dao động bên trong chính
  • Kết nối / ngắt kết nối lập trình viên PICkit 3 của tôi
  • Thêm điện dung 470 uF vào đường ray 5V
  • Thêm / xóa .1 uF trên pullup 4.7k trên chân MCLR của tôi
  • Vô hiệu hóa tất cả các ngắt trong mã và không để lại gì ngoài các cập nhật EEPROM trong vòng lặp chính
  • Thêm độ trễ 1,5 giây vào thói quen khởi động trước khi tôi bắt đầu đọc EEPROM

Tôi cũng đã viết mã kiểm tra riêng không làm gì ngoài việc liên tục ghi các giá trị vào EEPROM và sau đó đọc lại chúng, đảm bảo rằng giá trị không bị thay đổi. Hàng chục ngàn lần lặp lại không có lỗi. Tất cả những gì tôi có thể kết luận là có gì đó không ổn với việc đọc hoặc viết EEPROM, đặc biệt là khi bật / tắt nguồn.

Tôi đã sử dụng cùng các thư viện EEPROM từ năm 2007. Tôi đã thấy các trục trặc không thường xuyên, nhưng không có gì có thể lặp lại. Mã liên quan có thể được tìm thấy ở đây:
http://srange.net/code/eeprom.c
http://srange.net/code/readEEByte.s
http://srange.net/code/eraseEEWord.s
http: / /srange.net/code/writeEEWord.s

Tôi đã thấy các lỗi EEPROM trước đây trong các ứng dụng khác, nhưng luôn gặp sự cố một lần, không có gì có thể lặp lại hoặc nhất quán này.

Có ai có bất cứ ý tưởng những gì đang xảy ra? Tôi đang hết thứ để thử.


Vui lòng xem tại đây để cập nhật về cách giải quyết vấn đề này: Electronics.stackexchange.com/questions/38083/iêu
Stephen Collings

Câu trả lời:


3

Hai điều tôi nghĩ đến:

Đầu tiên, theo bảng dữ liệu, một chu trình xóa-ghi mất ít nhất 0,8ms và tối đa 2,6ms. Bạn nói rằng bạn có một ngắt trong mỗi 1ms, điều này có thể dẫn đến thao tác ghi. Tôi đã thấy trong mã mà bạn vô hiệu hóa các ngắt cho các phần của xóa và cho các phần của chức năng ghi. Nhưng bạn vẫn có thể nhận được sự xen kẽ hài hước của các lệnh gọi hàm. Có lẽ nó giúp khi bạn vô hiệu hóa các ngắt cho toàn bộ chuỗi xóa và viết?

Thứ hai - bạn có thể muốn ghi trong khi mất điện và ghi EEPROM xảy ra chính xác trong thời điểm khi điện áp cung cấp xuống dưới điện áp hoạt động. Bạn có thể thử theo dõi điện áp cung cấp và từ chối ghi khi nó ở dưới, giả sử, 4.5V. Điều này giả định rằng nó duy trì đủ lâu trên 2,7V là điện áp hoạt động tối thiểu và phát hiện ra màu nâu được đặt để kích hoạt chỉ dưới điểm đó.


Bạn đang ở gần! Chu trình bị xóa-> ghi, vì vậy nếu mất điện giữa xóa và ghi, bạn sẽ mất dữ liệu của mình. Giải pháp đầu tiên của tôi là chia EEPROM thành nhiều bản sao dự phòng, được tự động kiểm tra sự không nhất quán. Nhưng vì đã ăn 3/4 EEPROM của tôi, tôi thay thế nó bằng một bộ đệm ghi đơn giản. Bộ đệm sẽ là một khối EEPROM đặc biệt chứa dữ liệu được ghi, địa chỉ để ghi và một cờ cho biết rằng việc ghi chưa hoàn tất. Điều này sẽ giải quyết vấn đề trong khi chiếm ít không gian hơn.
Stephen Collings

Bây giờ tôi có thể xác nhận rằng phương pháp tiếp cận dựa trên bộ đệm của tôi hoạt động và không bị mất dữ liệu do mất điện không đồng bộ giữa xóa và ghi.
Stephen Collings

5

Bạn đã xem xét rất nhiều vấn đề phần cứng có thể. Điều đó tốt, nhưng đây rất có thể là một lỗi phần sụn.

Thật không may, mã nguồn của bạn được ghi lại kém và được định dạng là khó theo dõi trực quan. Tệp đầu tiên của bạn chứa khai báo các thói quen bên ngoài ở trên cùng:

void readEEByte (int unsign int, unsign int, void *);
void eraseEEWord (int unsign int, unsign int);
void writeEEWord (int unsign int, unsign int, void *);

Không chỉ là một ý tưởng tồi khi đặt các khai báo như riêng tư này trong các mô-đun máy khách, không có một nhận xét nào trong tầm nhìn! Chúng tôi chỉ có thể đoán những gì bạn dự định những thói quen này sẽ làm từ tên của họ và các đối số cuộc gọi hoàn toàn không có giấy tờ. Hơn nữa trong tập tin đó, bạn có các dòng khác nhau bắt đầu bằng "//" và toàn bộ dòng có dấu bằng. Chúng thêm lộn xộn thị giác làm cho nó quá nhiều rắc rối để cố gắng làm theo mã.

Bạn có thể nói rằng không ai trong số này quan trọng đối với hoạt động của mã. Tuy nhiên, thực hành lập trình xấu như thế này rất quan trọng. Chúng làm cho mã được viết kém và làm cho khó phát hiện ra lỗi hoặc thậm chí những gì mã được cho là phải làm. Tất cả điều này dẫn đến việc khó tìm ra vấn đề, như bạn đang khám phá. Thậm chí, bạn còn tự nói rằng thỉnh thoảng bạn đã thấy những trục trặc từ mã này từ năm 2007. Đó có thể là một đầu mối mạnh mẽ của một lỗi, thậm chí có thể là do thiết kế tổng thể xấu.

Khắc phục tình trạng lộn xộn, ghi lại đúng tất cả các giao diện và đưa các khai báo chung vào các tệp mà bạn viết một lần, sau đó tham chiếu khi cần. Ngoài ra tuyên bố của tôi về tôi không có cảnh báo xây dựng nào có vẻ phù hợp là một lá cờ đỏ khổng lồ. Một lần nữa, sửa chữa mớ hỗn độn. Khi gỡ lỗi, luôn luôn theo dõi các vấn đề dễ tái tạo và có thể sửa chữa trước. Đôi khi những điều đó thực sự là nguyên nhân của những vấn đề khó khăn, hoặc đôi khi trong việc khắc phục chúng, bạn phát hiện ra nguyên nhân của những vấn đề khác. Trình biên dịch đang cảnh báo bạn về sự chậm chạp trên một đĩa bạc. Nhiều hơn những gì bạn muốn? Bạn không nên có các biến không được sử dụng vì chúng gây nhầm lẫn cho bất kỳ ai đang cố gắng hiểu mã của bạn và không có lý do nào để bỏ lỡ các dòng mới. Một lần nữa, sửa chúng rõ ràng, đặc biệt là trước khi yêu cầu bất cứ ai khác nhìn vào mã của bạn.

Gọn gàng và chú ý đến vấn đề chi tiết . Rất nhiều.

 


Bạn hoàn toàn đúng về mã. Để chúng tôi rõ ràng, tôi đã bắt đầu sử dụng mã này năm năm trước, nhưng một người khác đã viết nó. Tôi không viết những thứ trông như thế này. Tôi vẫn nên sửa nó, và nó không tốt mà tôi không có. Chỉ để tôi trông không giống QUITE như một kẻ ngốc. :-)
Stephen Collings

2
Truy cập EEPROM nội bộ thật dễ dàng. Đối với những thứ đơn giản như vậy, việc viết mã của riêng bạn sẽ dễ dàng hơn là cố gắng tìm ra cách phần mềm sửa lỗi của người khác hoạt động, sau đó vá nó cho đến khi nó có vẻ hoạt động. Đọc bảng dữ liệu và viết mã. Bạn sẽ hoàn thành trong một giờ.
Olin Lathrop

Tôi đồng ý với Olin ở đây rằng nó rất có thể là phần sụn. Phần errata đề cập không có gì là tanh với EEPROM.
Adam Lawrence

2
@Madmad - Các tờ Errata có thể không nói có phần gì đó tanh với phần đó, nhưng họ sẽ không bao giờ nói rằng không có gì tanh với nó :-)
stevenvh

1
@stevenvh Giao dịch của tôi với Microchip và FAE của họ chủ yếu là tích cực. Lỗi cho các bộ phận tôi đang sử dụng là chính xác và họ đã nhảy vào để giúp chúng tôi giải quyết các vấn đề, thường tìm cách giải quyết cho chúng tôi.
Adam Lawrence

0

Tôi đã có một hành vi giống hệt với 4 chiếc DSPIC30F6014A (khoảng 10 chiếc được sử dụng trong vài tháng qua ..), cách duy nhất để tránh hỏng dữ liệu lẻ tẻ trong khi tắt nguồn là đặt MCLR ngay trước khi tắt máy.

Rõ ràng điều này là không khả thi trong thực tế, vì vậy tôi đã chọn thay thế "DSP" xấu, nếu có ai có giải pháp khác thay thế ...


3
Tại sao điều đó không khả thi? Việc phát hiện mất điện được thực hiện rất nhiều, ngay cả để lưu dữ liệu vào EEPROM ở giây cuối cùng.
stevenvh
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.