Интернет-магазин

Просмотр корзины
В корзине:

товаров - 0 шт.



§ 41. USART. Пример практической реализации.

Киселев Роман, Июнь 2007
Статья обновлена 26 Мая 2014

Файлы к статье скачать


В этой статье попробуем собрать простое устройство на МК, которое будет принимать байт информации через COM-порт и немедленно выводить его на семисегментном индикаторе, а также отправлять подтверждение о доставке обратно в компьютер.


Если Вы читали предыдущую статью (надеюсь на это), то, наверное, заметили, что рабочие напряжения в COM-порту +12 В и -12 В, а МК оперирует напряжениями +5 В и 0 В. Для того, чтобы все работало нормально, нужно установить преобразователь уровней. Рекомендую ставить MAX232. Потребуются, помимо микросхемы, 5 конденсаторов на 1 мкФ.

При работе с COM-портом именно эта микросхема находит наиболее частое применение. Если Вы купили макетную плату с разводкой под СОМ-порт, то там, скорее всего, будет и готовая разводка под установку MAX232 и конденсаторов. Правда, когда я купил свою плату, то сначала припаял МК и цепь питания, потом СОМ-порт. Долго не мог понять, как крепить преобразователь уровня. И тут вдруг выяснилось, что все компоненты я припаял не с той стороны к плате :-). Но не переделывать же все! Поэтому я прицепил СОМ-порт и МАХ232 к "правильной" стороне, а остальное оставил на "неправильной".

У меня в схеме задействованы выводы 11 (T1in) и 12 (R1out). Соответственно, вывод 13 (R1in) подключен к 3-му выводу розетки СОМ-порта (RXD), а 14-й вывод МАХ-232 (T1out) подсоединен ко 2-му выводу розетки СОМ-порта (TXD).

Теперь нужно МАХ232 подсоединить к МК. У ATMEGA16 USART использует 14-й вывод PB0 (RXD) для приема данных и PB1 (TXD) для отправки. Соответственно, PB0 нужно прикрепить к 12-му выводу МАХ232, а PB1 к 11-му. Ну и все. Не забудьте только соединить "земли" МК, МАХ232 и СОМ-порта между собой! :-)

Остается лишь написать программу для МК (для ПК тоже можно). В данном примере реализована работа с кварцем 11,0592 МГц, битрейт 115,2 кбит/с, 8 информационных бит, нет бита четности, 1 стоп-бит, скорость удвоенная. С большим, чем 115,2 кбит/с битрейтом мой компьютер работает с глюками.

Ниже приведен код программы для МК.

#include "iom16.h"
#define a 1
#define b 4
#define c 16
#define d 64  // Это для индикатора
#define e 128
#define f 2
#define g 8
#define DP 32

unsigned char      Dig[10];
// В этих переменных хранятся цифры, которые нужно отобразить
char               Disp5, Disp6, Disp7;

// Функция выделяет цифры из трехзначного числа Number
void Display (unsigned char Number)
{
  unsigned char Num1, Num2, Num3;
  Num1=Num2=0;
  while (Number >= 100)  
  {
    Number -= 100;  
    Num1++;  
  }
  while (Number >= 10) 
  {
    Number -= 10;  
    Num2++; 
  }
  Num3 = Number;
  Disp5 = Dig[Num1];
  Disp6 = Dig[Num2];
  Disp7 = Dig[Num3];
}

void USART_init()
{
  UCSRA = (1 << 1); // Установка двойной скорости
  UCSRB |= (1 << 7) | (1 << 4) | (1 << 3); // Прерывание по приему данных, включены приемник и передатчик
  UCSRC |= (1 << 7); // Запись в UCSRC
  UCSRC |= (1 << 1) | (1 << 2); // Размер кадра данных 8 бит
  UCSRC -= 128; // Запись в UBRRH
  UBRRH = 0;
  UBRRL = 11; // Битрейт равет 115200 бит в секунду
}

