Thông báo

Collapse
No announcement yet.

Ghi vào bộ nhớ EEPROM

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • #16
    Nguyên văn bởi Le Thi Bich Xem bài viết
    Nếu viết một chương trình còn eeprom_doc, hoặc eeprom viết
    trong chương trình chính khi cần đọc dữ liệu ở một địa chỉ em chỉ cần dug lệnh i=eeprom_doc(0x0xxx) và dùng lệnh này em có thể đặt vào một chương trình con khác để có thể đọc dữ liệu nhiều lần ở nhiều địa chỉ khác nhau. Còn dùng cách khai báo trên mỗi lần muốn gi đọc ở một địa chỉ nào thì lại phải khai báo một biến cho một địa chỉ đó
    bạn ko cần phải viết ctrinh con đọc viết làm j cho mệt..?
    giả sử bạn cần lưu 3 số int a,b,c vào eep thì khai báo như sau:

    Code:
         eeprom int a,b,c;
    sau đó bạn muốn đọc hoặc ghi thì chỉ việc viết:
    Code:
        int x,y,z; //biến khai báo trong ram
        x=a;      //đọc giá trị int a được lưu trong eep về x
        y=b;
        z=c;
    .....
       a=x;      //lưu giá trị int x vào a trong eep.
       b=y;
    ....
    chỉ đơn giản như vậy.. đâu cần quản lí gì đâu nhỉ. hầu hết là giống như khi sử dụng biến trong Ram.

    Comment


    • #17
      Nguyên văn bởi dt_love Xem bài viết
      bạn ko cần phải viết ctrinh con đọc viết làm j cho mệt..?
      giả sử bạn cần lưu 3 số int a,b,c vào eep thì khai báo như sau:

      Code:
           eeprom int a,b,c;
      sau đó bạn muốn đọc hoặc ghi thì chỉ việc viết:
      Code:
          int x,y,z; //biến khai báo trong ram
          x=a;      //đọc giá trị int a được lưu trong eep về x
          y=b;
          z=c;
      .....
         a=x;      //lưu giá trị int x vào a trong eep.
         b=y;
      ....
      chỉ đơn giản như vậy.. đâu cần quản lí gì đâu nhỉ. hầu hết là giống như khi sử dụng biến trong Ram.
      Vâng nhưng nếu dùng cách này codevision se tư đông đặt dữ liệu biến vào một địa chỉ nào đó. Trong datasheet có khuyến cáo nên hạn chế lưu dữ liệu ở vùng địa chỉ 0x00 thế em không muốn lưu ở đây sẽ không làm được anh ơi
      Thiết kế chế tạo các loại máy xoáy nắp, chiết rót định lượng dùng trong dược phẩm và thực phẩm.

      Comment


      • #18
        Nguyên văn bởi Le Thi Bich Xem bài viết
        Vâng nhưng nếu dùng cách này codevision se tư đông đặt dữ liệu biến vào một địa chỉ nào đó. Trong datasheet có khuyến cáo nên hạn chế lưu dữ liệu ở vùng địa chỉ 0x00 thế em không muốn lưu ở đây sẽ không làm được anh ơi
        ah. vậy là bạn muốn nó tránh ghi vào địa chỉ 0x00 thôi chứ j:
        vậy thì bạn làm như sau:
        Code:
        unsigned char unuse @0; // đặt đầu tiên trước khi khai báo biến lưu trong eep
        và sau đó khai báo các biến khác.. trong ctrinh của mình thì ko sử dụng đến biến unuse là ok.

        Comment


        • #19
          đây là code mà thằng CV xài đây.

          data ở R30;
          địa chỉ của eep ở R27,R26 (X res)

          Code:
          __EEPROMWRB:
          	SBIS EECR,EEWE
          	RJMP __EEPROMWRB1
          	WDR
          	RJMP __EEPROMWRB
          __EEPROMWRB1:
          	IN   R25,SREG
          	CLI
          	OUT  EEARL,R26
          	OUT  EEARH,R27
          	SBI  EECR,EERE
          	IN   R24,EEDR
          	CP   R30,R24
          	BREQ __EEPROMWRB0
          	OUT  EEDR,R30
          	SBI  EECR,EEMWE
          	SBI  EECR,EEWE
          __EEPROMWRB0:
          	OUT  SREG,R25
          	RET
          trước khi ghi nó có đoạn đọc và so sánh dữ liệu, nếu trùng data thì nó sẽ ko ghi--> có lẽ là để tăng số lần ghi..

          Comment


          • #20
            Nguyên văn bởi dt_love Xem bài viết
            ý bạn là sao nhỉ..? ko tiện lợi?
            khi bạn khai báo biến trong eep thì đâu nhất thiết bạn phải định địa chỉ của nó để làm j nhỉ..? bạn chỉ cần quản lí theo tên biến là đủ rồi. ?
            lúc đó bạn khai báo cả mảng int 2 chiều vài trăm byte cũng chẳng sao.
            hầu hết các phép tính cho biến trên ram đều sử dụng được cho biến trên eep
            Chào dt_love!
            Thực ra theo ý của bạn nói đúng. Tuy nhiên để quản lý dữ liệu được tốt, thông thường người viết hay khai báo dữ liệu kiểu tường minh. Nếu không khai báo địa chỉ cụ thể cho biến eeprom, có hai trường hợp xảy ra như sau:
            - Nếu số lượng biến eeprom không thay đổi ( cả kiểu biến và số lượng biến) thì địa chỉ của các biến do trình biên dịch cấp phát tự động là cố định. Tức là không vấn đề gì cả.
            - Nếu số lượng biến do qua trình viết có thay đổi so với ban đầu (cả về số lượng và kiểu biến) vì lý do nâng cấp hoặc chỉnh sửa lại phần mềm, hoặc trong một số ứng dụng người ta cần nạp sẵn dữ liệu vào eeprom hoặc họ không muốn dữ liệu trong eeprom của họ bị mất, người ta phải khai báo biến eeprom theo một địa chỉ đã định sẵn bởi người viết code để dễ dàng lấy lại dữ liệu mà không bị sai dữ liệu. Ví dụ:
            ----------chương trình viết được sử dụng khi chưa có nhu cầu nâng cấp-----
            // giả sử sẽ lưu lại số lần ấn phím ( số lần ấn không quá 255 chẳng hạn cho dễ hiểu)
            // các phím ấn nối với các port tương ứng
            #define Phim1 PIND.1
            #define Phim2 PIND.2
            #define Phim3 PIND.3
            //...........................
            #define Phim7 PIND.7

            eeprom char so1 ;
            eeprom char so2 ;
            eeprom char so3 ;
            //.....................
            eeprom char so7 ;
            //........................

            void main(void)
            {
            khoi_tao_he_thong(); //khởi tạo phần cứng ở đây

            while(1)
            {
            if(!Phim1) //bam phim 1
            {
            so1++;
            while(!Phim1);
            delay_ms(100);
            }
            if(!Phim2) //bam phim 2
            {
            so2++;
            while(!Phim2);
            delay_ms(100);
            }
            //.....tương tự với các phím khác
            printf("so1:%d,so2:%d,...",so1,so2,....so7);

            }

            }

            Kết quả hiện ra như sau:

            so1:10,so2:3,so3:8,so4:12,.......,so7:219

            Nhưng sau này người ta không muốn dùng phím PIND.2 nữa và bỏ nó đi mà vẫn muốn dữ lại dữ liệu trong eeprom của các phím khác. Người ta xóa bỏ phần khai báo biến eeprom char so2 ; lúc đó người ta cho hiển thị như sau:
            printf("so1:%d,so3:%d,...",so1,so3,....);
            kết quả hiện ra là: so1:10,so3:3,so4:8...... tức là biến đứng đằng sau biến bị xóa lúc này có địa chỉ là biến đã bị xóa trước, và các biến kế tiếp sẽ bị lệch địa chỉ tương tự như vậy.

            => Nên khai báo biến theo kiểu tường minh để dễ quản lý và người kế nhiệm dễ tiếp cận thôi.
            n
            ĐT: 0986 492 489

            Tham khảo:

            Comment


            • #21
              hi, lại gặp bác minhhieu ở đây rồi...
              Nhưng sau này người ta không muốn dùng phím PIND.2 nữa và bỏ nó đi mà vẫn muốn dữ lại dữ liệu trong eeprom của các phím khác. Người ta xóa bỏ phần khai báo biến eeprom char so2 ; lúc đó người ta cho hiển thị như sau:
              printf("so1:%d,so3:%d,...",so1,so3,....);
              kết quả hiện ra là: so1:10,so3:3,so4:8...... tức là biến đứng đằng sau biến bị xóa lúc này có địa chỉ là biến đã bị xóa trước, và các biến kế tiếp sẽ bị lệch địa chỉ tương tự như vậy.
              thực ra vấn đề này cũng dễ giải quyết thôi. bạn bỏ nút đi, nhưng đừng xóa dòng khai báo
              Code:
              eeprom char so2;
              hoặc nếu như bạn cần sử dụng địa chỉ này để lưu dữ liệu thì chỉ việc thay tên biến so2 bằng tên biến mới.. thế là xong (với đk biến mới có cùng số byte sử dụng với biến cũ).
              => Nên khai báo biến theo kiểu tường minh để dễ quản lý và người kế nhiệm dễ tiếp cận thôi.
              hic.. lỡ đâu lúc đang lâp trình, khai báo mấy cái mảng 3 chiều.. mà người ngơ ngơ ko tập trung thì dễ tính sai địa chỉ lắm ah. lúc đó thì có thể sẽ debug mỏi tay mà ko biết lỗi ở đâu..

              Comment


              • #22
                Nguyên văn bởi dt_love Xem bài viết
                để sử dụng eep trong codevision thì khai báo như sau:
                thêm dòng eeprom trước các khai báo biến bình thường.
                vd: eeprom unsigned char eep_var;
                khi đó trình biên dịch sẽ tự động định địa chỉ cho biến này.

                nếu muốn đặt biến này vào địa chỉ a trong eeprom thì khai báo như sau:
                eeprom unsigned char eep_var @a;
                CVAVR cỡ 1.25.9 thì nó lại không hiểu "eeprom unsigned char eep_var @a;" gì!
                Đơn giản và dễ dàng thì tốt nhất cứ dùng "eeprom unsigned char eep_var;". Trường hợp muốn kiểm soát chặt thì sài 2 hàm này thôi:
                EEPROM_viet(unsigned int dchi, unsigned char dlieu);
                biến = EEPROM_doc(unsigned int dchi);
                Last edited by zemen; 01-09-2009, 19:08. Lý do: Xin sửa lại 2.59 thành 1.2.59
                !e

                Comment


                • #23
                  Nguyên văn bởi zemen Xem bài viết
                  CVAVR cỡ 2.59 thì nó lại không hiểu "eeprom unsigned char eep_var @a;" gì!
                  Đơn giản và dễ dàng thì tốt nhất cứ dùng "eeprom unsigned char eep_var;". Trường hợp muốn kiểm soát chặt thì sài 2 hàm này thôi:
                  EEPROM_viet(unsigned int dchi, unsigned char dlieu);
                  biến = EEPROM_doc(unsigned int dchi);
                  ủa, bản 2.59 là bản nào vậy kà.. mình đang xài bản 2.03.4 thấy chạy cũng ok.

                  Comment


                  • #24
                    Nguyên văn bởi dt_love Xem bài viết
                    hi, lại gặp bác minhhieu ở đây rồi...

                    thực ra vấn đề này cũng dễ giải quyết thôi. bạn bỏ nút đi, nhưng đừng xóa dòng khai báo
                    Code:
                    eeprom char so2;
                    hoặc nếu như bạn cần sử dụng địa chỉ này để lưu dữ liệu thì chỉ việc thay tên biến so2 bằng tên biến mới.. thế là xong (với đk biến mới có cùng số byte sử dụng với biến cũ).
                    Thực tế để vậy cũng được, tuy nhiên cứ nhiều nhiều như vậy sẽ làm kích thước của chương trình sau khi biên dịch tăng lên và với các phiên bản codevision V2 có các cảnh báo rất nhiều nên thoải mái để tìm các cảnh báo. hiiii.


                    [quote=dt_love;hic.. lỡ đâu lúc đang lâp trình, khai báo mấy cái mảng 3 chiều.. mà người ngơ ngơ ko tập trung thì dễ tính sai địa chỉ lắm ah. lúc đó thì có thể sẽ debug mỏi tay mà ko biết lỗi ở đâu..[/quote]
                    Trong lúc lập trình nếu ngơ ngơ không tập trung thì mình nghĩ nên dừng lại và đi chơi cho thoải mái, lỡ đâu cứ cho chạy trong lúc này khéo cả nhà máy tiêu mất.
                    Tóm lại có rất nhiều cách lập trình để thực hiện được bài toán, song song với công việc này họ luôn luôn mong muốn code tối ưu và ít mã lệnh nhất (không tính đến asm). Và người ta hướng đến việc lập trình một cách tường minh nhất. Nếu chúng ta đã từng làm việc với công nghệ dotnet như trong môi trường C# 2005 trở lên sẽ thấy trình biên dịch quản lý việc này rất tốt và cũng rất khó tính....=> chất lượng cũng.... Mình cũng chưa đủ trình để phân tích và giải thích thêm về vấn đề này, các bạn tham khảo thêm một số sách nước ngoài họ viết rất tỉ mỉ về vấn đề đó.
                    Chúc một ngày Quốc Khánh vủi vẻ!
                    n
                    ĐT: 0986 492 489

                    Tham khảo:

                    Comment


                    • #25
                      Có ai biết cách tìm kiếm dữ liệu trên rom làm sao ko? Và cách map dữ liệu từ vùng nhớ trong ram vào một vùng nhớ cụ thể (địa chỉ cụ thể) trong rom không?
                      Hai hàm trong datasheet về vấn đến đọc và ghi dữ liệu cho eeprom có vấn đề! Mình đã test nhiều lần và kết quả không đúng. Mình đang sử dụng atmega16
                      Chân thành cảm ơn các bạn!
                      |

                      Comment


                      • #26
                        Nguyên văn bởi hai_lua_t2 Xem bài viết
                        Có ai biết cách tìm kiếm dữ liệu trên rom làm sao ko? Và cách map dữ liệu từ vùng nhớ trong ram vào một vùng nhớ cụ thể (địa chỉ cụ thể) trong rom không?
                        Hai hàm trong datasheet về vấn đến đọc và ghi dữ liệu cho eeprom có vấn đề! Mình đã test nhiều lần và kết quả không đúng. Mình đang sử dụng atmega16
                        Chân thành cảm ơn các bạn!
                        Bạn sử dụng hàm nào? và bạn dùng như thế nà mà ko đúng?

                        Comment


                        • #27
                          ai biết xin chỉ giúp, tại sao mỗi lần tắt nguồn thì dữ liệu trong eeprom lại trở về mặc định.
                          Có cách nào khắc phục không?

                          Comment


                          • #28
                            Nguyên văn bởi conkhicodon Xem bài viết
                            ai biết xin chỉ giúp, tại sao mỗi lần tắt nguồn thì dữ liệu trong eeprom lại trở về mặc định.
                            Có cách nào khắc phục không?
                            Trở về mặc định là FF hay là giá trị bạn đặt ban đầu?
                            Bạn dùng hàm nào để ghi vào eeprom, khả năng là bạn vẫn chưa ghi được dữ liệu vào eeprom mà nó chỉ mới nằm trên ram thôi.

                            Comment


                            • #29
                              Mình dùng lệnh ghi đọc EEprom rất ổn định, các bạn có thể tham khảo.

                              CodeVision 2.03.4

                              void Write_EEPROM(unsigned int dchi, unsigned char dlieu)
                              {
                              while(EECR.1);
                              EEAR = dchi;
                              EEDR = dlieu;
                              EECR.2 = 1;
                              EECR.1 = 1;
                              }

                              //doc 1 byte du lieu tu dia chi cua eeprom//////////////////////////
                              unsigned char Read_EEPROM(unsigned int dchi)
                              {
                              while(EECR.1);
                              EEAR = dchi;
                              EECR.0 = 1;
                              return EEDR;
                              }

                              Chúc thành công.

                              Comment


                              • #30
                                mình cũng dùng chương trình như Vandungevn nhưng khi mất điện thì mất luôn dữ liệu
                                Đây là chương trình của mình, mong các cao thủ chỉ giáo. Thanks

                                dem1++;

                                x=getchar();


                                if (x==t)
                                k=0;

                                else
                                {
                                if(x==0)
                                {k=1;}
                                if(k==1)
                                {dem++;

                                if(dem==1)
                                {
                                Write_EEPROM(0x0001,x);
                                }
                                if(dem==2)
                                {
                                Write_EEPROM(0x0002,x);
                                }
                                if(dem==3)
                                {
                                Write_EEPROM(0x0003,x);
                                }
                                if(dem==4)
                                {
                                Write_EEPROM(0x0004,x);
                                }
                                if(dem==5)
                                {
                                Write_EEPROM(0x0005,x);
                                }
                                if(dem==6)
                                {
                                Write_EEPROM(0x0006,x);
                                }
                                if(dem==7)
                                {
                                Write_EEPROM(0x0007,x);
                                }
                                if(dem==8)
                                {
                                Write_EEPROM(0x0008,x);
                                }
                                if(dem==8)
                                {dem=0;}
                                t=x;
                                }
                                }

                                if(dem1>=10 & dem1<40)
                                PORTB=mang[Read_EEPROM(0x0005)];
                                if(dem1>=40 & dem1<70)
                                PORTB=mang[Read_EEPROM(0x0004)];
                                if(dem1>=70 & dem1<100)
                                PORTB=mang[Read_EEPROM(0x0006)];
                                if(dem1==100)
                                dem1=11;
                                Phạm Duy Quý

                                PN:0973291335


                                Dám nghĩ,dám nói,dám làm

                                Comment

                                Về tác giả

                                Collapse

                                thanhtuandkh Tìm hiểu thêm về thanhtuandkh

                                Bài viết mới nhất

                                Collapse

                                Đang tải...
                                X