Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Настройка USART1 в AT91SAM9261
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
ZAA
Добрый день!
Использую отладочную плату AT91SAM9261-EK. Ядро linux-2.6.30 с наложенными патчами. Необходимо настроить USART1 на режим RS485 и затем производить опрос датчиков по протоколу modbusRTU.
Как я понимаю, в ядре существует драйвер последовательного порта. Но по умолчанию настраивается только DBGU.
В файле linux/arch/arm/mach-at91/board-sam9261ek.c в функции ek_init_map_io
Код
static void __init ek_map_io(void)
{
    /* Initialize processor: 18.432 MHz crystal */
    at91sam9261_initialize(18432000);

    /* Setup the LEDs */
    at91_init_leds(AT91_PIN_PA13, AT91_PIN_PA14);

    /* DGBU on ttyS0. (Rx & Tx only) */
    at91_register_uart(0, 0, 0);

    /* set serial console to ttyS0 (ie, DBGU) */
    at91_set_serial_console(0);
}

я добавляю строку
Код
at91_register_uart(AT91SAM9261_ID_US1, 1, 0);

ТАкже в файле linux/drivers/char/atmel_serial.c в функции atmel_set_mctrl и atmel_set_termios меняю строки:
Код
if (port->irq == 7) // USART1 is a rs485
{
     mode |= ATMEL_US_USMODE_RS485;
}
else
{
     mode |= ATMEL_US_CHMODE_NORMAL;
}


Таким образом, после загрузки ядра в каталоге /dev кроме ttyS0(которое отвечает за DBGU) появляется файл ttyS1, который, как я понимаю, отвечает за USART1??? Или я неправильно понимаю???
Значит ли это, что я могу, как в обычном случае, открывать порт в своей программе, читать и писать в него??
Код
//********************************************************************************
*****
//input : Mbc_port - string with the device to open (/dev/ttyS0, /dev/ttyS1,...);
//        Mbc_speed - speed (baudrate)
//        Mbc_parity - 0=don't use parity, 1=use parity EVEN, -1 use parity ODD
//        Mbc_bit_l - number of data bits : 7 or 8 USE EVERY TIME 8 DATA BITS
//        Mbc_bit_s - number of stop bits : 1 or 2
//answer; device descriptor
//********************************************************************************
****/
int Mb_open_device(char Mbc_port[20], int Mbc_speed, int Mbc_parity, int Mbc_bit_l, int Mbc_bit_s)
{
  int fd;

  fd = open(Mbc_port, O_RDWR | O_NOCTTY | O_NDELAY);
  if (fd < 0)
  {
    perror("Open device failure\n");
    exit(-1);
  }
  else
  {
      fcntl(fd, F_SETFL, 0);
  }

  tcgetattr(fd, &saved_tty_parameters);

  switch (Mbc_speed)
  {
      case 2400:
        cfsetispeed(&Mb_tio, B2400);
        cfsetospeed(&Mb_tio, B2400);
        break;

      case 4800:
        cfsetispeed(&Mb_tio, B4800);
        cfsetospeed(&Mb_tio, B4800);
        break;

      case 9600:
        cfsetispeed(&Mb_tio, B9600);
        cfsetospeed(&Mb_tio, B9600);
        break;

      case 19200:
        cfsetispeed(&Mb_tio, B19200);
        cfsetospeed(&Mb_tio, B19200);
        break;

      case 38400:
        cfsetispeed(&Mb_tio, B38400);
        cfsetospeed(&Mb_tio, B38400);
        break;

      case 57600:
        cfsetispeed(&Mb_tio, B57600);
        cfsetospeed(&Mb_tio, B57600);
        break;

      case 115200:
        cfsetispeed(&Mb_tio, B115200);
        cfsetospeed(&Mb_tio, B115200);
        break;
  }

  Mb_tio.c_cflag |= (CLOCAL | CREAD);

  tcsetattr(fd, TCSANOW, &Mb_tio);

  Mb_tio.c_cflag &= ~PARENB;
  Mb_tio.c_cflag &= ~CSIZE;
  Mb_tio.c_cflag |= CS8;
  Mb_tio.c_cflag |= CSTOPB;

  Mb_tio.c_lflag |= ICANON;

  Mb_tio.c_iflag &= ~(IXON | IXOFF | IXANY);

  return fd;
}