void Dig_init()
{
  Dig[0] = (a+b+c+d+e+f);
  Dig[1] = (b+c);
  Dig[2] = (a+b+g+e+d);
  Dig[3] = (a+b+g+c+d);
  Dig[4] = (f+g+b+c);
  Dig[5] = (a+f+g+c+d);
  Dig[6] = (a+f+g+c+d+e);
  Dig[7] = (a+b+c);
  Dig[8] = (a+b+c+d+e+f+g);
  Dig[9] = (a+b+c+d+f+g);
}

void io_init() // Инициализация портов ввода/вывода
{
  DDRA = 0xFF;
  PORTA = 0;
  DDRC |= (1 << PINC5) | (1 << PINC6) |(1 << PINC7);
  PORTC = 0;
  DDRB = 1;
}

void main()
{
  unsigned char j, k = 0;
  USART_init();
  Dig_init();
  Display(0);
  SREG |= (1 << 7);
  io_init();
  while(1) // Отображение принятого байта
  {
    for (j = 0; j <= 50; j++){} // Задержка для отображения цифры
    (k == 3) ? k = 0 : k++;
    PORTC &= 31;  //Очистка PC7, PC6, PC5
    for (j = 0; j<=30; j++){} // Задержка для выключения транзистора
    switch (k)
    {
      case 0: PORTC |= (1 << PINC7); // Единицы
              PORTA = Disp7;
        break;
      case 1: PORTC |= (1 << PINC6); // Десятки
              PORTA = Disp6;
        break;
      case 2: PORTC |= (1 << PINC5); // Сотни
              PORTA = Disp5;
    }  
  }
}

#pragma vector = USART_RXC_vect
__interrupt void Recieve()
{
  unsigned char temp = 0;
  unsigned char* str = " Hello! My name is AtMega16! "; // Строка данных
  char t,l;
  temp = UDR; // Чтение принятых данных
  Display (temp); // Отображение числа на индикаторе
  PORTB = 1 - PORTB; // Зажигаем/гасим светодиод на PB0
  if (temp == 5) // Отправка строки, если принятый байт равен 5
  {
    for (t=0; t < 28; t++)
    {
      UDR = str[t]; // Отправка строки
      for (l=0; l < 200; l++) // Задержка (чтобы успел отправить число)
      { }
    }
  }
  else
  UDR = temp; // Отправка обратно принятого числа
}

Теперь нужно позаботиться о программе в компьютере, которая будет управлять СОМ-портом и работать с МК. Можно просто взять готовую программу из статей о СОМ-порте компьютера, основанную на библиотеке SerialGate.dll. Скачать данный софт как и программу Termonal.exe (о ней далее) можно в файлах к данной статье.

Запускаем программу, подключаем наше устройство к СОМ-порту, подаем питание на него, в программе выбираем СОМ-порт и устанавливаем битрейт 115200 бит/с. Давайте отправим какой-нибудь символ, например, "&". МК отправит его обратно и отобразит на индикаторе его номер - 38. Отправив строку, получаем ее обратно. Заметьте, что при нечетном количестве символов меняется состояние светодиода, подключенного к PB0. При каждом прерывании он загорается либо гаснет.


Теперь давайте рассмотрим другую программу из этого архива - Terminal.exe. Не знаю, кто ее автор, но ему СПАСИБО!

Это очень мощная и удобная программа, позволяющая делать с СОМ-портом практически все, что угодно. Запустив программу, выберите номер порта, битрейт 115200, 8 битов данных, четность "none", 1 стоп бит. Нажимаем Connect и можем теперь отправлять данные МК. Символы передаются так же, как и в предыдущей программе, в виде их ASCII - значений, но если набрать "#xxx", где ххх-трехзначное число до 255, то можно передать любой символ, в т.ч. и непечатный. Если МК получает символ с номером 5, то он вместо него обратно отсылает строку " Hello! My name is AtMega16! ". 13-й символ - это переход на след. строчку. Кстати, ASCII таблица в программе тоже есть.



© Киселев Роман
Июнь 2007
http://www.kernelchip.ru



© KERNELCHIP 2006 - 2017