Реклама ⓘ
Главная » Микроконтроллеры
Призовой фонд
на апрель 2024 г.
1. 100 руб.
От пользователей

Реклама ⓘ

Управляющая программа высокого уровня

Текст главного модуля управляющей программы высокого уровня на языке Delphi приведен ниже.

В начале своей работы программа пытается последовательно открыть первые четыре COM-порта компьютера. Через каждый порт, дескриптор которого удалось получить, устройству посылается запрос на передачу строки подтверждения “ATmega8”. Если строка была получена, то программа продолжает свое продолжение. В противном случае приложение закрывается.

Основная программа

Когда связь успешно установлена, появляется окно основной формы, вид которой изображен выше. Пользователю доступно два действия: стирание и программирование FLAS-памяти. В последнем случае данные из HEX-файла переносятся в буфер для записи и по страницам передаются в микроконтроллер. После завершения записи производится верификация памяти программ. При этом данные считываются из устройства в буфер для чтения. Результатом удачной операции программирования будет являться равенство содержимого обоих буферов.

Размер файла не должен превышать 4096–128=3968 слов, иначе во время записи произойдет повреждение загрузчика. По этой же причине стиранию подлежат только первые 124 из 128 страниц памяти программ. Перед записью HEX-файла ведется проверки диапазона адресов и контрольной суммы каждой из строк. Файл должен быть 8-ричным файлом формата Intel Hex и, кроме этого, не должен содержать команд смещения адресов. Присутствие, например строки :020000020100FB (смещение начального адреса записи на 0x0100 б) приведет к ошибки.

unit MainUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, ComCtrls, ExtCtrls, AppEvnts, CheckLst;

type
 TMainForm = class(TForm)
  PbProgressBar: TProgressBar;
  LbInfo: TLabel;
  CbLowFuse: TCheckListBox;
  CbHighFuse: TCheckListBox;
  CbLockBits: TCheckListBox;
  BtFilePath: TButton;
  EdFilePath: TEdit;
  BtProgramFlash: TBitBtn;
  BtEraseFlash: TBitBtn;
  DlOpenDialog: TOpenDialog;
  function  StrToHex(const Sim: char): byte;
  function  CheckHexFile: boolean;
  function  PrepareFlashBuffer: boolean;
  function  ProgramFlash: boolean;
  procedure ReadFuseBits;
  function  ReadFlash: boolean;
  function  EraseFlash: boolean;
  procedure OnFormCreate(Sender: TObject);
  procedure OnFormDestroy(Sender: TObject);
  procedure BtFilePathClick(Sender: TObject);
  procedure BtProgramFlashClick(Sender: TObject);
  procedure BtEraseFlashClick(Sender: TObject);
end;

var
  MainForm: TMainForm;
  PortHandle: THandle; //дескриптор COM-порта
  FlashWriteBuffer: array of word;//массивы данных для записи во FLASH-памяти
  FlashReadBuffer: array of word;//массивы прочитанных из FLASH-памяти данных

const
FLASH_SIZE = 4096;//число слов FLASH-памяти программ (4096 слова для ATmega8)
PAGE_SIZE = 32;//число слов в странице (32 слова для ATmega8)

implementation

{$R *.dfm}

//  Функция открытия COM-порта. В качестве параметра принимает номер порта 
//ComNumber в интервале 0…9. В случае удачного завершения возвращает 0.
function OpenPort(const ComNumber: cardinal): boolean;
var ComName:string;
begin
 ComName:=Format('\\.\COM%-d',[ComNumber]);
//  API-функция CreateFile производит открытие COM-порта по имени, в режиме
//чтения/записи. Установка флага FILE_FLAG_OVERLAPPED позволяет использовать
//асинхронные операции чтения/записи. При удачном завершении функция
//возвращает дескриптор устройства; в случае ошибки - INVALID_HANDLE_VALUE.
 PortHandle:=CreateFile(PChar(ComName),GENERIC_READ or GENERIC_WRITE,0,
    nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED,0);
 Result:=PortHandle<>INVALID_HANDLE_VALUE;
end;

//  Процедура закрытия COM-порта. 
procedure ClosePort;
begin
//  API-функция CloseHandle закрывает дескриптор, полученный вызовом
//CreateFile.
 CloseHandle(PortHandle);
end;

