printf(
" Введите имя файла: " ); 
                                      gets(
fname ); 
                                      fsize
= CHIPSIZE; 
                                      if
(load_data( fname, pgmdata, &fsize )) { 
                                                if
(!verify( &control, pgmdata, fsize )) { 
                                                          puts(
"\nНажмите Enter для продолжения..." ); 
                                                          gets(
pch ); 
                                                } 
                                      }
else { 
                                                _clearscreen(
_GCLEARSCREEN ); 
                             puts( "
Ошибка открытия или чтения входного файла данных." ); 
                                                puts(
"\nНажмите Enter для продолжения..." ); 
                                                gets(
pch ); 
                                      } 
                                      break; 
                             case 'h':       //
запись содержимого чипа в файл 
                                      printf(
" Введите имя файла: " ); 
                                      gets(
fname ); 
                                      xread(
&control, pgmdata, CHIPSIZE ); 
                                      if
(!save_data( fname, pgmdata, CHIPSIZE )) { 
                                                _clearscreen(
_GCLEARSCREEN ); 
                             puts("Ошибка
открытия или чтения выходного файла данных."); 
                                                puts(
"\Нажмите Enter для продолжения..." ); 
                                                gets(
pch ); 
                                      } 
                                      break; 
                             case 'i':        //
проверка: пустой чип или нет 
                                      _clearscreen(
_GCLEARSCREEN );   
                                       if
(blank( &control )) 
                                                puts(
"Устройство чистое" ); 
                                      else 
                                                puts(
" Устройство не чистое " ); 
                                      puts(
"\nНажмите Enter для продолжения..." ); 
                                      gets(
pch ); 
                                      break; 
                             case 'j':        //
чтение байтов сигнатуры 
                                      _clearscreen(
_GCLEARSCREEN ); 
                                      signature(
&control ); 
                                      puts(
"\nНажмите Enter для продолжения..." ); 
                                      gets(
pch ); 
                                      break; 
                             case 'l':        //
запись Lock Bit 1 
                                      lock(
&control, 1 ); 
                                      break; 
                             case 'n':       //
запись Lock Bit 2 
                                      lock(
&control, 2 ); 
                                      break; 
                             case 'x':       //
выход из программы 
                             default: 
                                      _clearscreen(
_GCLEARSCREEN ); 
                                      tend();                             //
выключаем таймер 
                                      enable_traps();                 
                                      exit(
0 ); 
                   } 
          } 
} 
 
//        Чтение данных из введенного
файла в указанный массив. Если  
//        файл меньше чем указанное
количество байт, читаем полный файл 
//        и изменяем количество байт,
чтобы отразить меньший размер файла. 
//        Сталкиваясь с концом файла
раньше, чем удовлетворено количество 
//        байт – не ошибка. Если файл
больше чем указанное количество байт 
//        читаем только указанное
количество байт. 
 
 
BOOLEAN load_data( fname, store, sptr ) 
char fname[]; 
BYTE store[]; 
int *sptr; 
{ 
          FILE *fptr; 
          int nbytes; 
 
          if ((fptr = fopen( fname,
"rb" )) == NULL) 
                   return( FALSE );             //
не удается открыть файл 
          nbytes = fread( store, 1,
*sptr, fptr ); 
          if (ferror( fptr )) 
                   return( FALSE );             //
не удается прочитать файл 
          if (feof( fptr ))                           //
проверка на конец файла 
                   *sptr = nbytes;                         //
уменьшаем количество байт 
          fclose( fptr ); 
          return( TRUE ); 
} 
 
 
//        Запись данных из указанного
массива в обозначенный файл. 
//        Возвращает булево значение,
обозначающее успех или неудачу. 
 
