Thông báo

Collapse
No announcement yet.

Hỏi về thuật toán!

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

  • Hỏi về thuật toán!

    Em có bài toán như thế này:

    Trên màn hình LCD 16x2 có 2 giá trị là nhiệt độ và áp suất được điều khiển bởi 4 nút bấm được nối trực tiếp với các chân atmega16: Ap suất(PIND.3), Nhiệt độ(PIND.4), Tăng(PIND.5), Giảm(PIND.6).
    Yêu cầu: Khi nhấn vào Thay đổi giá trị của áp suất, nhiệt độ thông qua 4 phím này (Ví dụ muốn tăng áp suất thì ấn nút Áp suất và ấn nút tăng).
    Tuy nhiên em loai hoay mãi mà vẫn chưa thiết kế được thuật toán cho chương trình này. Bác nào có thể thiết kế giúp em một thuật toán tốt cho bài toán này không ạ.
    EM xin cảm ơn nhiều

  • #2
    Nguyên văn bởi tudomuonnam Xem bài viết
    Em có bài toán như thế này:

    Trên màn hình LCD 16x2 có 2 giá trị là nhiệt độ và áp suất được điều khiển bởi 4 nút bấm được nối trực tiếp với các chân atmega16: Ap suất(PIND.3), Nhiệt độ(PIND.4), Tăng(PIND.5), Giảm(PIND.6).
    Yêu cầu: Khi nhấn vào Thay đổi giá trị của áp suất, nhiệt độ thông qua 4 phím này (Ví dụ muốn tăng áp suất thì ấn nút Áp suất và ấn nút tăng).
    Tuy nhiên em loai hoay mãi mà vẫn chưa thiết kế được thuật toán cho chương trình này. Bác nào có thể thiết kế giúp em một thuật toán tốt cho bài toán này không ạ.
    EM xin cảm ơn nhiều
    bạn dùng ngắt để quét phím ! chương trình phục vụ ngắt này sẽ phát hiện phím bạn nhấn rồi thực hiện chức năng của nút đó !
    sau đó quay lại chương trình chính , chương trình chính là code chỉ để hiển thị các giá trị lên LCD thôi ! OK
    Chúc thành công !
    0945061338(vocam.h@gmail.com,lehanhdtk3@gmail.com)
    ||
    PROGRAMING(C,ASM),HARDWARE,LMD,RTC,GPRS,GPS....ALL OF VDK

    Comment


    • #3
      Nguyên văn bởi tudomuonnam Xem bài viết
      Em có bài toán như thế này:

      Trên màn hình LCD 16x2 có 2 giá trị là nhiệt độ và áp suất được điều khiển bởi 4 nút bấm được nối trực tiếp với các chân atmega16: Ap suất(PIND.3), Nhiệt độ(PIND.4), Tăng(PIND.5), Giảm(PIND.6).
      Yêu cầu: Khi nhấn vào Thay đổi giá trị của áp suất, nhiệt độ thông qua 4 phím này (Ví dụ muốn tăng áp suất thì ấn nút Áp suất và ấn nút tăng).
      Tuy nhiên em loai hoay mãi mà vẫn chưa thiết kế được thuật toán cho chương trình này. Bác nào có thể thiết kế giúp em một thuật toán tốt cho bài toán này không ạ.
      EM xin cảm ơn nhiều
      Nếu chỉ thực hiện chức năng trên, sao bạn k quy định 2 nút dành cho nhiệt độ, 2 nút dành cho áp suất??? Như vậy sẽ dễ viết hơn.

      Vote hộ tớ với. Thanks!

      Comment


      • #4
        Cảm ơn các bác nhiều. Bây giờ bài toán của em hơi khác một tý. Bình thường một sự kiến ấn phím (nhấn và nhả phím) sẽ làm cho áp suất tăng lên một đơn vị. Nhưng bài toán yêu cầu nếu nhấn dí liên tục trong 1 khoảng thời gian(5s chẳng hạn) thì áp suất sẽ tăng 5 đơn vị sau đó nếu ấn dí 10s áp suất sẽ tăng 10 đơn vị. Vậy em sẽ phải lập trình bài toán thế nào ạ. Mong các bác giải đáp giùm em với.

        Comment


        • #5
          Thuật toán !

          Nguyên văn bởi tudomuonnam Xem bài viết
          Cảm ơn các bác nhiều. Bây giờ bài toán của em hơi khác một tý. Bình thường một sự kiến ấn phím (nhấn và nhả phím) sẽ làm cho áp suất tăng lên một đơn vị. Nhưng bài toán yêu cầu nếu nhấn dí liên tục trong 1 khoảng thời gian(5s chẳng hạn) thì áp suất sẽ tăng 5 đơn vị sau đó nếu ấn dí 10s áp suất sẽ tăng 10 đơn vị. Vậy em sẽ phải lập trình bài toán thế nào ạ. Mong các bác giải đáp giùm em với.
          Chào bạn ! Xin góp chút ý kiến cùng bạn :
          Thuật toán mà bạn nói ở đây giống như trong bán phím máy tính !!
          Và theo mình thì bạn có thể dùng một timer nữa ! Mỗi khi có sự kiện nhấn phím thì khởi động timer (định thời 1s)! Khi nhả phím thì tắt và reset bộ timer, Vậy nếu bạn giữ phím trong một khoảng thời gian đủ làm bộ timer tràn , thì sẽ có ngắt timer xảy ra , Trong trình phục vụ ngắt timer bạn cho giá trị của biến đếm tăng lên 1 đơn vị , vậy sau n giây bạn sẽ biến đếm tăng lên n đơn vị . Khi nhả phím bạn đem n đơn vị này cộng với giá trị hiện tại của áp suất là OK, và khi đó cũng đặt biến đếm =0 để dùng cho lần nhấn phím sau !
          Chúc bạn thành công !
          0945061338(vocam.h@gmail.com,lehanhdtk3@gmail.com)
          ||
          PROGRAMING(C,ASM),HARDWARE,LMD,RTC,GPRS,GPS....ALL OF VDK

          Comment


          • #6
            Chào bạn,

            Cái vấn đề của bạn chỉ là quét phím thôi, bạn muốn có 1 chương trình quét phím tổng quát để nhận các phím. Mình xin góp ý cho bạn vài ý kiến:
            1> Bạn nên dùng timer để tạo ngắt và quét phím trong ngắt. Timer này nên ngắt từ 16Hz ~ 32Hz (sẽ đủ nhanh để bạn có thể không bị mất phím nào khi nhấn)
            2> Chương trình quét phím phải đáp ứng các yêu cầu sau: biết khi nào thì có phím nhấn hoặc phìm nhả ra. Phím được nhấn trong thời gian bao lâu

            Cái bạn nói 5s thì trong các đồ dùng điện tử người ta gọi là "fast advance" nghĩa là khi phím được giữ 1 khoảng thời gian cố định thì nó sẽ gởi ra các giá trị phím nhấn liên tục cho chương trình chính.

            Dưới đây là source code cho việc quét phím đảm bảo tất cả các yêu cầu về quét phím (bạn có thể dùng cho bất kỳ MCU nào):

            void keyScan(void)
            {
            V_PortValue = P0_IN; // đọc giá trị từ các chân của MCU
            V_PortValue &= KEY_MASK; // read key Ports
            if (F_keyPressed == TRUE)
            {
            // if key has been pressed
            if (V_PortValue == KEY_NULL)
            {
            // key is released
            F_keyPressed = FALSE;
            F_newEvent = TRUE;
            }
            else
            {
            if (V_keyTemp == V_PortValue)
            {
            // key is not changed
            V_keyTime++;
            if (V_keyTime%4 == 0)
            {
            if (V_keyTime >= 32)
            {
            F_newEvent = TRUE;
            F_newKey = TRUE;
            V_keyHold1s = V_keyTemp;
            }
            if (V_keyTime >= 64)
            V_keyHold2s = V_keyTemp;
            if (V_keyTime >= 96)
            {
            V_keyHold3s = V_keyTemp;
            V_keyTime -= 4;
            }
            }
            }
            else
            {
            // new key is pressed
            F_newEvent = TRUE;
            F_newKey = TRUE;
            V_keyTemp = V_PortValue;
            V_keyValue = V_PortValue; // update key Value
            V_keyHold1s = KEY_NULL;
            V_keyHold2s = KEY_NULL;
            V_keyHold3s = KEY_NULL;
            V_keyTime = 0;
            }
            }
            }
            else
            {
            // if no key pressed
            if (V_PortValue != KEY_NULL)
            {
            // new key is pressed
            F_newEvent = TRUE;
            F_newKey = TRUE;
            V_keyTemp = V_PortValue;
            V_keyValue = V_PortValue; // update key Value
            V_keyHold1s = KEY_NULL;
            V_keyHold2s = KEY_NULL;
            V_keyHold3s = KEY_NULL;
            V_keyTime = 0;
            }
            }
            }

            Comment


            • #7
              Nguyên văn bởi gltd Xem bài viết

              void keyScan(void)
              {
              V_PortValue = P0_IN; // đọc giá trị từ các chân của MCU
              V_PortValue &= KEY_MASK; // read key Ports
              if (F_keyPressed == TRUE) // F_keypress có phải là giá trị kiem tra từ timer trả về ???
              {
              // if key has been pressed
              if (V_PortValue == KEY_NULL)
              {
              // key is released
              F_keyPressed = FALSE;
              F_newEvent = TRUE;
              }
              else
              {
              if (V_keyTemp == V_PortValue)
              {
              // key is not changed
              V_keyTime++;
              if (V_keyTime%4 == 0)
              {
              if (V_keyTime >= 32) //Giá trị này có quá ít chăng???
              {
              F_newEvent = TRUE;
              F_newKey = TRUE;
              V_keyHold1s = V_keyTemp;
              }
              if (V_keyTime >= 64)
              V_keyHold2s = V_keyTemp;
              if (V_keyTime >= 96)
              {
              V_keyHold3s = V_keyTemp;
              V_keyTime -= 4; //???
              }
              }
              }
              else
              {
              // new key is pressed
              F_newEvent = TRUE;
              F_newKey = TRUE;
              V_keyTemp = V_PortValue;
              V_keyValue = V_PortValue; // update key Value
              V_keyHold1s = KEY_NULL;
              V_keyHold2s = KEY_NULL;
              V_keyHold3s = KEY_NULL;
              V_keyTime = 0;
              }
              }
              }
              else
              {
              // if no key pressed
              if (V_PortValue != KEY_NULL)
              {
              // new key is pressed
              F_newEvent = TRUE;
              F_newKey = TRUE;
              V_keyTemp = V_PortValue;
              V_keyValue = V_PortValue; // update key Value
              V_keyHold1s = KEY_NULL;
              V_keyHold2s = KEY_NULL;
              V_keyHold3s = KEY_NULL;
              V_keyTime = 0;
              }
              }
              }
              Cảm ơn bạn về chương trình này nhưng trong chương trình này mình có vài chỗ chưa hiểu(đã được in đậm). Mong bạn chú thích rõ hộ mình vài chỗ với. Rất cảm ơn chương trình của bạn!
              Last edited by tudomuonnam; 15-01-2009, 18:23.

              Comment


              • #8
                Đây là các câu trả lời của mình:

                1> Biến F_keyPressed dùng để lưu trạng thái của key trước khi gọi chương trình quét phím. F_keyPressed = 1 là key đang được nhấn, còn nếu giá trị = 0 là key chưa được nhấn. Biến này sẽ bật lên 1 khi chương trình quét phím nhận biết là có key nhấn. Khi key được nhả ra thì biến này sẽ về 0

                2> Chương trình của mình dùng ngắt timer 32Hz để quét và nếu key được nhấn và giữ thì 1trong 1s sẽ gởi ra 8(V_keyTime%4 = 0) giá trị key nhấn (tương tự như bạn nhấn phím 8 lần). Biến V_keyTime để đo thời gian phím được nhấn V_keyTime = 32 tương ứng với phím được nhấn trong 1s. Do trong chương trình mình cần kiểm tra khi nào phím nhấn được 1s thì sẽ xuất giá trị ra V_keyHold1s nên mình so sánh với 32, với phím nhấn và giữ 2s thì giá trị so sánh là 64. Do đó tùy bạn muốn ktra giá trị phím nhấn trong bao nhiêu giây thì bạn sẽ so sánh với n*k (n là số giây và k là tần số ngắt của timer)

                3> V_keyTime -=4; để tránh tình trạng giá trị thời gian phím nhấn bị tràn. Giả sử bạn dùng biến char (8bits) để chưa giá trị thời gian phím nhấn, và bạn cần ktra giá trị phím nhấn sau 5s, bạn dùng ngắt 32Hz thì sau khi so sánh V_keyTime = 5*32 = 160 bạn sẽ tiếp tục nhấn đến 10s lúc đó nếu bạn ko điều chỉnh V_keyTime thì sẽ bị tràn và bạn ko nhận đúng giá trị phím nhấn

                Comment


                • #9
                  Nguyên văn bởi gltd Xem bài viết
                  Đây là các câu trả lời của mình:

                  1> Biến F_keyPressed dùng để lưu trạng thái của key trước khi gọi chương trình quét phím. F_keyPressed = 1 là key đang được nhấn, còn nếu giá trị = 0 là key chưa được nhấn. Biến này sẽ bật lên 1 khi chương trình quét phím nhận biết là có key nhấn. Khi key được nhả ra thì biến này sẽ về 0

                  2> Chương trình của mình dùng ngắt timer 32Hz để quét và nếu key được nhấn và giữ thì 1trong 1s sẽ gởi ra 8(V_keyTime%4 = 0) giá trị key nhấn (tương tự như bạn nhấn phím 8 lần). Biến V_keyTime để đo thời gian phím được nhấn V_keyTime = 32 tương ứng với phím được nhấn trong 1s. Do trong chương trình mình cần kiểm tra khi nào phím nhấn được 1s thì sẽ xuất giá trị ra V_keyHold1s nên mình so sánh với 32, với phím nhấn và giữ 2s thì giá trị so sánh là 64. Do đó tùy bạn muốn ktra giá trị phím nhấn trong bao nhiêu giây thì bạn sẽ so sánh với n*k (n là số giây và k là tần số ngắt của timer)

                  3> V_keyTime -=4; để tránh tình trạng giá trị thời gian phím nhấn bị tràn. Giả sử bạn dùng biến char (8bits) để chưa giá trị thời gian phím nhấn, và bạn cần ktra giá trị phím nhấn sau 5s, bạn dùng ngắt 32Hz thì sau khi so sánh V_keyTime = 5*32 = 160 bạn sẽ tiếp tục nhấn đến 10s lúc đó nếu bạn ko điều chỉnh V_keyTime thì sẽ bị tràn và bạn ko nhận đúng giá trị phím nhấn
                  Vậy ngắt 32Hz của gltd chỉ dùng làm time stick thôi phải không? Khi có nút ấn thì bật ngắt lên và tăng biến V_keyTime lên. Nhưng sao trong chương trình không có chỗ nào bật ngắt nhỉ? Và câu lệnh

                  //key is not change
                  V_keyTime++

                  có ý nghĩa gì nhỉ?
                  Thêm một chút nữa là mình dùng nhiều phím có chức năng fast advance như trên thì phải sắp xếp chương trình như thế nào?
                  Cảm ơn nhiều!
                  Last edited by tudomuonnam; 07-02-2009, 08:45.

                  Comment


                  • #10
                    sao bạn không đổi thanh 1 tăng 1giảm cho nhiệt độ, một bộ nữa cho áp suất?
                    Last edited by kkhg; 07-02-2009, 10:26.

                    Comment


                    • #11
                      ngắt 32Hz dùng để tạo các khe thời gian để gọi chương trình quét phím thôi. Bạn nên dùng timer để tạo ngắt và gọi hàm quét phím trong ngắt này. Biến V_keyTime dùng để đo thời gian phím đã được nhấn (chẳng hạn bạn muốn biết phím được nhấn trong vòng bao lâu thì bạn xem giá trị của V_keyTime). Nếu bạn dùng nhiều phím có chức năng fast advance thì cũng không ảnh hưởng gì đến chương trình, vì các giá trị đã được các biến V_keyHold1s, V_keyHold2s và V_keyHold3s lưu giữ rồi.

                      Comment


                      • #12
                        Bạn có thể đưa source đầy đủ lên đc ko. Nói thực trong bài viết của bạn có rất nhiều biến và thiếu nhiều cái nữa. mình đọc ko hiểu j hết.

                        Comment


                        • #13
                          Bạn xem lại ở trang trước nhé, mình có gởi source code lên và có giải thích về nguyên lý của source code cũng như ý nghĩa của các biến rồi mà. Source code này của mình đã được ứng dụng trong thực tế nhiều năm rồi, chắc chắn là không thiếu hay không có vấn đề gì hết. Bạn chịu khó tham khảo nhé.

                          Comment

                          Về tác giả

                          Collapse

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

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

                          Collapse

                          Đang tải...
                          X