//  Процедура задания настроек COM-порта. В качестве параметров принимает:
//скорость обмена BaudRate, тип контроля четность Parity, количество стоп-бит
//StopBits и разрядность данных ByteSize.
//  Скорость обмена BaudRate в бит/с задается одной из констант: 
//CBR_110  =    110, CBR_300   =   300, CBR_600   =   600, CBR_1200  =  1200,
//CBR_2400 =   2400, CBR_4800  =  4800, CBR_4800  =  9600, CBR_4800  = 14400,
//CBR_19200 = 19200, CBR_19200 = 19200, CBR_38400 = 38400, CBR_56000 = 56000,
//CBR_57600 = 57600, CBR_115200 = 115200.
//  Контроль четности Parity задается одной из констант:
//NOPARITY    = 0 – контроль четности отсутствует(бит четности отсутствует),  
//ODDPARITY   = 1 – проверка на нечетность(бит четности дополняет сумму 
//                                единиц в слове данных до нечетного числа),    
//EVENPARITY  = 2 – проверка на четность(бит четности дополняет сумму
//                                  единиц в слове данных до четного числа),
//MARKPARITY  = 3 – проверка бита четности на 1,
//SPACEPARITY = 4 – проверка бита четности на 0.
//  Количество стоп-бит StopBits задается одной из констант:
//ONESTOPBIT    = 0 – 1 стоп-бит,
//ONE5STOPBITS  = 1 – 1.5 стоп-бит,
//TWOSTOPBITS   = 2 – 2 стоп-бит(только для 6…8-битовых данных).
//  Разрядность данных ByteSize может быть 5…8 бит.
procedure SetComProperty (const BaudRate,Parity,StopBits,ByteSize: cardinal);
var DCB:TDCB;
begin
//  Основные настройки COM-порта содержит структура DCB.   
 FillChar(DCB,SizeOf(DCB),0);
 DCB.DCBLength:=SizeOf(DCB);
 DCB.Flags:=1;
 DCB.BaudRate:=BaudRate;
 DCB.Parity:=Parity;
 DCB.StopBits:=StopBits;
 DCB.ByteSize:=ByteSize;
//  API-функция SetCommState переписывает структуру DCB порта.
 SetCommState(PortHandle,DCB);
end;

//  Функция чтения буфера данных из COM-порта. В качестве параметров
//принимает: указатель на буфер памяти Buffer и размер буфера BufSize. В
//случае удачного завершения функция возвращает 0.
function ReadBuffer(var Buffer:Pointer;const BufSize:cardinal): boolean;
var BytesRead:cardinal;
    ReadOL:TOverlapped;
    ReadDone:cardinal;
begin
 FillChar(ReadOL,SizeOf(ReadOL),0);
//  API-функция Функция CreateEvent создает событие ReadOL.hEvent (дескриптор
//события ReadOL.hEvent размещен в структуре асинхронного доступа ReadOL типа
//TOverlapped), которое будет переведено в сигнальное состояние после
//завершения операции асинхронного чтения.
 ReadOL.hEvent:=CreateEvent(nil,true,true,nil);
 try
//  API-функция Функция ReadFile производит чтение данных из COM-порта. В
//случае удачного завершения функция возвращает 0. В данном случае чтение
//происходит в асинхронном режиме. После вызова ReadFile поток не блокируется
//до окончания операции, а продолжает свое выполнение. О завершении операции
//чтения можно судить по состоянию объекта ReadOL.hEvent, который должен
//перейти в сигнальное состояние.
  ReadFile(PortHandle,Buffer^,BufSize,BytesRead,@ReadOL);
//  API-функция Функция WaitForSingleObject ожидает перевода в сигнальное
//состояние объекта синхронизации определенный период времени. В нашем случае
//объектом служит событие ReadOL.hEvent, интервал времени 100 мс. При
//успешном завершении (если объект перешел в сигнальное состояние раньше,
//чем истек период ожидания) функция возвратит код WAIT_OBJECT_0.
 ReadDone:=WaitForSingleObject(ReadOL.hEvent,100);
 finally
  Result:= ReadDone = WAIT_OBJECT_0;
//  API-функция Функция CloseHandle закрывает дескриптор события
//ReadOL.hEvent, полученный с помощью CreateEvent.
  CloseHandle(ReadOL.hEvent);
 end;
end;

//  Функция записи буфера данных в COM-порт. В качестве параметров
//принимает: указатель на буфер памяти Buffer и размер буфера BufSize. В
//случае удачного завершения функция возвращает 0.
function WriteBuffer (var Buffer:Pointer; const BufSize:cardinal): boolean;
var BytesWritten:cardinal;
    WriteOL:TOverlapped;
    WriteDone:cardinal;