BOOLEAN save_data( fname, store, bcount ) 
char fname[]; 
BYTE store[]; 
int bcount; 
{ 
          FILE *fptr; 
 
          if ((fptr = fopen( fname,
"wb" )) == NULL) 
                   return( FALSE );             //
не удается открыть файл 
          if (fwrite( store, 1, bcount,
fptr ) != bcount) 
                   return( FALSE );             //
не удается записать в файл 
          fclose( fptr ); 
          return( TRUE ); 
} 
 
 
//        Полная очистка памяти
предложенная перед программированием. 
 
void erase( cptr ) 
BYTE *cptr; 
{ 
          reset( cptr );                              //
сброс по умолчанию 
          set_function( CHIP_ERASE );           //
выбор функции 
          enable_address( cptr );                       //
разрешение func, PROG* 
          delay( (BIGINT)(10 * TCVT) );                   //
задержка 10мкс 
          enable_RST( cptr );                            //
RST=12v 
          delay( (BIGINT)(15000 * TCVT)
);    // задержка 15 мс фронт RST ->PROG* 
          pulse( cptr, 10000 );                           //
применение 10 мс импульса PROG* 
          delay( (BIGINT)(10 * TCVT) );                   //
задержка PROG*->adr/data 
          reset( cptr );                              //
сброс по умолчанию 
          delay( (BIGINT)(15000 * TCVT)
);    // задержка 15 мс для спада RST 
} 
 
 
//        Программируем чип содержанием
указанного массива данных. 
//        Указанное количество байт может
быть меньше чем количество  
//        байт в массиве или чипе.
Программирование всегда начинается с  
//        нулевого адреса. 
 
void program( cptr, data, count ) 
BYTE *cptr, data[]; 
int count; 
{ 
          WORD addr; 
 
          reset( cptr );                              //
сброс по умолчанию 
          pulse_RST( cptr, 10 );                        //
сброс счетчика адресов 
          set_function( WRITE_DATA );                   //
выбор функции 
          enable_address( cptr );                       //
разрешение function, PROG* 
          enable_data( cptr );                             //
разрешение шины перед записью 
          delay( (BIGINT)(10 * TCVT) );                   //
задержка function->RST 
          enable_RST( cptr );                            //
RST=12v 
          delay( (BIGINT)(15000 * TCVT)
);    // задержка 15 мс фронт RST ->PROG* 
 
          for (addr=0; addr<count;
addr++) { 
                   set_data( data[addr]
);               // применение data 
                   delay( (BIGINT)(10 *
TCVT) );          // задержка data->PROG* 
                   pulse( cptr, 100 );            //
применение 100 мкс импульса PROG* 
                   delay( (BIGINT)(1500 *
TCVT) );      // задержка 1.5 мс для записи 
                   pulse_XTAL1( cptr, 10
);          // увеличиваем счетчик адресов 
          } 
 
          reset( cptr );                              //
сброс по умолчанию 
          delay( (BIGINT)(15000 * TCVT)
);    // задержка 15 мс для спада RST  
}                                                                                                                        
 
//        Чтение содержимого чипа в
указанный массив данных 
//        Указанное
количество байт может быть меньше чем количество  
//        байтов в чипе. Чтение всегда
начинается с нулевого адреса. 
 
void xread( cptr, data, count ) 
BYTE *cptr, data[]; 
int count; 
{ 
          BYTE tmp; 
          WORD addr; 
 
          reset( cptr );                              //
сброс по умолчанию 
          pulse_RST( cptr, 10 );                        //
сброс счетчика адресов 
          set_function( READ_DATA );            //
выбор функции 
          enable_address( cptr );                       //
разрешение function, PROG* 
 
          for (addr=0; addr<count;
addr++) { 
                   delay( (BIGINT)(10 *
TCVT) );          // задержка address->data 
                   data[addr] =
get_data(); 
                   pulse_XTAL1( cptr, 10
);          // увеличиваем счетчик адресов 
          } 
 
          reset( cptr );                              //
сброс по умолчанию 
} 
 
