roboforum.ru

Технический форум по робототехнике.

Софтовая часть программатора для atmega16

Программирование микроконтроллеров AVR, PIC, ARM.
Разработка и изготовление печатных плат для модулей.

Софтовая часть программатора для atmega16

Сообщение zi4rox » 19 апр 2008, 10:51

Всем привет,

Скажу сразу - делаю курсовик, поэтому выбор лпт порта и "изобретание велосипеда" - самому не особо нравиться, но теперь уже разбираюсь и пытаюсь с этим бороться.

Задача: Программа, написанная на одном из языков высокого уровня для ПК, которая осуществляет запись скомпилированной программы с использованием одного из стандартных портов (LPT) в микроконтроллер (ATMEGA16). Записанная программа должна быть представлена в HEX коде.
* программатор стк200

Ситуация на данный момент следующая:

1. Задача по прежнему - написать софтину, которая прошивает амегу16
2. Научился управлять ЛПТ, т.е 1-0 подавать могу на какой либо из ног

Локальная задача, которую необходимо решить:
Пытаяюсь эмулировать SPI интерфейс - но никак не получается, помогите разобраться плиз.

Алогритм входа в режим программирования (из даташита):
1. Подать питание, при этом RESЕT и SCK должны быть 0.
2. Подождать как минимум 20 мс затем включить режим SPI Serial Programming
[послать 4 байта на MOSI]:
Byte1: 1010 1100
Byte2: 0101 0011
Byte3: xxxx xxxx // не важно что посылается
Byte4: xxxx xxxx // не важно что посылается
3. Проверить вошел ли контроллер в режим программирования.(Проверить синхронизацию). Когда режим синхронизации установлен, то 2ой байт ответит назад $53 запрашивая при этом 3ий байт. Не зависимо от того был ли правильно получен ответ или нет - нужно обязательно передать все 4 байта. Если этого не произошло, то задать 1 на RESET и повторить заново.

Вот, т.е хорошей проверкой того правильно я сделал или нет - будет то что при посылке 3его байта я получу в ответ $53. Но увы, пока этого не происходит, с чем и прошу помочь разобраться.

Прошу посмотрите как делаю в коде, возможно логика не та у меня и делаю не правильно:
{
Решился писать в Дельфях, потому что удобную либо под лпт нашел, если у кого то неприязнь к паскалю - заранее сорри. Комментарии к коду справа, после //
Значение функций MOSI; SCK; RESET; VCC; - при вызове они инвертируют то что было на этой ноге перед вызовом. Т.е Если на ноге MOSI было 0 после вызова станет 1. и наоборот.
MISO - читает 1 или 0 с ноги.
}

Да и ещё, - по даташиту: Запись в контроллер происходит по фронту, а чтение из мк по спаду. Т.е если я правильно понял, чтобы мк считал 1 например - я сначала её выставляю, а потом подаю положительный импульс на SCK.