begin
 FillChar(WriteOL,SizeOf(WriteOL),0);
//  API-функция Функция CreateEvent создает событие WriteOL.hEvent (дескриптор
//события WriteOL.hEvent размещен в структуре асинхронного доступа WriteOL типа
//TOverlapped), которое будет переведено в сигнальное состояние после
//завершения операции асинхронной записи.
 WriteOL.hEvent:=CreateEvent(nil,true,true,nil);
 try
//  API-функция Функция WriteFile производит запись данных в COM-порт. В
//случае удачного завершения функция возвращает 0. В данном случае запись
//происходит в асинхронном режиме. После вызова WriteFile поток не
//блокируется до окончания операции, а продолжает свое выполнение.
//О завершении операции чтения можно судить по состоянию объекта.
  WriteFile(PortHandle,Buffer^,BufSize,BytesWritten,@WriteOL);
//  API-функция Функция WaitForSingleObject ожидает перевода в сигнальное
//состояние объекта синхронизации определенный период времени. В нашем случае
//объектом служит событие WriteOL.hEvent, интервал времени 100 мс. При
//успешном завершении (если объект перешел в сигнальное состояние раньше,
//чем истек период ожидания) функция возвратит код WAIT_OBJECT_0.
 WriteDone:=WaitForSingleObject(WriteOL.hEvent,100);
 finally
  Result:= WriteDone = WAIT_OBJECT_0;
//  API-функция Функция CloseHandle закрывает дескриптор события
//WriteOL.hEvent, полученный с помощью CreateEvent.
  CloseHandle(WriteOL.hEvent);
 end;
end;

//  Функция чтения байта данных из COM-порта. Возвращает прочитанный байт. 
function ReadByte: byte;
var Ptr:Pointer;
begin
 Ptr:=@Result;
 ReadBuffer(Ptr,1);
end;

//  Процедура записи байта данных в COM-порт. В качестве параметров принимает
//байт данных для записи.
procedure WriteByte(const TX:byte);
var Ptr:Pointer;
begin
 Ptr:=@TX;
 WriteBuffer(Ptr,1);
end;

//  Функция преобразования символов ACSII (“0”…“9”, “A”…“F”) в число. В
//качестве параметров принимает символ, подлежащий преобразованию Sim.
//Возвращает преобразованное число.
function TMainForm.StrToHex(const Sim: char): byte;
begin
 if ((Byte(Sim)>=$30) and (Byte(Sim)<=$39)) then Result:= Byte(Sim)-$30
 else Result:= Byte(Sim)-$37;
end;

//  Функция проверки HEX-файла на ошибки. В случае удачного завершения
//возвращает 0.
function TMainForm.CheckHexFile: boolean;
var F:TStringList;
    Str: string;
    Size,Sum: Byte;
    I,J: integer;
begin
 Result:= false;
 F:= TStringList.Create;
 F.LoadFromFile(EdFilePath.Text);
 Str:= F.Strings[F.Count-1];
//  Если 4 последних символа последней строки отличны от “01FF” (признак
//конца файла), то HEX-файл поврежден.
 if Copy(Str,Length(Str)-3,4)<>'01FF' then begin
  F.Free;
  Exit;
 end;
//  Если в начале хотя бы одной из строк отсутствует символ “:” (признак
//начала строки), то HEX-файл поврежден.
 for I:= 0 to F.Count-1 do begin
  Str:= F.Strings[I];
  if Str[1]<>':' then begin
   F.Free;
   Exit;
  end;
  Size:= 16*StrToHex(Str[2])+StrToHex(Str[3])+4;
  Sum:=0;
//  Если в хотя бы одной из строк не сходится контрольная сумма (сумма всех
//байтов в строке без учета переполнения должна равняться 0), то HEX-файл
//поврежден.
  for J:= 0 to Size do Sum:= Byte(Sum+16*StrToHex(Str[2*J+2])+
   StrToHex(Str[2*J+3]));
  if Sum <> 0 then begin
   F.Free;
   Exit;
  end;
 end;
 F.Free;
 Result:=true;
end;

//  Функция подготовки данных для записи. В случае удачного завершения
//возвращает 0.
function TMainForm.PrepareFlashBuffer: boolean;
var F: TStringList;
    Str: string;
    W,Size,MaxFlashSize,Offset: word;
    I,J,K: integer;
