Thông báo

Collapse
No announcement yet.

Giao tiếp máy tính với AVR

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

  • Giao tiếp máy tính với AVR

    Mình thực hiện giao tiếp máy tính với AVR để điều khiển 8 LED đơn, mình giao tiếp sử dụng VB 6.0, con trên AVR sd codevision nhưng ko hiểu tại sao khi giao tiếp dữ liệu của mình truyền xuống được nhưng lại bi sai bét hết đèn sáng lung tung. Mình mong được sự giúp đỡ của các bạn trong diễn đàn, Xin chân thành cảm ơn
    Đây là code trên VB
    Private Sub Command1_Click()
    s = Chr(Text1.Text) 'LAY GIA TRI TU TEXT1
    MSComm1.Output = s 'TRUYEN RA CONG COM
    'MSComm1.Output = Chr(2)
    End Sub

    Private Sub Command2_Click()
    's = MSComm1.Input 'NHAN DU LIEU TU CONG COM
    MSComm1.Output = Hex(4)
    End Sub

    Private Sub Command3_Click()
    'KET THUC CHUONG TRINH
    End
    End Sub

    Private Sub Form_Load()
    Dim s() As Byte
    MSComm1.CommPort = 1
    If MSComm1.PortOpen Then
    MSComm1.PortOpen = False
    End If
    MSComm1.Settings = "9600,N,8,1" 'DE TRUYEN NHAN DU LIEU TA PHAI MO CONG COM
    MSComm1.InputMode = 1
    MSComm1.InBufferCount = 0
    MSComm1.InputLen = 0
    MSComm1.PortOpen = True
    End Sub
    Đây là code trên vdk sd codevision

    #include <mega32.h>

    #define RXB8 1
    #define TXB8 0
    #define UPE 2
    #define OVR 3
    #define FE 4
    #define UDRE 5
    #define RXC 7

    #define FRAMING_ERROR (1<<FE)
    #define PARITY_ERROR (1<<UPE)
    #define DATA_OVERRUN (1<<OVR)
    #define DATA_REGISTER_EMPTY (1<<UDRE)
    #define RX_COMPLETE (1<<RXC)

    // USART Receiver buffer
    #define RX_BUFFER_SIZE 8
    unsigned char rx_buffer[RX_BUFFER_SIZE];

    #if RX_BUFFER_SIZE<256
    unsigned char rx_wr_index,rx_rd_index,rx_counter;
    #else
    unsigned int rx_wr_index,rx_rd_index,rx_counter;
    #endif

    // This flag is set on USART Receiver buffer overflow
    bit rx_buffer_overflow;

    // USART Receiver interrupt service routine
    interrupt [USART_RXC] void usart_rx_isr(void)
    {
    unsigned char status,data;
    status=UCSRA;
    data=UDR;
    if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
    {
    rx_buffer[rx_wr_index]=data;
    if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
    if (++rx_counter == RX_BUFFER_SIZE)
    {
    rx_counter=0;
    rx_buffer_overflow=1;
    };
    };
    }

    #ifndef _DEBUG_TERMINAL_IO_
    // Get a character from the USART Receiver buffer
    #define _ALTERNATE_GETCHAR_
    #pragma used+
    char getchar(void)
    {
    unsigned char data;
    while (rx_counter==0);
    data=rx_buffer[rx_rd_index];
    if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
    #asm("cli")
    --rx_counter;
    #asm("sei")
    return data;
    }
    #pragma used-
    #endif

    // USART Transmitter buffer
    #define TX_BUFFER_SIZE 8
    unsigned char tx_buffer[TX_BUFFER_SIZE];

    #if TX_BUFFER_SIZE<256
    unsigned char tx_wr_index,tx_rd_index,tx_counter;
    #else
    unsigned int tx_wr_index,tx_rd_index,tx_counter;
    #endif

    // USART Transmitter interrupt service routine
    interrupt [USART_TXC] void usart_tx_isr(void)
    {
    if (tx_counter)
    {
    --tx_counter;
    UDR=tx_buffer[tx_rd_index];
    if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0;
    };
    }

    #ifndef _DEBUG_TERMINAL_IO_
    // Write a character to the USART Transmitter buffer
    #define _ALTERNATE_PUTCHAR_
    #pragma used+
    void putchar(char c)
    {
    while (tx_counter == TX_BUFFER_SIZE);
    #asm("cli")
    if (tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0))
    {
    tx_buffer[tx_wr_index]=c;
    if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;
    ++tx_counter;
    }
    else
    UDR=c;
    #asm("sei")
    }
    #pragma used-
    #endif

    // Standard Input/Output functions
    #include <stdio.h>
    unsigned char temp;

    // Declare your global variables here

    void main(void)
    {
    // Declare your local variables here

    // Input/Output Ports initialization
    // Port A initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTA=0x00;
    DDRA=0x00;

    // Port B initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTB=0x00;
    DDRB=0x00;

    // Port C initialization
    // Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
    // State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
    PORTC=0xFF;
    DDRC=0xFF;

    // Port D initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTD=0x00;
    DDRD=0x00;

    // Timer/Counter 0 initialization
    // Clock source: System Clock
    // Clock value: Timer 0 Stopped
    // Mode: Normal top=FFh
    // OC0 output: Disconnected
    TCCR0=0x00;
    TCNT0=0x00;
    OCR0=0x00;

    // Timer/Counter 1 initialization
    // Clock source: System Clock
    // Clock value: Timer 1 Stopped
    // Mode: Normal top=FFFFh
    // OC1A output: Discon.
    // OC1B output: Discon.
    // Noise Canceler: Off
    // Input Capture on Falling Edge
    // Timer 1 Overflow Interrupt: Off
    // Input Capture Interrupt: Off
    // Compare A Match Interrupt: Off
    // Compare B Match Interrupt: Off
    TCCR1A=0x00;
    TCCR1B=0x00;
    TCNT1H=0x00;
    TCNT1L=0x00;
    ICR1H=0x00;
    ICR1L=0x00;
    OCR1AH=0x00;
    OCR1AL=0x00;
    OCR1BH=0x00;
    OCR1BL=0x00;

    // Timer/Counter 2 initialization
    // Clock source: System Clock
    // Clock value: Timer 2 Stopped
    // Mode: Normal top=FFh
    // OC2 output: Disconnected
    ASSR=0x00;
    TCCR2=0x00;
    TCNT2=0x00;
    OCR2=0x00;

    // External Interrupt(s) initialization
    // INT0: Off
    // INT1: Off
    // INT2: Off
    MCUCR=0x00;
    MCUCSR=0x00;

    // Timer(s)/Counter(s) Interrupt(s) initialization
    TIMSK=0x00;

    // USART initialization
    // Communication Parameters: 8 Data, 1 Stop, No Parity
    // USART Receiver: On
    // USART Transmitter: On
    // USART Mode: Asynchronous
    // USART Baud rate: 9600
    UCSRA=0x00;
    UCSRB=0xD8;
    UCSRC=0x86;
    UBRRH=0x01;
    UBRRL=0x03;

    // Analog Comparator initialization
    // Analog Comparator: Off
    // Analog Comparator Input Capture by Timer/Counter 1: Off
    ACSR=0x80;
    SFIOR=0x00;

    // Global enable interrupts
    #asm("sei")

    while (1)
    {
    if (rx_counter>0)
    temp=getchar();
    PORTC=temp;
    putchar(temp);
    // Place your code here

    };
    }

  • #2
    Nguyên văn bởi tiger2007 Xem bài viết
    Mình thực hiện giao tiếp máy tính với AVR để điều khiển 8 LED đơn, mình giao tiếp sử dụng VB 6.0, con trên AVR sd codevision nhưng ko hiểu tại sao khi giao tiếp dữ liệu của mình truyền xuống được nhưng lại bi sai bét hết đèn sáng lung tung. Mình mong được sự giúp đỡ của các bạn trong diễn đàn, Xin chân thành cảm ơn
    Đây là code trên VB
    Private Sub Command1_Click()
    s = Chr(Text1.Text) 'LAY GIA TRI TU TEXT1
    MSComm1.Output = s 'TRUYEN RA CONG COM
    'MSComm1.Output = Chr(2)
    End Sub

    Private Sub Command2_Click()
    's = MSComm1.Input 'NHAN DU LIEU TU CONG COM
    MSComm1.Output = Hex(4)
    End Sub

    Private Sub Command3_Click()
    'KET THUC CHUONG TRINH
    End
    End Sub

    Private Sub Form_Load()
    Dim s() As Byte
    MSComm1.CommPort = 1
    If MSComm1.PortOpen Then
    MSComm1.PortOpen = False
    End If
    MSComm1.Settings = "9600,N,8,1" 'DE TRUYEN NHAN DU LIEU TA PHAI MO CONG COM
    MSComm1.InputMode = 1
    MSComm1.InBufferCount = 0
    MSComm1.InputLen = 0
    MSComm1.PortOpen = True
    End Sub
    Đây là code trên vdk sd codevision

    #include <mega32.h>

    #define RXB8 1
    #define TXB8 0
    #define UPE 2
    #define OVR 3
    #define FE 4
    #define UDRE 5
    #define RXC 7

    #define FRAMING_ERROR (1<<FE)
    #define PARITY_ERROR (1<<UPE)
    #define DATA_OVERRUN (1<<OVR)
    #define DATA_REGISTER_EMPTY (1<<UDRE)
    #define RX_COMPLETE (1<<RXC)

    // USART Receiver buffer
    #define RX_BUFFER_SIZE 8
    unsigned char rx_buffer[RX_BUFFER_SIZE];

    #if RX_BUFFER_SIZE<256
    unsigned char rx_wr_index,rx_rd_index,rx_counter;
    #else
    unsigned int rx_wr_index,rx_rd_index,rx_counter;
    #endif

    // This flag is set on USART Receiver buffer overflow
    bit rx_buffer_overflow;

    // USART Receiver interrupt service routine
    interrupt [USART_RXC] void usart_rx_isr(void)
    {
    unsigned char status,data;
    status=UCSRA;
    data=UDR;
    if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
    {
    rx_buffer[rx_wr_index]=data;
    if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
    if (++rx_counter == RX_BUFFER_SIZE)
    {
    rx_counter=0;
    rx_buffer_overflow=1;
    };
    };
    }

    #ifndef _DEBUG_TERMINAL_IO_
    // Get a character from the USART Receiver buffer
    #define _ALTERNATE_GETCHAR_
    #pragma used+
    char getchar(void)
    {
    unsigned char data;
    while (rx_counter==0);
    data=rx_buffer[rx_rd_index];
    if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
    #asm("cli")
    --rx_counter;
    #asm("sei")
    return data;
    }
    #pragma used-
    #endif

    // USART Transmitter buffer
    #define TX_BUFFER_SIZE 8
    unsigned char tx_buffer[TX_BUFFER_SIZE];

    #if TX_BUFFER_SIZE<256
    unsigned char tx_wr_index,tx_rd_index,tx_counter;
    #else
    unsigned int tx_wr_index,tx_rd_index,tx_counter;
    #endif

    // USART Transmitter interrupt service routine
    interrupt [USART_TXC] void usart_tx_isr(void)
    {
    if (tx_counter)
    {
    --tx_counter;
    UDR=tx_buffer[tx_rd_index];
    if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0;
    };
    }

    #ifndef _DEBUG_TERMINAL_IO_
    // Write a character to the USART Transmitter buffer
    #define _ALTERNATE_PUTCHAR_
    #pragma used+
    void putchar(char c)
    {
    while (tx_counter == TX_BUFFER_SIZE);
    #asm("cli")
    if (tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0))
    {
    tx_buffer[tx_wr_index]=c;
    if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;
    ++tx_counter;
    }
    else
    UDR=c;
    #asm("sei")
    }
    #pragma used-
    #endif

    // Standard Input/Output functions
    #include <stdio.h>
    unsigned char temp;

    // Declare your global variables here

    void main(void)
    {
    // Declare your local variables here

    // Input/Output Ports initialization
    // Port A initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTA=0x00;
    DDRA=0x00;

    // Port B initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTB=0x00;
    DDRB=0x00;

    // Port C initialization
    // Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
    // State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
    PORTC=0xFF;
    DDRC=0xFF;

    // Port D initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTD=0x00;
    DDRD=0x00;

    // Timer/Counter 0 initialization
    // Clock source: System Clock
    // Clock value: Timer 0 Stopped
    // Mode: Normal top=FFh
    // OC0 output: Disconnected
    TCCR0=0x00;
    TCNT0=0x00;
    OCR0=0x00;

    // Timer/Counter 1 initialization
    // Clock source: System Clock
    // Clock value: Timer 1 Stopped
    // Mode: Normal top=FFFFh
    // OC1A output: Discon.
    // OC1B output: Discon.
    // Noise Canceler: Off
    // Input Capture on Falling Edge
    // Timer 1 Overflow Interrupt: Off
    // Input Capture Interrupt: Off
    // Compare A Match Interrupt: Off
    // Compare B Match Interrupt: Off
    TCCR1A=0x00;
    TCCR1B=0x00;
    TCNT1H=0x00;
    TCNT1L=0x00;
    ICR1H=0x00;
    ICR1L=0x00;
    OCR1AH=0x00;
    OCR1AL=0x00;
    OCR1BH=0x00;
    OCR1BL=0x00;

    // Timer/Counter 2 initialization
    // Clock source: System Clock
    // Clock value: Timer 2 Stopped
    // Mode: Normal top=FFh
    // OC2 output: Disconnected
    ASSR=0x00;
    TCCR2=0x00;
    TCNT2=0x00;
    OCR2=0x00;

    // External Interrupt(s) initialization
    // INT0: Off
    // INT1: Off
    // INT2: Off
    MCUCR=0x00;
    MCUCSR=0x00;

    // Timer(s)/Counter(s) Interrupt(s) initialization
    TIMSK=0x00;

    // USART initialization
    // Communication Parameters: 8 Data, 1 Stop, No Parity
    // USART Receiver: On
    // USART Transmitter: On
    // USART Mode: Asynchronous
    // USART Baud rate: 9600
    UCSRA=0x00;
    UCSRB=0xD8;
    UCSRC=0x86;
    UBRRH=0x01;
    UBRRL=0x03;

    // Analog Comparator initialization
    // Analog Comparator: Off
    // Analog Comparator Input Capture by Timer/Counter 1: Off
    ACSR=0x80;
    SFIOR=0x00;

    // Global enable interrupts
    #asm("sei")

    while (1)
    {
    if (rx_counter>0)
    temp=getchar();
    PORTC=temp;
    putchar(temp);
    // Place your code here

    };
    }
    bạn xem thử lại khi bạn truyền xuống AVR thì AVR nhận về mã gì? theo mình thì nhận về ASCII nên đèn của bạn sáng theo mã ASCII. Bạn xem kỹ lại thử xem.

    Comment


    • #3
      ko có cái mạch thì bó hand!

      Comment


      • #4
        bạn có sơ đồ của mach này khong cho minh vơi mình cũng đang bắt đầu nghiên cứu về avr thôi xin chân thành cảm ơn. Chúc mọi người mọt ngày vui vẻ.Thankyou!

        Comment


        • #5
          bạn tiger2007 ơi cho mình xin sơ đồ nguyên lý của mach này.Bạn có thể gửi cho mình theo địa chỉ "ngocthach241088@yahoo.com" mình chân thành cảm ơn

          Comment


          • #6
            mình cũng thể truyền xuống sai bét mà chẳng biết sai ở chỗ nào hihixxxx

            Comment


            • #7
              Bạn coi fusebit đúng tần số thạch anh chưa, đặt tốc độ baud của AVR và máy tính giống nhau chưa, nếu dùng thạch anh 1,2,4,8,12MHz thì chỉ nên dùng tốc độ baud= 4800 thôi, khi nào dùng đúng thạch anh 11.0592MHz thì mới có thể sử dụng tốc độ baud>4800 được
              Hướng dẫn cụ thể cho AVR tại đây :
              Hãy nhấn vào nút "Cảm ơn" để em biết rằng em đã giúp được một ai đó.

              Comment


              • #8
                Nguyên văn bởi phuc_07 Xem bài viết
                Bạn coi fusebit đúng tần số thạch anh chưa, đặt tốc độ baud của AVR và máy tính giống nhau chưa, nếu dùng thạch anh 1,2,4,8,12MHz thì chỉ nên dùng tốc độ baud= 4800 thôi, khi nào dùng đúng thạch anh 11.0592MHz thì mới có thể sử dụng tốc độ baud>4800 được
                Ko nhất thiết phải dùng thạch anh 11.0592Mhz, dùng các thạch anh khác cũng truyền nhận với Baud>4800 được, mặc dù có sai số, các bạn có thể xem trong CodeVision sai số đó, nói chung là ko ảnh hưởng lắm.

                Còn việc truyền nhận tín hiệu có sai thì bạn nên xem kĩ lại thử xem là truyền tín hiệu xuống là dạng mã Hex hay ASCII, cái này check bằng Led cũng đc mà. Ko thì thử = cách gửi kí tự xuống rồi VDK gửi trả lại máy tính. Mới làm truyền nhận bạn nên check cái này trước, sau này có kn rồi thì đỡ hơn.

                Với code của bạn, mình khuyên bạn thử mô phỏng trên Proteus xem, có lỗi giống thế ko, vì có thể có trường hợp bạn viết code đúng nhưng mạch của bạn có lỗi nào đó thì việc truyền nhận cũng ko chính xác được, lúc đó lại phải dò lỗi, khổ lắm

                Comment


                • #9
                  mình cho baud la 2400 thi truyền xuống ổn rồi nhưng mình dùng cái lệnh Text1.Text= Asc(MSComm1.Input) thì VB cứ nói sai và bào lỗi Dbug hoài là sao vậy bác nhỉ. mà cái e cần hơn là truyền từ VĐK lên máy tình chứ ko phải từ máy xuống AVR.

                  Comment


                  • #10
                    Nguyên văn bởi huyplc1 Xem bài viết
                    mình cho baud la 2400 thi truyền xuống ổn rồi nhưng mình dùng cái lệnh Text1.Text= Asc(MSComm1.Input) thì VB cứ nói sai và bào lỗi Dbug hoài là sao vậy bác nhỉ. mà cái e cần hơn là truyền từ VĐK lên máy tình chứ ko phải từ máy xuống AVR.
                    Truyền từ VDK lên bạn dùng lệnh gì? Nếu dùng CodeVision thì có mấy lệnh:
                    puts(string) hoặc printf(string) là kiểu gửi chuỗi ký tự lên. Mấy lệnh nào bạn tham khảo trong Help. Còn nếu dùng WinAVR thì cũng tương tự thôi.

                    Nhận trên PC thì chỉ cần câu lệnh: Text1.Text = MSComm1.Input là đc với kiểu nhận là String.

                    Có 1 điều mình muốn hỏi bạn truyền nhận là dạng COM thực hay COM ảo. Vì mình đã từng thử dạng COM ảo và nhận thấy VB6 nhận COM ảo ko đc chính xác cho lắm, hoặc có thể cách truyền nhận COM ảo với chuỗi ký tự truyền về mình xử lý chưa chính xác.

                    Comment


                    • #11
                      kí tự bạn truyền từ PC xuống là kiểu char. như vậy bạn phải trừ đi 48 (bảng mã ASCII) thì sẽ đúng :
                      PORTC=temp-48;

                      Comment

                      Về tác giả

                      Collapse

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

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

                      Collapse

                      Đang tải...
                      X