Код: Выделить всёРазвернуть
  Lpt.WritePort(GetCurrentPort,LPT_DATA_REG,0); // SCK = 0 MOSI = 0 RESET = 0 VCC = 0. Везде нули
  VCC; // VCC = 1
  Delay(40); // ждем 40мс с запасом

  SCK; // SCK = 1 MOSI = 0
  SCK; // SCK = 0
  SCK; // SCK = 1 MOSI = 0
  SCK; // SCK = 0
  MOSI;
  SCK; // SCK = 1 MOSI = 1
  SCK; // SCK = 0
  SCK; // SCK = 1 MOSI = 1
  SCK; // SCK = 0
  MOSI;
  SCK; // SCK = 1 MOSI = 0
  SCK; // SCK = 0
  MOSI;
  SCK; // SCK = 1 MOSI = 1
  SCK; // SCK = 0
  MOSI;
  SCK; // SCK = 1 MOSI = 0
  SCK; // SCK = 0
  MOSI;
  SCK; // SCK = 1 MOSI = 1
  SCK; // SCK = 0


  SCK; // SCK = 1 MOSI = 1
  SCK; // SCK = 0
  SCK; // SCK = 1 MOSI = 1
  SCK; // SCK = 0
  MOSI;
  SCK; // SCK = 1 MOSI = 0
  SCK; // SCK = 0
  SCK; // SCK = 1 MOSI = 0
  SCK; // SCK = 0
  MOSI;
  SCK; // SCK = 1 MOSI = 1
  SCK; // SCK = 0
  MOSI;
  SCK; // SCK = 1 MOSI = 0
  SCK; // SCK = 0
  MOSI;
  SCK; // SCK = 1 MOSI = 1
  SCK; // SCK = 0
  MOSI;
  SCK; // SCK = 1 MOSI = 0
  SCK; // SCK = 0


  SCK; // SCK = 1 MOSI = 0
  SCK; // SCK = 0
  Memo1.Lines.Add(MISO); // читаю что на ноге MISO
  SCK; // SCK = 1 MOSI = 0
  SCK; // SCK = 0
  Memo1.Lines.Add(MISO); // читаю что на ноге MISO
  SCK; // SCK = 1 MOSI = 0
  SCK; // SCK = 0
  Memo1.Lines.Add(MISO); // читаю что на ноге MISO
  SCK; // SCK = 1 MOSI = 0
  SCK; // SCK = 0
  Memo1.Lines.Add(MISO); // читаю что на ноге MISO
  SCK; // SCK = 1 MOSI = 0
  SCK; // SCK = 0
  Memo1.Lines.Add(MISO); // читаю что на ноге MISO
  SCK; // SCK = 1 MOSI = 0
  SCK; // SCK = 0
  Memo1.Lines.Add(MISO); // читаю что на ноге MISO
  SCK; // SCK = 1 MOSI = 0
  SCK; // SCK = 0
  Memo1.Lines.Add(MISO); // читаю что на ноге MISO
  SCK; // SCK = 1 MOSI = 0
  SCK; // SCK = 0
  Memo1.Lines.Add(MISO); // читаю что на ноге MISO


  SCK; // SCK = 1 MOSI = 0
  SCK; // SCK = 0
  SCK; // SCK = 1 MOSI = 0
  SCK; // SCK = 0
  SCK; // SCK = 1 MOSI = 0
  SCK; // SCK = 0
  SCK; // SCK = 1 MOSI = 0
  SCK; // SCK = 0
  SCK; // SCK = 1 MOSI = 0
  SCK; // SCK = 0
  SCK; // SCK = 1 MOSI = 0
  SCK; // SCK = 0
  SCK; // SCK = 1 MOSI = 0
  SCK; // SCK = 0
  SCK; // SCK = 1 MOSI = 0
  SCK; // SCK = 0



В результате байт синхронизации не приходит, значение на MISO - постоянно 1.

Прошу проглядеть плиз, и пнуть меня в нужном направлении плиз. Также если у кого нибудь есть какие нароботки или исходники которые могут помочь по сабжу - буду мега благодарен.
zi4rox
 
Сообщения: 5
Зарегистрирован: 19 апр 2008, 10:43

Re: Софтовая часть программатора для atmega16

Сообщение Master » 19 апр 2008, 11:54

Фигасе, такую задачу сходу не решишь, вначале научись управлять ЛПТ портом, в это тебе поможет поиск по сайту и сайт Валерия Ковтуна.
Аватара пользователя
Master
 
Сообщения: 4468
Зарегистрирован: 21 дек 2006, 19:56
Откуда: Украина, г.Одесса
прог. языки: Delphi и С

Re: Софтовая часть программатора для atmega16

Сообщение zi4rox » 19 апр 2008, 12:00

Master писал(а):Фигасе, такую задачу сходу не решишь, вначале научись управлять ЛПТ портом, в это тебе поможет поиск по сайту и сайт Валерия Ковтуна.


ЛПТ управлять научился, как раз сайт Валерия и был учебным полигоном. Проблема с эмуляцией SPI - не могу разобраться что к чему. (Код корявый привел конечно, но побитно чтобы разобраться что после чего должно идти)
zi4rox
 