//        Сравнение содержания чипа с
указанным массивом данных. 
//        Указанное количество байт может
быть меньше количества 
//        байт в чипе. Сравнение всегда
начинается с нулевого адреса.  
//        Различия отображаются адресом
несовпадающих значений и  
//        два байта: один – из памяти
микроконтроллера, другой – тем,  
//        что ожидали. Возвращенное
булево значение показывает  
//        было ли успешным сравнение. 
 
BOOLEAN verify( cptr, data, count ) 
BYTE *cptr, data[]; 
int count; 
{ 
          BYTE tmp; 
          BOOLEAN flag=TRUE; 
          WORD addr; 
 
          reset( cptr );                              //
сброс по умолчанию 
          pulse_RST( cptr, 10 );                        //
сброс счетчика адресов 
          set_function( READ_DATA );            //
выбор функции 
          enable_address( cptr );                       //
разрешение function, PROG* 
 
          for (addr=0; addr<count;
addr++) { 
                   delay( (BIGINT)(10 *
TCVT) );          // задержка address->data 
                   if ((tmp = get_data())
!= data[addr]) { 
                             if (flag) {               
 
                                      _clearscreen(
_GCLEARSCREEN );   
                             } 
              printf("Несовпадение в
%.4X  is %.2X sb %.2X\n", addr, tmp, data[addr] ); 
                             flag =
FALSE; 
                   } 
                   pulse_XTAL1( cptr, 10
);          // увеличиваем счетчик адресов 
          } 
 
          reset( cptr );                              //
сброс по умолчанию 
          return( flag ); 
} 
 
 
//        Определяем, стерт ли чип.
Расположение отказов не определяется. 
//        Возвращенное булево значение
указывает чистый чип или нет. 
 
 
BOOLEAN blank( cptr ) 
BYTE *cptr; 
{ 
          BYTE tmp; 
          BOOLEAN flag = TRUE;                            //
значение по умолчанию – чистый 
          WORD addr; 
 
          reset( cptr );                              //
сброс по умолчанию 
          pulse_RST( cptr, 10 );                        //
сброс счетчика адресов 
          set_function( READ_DATA );            //
выбор функции 
          enable_address( cptr );                       //
разрешаем function, PROG* 
 
          for (addr=0; addr<CHIPSIZE;
addr++) { 
                   delay( (BIGINT)(10 *
TCVT) );          // задержка address->data 
                   if (get_data() !=
0xff)                // сравнение со стертым значением 
                             flag =
FALSE;                // не чистый 
                   pulse_XTAL1( cptr, 10
);          // увеличиваем счетчик адресов 
          } 
 
          reset( cptr );                              //
сброс по умолчанию 
          return( flag ); 
} 
 
 
//        Читаем байты сигнатуры. 
//        Первый байт в нулевом адресе,
второй в первом. Когда установлены в 
//        1Еh и 11h соответственно они
идентифицируют АТ89С1051 контроллер. 
//        Третий байт во втором адресе
указывает программирование 12 вольтами, 
//        когда установлен в FFh. 
 
void signature( cptr ) 
BYTE *cptr; 
{ 
          BYTE tmp1, tmp2, tmp3; 
 
          reset( cptr );                              //
сброс по умолчанию 
          pulse_RST( cptr, 10 );                        //
сброс счетчика адресов 
          set_function( READ_SIGNATURE );          //
выбор функции 
          enable_address( cptr );                       //
разрешаем func, PROG* 
          delay( (BIGINT)(10 * TCVT) );                   //
задержка address->data 
          tmp1 = get_data();                    //
чтение первого байта 
 
          pulse_XTAL1( cptr, 10 );                   //
увеличиваем счетчик адресов 
          delay( (BIGINT)(10 * TCVT) );                   //
задержка address->data 
          tmp2 = get_data();                    //
чтение второго байта 
 
          pulse_XTAL1( cptr, 10 );                   //
увеличиваем счетчик адресов 
          delay( (BIGINT)(10 * TCVT) );                   //
задержка address->data 
          tmp3 = get_data();                    //
чтение третьего байта 
 
          printf( "signature byte
1:  %.2X\n", tmp1 ); 
          printf( "signature byte
2:  %.2X\n", tmp2 ); 
          printf( "signature byte
3:  %.2X\n", tmp3 ); 
          reset( cptr );                              //
сброс по умолчанию 
} 
 
 
//        Запись указанных Lock Bits. 
 
void lock( cptr, lbit ) 
BYTE *cptr; 
int lbit; 
{ 
          reset( cptr );                              //
сброс по умолчанию 
 
          switch (lbit) {                                     //
выбор функции 
                   case 1: 
                             set_function(
WRITE_LOCK_1 ); 
                             break; 
                   case 2: 
                             set_function(
WRITE_LOCK_2 ); 
                             break; 
          } 
 
          enable_address( cptr );                       //
разрешение function, PROG* 
          enable_RST( cptr );                            //
RST=12В 
          delay( (BIGINT)(15000 * TCVT)
);    // задержка 15 мс фронт RST ->PROG* 
          pulse( cptr, 100 );                     //
применение 100 мкс импульса PROG* 
          delay( (BIGINT)(10 * TCVT) );                   //
задержка PROG*->adr/data 
          reset( cptr );                              //
сброс по умолчанию 
          delay( (BIGINT)(15000 * TCVT)
);    // задержка 15 мс для спада RST 
} 
 
//        Возвращение программатора в
пассивное состояние. 
 
void reset( cptr ) 
BYTE *cptr; 
{ 
          outp( pdata, 0 );              //
установка данных 
 
          outp( pctrl, 0x08 );          //
выбираем control latch 
          outp( pctrl, 0x09 );          //
latch data 
          outp( pctrl, 0x08 ); 
 
          outp( pctrl, 0x0c );          //
выбираем нижний адрес latch 
          outp( pctrl, 0x0d );          //
latch data 
          outp( pctrl, 0x0c ); 
 
          outp( pctrl, 0x00 );          //
выбираем верхний адрес latch 
          outp( pctrl, 0x01 );          //
latch data 
          outp( pctrl, 0x00 ); 
 
          outp( pdata, 0xff );          //
установка данных 
 
          outp( pctrl, 0x04 );          //
выбираем data latch 
          outp( pctrl, 0x05 );          //
latch data 
 
          outp( pctrl, 0x04 );          //
сигналы управления неактивны 
          outp( pdata, 0 );              //
очистка данных 
 
          *cptr = 0;                        //
запись значения control latch 
} 
 
//        Подпрограмма выбора функции. 
//        Записывается только 3 младших
значащих бита 
 
void set_function( func ) 
BYTE func; 
 
 
//        Запись указанного значения в
программатор. 
 
void set_data( outdata ) 
BYTE outdata; 
{ 
          outp( pdata, outdata );               //
установка выходных данных 
 
          outp( pctrl, 0x04 );          //
выбор data latch 
          outp( pctrl, 0x05 );          //
latch data 
          outp( pctrl, 0x04 ); 
 
//        outp( pctrl, 0x04 );          //
сигналы управления неактивны 
          outp( pdata, 0 );              //
очистка данных 
} 
 
 
//        Данные возврата подают на линии
данных программатора. 
//        Сначала нельзя запретить latch
выходных данных программатора.  
//        Некоторые платы параллельного интерфейса
позволяют заблокировать  
//        буфер выходных данных
устанавливая 5-й бит в регистре управления. 
 
BYTE get_data( void ) 
{ 
          BYTE tmp; 
 
          outp( pdata, 0xff );       //
установка данных LPT порта в высокое состояние 
          outp( pctrl, 0x24 );          //
запрещение передачи данных LPT порта 
          outp( pctrl, 0x26 );          //
разрешение чтения буфера данных 
 
          delay( (BIGINT)(10 * TCVT) );          //
задержка 10 мкс 
          tmp = inp( pdata );          //
получение данных 
 
          outp( pctrl, 0x04 );          //
сигналы управления неактивны 
          outp( pdata, 0 );              //
очистка данных 
 
          return( tmp ); 
} 
 
 
//        Разрешение выводов
программатора: address and function latches. 
//        PROG* (P3.2) также разрешен. 
 
void enable_address( cptr ) 
BYTE *cptr; 
 
 
//        Запрещение выводов
программатора: address and function latches. 
//        PROG* (P3.2) также запрещен. 
 
void disable_address( cptr ) 
BYTE *cptr; 
{ 
          outp( pdata, (*cptr &=
~0x10) );         // установка данных 
 
          outp( pctrl, 0x08 );          //
выбор control latch 
          outp( pctrl, 0x09 );          //
latch data 
          outp( pctrl, 0x08 ); 
 
          outp( pctrl, 0x04 );          //
сигналы управления неактивны 
          outp( pdata, 0 );              //
очистка данных 
} 
 
 
//        Разрешение вывода данных
программатора. 
 
void enable_data( cptr ) 
BYTE *cptr; 
 
 
//        Запрещение вывода данных
программатора. 
 
void disable_data( cptr ) 
BYTE *cptr; 
{ 
          outp( pdata, (*cptr &= ~0x20)
);         // set up data 
 
          outp( pctrl, 0x08 );          //
выбор control latch 
          outp( pctrl, 0x09 );          //
latch data 
          outp( pctrl, 0x08 ); 
 
          outp( pctrl, 0x04 );          //
сигналы управления неактивны 
          outp( pdata, 0 );              //
очистка данных 
} 
 
 
//        Разрешение 12 вольт на RST. 
//        Обратите
внимание, что RST не сможет мгновенно достигнуть  
//        указанного
значения. 
 
void enable_RST( cptr ) 
BYTE *cptr; 
сигналы управления неактивны 
 
 
//        Возвращение RST к 5 вольтам. 
//        Обратите
внимание, что RST не сможет мгновенно достигнуть  
//        указанного
значения. 
 
 
void disable_RST( cptr ) 
BYTE *cptr; 
{ 
          outp( pdata, (*cptr &=
~0x80) );         // установка данных 
 
          outp( pctrl, 0x08 );          //
выбор control latch 
          outp( pctrl, 0x09 );          //
latch data 
          outp( pctrl, 0x08 ); 
 
          outp( pctrl, 0x04 );          //
сигналы управления неактивны 
          outp( pdata, 0 );              //
очистка данных 
} 
 
 
//        Генерируем низко идущий импульс
на RST указанной продолжительности. //          Время должно быть определено в
микросекундах. 
 
void pulse_RST( cptr, time ) 
BYTE *cptr; 
int time; 
 
 
//        Генерируем высоко идущий
импульс на XTAL1 указанной 
//        продолжительности. Время должно
быть определено в микросекундах. 
 
void pulse_XTAL1( cptr, time ) 
BYTE *cptr; 
int time; 
          outp( pctrl, 0x08 ); 
 
//        Генерируем низко идущий импульс
на PROG* указанной 
//        продолжительности. Время должно
быть определено в микросекундах. 
 
void pulse( cptr, time ) 
BYTE *cptr; 
int time; 
 
 
//        Задержка на указанную
продолжительность. Каждый тик равен  
//        1/1193180 секунды (0,838мкс) 
 
void delay( xcount ) 
BIGINT xcount; 
{ 
          BIGINT count0; 
 
//        printf( "Счет таймера=
%lu\n", xcount ); 
 
          tread();                            //
чтение счета таймера 
          count0 = tcount;              //
установка начального значения 
          do                                  //
повторение пока дельта >= указанного значения 
                   tread();                  //
чтение значения таймера 
          while (tcount - count0 <
xcount); 
} 
 
7. Моделирование схемы в системе
автоматизированного проектирования OrCAD 
 
 
Для проведения моделирования части схемы использовался САПР OrCAD
версии 9.2. Моделировался ключ на транзисторе КТ815А. Так как в библиотеки
OrCAD-а не содержат отечественных элементов, то для моделирования был взят
аналогичный западный транзистор. На рисунке 4.1 изображена схема электрическая
принципиальная, подготовленная в схемном редакторе OrCAD Capture.
Рис 7.1. Схема
электрическая принципиальная 
Все элементы схемы были выбраны командой
Place/Part. Для симуляции сигналов нужно создать правило с помощью команды
Pspice/New Simulation Profile, далее настроив его можно приступать к симуляции
процесса. Также нужно поставить маркеры напряжения, тока в том месте в котором
хотелось бы видеть процесс. В данном случае на базу транзистора должен подаваться
логический сигнал с микроконтроллера, который мы создали в редакторе сигналов
Stimulus Editor. Для перехода в него нужно выделить элемент DigStim, нажать на
правую кнопку и выбрать Edit Pspice Stimulus. При 
 
 
выполнении этого действия мы переходим в Stimulus Editor в
котором создаем логический сигнал, например как показано на рисунке 4.1
 
 
Рис 7.2. Главное окно
Stimulus Editor`а с сигналам sig
Рис 7.3. Главное окно
Pspice A/D 
 
Создав этот сигнал можно переходить к симуляции нашего процесса, при
нажатии Pspice/Run мы переходим в Pspice A/D (рис 4.3) 
В
данном окне видно изменение напряжения в том месте нашей схемы в которой мы
поставили маркер. Для общей видимости зависимости сигнала на коллекторе
транзистора от сигнала с микроконтроллера можно вывести сигнал последнего,
нажатием на Trace/Add Trace… мы увидим цифровой сигнал который попадает на базу
транзистора. 
 
Выводы. 
В работе рассмотрено создание
программатора микроконтроллеров Atmel серии АТ89 с
подключением к LPT-порту компьютера. Была разработана электрическая
схема, печатная плата и сборочный чертеж, показывающие, что программатор
микроконтроллеров Atmel серии АТ89 может быть
спроектирован и после изготовлен на элементной базе,
выпускаемой предприятиями СНГ.  
Требования технического задания выполнены
полностью. 
Все выполненные
расчеты подтверждают работоспособность конструкции и позволяют сделать вывод об
успешном ее функционировании при воздействии на нее допустимых климатических и
механических воздействий. 
Графическая часть и
приведенные в настоящем проекте результаты расчетов подтверждают, что задание
на курсовое проектирование выполнено в полном объеме. 
Литература. 
1.           
Голубков А.
Программатор МК Atmel серии АТ89. – Радио, 2003, №9,
с. 24 – 25. 
2.           
Рюмик С. 
“Параллельный” программатор для АТ89. – Радио, 2004, №2, с. 28 – 31. 
3.           
Мактас М. Я.
Восемь уроков по P-CAD - М.: солон-Пресс, 2003.-224с.:ил. 
4.           
AT89 Series
Programmer Interface <http://www.atmel.com/dyn/resources/
prod_documents/APCPGM.EXE >. 
5.           
Ханке Х.-И.,
Фабиан Х. Технология производства радиоэлектронной аппаратуры: Пер. с нем./ Под
ред. В. Н. Черняева. – М.: Энергия. 1980. – 464 с., ил. 
6.           
Ванін В. В., Бліок А. В.,
Гнітецька Г. О. Оформлення конструкторської документації. Навчальний посібник.
– К.: “Каравела”, 2003. – 160 с. 
7.           
Партала О.
Н.  Радиокомпоненты и материалы: Справочник. – К.: Радіоаматор, М.: КУбК-а, 1998. – 720с.:
ил. 
 
ГОСТ 23751-86. Платы
печатные. Основные параметры и размеры. 
 
 
     
Страницы: 1, 2, 3, 4, 5, 6 
   
 |