Thông báo

Collapse
No announcement yet.

Cách quét LED 7 đoạn

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

  • Cách quét LED 7 đoạn

    Vấn đề này trên 4rum đã có nhiều rồi, mình đưa ra mục này cho các bác newbie tiện tham khảo.

    Phần cứng:
    8 chân data (A, B, C, D, E, F, G, dot) của các LED7 đấu chung với nhau và đấu về 1 port của uC. Mức logic 0 để điều khiển từng đoạn sáng.
    Phần điều khiển cấp nguồn cho từng LED7 (trong ví dụ này tối đa 16 LED) đấu về 2 port của uC. Tại một thời điểm chỉ có 1 trong các LED7 này được cấp nguồn, các LED7 còn lại tắt. Output logic 1 để điều khiển cấp nguồn.

    Nguyên lý:
    Lần lượt cấp nguồn cho từng LED7, đối với LED7 thứ n, xuất dữ liệu của LED7 thứ n (lưu trong buffer). -> tại một thời điểm chỉ có 1 LED7 sáng với dữ liệu của nó. Delay một khoảng thời gian, sau đó chuyển sang LED7 khác.
    Theo nguyên lý lưu ảnh 24h/s (đối với uC thì nên nhanh hơn khoảng 50h/s) ta sẽ thấy giá trị của từng LED7.

    File Led7.h
    Code:
    #ifndef _LED7_H_
    #define _LED7_H_
    
    //---------------------------------------------------//
    #define L7_COUNT	16
    
    // Define LED7 control pin
    #define L7_P1_PORT	PORTC
    #define L7_P1_DDR	DDRC
    #define L7_P2_PORT	PORTB
    #define L7_P2_DDR	DDRB
    
    
    //---------------------------------------------------//
    // Define LED7 data pin
    
    #define L7_DATA_PORT	PORTA
    #define L7_DATA_DDR	DDRA
    
    #define L7_a	0
    #define L7_b	1
    #define L7_c	2
    #define L7_d	3
    #define L7_e	4
    #define L7_g	6
    #define L7_o	7
    
    //---------------------------------------------------//
    // Define LED character
    
    #define La	(1 << L7_a)
    #define Lb	(1 << L7_b)
    #define Lc	(1 << L7_c)
    #define Ld	(1 << L7_d)
    #define Le	(1 << L7_e)
    #define Lf	(1 << L7_f)
    #define Lg	(1 << L7_g)
    #define Lo	(1 << L7_o)
    
    #define NUM_0	~(La|Lb|Lc|Ld|Le|Lf)
    #define NUM_1	~(Lb|Lc)
    #define NUM_2	~(La|Lb|Ld|Le|Lg)
    #define NUM_3	~(La|Lb|Lc|Ld|Lg)
    #define NUM_4	~(Lb|Lc|Lf|Lg)
    #define NUM_5	~(La|Lc|Ld|Lf|Lg)
    #define NUM_6	~(La|Lc|Ld|Le|Lf|Lg)
    #define NUM_7	~(La|Lb|Lc)
    #define NUM_8	~(La|Lb|Lc|Ld|Le|Lf|Lg)
    #define NUM_9	~(La|Lb|Lc|Ld|Lf|Lg)
    
    #define NUM_A	~(La|Lb|Lc|Le|Lf|Lg)
    #define NUM_C	~(La|Ld|Le|Lf)
    #define NUM_E	~(La|Ld|Le|Lf|Lg)
    #define NUM_F	~(La|Le|Lf|Lg)
    #define NUM_H	~(Lb|Lc|Le|Lf|Lg)
    #define NUM_L	~(Ld|Le|Lf)
    #define NUM_P	~(La|Lb|Le|Lf|Lg)
    #define NUM_U	~(Lb|Lc|Ld|Le|Lf)
    
    #define NUM_0d	(NUM_0&(~Lo))
    #define NUM_1d	(NUM_1&(~Lo))
    #define NUM_2d	(NUM_2&(~Lo))
    #define NUM_3d	(NUM_3&(~Lo))
    #define NUM_4d	(NUM_4&(~Lo))
    #define NUM_5d	(NUM_5&(~Lo))
    #define NUM_6d	(NUM_6&(~Lo))
    #define NUM_7d	(NUM_7&(~Lo))
    #define NUM_8d	(NUM_8&(~Lo))
    #define NUM_9d	(NUM_9&(~Lo))
    
    #define NUM_Ad	(NUM_A&(~Lo))
    #define NUM_Cd	(NUM_C&(~Lo))
    #define NUM_Ed	(NUM_E&(~Lo))
    #define NUM_Fd	(NUM_F&(~Lo))
    #define NUM_Hd	(NUM_H&(~Lo))
    #define NUM_Ld	(NUM_L&(~Lo))
    #define NUM_Pd	(NUM_P&(~Lo))
    #define NUM_Ud	(NUM_U&(~Lo))
    
    //---------------------------------------------------//
    unsigned char L7_CHARS[36] = 
    	{NUM_0,  NUM_1,  NUM_2,  NUM_3,  NUM_4,  NUM_5,  NUM_6,  NUM_7,  NUM_8,  NUM_9,
    	 NUM_0d, NUM_1d, NUM_2d, NUM_3d, NUM_4d, NUM_5d, NUM_6d, NUM_7d, NUM_8d, NUM_9d,
    	 NUM_A,  NUM_C,  NUM_E,  NUM_F,  NUM_H,  NUM_L,  NUM_P,  NUM_U,
    	 NUM_Ad, NUM_Cd, NUM_Ed, NUM_Fd, NUM_Hd, NUM_Ld, NUM_Pd, NUM_Ud};
    
    #endif

    File Led7.c
    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    
    #include "led7.h"
    
    unsigned char L7_DataBuffer[L7_COUNT] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
    
    //-------------------------------------------------------------------//
    main (void)
    {
    	unsigned char L7_Index;
    	unsigned int L7_CtrlMask;
    
    	L7_P1_PORT = 0xFF; L7_P2_PORT = 0xFF;
    	L7_P1_DDR = 0xFF;  L7_P2_DDR = 0xFF;
    	L7_P1_PORT = 0x00; L7_P2_PORT = 0x00;
    
    	L7_DATA_PORT = 0xFF; L7_DATA_DDR = 0xFF;
    
    	while (1)
    	{
    		// Scan LED7
    		for (L7_Index=0; L7_Index<=L7_COUNT; L7_Index++)
    		{
    			L7_CtrlMask = (1<<L7_Index);
    			L7_DATA_PORT = L7_CHARS[L7_DataBuffer[L7_Index]];
    			L7_P1_PORT = (unsigned char)(L7_CtrlMask & 0x00FF);
    
    			if (L7_COUNT > 8) {
    				L7_P2_PORT = (L7_CtrlMask>>8);
    			}
    
    			_delay_ms(1);
    
    			L7_P1_PORT = 0x00;
    			L7_P2_PORT = 0x00;
    		}
    	}
    }
    

  • #2
    Có ai có CT viết bằng asm ko?

    Comment


    • #3
      Nguyên văn bởi HiMas88 Xem bài viết
      Có ai có CT viết bằng asm ko?
      viết = asm dùng thuật toán tương tự mà.
      bạn cần lắm ko?để mai tớ gửi cho.

      Comment


      • #4
        Mình mới làm quen với CodevisionAVR nên không hiểu
        #ifndef _LED7_H_
        #define _LED7_H_
        Hai dòng đấy có nghĩa là gì vậy?
        Tại sao lại phải viết: _LED_H_ Sao nhiều gạch ngang thế? mình mở cac headfine trong thư mục INC của codevisionAVR thấy nó cũng hay viết như vậy.

        Còn dòng này nữa:
        #define L7_COUNT 16
        Có tác dụng gì vậy? mà minh không thấy L7_COUNT đươc sử dụng ở chỗ nào trong fine Led7.h.

        Đừng cười vì những câu hỏi ngớ ngẩn nhé,Mình là dân IT mới làm quen với lập trình C mà.
        Last edited by bockhoi; 22-11-2008, 00:40.

        Comment


        • #5
          Code:
          #include <mega16.h>
          #include<delay.h>
          
          // Declare your global variables here
          char num[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
          char dv; 
          char ch;
          char i;
          void main(void)
          {
          // Declare your local variables here
          
          PORTA=0x00;     // PORTA la 8 output
          DDRA=0xFF;
          
          PORTB=0x00;     //PORTB la 2 input
          DDRB=0x03;
          dv=0;
          ch=0;
          while (1)
                {
                // Place your code here   
                if(ch>9)
                {
                    dv=0;
                    ch=0;
                }
                else
                 {
                     if( dv>9)
                     {
                         ch++ ;
                         dv=0 ;
                     }
                     else
                     {
                         for(i=0;i<=240;i++)
                         {
                             PORTB.0=0;
                             PORTA=num[dv]; 
                             PORTB.1=1;
                             delay_us(300);
                             PORTB.1=0;
                             PORTA=num[ch]; 
                             PORTB.0=1;  
                             delay_us(300);  
                         }
                     dv++;
                     }
                 }  
                };
          }
          mình đếm từ 00=>> 99 thì reset lại đếm tiếp , mình mới học ,có gì chỉ bảo mình thêm nha ! ^^!
          Last edited by hello020389; 09-05-2010, 13:53.

          Comment


          • #6
            asm mình còn biết chứ các ngôn ngữ khác thì chưa biết mình còn phải cố gắng nhiều hơn

            Comment


            • #7
              Chào các anh em,mình cũng vừa mới viết thử 1 ct bằng ASM để chạy LED 7 thanh,mạch mô phỏng bằng Proteus với 5 linh kiện:
              1,Atmega8
              2,LED 7 segment common anode
              3,Chip 7447
              4,Resistor 10 Ohm
              5,Hai button để đếm số ngược/xuôi cho LED

              Mình đã viết xong nhưng ko hiểu sao vẫn ko chạy,các bros nhận xét hộ mình đoạn code sau với:

              ;Trong vi du nay ta su dung 2 port cua Atmega8
              ;PortD dung xuat du lieu(so dem) ra chip 7447 sau do display tren LED 7 doan
              ;PortB dung nhu ngo nhap,tin hieu tu cac button se dc At8 nhan qua 2 chan PB0 va PB1


              .INCLUDE"M8DEF.INC"
              .CSEG
              .ORG 0x0000
              RJMP BATDAU
              .ORG 0x020
              BATDAU:

              ;KHOI DONG STACK POINTER-SP

              LDI R17,HIGH(RAMEND)
              LDI R16,LOW(RAMEND)
              OUT SPH,R17
              OUT SPL,R16

              ;KHOI DONG CAC PORT

              CLR R16 ;XOA R16 > R16=0
              OUT DDRB,R16 ;XUAT GTRI 0 TU R16 VAO DDRB,DDRB LA NGO NHAP
              LDI R16,$1 ;SET TAT CA GTRI CUA R16 LEN 1
              OUT PORTB,R16 ;PORTB=0xFF & DDRB=0,KEO LEN CAC CHAN PORTB

              OUT DDRD,R16 ;DDRD=0xFF,PORTD LA NGO XUAT

              CLR R25 ;XOA R25(la thanh ghi chua so dem)
              SER R20 ;R20 la thanh ghi chua gtri trc do cua PINB

              MAIN:

              IN R21,PINB ;DOC GIA TRI TU PINB,TUC TU CAC BUTTON
              RCALL SOSANH ;GOI SUBROUTINE SOSANH
              OUT PORTD,R25 ;XUAT GTRI TU R25(gia tri dem) RA PORTD

              SBRS R21,0 ;NEU BIT 0 CUA R21(tuc chan PB0)=1 THI BO QUA DONG
              RCALL TANG ;NHAY DEN SUBROUTINE TANG GTRI DEM

              SBRS R21,1 ;NEU BIT 1 CUA R21(tuc chan PB1)=1 THI BO QUA DONG
              RCALL GIAM ;NHAY DEN SUBROUTINE GIAM GTRI DEM

              MOV R20,R21 ;LUU LAI TRANG THAI PINB

              RJMP MAIN ;QUAY LAI CHTRINH CHINH

              ;CHUONG TRINH CON
              ;Subroutine kiem tra gioi han (tu 0-9) cua so dem

              SOSANH:

              CPI R25,10
              BREQ RESET0 ;NEU GTRI DEM=10 THI TRA VE 0

              CPI R25,255
              BREQ RESET9 ;NEU GRI DEM=255 THI TRA VE 9

              RJMP QUAYVE ;NHAY DEN LABEL QUAYVE

              RESET0:

              LDI R25,$0 ;TRA GTRI DEM VE 0
              RJMP QUAYVE

              RESET9:

              LDI R25,$9 ;GAN 9 CHO GTRI DEM

              QUAYVE:

              RET

              ;Subroutine tang so dem 1 don vi neu thoa man dkien

              TANG:

              SBRS R20,0
              RET
              INC R25
              RET

              ;Subroutine giam so dem 1 don vi neu thoa man dkien

              GIAM:

              SBRS R20,1
              RET
              DEC R25
              RET
              Thanks in advance!
              Missed the boat...caught the Titanic,don't worry,dudes.

              Comment


              • #8
                Ồ,mình đã debug lại rồi,đã chạy ngon,nhưng ko hiểu sao lại không hiển thị đc số 8,các số khác vẫn bt?
                Missed the boat...caught the Titanic,don't worry,dudes.

                Comment


                • #9
                  Nguyên văn bởi luugu Xem bài viết
                  Ồ,mình đã debug lại rồi,đã chạy ngon,nhưng ko hiểu sao lại không hiển thị đc số 8,các số khác vẫn bt?
                  Mạch thật hay mô phỏng. Nếu là mô phỏng do nguồn cấp không đủ. Đến số 8 thì 7 led đều tắt.

                  Comment


                  • #10
                    Nguyên văn bởi duong_act Xem bài viết
                    Mạch thật hay mô phỏng. Nếu là mô phỏng do nguồn cấp không đủ. Đến số 8 thì 7 led đều tắt.
                    Cảm ơn bạn,ở đây thì nên sửa thế nào ợ?Mình mới mô phỏng bằng proteus thôi,biên dịch qua AVR Studio,nếu ấn button thì cả 2 đều bị ngóm khi đến số 8,sang số 9 hoặc về số 7 đều đc,nói chung chỉ ko hiện đc số 8 thôi.Mình có hỏi 1 anh thì anh ấy bảo thỉnh thoảng linh kiện trong proteus cũng có vấn đề,có phải như vậy ko ạ?Mình thử thay các thông số clock frequency,.. cho Atmega8 mà vẫn ko thấy thay đổi gì cả.Nguồn cấp là 5V có là đủ?
                    Anyway,thanks
                    Missed the boat...caught the Titanic,don't worry,dudes.

                    Comment


                    • #11
                      Chuơng trình của bạn hình như mới chỉ có 1 led 7 thanh thôi thì phải .Nếu vậy thì mô phỏng vẫn đảm bảo dc phần cứng . Mà nhìn qua chương trình của bạn thấy na ná giống chương trình ở hocavr.com thì phải .À đây rồi. Thử xem qua đi nhá http://www.hocavr.com/index.php/lectures/cautrucavr

                      Comment


                      • #12
                        Chắc là đúng nó rồi,bạn mình gửi cho mình đoạn code này,chắc lấy ở hocavr.com,mà mình vừa test đoạn code trên í cũng dính phải lỗi đấy,lạ nhỉ ?
                        Missed the boat...caught the Titanic,don't worry,dudes.

                        Comment


                        • #13
                          Code đấy là chuẩn đấy ! Có lẽ bạn nên xem lại phần cứng của mình đi

                          Comment


                          • #14
                            bạn cho mjnh ít tài liêu hoc viết chương trình trên condvision đuoc không

                            Comment


                            • #15
                              Nguyên văn bởi hello020389 Xem bài viết
                              Code:
                              #include <mega16.h>
                              #include<delay.h>
                              
                              // Declare your global variables here
                              char num[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
                              char dv; 
                              char ch;
                              char i;
                              void main(void)
                              {
                              // Declare your local variables here
                              
                              PORTA=0x00;     // PORTA la 8 output
                              DDRA=0xFF;
                              
                              PORTB=0x00;     //PORTB la 2 input
                              DDRB=0x03;
                              dv=0;
                              ch=0;
                              while (1)
                                    {
                                    // Place your code here   
                                    if(ch>9)
                                    {
                                        dv=0;
                                        ch=0;
                                    }
                                    else
                                     {
                                         if( dv>9)
                                         {
                                             ch++ ;
                                             dv=0 ;
                                         }
                                         else
                                         {
                                             for(i=0;i<=240;i++)
                                             {
                                                 PORTB.0=0;
                                                 PORTA=num[dv]; 
                                                 PORTB.1=1;
                                                 delay_us(300);
                                                 PORTB.1=0;
                                                 PORTA=num[ch]; 
                                                 PORTB.0=1;  
                                                 delay_us(300);  
                                             }
                                         dv++;
                                         }
                                     }  
                                    };
                              }
                              mình đếm từ 00=>> 99 thì reset lại đếm tiếp , mình mới học ,có gì chỉ bảo mình thêm nha ! ^^!
                              Chào anh em cũng đang học avr, bước đầu tìm hiểu cách quét led 7 đoạn. chương trình anh viết có thể giải thích cho em được ko? thanks anh.

                              Comment

                              Về tác giả

                              Collapse

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

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

                              Collapse

                              Đang tải...
                              X