int main (int argc, char **argv)
{
    int fd;
    char buf[10];
    int result, result1, i;

    fd = Mb_open_device("/dev/ttyS1", 9600, 0, 8, 1);
    if (fd < 0)
    {
        printf("Failed to open device\n");
        return 1;
    }

    result = read (fd, buf, 2);
    if (result == -1)
    {
         printf("failed to read to the port\n");
         return 1;
     }

    result1 = write (fd, "ABCD", 5);
    if (result1 == -1)
    {
        printf("failed to write to the port\n");
        return 1;
    }
}

Пожалуйста, подскажите, в правильном ли направлении я движусь, и, если возможно, укажите ссылку на какой-нить настроечный пример. unsure.gif
ZAA
У себя же нашла ошибку. В файле board-sam9261.c вместо
Код
at91_register_uart(AT91SAM9261_ID_US1, 1, 0);

Нужно
Код
at91_register_uart(AT91SAM9261_ID_US1, 1, UART_RTS); (название последнего параметра точно не помню, но он отвечает за линию RTS и нулю не равен, как было у меня сначала)

Теперь после записи в порт на комп приходят байты данных (пользуюсь cutecom'ом), НО они неверные - если посылаю 0 1 2 3 4 ...31 , на комп приходит e0 e1 e2 e3 e4...ff. Начиная с 32 последовательность повторяется и так далее...Скорость, четность, биты и стопбиты проверяла уже много раз. В чем может быть ошибка?
aaarrr
Цитата(ZAA @ Jan 20 2010, 21:05) *
Скорость, четность, биты и стопбиты проверяла уже много раз. В чем может быть ошибка?

Проверьте длину слова еще раз, уж очень это похоже на пятибитную передачу. Скорость, четность и стоп-биты явно ни при чем, если картинка действительно такая четкая, как в вашем описании.

Стоп. Так это RS485? Тогда проверьте формирование сигнала разрешения на передатчик, не укорочен ли он.
ZAA
Цитата(aaarrr @ Jan 20 2010, 21:19) *
Проверьте длину слова еще раз, уж очень это похоже на пятибитную передачу. Скорость, четность и стоп-биты явно ни при чем, если картинка действительно такая четкая, как в вашем описании.

Спасибо, попробую))
aaarrr
Проверьте еще формирование сигнала разрешения на передатчик, не укорочен ли он. Я как-то не обратил сразу внимание, что это RS485.
ZAA
Цитата(aaarrr @ Jan 20 2010, 21:24) *
Проверьте еще формирование сигнала разрешения на передатчик, не укорочен ли он. Я как-то не обратил сразу внимание, что это RS485.

Нашла ошибку. ДЕйствительно, дело было в длине слова.
При настройке порта почему-то (невнимательность или глупость всему виной biggrin.gif ) функция tcsetattr(fd, TCSANOW, &Mb_tio); вызывалась до установки длины слова, четности и стопбитов. Поэтому изменения входных параметров никак реально не влияли на параметры порта (вставила printk в текст драйвера - там все время при настройке попадали в 5-битный режим)
Неправильно:
Код
tcsetattr(fd, TCSANOW, &Mb_tio);
Mb_tio.c_cflag &= ~PARENB;
Mb_tio.c_cflag &= ~CSIZE;
Mb_tio.c_cflag |= CS8;
Mb_tio.c_cflag |= CSTOPB;

Правильно
Код
Mb_tio.c_cflag &= ~PARENB;
Mb_tio.c_cflag &= ~CSTOPB;
Mb_tio.c_cflag &= ~CSIZE;
switch (Mbc_bit_l)
{
      case 5:
      Mb_tio.c_cflag |= CS5;
      break;

      case 6:
      Mb_tio.c_cflag |= CS6;
      break;

      case 7:
      Mb_tio.c_cflag |= CS7;
      break;

      case 8:
      Mb_tio.c_cflag |= CS8;
      break;
  }
switch (Mbc_bit_s)
{
      case 1:
      break;

      case 2:
      Mb_tio.c_cflag |= CSTOPB;
      break;
}
tcsetattr(fd, TCSANOW, &Mb_tio);

Все заработало! Спасибо большое, aaarrr))
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.