begin
 Result:= false;
 F:=TStringList.Create;
 F.LoadFromFile(EdFilePath.Text);
 Str:=F.Strings[F.Count-2];
 Size:=0;
 for I:=0 to 3 do Size:= 16*Size+StrToHex(Str[4+I]);
 MaxFlashSize:= (Size+16*StrToHex(Str[2])+StrToHex(Str[3])) div 2;
// Если максимальный размер HEX-файла превышает размер доступной памяти
//программ (загрузчик boot-loader размещен в Boot Loader Section размером 128
//слов), то запись не возможна.
 if MaxFlashSize > (FLASH_SIZE-128) then begin
  F.Free;
  Exit;
 end;
//  Выделение под буфер памяти в MaxFlashSize 16-разрядных слов, чистка и
//заполнение его данными из HEX-файла.
 SetLength(FlashWriteBuffer,MaxFlashSize);
 SetLength(FlashReadBuffer,MaxFlashSize);
 for I:=0 to MaxFlashSize-1 do FlashWriteBuffer[I]:= $FFFF;
 for I:=0 to F.Count-2 do begin
  Str:= F.Strings[I];
  if Copy(Str,8,2)<>'00' then Continue;
  Size:= (16*StrToHex(Str[2])+StrToHex(Str[3])) div 2;
  Offset:= 0;
  for J:=0 to 3 do Offset:=16*Offset+StrToHex(Str[4+J]);
  for J:=0 to Size-1 do begin
   W:=0;
   for K:=0 to 3 do W:=16*W+StrToHex(Str[4*J+K+10]);
   FlashWriteBuffer[Offset div 2 +J]:= W;
  end;
 end;
 F.Free;
 Result:= true;
end;

//  Процедура чтения байтов конфигурации и содержимого ячеек защиты.
procedure TMainForm.ReadFuseBits;
var LowFuseBit,HighFuseBit,LockBits: byte;
    I: integer;
begin
//  Передача команды чтения (символ “F”).
 WriteByte(Byte('F'));
//  Чтение младшего байта конфигурации.
 LowFuseBit:=ReadByte;
//  Чтение ячеек защиты.
 LockBits:=ReadByte;
//  Чтение старшего байта конфигурации.
 HighFuseBit:=ReadByte;
 for I:=0 to 7 do CbLowFuse.Checked[I]:=((LowFuseBit shl I) and $80)<>$80;
 for I:=0 to 7 do CbHighFuse.Checked[I]:=((HighFuseBit shl I) and $80)<>$80;
 LockBits:=LockBits shl 2;
 for I:=0 to 3 do CbLockBits.Checked[I]:=((LockBits shl I) and $80)<>$80;
end;

//  Функция программирования FLASH-памяти. В случае удачного завершения
//возвращает 0.
function TMainForm.ProgramFlash: boolean;
var Adress,Data,Page: word;
    I,J: integer;
begin
 Result:= false;
 PbProgressBar.Visible:= true;
 PbProgressBar.Position:=0;
 PbProgressBar.Min:=0;
 PbProgressBar.Max:=Length(FlashWriteBuffer);
 Page:= Length(FlashWriteBuffer) div PAGE_SIZE + 1;
 Adress:=0;
//  Программирование FLASH-памяти из буфера FlashWriteBuffer. Сначала
//передается команда программирования (символ “P”). Затем передаются номер
//страницы и 32 слова для записи.
 for I:=0 to Page-1 do begin
  WriteByte(Byte('P'));
  WriteByte(Byte(Adress and $00FF));
  WriteByte(Byte((Adress and $FF00) shr 8));
  for J:=0 to PAGE_SIZE-1 do begin
   if (PAGE_SIZE*I+J) >= Length(FlashReadBuffer) then Data:= $FFFF else
    Data:= FlashWriteBuffer[PAGE_SIZE*I+J];
   WriteByte(Byte((Data and $FF00) shr 8));
   WriteByte(Byte(Data and $00FF));
//  Небольшая задержка времени и принудительный запуск цикла обработки ообщений.
   Sleep(10);
   Application.ProcessMessages;
  end;
//  Если после завершения операции микроконтроллер не выдал символ
//подтверждения “!”, то произошла ошибка записи.
  if ReadByte <> Byte('!') then begin
   PbProgressBar.Visible:= false;
   Exit;
  end;
  Adress:= Adress + 2*PAGE_SIZE;
  PbProgressBar.Position:= PbProgressBar.Position+PAGE_SIZE;
 end;
 PbProgressBar.Visible:= false;
 Result:= true;
end;

