Atmega和ARM UART连接。奇怪的行为

时间:2011-06-11 12:10:48

标签: arm avr uart

所以,这是一个复杂的问题而且与AVR无关,但我认为这个问题出现在Atmega。

  • 我有基于ARM NUC745的FOSCAM WI-FI摄像头,它符合uClinux的要求。该摄像机上有UART端口,与我的Atmega板连接。同时ARM板上的UART用于控制台输出和输入。

  • 我可以通过摄像头提供的Web界面发送命令,这些命令通过UART通过ARM板传到Atmega板。

  • 我为Atmega编写了一个程序,用于读取ARM发送给UART的数据。所有数据似乎都是由Atmega收到的。关于收到的数据,Atmega通过UART将Atmega的数据发送到ARM板。在VMLAB中,我可以看到数据在示波器中出现。但ARM板不接收该数据。当我从ARM板断开Atmega板并从我的iMac将ARM板连接到终端时,Atmega发送的所有数据都快速出现在终端中,我为ARM板写的程序接收到所有数据。

这是非常奇怪的行为。似乎终端连接和Atmega串口连接不同,我无法理解为什么:((

很抱歉我无法正确格式化代码

以下是Atmega的代码

/*
 * main.c
 *
 *  Created on: 25.05.2011
 *      Author: moldov
 */

#include <avr/io.h>              // Most basic include files
#include <avr/interrupt.h>       // Add the necessary ones here

//flash char string_1[]="Prog Start";
//const char left[] PROGMEM ="no support\0x0ALLno support\0x0D\0x0A";


char command_indicator;

#define TXB8 0
#define RXB8 1
#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)


//TCCR1A
#define WGM11 1
#define WGM10 0
#define COM1A1 7
#define COM1A0 6
#define COM1B1 5
#define COM1B0 4
//TCCR1B
#define WGM13 4
#define WGM12 3
#define CS0 0
#define CS1 1
#define CS2 2


void USART_Transmit( unsigned char data );
void USART_Init( unsigned int baud );
unsigned char USART_Receive( void );

ISR(USART_RXC_vect) {
    char status, data;
    status=UCSRA;
    data=UDR;

    if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) {

    if (command_indicator == '$') {
            switch (data ) {
            case 'C':
                PORTB |= 0x03;
                PORTD |= 0x30;
                USART_Transmit('C');
            break;

            case 'V':
                PORTB &= ~0x03;
                PORTD &= ~0x30;
                USART_Transmit('V');
            break;

            case 'Z':
                PORTB |= (1 << 3);
                USART_Transmit('Z');
            break;

            case 'X':
                PORTB &= ~(1 << 3);
                USART_Transmit('X');
            break;

            case 'F':
                PORTB |= (1 << 0);
                PORTB |= (1 << 1);
                USART_Transmit('F');
               USART_Transmit(13);
            USART_Transmit(10);

            break;

            case 'B':
                PORTB &= ~(1 << 0);
                PORTB &= ~(1 << 1);
                USART_Transmit('B');
            break;


            case 'L':
                USART_Transmit('L');
            break;

            case 'R':
                USART_Transmit('R');
            break;

            case '0':
                USART_Transmit('0');
                OCR1AL = 0x00; // 0x00FF это число 256
                OCR1BL = 0x00; // 0x00FF это число 256
            break;

            case '1':
                USART_Transmit('1');
                OCR1AL = 0x0F; // 0x00FF это число 256
                OCR1BL = 0x0F; // 0x00FF это число 256
            break;

            case '2':
                USART_Transmit('2');
                OCR1AL = 0x3F; // 0x00FF это число 256
                OCR1BL = 0x3F; // 0x00FF это число 256
            break;

            case '3':
                USART_Transmit('3');
                OCR1AL = 0x6F; // 0x00FF это число 256
                OCR1BL = 0x6F; // 0x00FF это число 256
            break;

            case '4':
                USART_Transmit('4');
                OCR1AL = 0x9F; // 0x00FF это число 256
                OCR1BL = 0x9F; // 0x00FF это число 256
            break;

            case  '5':
                USART_Transmit('5');
                OCR1AL = 0xCF; // 0x00FF это число 256
                OCR1BL = 0xCF; // 0x00FF это число 256
            break;
            }
            command_indicator = 0x00;


        }
        if(data =='$') {//If we send command "$" shows that
        command_indicator = '$';
            //PORTB &= ~(1 << 3);
        }
    }

}
void USART_Transmit( unsigned char data ) {
    /* Wait for empty transmit buffer */
    while ( !( UCSRA & (1<<UDRE)) ); /* Put data into buffer, sends the data */
    UDR = data;
}
void USART_Init( unsigned int baud ) {
    /* Set baud rate */
    UBRRH = (unsigned char)(baud>>8);
    UBRRL = (unsigned char)baud;

    /* Enable receiver and transmitter */
    UCSRB = (1<<RXEN)|(1<<TXEN);
    UCSRC = (1<<URSEL)|(0<<USBS)|(3<<UCSZ0);  // Set frame format: 8data, 1stop bit
    UCSRB |= (1 << RXCIE); // Enable the USART Recieve Complete interrupt (USART_RXC)
    sei();// Enable the Global Interrupt Enable flag so that interrupts can be processed
}
unsigned char USART_Receive( void ) {
    /* Wait for data to be received */
    while ( !(UCSRA & (1<<RXC)) ); /* Get and return received data from buffer */
    return UDR;
}
// ***********************************************************
// Main program
//
int main(void) {

    //DDRD=0xFF;
    DDRD = 0x30; //4-5-й пин порта D настроим как выход
    DDRB = 0xFF; //
    // Настройка TIMER1 для генерации ШИМ


    TCCR1A = 0x00; //stop Timer

    TCNT1H = 0xFF; // 11111111
    TCNT1L = 0x00; // 00000000

    /* регистр OCR1A состоит из двух 8-ми битных регистров OCR1AH и OCR1AL запись в них нужно проводить в указанной последовательности! */
    OCR1AH = 0x00;
    OCR1AL = 0x00;
    OCR1BH = 0x00;
    OCR1BL = 0x00;
    ICR1H  = 0x00;
    ICR1L  = 0x00;

    //Got from OR Project
    TCCR1A = 0xA1;
    TCCR1B = 0x0A;

    //Скорость USART 115200 при кварцевом генераторе 7.3MHz USART_Init (0x03);
    USART_Init (0x03);
    USART_Transmit('O');//Передаем при включении
    USART_Transmit('k');//сообщение "Ok!", что свидетельствует
    USART_Transmit('!');//о правильно работе программы
    USART_Transmit(0x0d);//переход в начало строки
    USART_Transmit(0x0a);//переход на новую строку
    while(1) {}             // Infinite loop; define here the

} 

ARM linux的代码

#include <fcntl.h>      /* open() and O_XXX flags */
//#include <stdio.h>
#include <unistd.h>
//#include <sys/stat.h> /* S_IXXX flags */
//#include <unistd.h>   /* close() */

int main (int argc, char ** argv){
    const char * name = "/home/kiss.txt";

        int mode = 0777;
    int flags = O_WRONLY | O_CREAT | O_EXCL;
    int fd = open (name , flags, mode);
    printf ("File descriptor is: %d", fd);
        int tty_fd = open ("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY );
    if (tty_fd == -1) {
        perror ("open_port:Unable to open /dev/ttyS0 - ");
    }
    else {
        unsigned char c='D';

        fcntl (tty_fd, F_SETFL,0);

        while (1) {
            if (read(tty_fd,&c,1)>0)        {
                write(STDOUT_FILENO,&c,1);
                write(fd,&c,1);

            }              // if new data is available on the serial port, print it out
            if (read(STDIN_FILENO,&c,1)>0)  {
                write(tty_fd,&c,1);
                write(fd,&c,1);
            }
        }

        close (tty_fd);
    }

    close (fd);
}

有人可以帮助我吗

2 个答案:

答案 0 :(得分:0)

听起来像是一个硬件流量控制问题。 CTS不是由Atemga设定的,类似的东西。

RGDS, 马丁

答案 1 :(得分:0)

如果每块电路板上的VCC之间存在很大差异,则可能需要电平转换器。