Сообщения: 5
Зарегистрирован: 19 апр 2008, 10:43

Re: Софтовая часть программатора для atmega16

Сообщение Master » 19 апр 2008, 12:23

Проблема с эмуляцией SPI

Не совсем понятна эта фраза, эмулирют в эмуляторе, в Протеусе, например, или в VMlab, а в чем ты эмулируешь?

Добавлено спустя 2 минуты 4 секунды:
Может байты в MISO нужно слать с небольшой задержкой?
Delay(1); или как там в делфи.
Аватара пользователя
Master
 
Сообщения: 4468
Зарегистрирован: 21 дек 2006, 19:56
Откуда: Украина, г.Одесса
прог. языки: Delphi и С

Re: Софтовая часть программатора для atmega16

Сообщение zi4rox » 19 апр 2008, 12:30

Master писал(а):Не совсем понятна эта фраза, эмулирют в эмуляторе, в Протеусе, например, или в VMlab, а в чем ты эмулируешь?


не так выразился сорри ) Имелось ввиду, что есть некоторый алгоритм для программирования по SPI (я выше описал в 1ом посте) вот по нему и пробую пройтись.

Master писал(а):Может байты в MISO нужно слать с небольшой задержкой?
Delay(1); или как там в делфи.


Ога, спс. Попробую задержку небольшую воткнуть, хотя сомнительно имхо )
zi4rox
 
Сообщения: 5
Зарегистрирован: 19 апр 2008, 10:43

Re: Софтовая часть программатора для atmega16

Сообщение zi4rox » 19 апр 2008, 23:48

Переписал все в процедуру. Стало заменто легче. Поигрался с задержками импульсов, временем чтения выхода (MISO) - резульатат по прежнему один: в контроллер байты передаются от контроллера отклика не получаю. (Проверял это дело этой софтиной - xlpt - в мк байты идут, отклика нет)

Привожу ниже листинг того, что в коде творится теперь:

В глобальных переменных имеем 2 массива на входные и выходные 4 байта инструкций
Код: Выделить всёРазвернуть
var
  spi_cmd: array [1..4] of byte;
  spi_out: array [1..4] of byte;


Процедура SPISend(spi_cmd); - которой в качестве параметра дается массив с 4мя байтами инструкции.
Посылает побитно на MOSI начиная с младшего бита. Также на каждый тактовый импульс считывает выход с мк (MISO) обрабатывает и в spi_out[] получаем 4 байта ответа (хотя поидее нужен только 1 - сделал на все)

Код: Выделить всёРазвернуть
procedure TForm1.SPISend (spi_cmd : array of byte);
var
  cnt_byte, cnt_bit, pin: byte;
  temp_in, temp_out: string;