//  Функция верификации данных FLASH-памяти. В случае удачного завершения
//возвращает 0.
function TMainForm.ReadFlash: boolean;
var Adress,Data,Page: word;
    I,J: integer;
begin
 Result:= false;
 PbProgressBar.Visible:= true;
 PbProgressBar.Position:=0;
 PbProgressBar.Min:=0;
 PbProgressBar.Max:=Length(FlashReadBuffer);
 Page:= Length(FlashReadBuffer) div PAGE_SIZE + 1;
 Adress:=0;
//  Считывание FLASH-памяти в буфер FlashReadBuffer. Сначала передается
//команда верификации (символ “R”). Затем передается номер страницы и
//считываются 32 слова.
 for I:=0 to Page-1 do begin
  WriteByte(Byte('R'));
  WriteByte(Byte(Adress and $00FF));
  WriteByte(Byte((Adress and $FF00) shr 8));
  for J:=0 to PAGE_SIZE-1 do begin
   Data:=ReadByte;
   Data:=(Data shl 8)+ReadByte;
   if (PAGE_SIZE*I+J) < Length(FlashReadBuffer) then
    FlashReadBuffer[PAGE_SIZE*I+J]:= Data;
   Application.ProcessMessages;
  end;
//  Если после завершения операции микроконтроллер не выдал символ
//подтверждения “!”, то произошла ошибка чтения.
  if ReadByte <> Byte('!') then begin
   PbProgressBar.Visible:= false;
   Exit;
  end;
  Adress:= Adress + 2*PAGE_SIZE;
  PbProgressBar.Position:= PbProgressBar.Position+PAGE_SIZE;
 end;
 PbProgressBar.Visible:= false;
 Result:= true;
end;


//  Функция стирания данных FLASH-памяти. В случае удачного завершения
//возвращает 0.
function TMainForm.EraseFlash: boolean;
var Adress,Page: word;
    I: integer;
begin
 Result:= false;
 PbProgressBar.Visible:=true;
 PbProgressBar.Position:=0;
 PbProgressBar.Min:=0;
 PbProgressBar.Max:=FLASH_SIZE-128;
 Page:=(FLASH_SIZE-128) div PAGE_SIZE;
 Adress:=0;
//  Стирание FLASH-памяти программ. Сначала передается команда стирания
//(символ “E”). Затем передается номер страницы.
 for I:=0 to Page-1 do begin
  WriteByte(Byte('E'));
  WriteByte(Byte(Adress and $00FF));
  WriteByte(Byte((Adress and $FF00) shr 8));
//  Небольшая задержка времени и принудительный запуск цикла обработки
//сообщений.
  Sleep(10);
  Application.ProcessMessages;
//  Если после завершения операции микроконтроллер не выдал символ
//подтверждения “!”, то произошла ошибка стирания.
  if ReadByte <> Byte('!') then begin
   PbProgressBar.Visible:= false;
   Exit;
  end;
  Adress:= Adress + 2*PAGE_SIZE;
  PbProgressBar.Position:= PbProgressBar.Position+PAGE_SIZE;
 end;
 PbProgressBar.Visible:= false;
 Result:= true;
end;

//  Обработчик события создания формы.
procedure TMainForm.OnFormCreate(Sender: TObject);
var Str: string;
    Found: boolean;
    I: integer;
begin
 Found:= false;
 SetLength(Str,7);
//  Попытка последовательно открыть первые 4 COM-порта.  
 for I:=1 to 4 do begin
  if not OpenPort(I) then Continue;
//  Если порт успешно открыт, то устанавливаем параметры связи (в данном
//случае 115200, 8-N-2).
  SetComProperty(CBR_115200,NOPARITY,TWOSTOPBITS,8);
//  Посылка микроконтроллеру запроса (символ “D”) выдать информацию о
//присутствии на линии.
  WriteByte(Byte('D'));
//  Если не получена строка из семи символов, то устройство не найдено.
  if not ReadBuffer(Pointer(Str),7) then begin
   ClosePort;
   Continue;
  end;
//  Если была получена строка подтверждения “ATmega8”, то устройство найдено
//и можно продолжать дальнейшую работу.
  Found:= Str = 'ATmega8';
  if Found then Break
  else ClosePort;
 end;
//  Если микроконтроллер не обнаружен, то приложение прекращает свою работу.
 if not Found then begin
  ShowMessage('Не удалось связаться с устройством!');
  Application.Terminate;
 end;
 LbInfo.Caption:= 'ATmega8 подключен к ' + Format('COM-%d.',[I]);
 ReadFuseBits;
