Thông báo

Collapse
No announcement yet.

Giao tiếp vdk với máy tính qua UART

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

  • Giao tiếp vdk với máy tính qua UART

    Chào các anh chị trong diễn đàn !
    Em thực hiện giao tiếp atmega16 với máy tính bằng UART.
    Em dùng timer để đếm lùi từ 99 về 00 sau mỗi 1 giây.Và em muốn gửi số đếm lùi đó lên máy tính.
    Nhưng em lại thấy nó hiện lên mã ASCII của ký tự tương ứng với mã từ 99 về 00.Em đã thử chuyển về kiểu nguyên %d của UDR nhưng vẫn không đươc.
    Vậy em phải làm sao để nó hiện ra đúng các số từ 99 về 00 đó ạ ?
    Code của em đây ạ :
    hàm cài đặt UART:

    void uart_setup(){
    //set baud,f=8Mhz
    UBRRH=0;
    UBRRL=51; //9600 bps
    //set khung truyen va kich hoat bo nhan du lieu
    UCSRA=0x00;
    UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //du lieu 8bit
    UCSRB=(1<<RXEN)|(1<<TXEN)|(1<<RXCIE); //cho phep truyen,nhan,ngat RxD
    sei(); //cho phep ngat toan cuc
    }

    Hàm truyền UART:
    void uart_char_tx(int chr){
    while (bit_is_clear(UCSRA,UDRE)); //cho den khi bit UDRE=1
    UDR = chr;
    }

    Hàm timer định thời 1 giây :
    volatile int dem2=99;
    void timer1(){
    //timer 1s
    TCCR1B |=(1<<CS12)|(0<<CS11)|(0<<CS10); //prescaler = 256
    TCNT1=34285; //khoi tao TCNT1=65535-(thoi_gian/((1/F_crystal)*prescaler))=34285 ; thoi_gian(s)
    TIMSK |=(1<<TOIE1); //cho phep ngat khi tran T/C1
    sei(); //set bit I (SREG) gloabal interrupt
    }

    //phuc vu ngat tran T/C1
    ISR (TIMER1_OVF_vect )
    {
    TCNT1 = 34285; //gan lai TCNT1 sau khi tran
    uart_char_tx(dem2);
    _delay_ms(50);
    dem2--;
    if(!dem2) dem2 = 99;
    }

    Hàm main:
    static FILE uartstd= FDEV_SETUP_STREAM(uart_char_tx, NULL,_FDEV_SETUP_WRITE);
    int main(void){
    uart_setup();
    timer1();
    while(1);
    return 0;
    }

    Click image for larger version

