1. THÔNG BÁO TUYỂN ADMIN DIỄN ĐÀN 2013
    Tìm kiếm nhà trọ - Ở ghép
    THÔNG BÁO BÁN ÁO SPKT.NET CHO THÀNH VIÊN DIỄN ĐÀN


    HÃY TÌM KIẾM Ở ĐÂY TRƯỚC KHI ĐẶT CÂU HỎI
    {xen:phrase loading}

Dịch bit biến LONG trong Codevision

Thảo luận trong 'Lập trình C cho vi điều khiển AVR cơ bản' bắt đầu bởi bestest_boy, 21 Tháng mười một 2009.

  1. bestest_boy New Member

    Số bài viết: 16
    Đã được thích: 0
    Điểm thành tích: 1
    Có bạn nào đã dùng lệnh dịch phải bit biến LONG (4bytes) cho mình hỏi tí. Khi dịch phải (>>) thì các bit bên trái sẽ được lắp đầy như thế nào với biến signed & unsigned?
    Mình đã thử nhưng hình như nó ko phải được lắp đầy bằng bit 0.
    Đối với biến kiểu int, và char thì mình làm bình thường.
    Mong giúp đỡ
  2. KN Servant. Servant.

    Số bài viết: 1,291
    Đã được thích: 3
    Điểm thành tích: 0
    Bình thường thì được lắp đầy bằng giá trị bit là 0. Nhưng do biến long 4 bytes nên còn liên quan đến các byte gần kề nữa. Đôi khi thanh ghi còn ghi giá trị củ nên khi bạn dịch bit vô tình nó đã nhảy vào thanh ghi của bạn.
    Nếu bạn gởi file ProtuesCode thì các bạn mới có thể giúp bạn tốt hơn.
    Thân chào:eek:k:
  3. bestest_boy New Member

    Số bài viết: 16
    Đã được thích: 0
    Điểm thành tích: 1
    Mã:
    #include <mega32.h>
    #include <delay.h>
    #include <stdio.h>
    void main(void)
    {
        long int c=0xffffffff; 
        unsigned char i;
        while (1)
          {
             for(i=0;i<32;i++)
             {
                c>>=1;
                printf("%x\n\r",c);
                delay_ms(1000);
             }
          }
    }
    
    Trên là đoạn code minh họa, mình dùng để test thử. Các phần khai báo USART mình ko đưa lên, các bạn hiểu ngầm dùm. Lẽ ra khi mô phỏng bên Proteus dùng Virtual Terminal, nó phải xuất dữ liệu như sau:
    Mã:
    7fffffff
    3fffffff
    1fffffff
    ....
    cho đến 0x00
    
    nhưng khi mình mô phỏng thì nó chỉ ra toàn ffff (càng lạ là chỉ có 2byte thôi chứ ko phải 4byte ???)
    [IMG]
    Như vậy là bên trái nó được lấp đầy bởi các bit 1.
    Sao lại như vậy? Sao các phép dịch trái (<<) hay dịch phải (>>) biến 1 or 2 byte đều lấp đầy bởi bit 0?
  4. KN Servant. Servant.

    Số bài viết: 1,291
    Đã được thích: 3
    Điểm thành tích: 0
  5. 05111007 New Member

    Số bài viết: 43
    Đã được thích: 0
    Điểm thành tích: 0
    Servant_KN up code lên cho mọi người cùng tham khảo. Mình cũng từng làm với cái dịch bit của kiểu "long int" này rồi. phép dịch bit thì ko sai. Nhưng phần hiển thị thì bị sai. Ko biết bạn Servant_KN dùng hàm "Printf" để put lên máy tính hay dùng cái khác.
  6. KN Servant. Servant.

    Số bài viết: 1,291
    Đã được thích: 3
    Điểm thành tích: 0
    Mình sử dụng Prinf (%s ) và khai báo unsigned long

  7. 05111007 New Member

    Số bài viết: 43
    Đã được thích: 0
    Điểm thành tích: 0
    Đúng là bạn dùng kiểu in Prin("%s) thì nó sẽ đc như vậy. Nhưng kết quả của bạn làm ra vẫn chưa đúng. biến "c" của bạn nếu bạn cho giá trị max của kiểu "unsigned long int" tức là c=0xFFFFFFFF thì sẽ ko cho ra kết quả đúng như phép dịch bit. cái này bạn có thể kiểm tra lại. Ý mình ở đây thì kết quả hiển thị nó sẽ đúng khi nhỏ hơn một giá trị lớn nhất mà nó có thể in lên màn hình terminal. Ngoài ra ko dùng lệnh printf(%s) thì bạn có thể dùng lệnh puts sẽ cho ra kết quả giống như bạn đã làm. bằng cách như sau:
    thay bằng
    mình chỉ có góp ý nhỏ với các bạn. Chúc mọi người làm việc tốt.
  8. KN Servant. Servant.

    Số bài viết: 1,291
    Đã được thích: 3
    Điểm thành tích: 0
    Thật ra thì em vẫn chưa hiểu ý anh lắm.
    Với lại ban đầu bạn bestest_boy đặt ra câu hỏi này không biết đang muốn viết chương trình hay chỉ muốn test thui.
    Thân chào
  9. 05111007 New Member

    Số bài viết: 43
    Đã được thích: 0
    Điểm thành tích: 0
    Thực ra thì mình cũng chỉ là lưu ý với bạn giá trị mà màn hình terminal xuất ra. Nếu bạn có giá trị là
    0xFFFFFFFF thì giá trị in lên màn hình ko phải là số theo hệ thập phân là "4294967295" mà nó chỉ là một số "2147483800" điều đó có nghĩa là phép in này có giới hạn về số mà bạn in lên man hình.
    còn vấn đề bạn "bestest_boy" thì bạn đã giải quyết rồi. Mình nhắc bạn lưu ý về cái giá trị in trên màn hình terminal. sau này có làm với kiểu số như thế này thì nên cẩn thận.
    Chúc thành công!
  10. KN Servant. Servant.

    Số bài viết: 1,291
    Đã được thích: 3
    Điểm thành tích: 0
    Bây giờ thì em đã hiểu. Em cũng đang tìm hiểu vì sao đây. Hàm in ra có giá trị giới hạn. Anh biết thì chỉ giáo với nha. Hiện tại thì chỉ biết sử dụng trong giới hạn thui
    Thanks
  11. bestest_boy New Member

    Số bài viết: 16
    Đã được thích: 0
    Điểm thành tích: 1
    Vậy nhờ các bạn xem hộ đoạn chương trình con này giúp & mô phỏng trên Proteus thử. Mục đích của đoạn code là tắt dần 32 leds nối với 32 chân IO của AVR theo chiều từ trái sang phải (bit lớn nhất tới bit nhỏ nhất)
    Mã:
    void tatdan(void)
    {
            unsigned char i=0;
            long int temp=0xffffffff,t=0;
            for (i=0;i<32;i++)
                    {                
                    t = (temp>>i);
                    PORTA=t;
                    PORTB=t>>8;
                    PORTC=t>>16;
                    PORTD=t>>24;
                    delay_ms(100);                                
                    }       
    }
    
    Khi mình mô phỏng thì tất cả các ngõ ra đều ở mức 1 suốt. Nếu mình đổi thành tắt dần từ phải qua trái thì OK
    Mã:
    t = (temp<<i);
    
    Hoặc làm với biến int hay char cũng OK.
  12. bestest_boy New Member

    Số bài viết: 16
    Đã được thích: 0
    Điểm thành tích: 1
  13. khoahoctre Giảng Viên

    Số bài viết: 451
    Đã được thích: 7
    Điểm thành tích: 16
    Khai báo unsigned long int thì mới được, với các khai báo của em thì con bit dấu. Nếu bạn đã giải quyết được nên đưa lên để mọi người kham khảo nhé!
  14. bestest_boy New Member

    Số bài viết: 16
    Đã được thích: 0
    Điểm thành tích: 1
    Hổm rày busy quá, hôm nay mới lên được. Post cho các bạn mới học 1 số kiểu hiệu ứng 32 led đơn để trang trí chơi. Có thể phát triển thêm nhiều kiểu khác cho phong phú. Các hiệu ứng mình viết thành chương trình con để dễ quản lý.

    Mã:
    #include <mega32.h>
    #include <delay.h>
    
    void sangdon(void)
    {
            unsigned char i,j;
            unsigned long c=1,temp1=0,temp2=0;
            for (j=32;j>0;j--)
                    {
                            for (i=0;i<j;i++)
                            {                
                                    temp2=(c<<i)|temp1;
                                    PORTA=temp2;
                                    PORTB=temp2>>8;
                                    PORTC=temp2>>16;
                                    PORTD=temp2>>24;
                                    delay_ms(30);                
                            }
                            temp1=temp2;
                            if (temp1==0xffffffff)
                            temp1=0;                        
                    }       
    }
    
    void choptat(void)
    {
            unsigned char i;
            unsigned long temp=0xAAAAAAAA;
            for(i=0;i<20;i++)
            {
                    temp=~temp;
                    PORTA=temp;
                    PORTB=temp>>8;
                    PORTC=temp>>16;
                    PORTD=temp>>24;
                    delay_ms(100);        
            }       
    }
    
    void sangdan(void)
    {
            unsigned char i;
            unsigned long c=1,temp=0;
            for (i=0;i<32;i++)
                    {                
                    temp = temp | (c<<i);
                    PORTA=temp;
                    PORTB=temp>>8;
                    PORTC=temp>>16;
                    PORTD=temp>>24;
                    delay_ms(30);                                
                    }       
    }
    
    void tatdan(void)
    {
            unsigned char i=0;
            unsigned long temp=0xffffffff;
            for (i=0;i<32;i++)
                    {                
                    temp=temp>>1;
                    PORTA=temp;
                    PORTB=temp>>8;
                    PORTC=temp>>16;
                    PORTD=temp>>24;
                    delay_ms(30);                                
                    }       
    }
    
    void sangngoaivao(void)
    {
            unsigned char i=0;
            unsigned int temp1=0,temp2=0,t1=0x01,t2=0x8000;
            
            for (i=0;i<16;i++)
                    {                
                    temp1=temp1 | (t1<<i);
                    temp2=temp2 | (t2>>i);
                    PORTA=temp1;
                    PORTB=temp1>>8;
                    PORTC=temp2;
                    PORTD=temp2>>8;
                    delay_ms(30);                                
                    }
                           
    }
    
    void sangtrongra(void)
    {
            unsigned char i=0;
            unsigned int temp1=0,temp2=0,t1=0x8000,t2=0x01;
            
            for (i=0;i<16;i++)
                    {                
                    temp1=temp1 | (t1>>i);
                    temp2=temp2 | (t2<<i);
                    PORTA=temp1;
                    PORTB=temp1>>8;
                    PORTC=temp2;
                    PORTD=temp2>>8;
                    delay_ms(30);                                
                    }
                           
    }
    
    void tattrongra(void)
    {
            unsigned char i=0;
            unsigned int temp1=0xffff,temp2=0xffff;
            for (i=0;i<16;i++)
                    {                
                    temp1=temp1>>1;
                    temp2=temp2<<1;
                    PORTA=temp1;
                    PORTB=temp1>>8;
                    PORTC=temp2;
                    PORTD=temp2>>8;
                    delay_ms(30);                                
                    }       
    }
    
    void tatngoaivao(void)
    {
            unsigned char i=0;
            unsigned int temp1=0xffff,temp2=0xffff;
            for (i=0;i<16;i++)
                    {                
                    temp1=temp1<<1;
                    temp2=temp2>>1;
                    PORTA=temp1;
                    PORTB=temp1>>8;
                    PORTC=temp2;
                    PORTD=temp2>>8;
                    delay_ms(30);                                
                    }       
    }
    
    void donngoaivao(void)
    {
            unsigned int temp1=0,temp2=0,c1=1,c2=0x8000,t1=0,t2=0;
            unsigned char i,j;
            for(j=16;j>0;j--)
            {
                    for(i=0;i<j;i++)
                    {
                            t1=temp1 | (c1<<i);
                            t2=temp2 | (c2>>i);
                            PORTA=t1;
                            PORTB=t1>>8;
                            PORTC=t2;
                            PORTD=t2>>8;
                            delay_ms(30);
                    }
                    temp1=t1;
                    temp2=t2;
                    if (temp1==0xffff) temp1=0;                
                    if (temp2==0xffff) temp2=0;
            }
    }
    
    void dontrongra(void)
    {
            unsigned int temp1=0,temp2=0,c1=1,c2=0x8000,t1=0,t2=0;
            unsigned char i,j;
            for(j=16;j>0;j--)
            {
                    for(i=0;i<j;i++)
                    {
                            t1=temp1 | (c1<<i);
                            t2=temp2 | (c2>>i);
                            PORTA=t2;
                            PORTB=t2>>8;
                            PORTC=t1;
                            PORTD=t1>>8;
                            delay_ms(30);
                    }
                    temp1=t1;
                    temp2=t2;
                    if (temp1==0xffff) temp1=0;                
                    if (temp2==0xffff) temp2=0;
            }
    }
    
    void main(void)
    {
           unsigned char m;
            while(1)
            {
                    
                    DDRA=0xff;
                    DDRB=0xff;
                    DDRC=0xff;
                    DDRD=0xff;
                    donngoaivao();
                    dontrongra();
                    sangdan();
                    tatdan();
                    choptat(); 
                    sangdon();
                    m=5;
                while(m)
                {
                    sangngoaivao();
                    sangtrongra();
                    tattrongra();
                    m--;
                }
                    m=5;
                while(m)
                {
                    sangtrongra();
                    tatngoaivao();
                    m--;
                }
            }
    }
    

Chia sẻ trang này