end;

//  Обработчик события уничтожения формы.
procedure TMainForm.OnFormDestroy(Sender: TObject);
begin
//  Посылка микроконтроллеру команды завершения связи (символ “O”).
 WriteByte(Byte('O'));
 if PortHandle <> INVALID_HANDLE_VALUE then ClosePort;
end;

//  Обработчик нажатия кнопки выбора пути к HEX-файлу.
procedure TMainForm.BtFilePathClick(Sender: TObject);
begin
 DlOpenDialog.Execute;
 EdFilePath.Text:= DlOpenDialog.FileName;
end;

//  Обработчик нажатия кнопки программирования FLASH-памяти.
procedure TMainForm.BtProgramFlashClick(Sender: TObject);
var Str: string;
    I: integer;
Begin
//  Если выбранный файл имеет расширение отличное от HEX, то 
//программирование не возможно. 
 Str:= Copy(EdFilePath.Text,Length(EdFilePath.Text)-3,4);
 if (Str <> '.hex') and (Str <> '.HEX') then begin
  ShowMessage('Файл должен иметь расширение .hex !');
  Exit;
 end;
//  Если путь, указанный к файлу не верный, то программирование не возможно. 
 if not FileExists(EdFilePath.Text) then begin
  ShowMessage('Файл не найден !');
  Exit;
 end;
//  Если в файле содержаться ошибки, то программирование не возможно. 
 if not CheckHexFile then begin
  ShowMessage('Файл поврежден !');
  Exit;
 end;
//  Если при подготовки данных оказалось, что размер HEX-файла превышает
//размер доступной памяти то программирование не возможно.
 if not PrepareFlashBuffer then begin
  ShowMessage('Слишком большой размер файла !');
  Exit;
 end;
 BtProgramFlash.Enabled:= false;
 BtEraseFlash.Enabled:= false;
 LbInfo.Caption:= 'Программирование...';
//  Запись данных из буфера FlashWriteBuffer.
 if not ProgramFlash then begin
  LbInfo.Caption:= 'Ошибка программирования !';
  BtProgramFlash.Enabled:= true;
  BtEraseFlash.Enabled:= true;
  Exit;
 end;
//  Чтение данных в буфер FlashReadBuffer.
 LbInfo.Caption:= 'Программирование... Верификация...';
 if not ReadFlash then begin
  LbInfo.Caption:= 'Ошибка чтения !';
  BtProgramFlash.Enabled:= true;
  BtEraseFlash.Enabled:= true;
  Exit;
 end;
//  Сравнение записанных и считанных данных. 
 for I:= 0 to Length(FlashWriteBuffer)-1 do begin
  if FlashReadBuffer[I] = FlashWriteBuffer[I] then Continue;
  ShowMessage(Format('Ошибка записи по адресу 0x%x : 0x%x вместо 0x%x !',
     [I,FlashReadBuffer[I],FlashWriteBuffer[I]]));
  LbInfo.Caption:= 'Ошибка верификации !';
  BtProgramFlash.Enabled:= true;
  BtEraseFlash.Enabled:= true;
  Exit;
 end;
 LbInfo.Caption:= 'Программирование успешно завершено.';
 BtProgramFlash.Enabled:= true;
 BtEraseFlash.Enabled:= true;
end;

//  Обработчик нажатия кнопки стирания FLASH-памяти.
procedure TMainForm.BtEraseFlashClick(Sender: TObject);
begin
 BtProgramFlash.Enabled:= false;
 BtEraseFlash.Enabled:= false;
 LbInfo.Caption:= 'Стирание...';
 if not EraseFlash then LbInfo.Caption:= 'Ошибка при стирании !' else
  LbInfo.Caption:= 'Стирание успешно завершено.';
 BtProgramFlash.Enabled:= true;
 BtEraseFlash.Enabled:= true;
end;

end. 

Скачать исходник проекта

Перейти к следующей части:

Теги:

Котов Игорь Юрьевич Опубликована: 2012 г. 0 0
Я собрал 0 0
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 0 Проголосовало: 0 чел.

Комментарии (0) | Я собрал (0) | Подписаться

Статью еще никто не комментировал. Вы можете стать первым.
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется сила тока?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

Pickit 2 - USB-программатор PIC-микроконтроллеров
Pickit 2 - USB-программатор PIC-микроконтроллеров
Квадрокоптер Syma X11 Набор начинающего радиолюбителя
вверх