Name:	Capture2.PNG
Views:	1
Size:	103.1 KB
ID:	1422857

  • #2
    Em dùng AVRStudio4, WinAVR để biên dịch.
    Các anh giúp em với,em đang cần gấp.

    Comment


    • #3
      Bạn hài quá. Đã khai báo
      static FILE uartstd= FDEV_SETUP_STREAM(uart_char_tx, NULL,_FDEV_SETUP_WRITE);
      Thì dùng hàm printf của C cho lành, chi tiết lên hocavr.com coi nhé.
      Ép kiểu cho UDR thì liên quan gì đâu.
      Bản chất việc hiện số là hiện các ký tự số bạn ah. Nếu không thèm dùng hàm printf thì làm như sau:
      Giả sử số cần gửi là có 2 chữ số, gọi là AB. Thì bạn phải gửi đi 2 byte (A+48) và (B+48). Trong đó 48 = '0'.

      Comment


      • #4
        tức là phải lấy hàng chục và hàng đơn vị của biến dem2 bằng cách chuc = dem2 / 10 ; don_vi = dem2 % 10.
        rồi gửi theo hàm uart_char_tx(chuc + 48);uart_char_tx(don_vi +48); hả anh.Lúc đầu em làm như thế và cho các hàm uart_char_tx() và ngắt tràn timer thì khi giao tiếp thực tế nó cứ kêu ting ting hoài a ạ

        Comment


        • #5
          Nó kêu vì bạn convert sai r. Xem lại code đi. Bạn gửi cái ký tự kêu chuông thì nó lại chẳng kêu.
          Điều đó nói lên rằng bạn dùng laptop và loa còn tốt, nhiều khả năng là máy HP. Máy PC kêu nghe phát bực )
          Ngoài ra, vì dùng lap nên phải có dây USB - RS232. Dây này hoạt động không ổn định lắm với hyper terminal. Bạn nên cài secureCRT để xem thông tin nhận được.

          Comment


          • #6
            và a góp ý ở trên thì e quên chưa xóa cái static FILE uartstd= FDEV_SETUP_STREAM(uart_char_tx, NULL,_FDEV_SETUP_WRITE);
            thực ra e dùng stdout=&uartstd; và hàm printf luôn cho ngắn.

            Comment


            • #7
              Thì code của e là hiển thị số từ 99 về 00,e thấy nó hiện được vài ký tự với mã là 99,98,97 tương ứng là c,b,a và sau đó nó xóa ngược lại của e,tức là nó xóa a,rồi xóa b,rồi xóa c sau đó nó kêu ting ting liên tục a ạ ?

              Comment


              • #8
                Bạn gửi vào cái ký tự xóa, nó lại chẳng xóa

                Comment


                • #9
                  Trời ơi,e thử in trực tiếp printf("%d",dem2); trong hàm phục vụ ngắt tràn timer1 thì in đúng giá trị từ 99 về 00 luôn a ạ.
                  Cái sai của e là e cứ tìm cách gán cái giá trị dem2 đó vào thanh ghi UDR rồi lại đọc thanh ghi UDR để in ra.
                  Nếu e viết printf("%d",UDR) ngay sau dòng gán UDR=dem2 thì nó sẽ in ra ký tự ascii và in ra số 0,e đoán là vì sau khi in ra ký tự ascii,khi đó thanh ghi UDR đã bị rỗng.
                  Cảm ơn a đã góp ý

                  Comment


                  • #10
                    Bạn đã dùng hàm printf thì không cần động đến UDR làm gì nữa, cứ quên nó đi :v.
                    Thứ 2, bạn nên viết một ngắt nhận r nối 2 đầu Tx vs Rx cho vui

                    Comment


                    • #11
                      A cho e hỏi thêm được không ạ.Hiện tại e mới hiển thị tự động từ 99 về 00.Bây giờ e muốn nhập giá trị bất kỳ từ bàn phím máy tính ví dụ e nhập số 40 để nó đêm lùi về 0
                      thì e phải làm như nào ạ.
                      Em có viết hàm nhận bằng ngắt RxD,nhưng vẫn không đc

                      Comment


                      • #12
                        Đó hoàn toàn là vấn đề app trên máy tính.
                        Bạn có thể tạo một chương trình truyền nhận đơn giản qua cổng RS232 (ảo hoặc thực cũng như nhau) bằng MATLAB.

                        Comment


                        • #13
                          Vì không có hàm scanf nên e chưa hiểu cách thức nhập đầu vào cho chương trình bằng các app trên máy tính ? và nếu đã nhập được thì các ký tự vừa nhập đó nó sẽ lưu vào đâu?

                          Comment


                          • #14
                            Nếu một app trên máy tính cho phép bạn gửi đi một chuỗi ký tự nhập vào từ bàn phím, thì tại cổng RS232, các byte sẽ lần lượt được truyền ra.
                            Phía MCU, nếu ngắt nhận được sử dụng, mỗi khi nhận xong một byte, ISR được gọi, trong ISR bạn gán biến nào đó bằng UDR là được. Bạn hoàn toàn có thể viết một giao thức của riêng bạn dùng UART, ví dụ như 2 byte đầu tiên truyền đọ dài gói tin, hoặc một ký tự nào đó do bạn quy định được truyền cuối gói để xác định kết thúc truyền, thường là NULL.

                            Comment

                            Về tác giả

                            Collapse

                            toan.ndn Tìm hiểu thêm về toan.ndn

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

                            Collapse

                            Đang tải...
                            X