begin
  for cnt_byte:=1 to 4 do begin
    temp_in:= IntToBin(spi_cmd[cnt_byte],8);
    temp_out:= '';

    for cnt_bit:=8 downto 1 do begin
      if SCK_HIGH then SCK;

      if MOSI_HIGH then
        pin:= 1 else
        pin:= 0;

      if StrToInt(temp_in[cnt_bit]) <> pin then
        MOSI;

      SCK;  // 1, фронт импульса

      {Delay(10); // Длительность импульса}

      If MISO_HIGH then
        temp_out:= temp_out+'1' else
        temp_out:= temp_out+'0';

      SCK;  // 0, спад импульса
    end;

    spi_out[cnt_byte]:= BinToInt(temp_out);

  end;

end;


Небольшое пояснение:

Код: Выделить всёРазвернуть
MISO_HIGH : boolean; // Возвращает true если на входе 1
MOSI_HIGH : boolean; // Возвращает true если на входе 1
SCK_HIGH : boolean; // Возвращает true если на входе 1

MISO,MOSI,SCK,VCC,RESET // Инвертирует значение на ножке. Если было 1 сделает 0 и наоборот.


Теперь инструкция на Programming Enable [1010 1100 | 0101 0011 | xxxx xxxx | xxxx xxxx] выглядит так:

Код: Выделить всёРазвернуть
  Lpt.WritePort(GetCurrentPort,LPT_DATA_REG,0); // SCK = 0 MOSI = 0 RESET = 0 VCC = 0
  VCC; // VCC = 1
  Delay(100);

  spi_cmd[1]:= $ac;
  spi_cmd[2]:= $53;
  spi_cmd[3]:= 0;
  spi_cmd[4]:= 0;

  SPISend(spi_cmd);

  if spi_out[3] <> $53 then
    Application.MessageBox('Синхронизация не прошла. Эхо не получено!','ERROR',MB_OK);


Значение на выходе MISO не меняется вообще. Как стоит 1 так до конца и не меняется. В результате чего значение spi_out:
spi_out[1] = 255 ($ff)
spi_out[2] = 255 ($ff)
spi_out[3] = 255 ($ff)
spi_out[4] = 255 ($ff)

Пытался читать и вовремя прихода импульса и до и после - нужного результата не дало. Прошу помощи и свежего взгляда со стороны.
zi4rox
 
Сообщения: 5
Зарегистрирован: 19 апр 2008, 10:43

Re: Софтовая часть программатора для atmega16

Сообщение Master » 20 апр 2008, 12:55

Возможно у МК отключен режим SPI программирования, попробуй обычным программатором считать фьюзы.
Аватара пользователя
Master
 
Сообщения: 4468
Зарегистрирован: 21 дек 2006, 19:56
Откуда: Украина, г.Одесса
прог. языки: Delphi и С

Re: Софтовая часть программатора для atmega16

Сообщение nicname » 20 апр 2008, 16:45

Вот схема высоковольтного программатора - http://attiny.netfirms.com/ , по-моему почти открытый проект ... Только он для тини11\12 , примечателен тем , что надо всего 4 резистора , 2 транзистора , и 3 разъёма ( питание я подключал вместо флоппика) . Документация на С - тебе разобраться , наверное не составит труда . Посмотри , может попробуешь переделать для меги16 , толпы народа будут тебе признательны в будущем , что скажешь ?
Изображение
nicname
 

Re: Софтовая часть программатора для atmega16

Сообщение zi4rox » 20 апр 2008, 19:45

Получилось войти в режим программирования! Отклик получил.
Дело было в том что надо было сначала MSB посылать (а у меня было наоборот - первым шел LSB). Не усмотрел это в ДШ.
Задержки вроде как не влияют вообще, импульсы доходят/читаються и без них, но для верности можно и оставить.

Через пару дней продолжу работу. Буду пробывать считать прошивку с мк. Если что не получиться - я к вам за помощью. Ещё раз всем спасибо за дельные идеи и советы.


* 2 nicname: Спасибо за отличную ссылку. Обязательно покопаюсь в коде
zi4rox
 
Сообщения: 5
Зарегистрирован: 19 апр 2008, 10:43

Re: Софтовая часть программатора для atmega16

Сообщение Aesthete Animus » 21 апр 2008, 02:13

2zi4rox
Где-то я Вас уже видел... :D
Aesthete Animus
 
Сообщения: 23
Зарегистрирован: 22 мар 2008, 21:01
Откуда: Белгород
Skype: dackinevitch_yan
прог. языки: C/C++

Re: Софтовая часть программатора для atmega16

Сообщение Myp » 21 апр 2008, 10:01

Зураб Нахимович Штольц? :)
<telepathmode>На вопросы отвечает Бригадир Телепатов!</telepathmode>
Всё уже придумано до нас!
Аватара пользователя
Myp
скрытый хозяин вселенной :)
 
Сообщения: 18018
Зарегистрирован: 18 сен 2006, 12:26
Откуда: Тверь по прозвищу Дверь
прог. языки: псевдокод =) сила в алгоритме!
ФИО: глубокоуважаемый Фёдор Анатольевич


Вернуться в Микроконтроллеры

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 11