Фотоаппарат своими руками

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

Неожиданно, но поиски того как сделать фотоаппарат самому привели меня к этой статье. В изготовлении я решил начать с освоения получения изображения. Так вот, умные люди говорят, что на атмегу нормальную матрицу не приделать. Но ничего, это мы еще посмотрим. А пока, вернемся к самому простому и что можно посадить на мегу, это оптический сенсор в любой мышке.

Как только, об этом узнал, принялся сразу разбирать все мышки в доме, но не все имеют сенсор способный выдавать дамп пикселей. Долгие поиски, показали, что такие сенсоры есть только в мышах Logitech. И тут мне повезло, у друга завалялась старя мыша. Разобрав ее, я увидел желанный ADNS. Вот по нему документация.

2013-03-23 13.27.13 В доке даже есть примеры схемы, одна из которых и есть эта мыш. Так что, проблем с пониманием чего к чему нет.

А что делать дальше?

Для начала надо продумать как все это будет работать. 

Флэшка своими руками

Привет всем. Для создания своей флэшки с блэк джеком и шлюхами я взял модуль памяти M25P32 (документация), контроллер ATMega168 (документация) и конвертер USB<->UART (SerialPort) (документация).

И так. Зачем все это нужно?

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

Схема

Без имени-2

Это документация на используемые схемы. Там же и есть способы их подключения.

FT232RL_V202 m25p32 atmega168

 

 

 

 

 

 

По сути же схема выглядит так

 

Протоколы

Здесь мы используем 2 основных протокола. Это UART и SPI оба они реализованы в контроллере, остается только привести их в удобный для себя вид.

Терминал

 

Основные ошибки с UARTом:

  • Забыть линию TXD настроить выходом ( например DDRD |= (1<<PD1) )
  • Скорость передачи лучше брать из стандартного ряда а значения для UBBR из мануала

Для проверки я использовал вот эту прогу (Terminal)

Не забывать при SPI:

  • Задать все порты (входы выходы)
  • Давать задержку между передачей и принятием данных

Программа

Для своего удобства разделил программу на несколько блоков

Вообще-то этот проект сделан чтобы автоматически прибавлять числа и записывать в память, но от изначальной задачи он отличается совсем немного.

Все изменения будут заключены в одном единственном блоке.

Пусть у нас будет 3 комманды:

  1. Запись данных
  2. Считывание данных
  3. Стирание

Изменения будут только в блоке прерывания:

ISR(USART_RX_vect){
 if(command==0xFF){
  command = UDR0;
 }else{
  switch(command){
   case 0x01://Запись данных

   break;
   case 0x02://Чтение данных

   break;
   case 0x03://Стирание данных

   break;
  }
 }
}

Проект

SoftWare

Наверное отдельно рассмотрю как делать ПО для такого типа приложений в другой статье. Но в общем и целом эта программа должна подключаться к одному из COM портов и передавать определенные пакеты данных.

HardWare

Это плата на которой это все тестилось.

2013-02-13 11.40.52

 

Питание так же от USB.

Заключение

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

 

SPI на других ногах

Как работать с встроенным в AVR SPI`ем будет описано в другой статье. Иногда возникает необходимость синхронного общения по этому протоколу с двумя устройствами (в моем случае это внешний АЦП и внешняя память).

atmega88_p2

И так, для всего этого берем любой контроллер AVR (я взял ATmega168) и определяемся где мы хотим разместить наш ручной SPI. Займет это все 3-4 порта, зависит от необходимости в канале SS. Для моих целей  SS не нужен, т.к. он выбран всегда.

Шаг 1: Определяем порты и частоту

В моем случае:

  • PC3 – выход
  • PC2 – вход
  • PC1 – тактирование

Чтобы не мучиться сразу зададим все дефайнами:

#define MO0 PORTC&=~(1<<PC3)
#define MO1 PORTC|=(1<<PC3) 
#define SCK 8
#define C SCK/2
#define SCK_ON PORTC|=(1<<PC1)
#define SCK_OFF PORTC&=~(1<<PC1)

Соответственно: 1,2  - строки определяют 1/0 на выходе; 5,6 – 1/0 на линии такта; SCK – количество тактов за один период SPI,  если частота кристалла 8МГц, а SPI 2МГц, то это число будет 4. Да и надо помнить, что меньше 2 оно не может быть.

Шаг 2: Определяем главную последовательность

   // Поднимаем такт для режима 4 (для 0 - опускаем линию такта)
   for(bit=0; bit<8;bit++){ // Далее передаем 8 бит данных
     //передаем первый бит входных данных (byte)
     // опускаем линию такта (для режима 0 - поднимаем)
     // считываем бит и записываем в выходной регистр
     // поднимаем линию такта (для режима 0 - опускаем)
   }

Таким образом у нас получится такая вот картина

1234921860_15347_FT18372_zilog_spi_sck_

 

Шаг 3: Расставляем по своим местам

unsigned char SPI (unsigned char byte){
   unsigned char re=0;
   unsigned char bit=0;
   SCK_ON;
   for(bit=0; bit<8;bit++){
      //write
      if (byte&(1<<bit))
         MO1;
      else
         MO0;
      //SCK on
      wait(C);
      SCK_OFF;
      //Read
      re<<=1;
      if(PINC&(1<<PC2))
         re|=(1<<0);//0x01
      else
         re&=~(1<<0);
      // SCK off
      wait(C);
      SCK_ON;
    }
}

 

Готовый проект My SPI под AVRStudio 6