Модераторы: PILOT, ManiaK, Mazzi
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Прошивка под USB HID Осциллограф 
:(
    Опции темы
micr
  Дата 15.4.2012, 14:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 15.4.2012

Репутация: нет
Всего: нет



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

Вот проект: USB Осциллограф

Вот весь код на Си (прошивка PIC):

Код


#define __USB_PIC_PERIF__ 1

#include <18F2550.h> //подключение внешнего заголовочного файла 
#device ADC=8 //подключение 8-разрядного АЦП
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN // подключение предохранителей
#use delay(clock=48000000) //частота процессора 

#build(reset=0x1, interrupt=0x8)          // место в памяти для байта сброса и место для прерываний
#ORG 0x0F00,0x0FFF {}                     // место в памяти для размещения следующей функции

#use rs232(stream=PC, baud=115200, xmit=PIN_C6, rcv=PIN_C7, ERRORS)// включение rs232


//DEFINE
#DEFINE USB_HID_DEVICE  TRUE //Включает код обработки HID
#define USB_EP1_TX_ENABLE  USB_ENABLE_INTERRUPT   // включает передачу прерываний с вывода TX
#define USB_EP1_TX_SIZE    64  //выделяет 64 байта для передачи
#define USB_EP1_RX_ENABLE  USB_ENABLE_INTERRUPT   //включает прием прерываний с вывода RX
#define USB_EP1_RX_SIZE    64  //выделяет 64 байта для приема

#define theSampleSize            512

#define usbConfirmAction         0
#define usbCheckStatus           1
#define usbReadRam               2
#define usbWriteRam              3
#define usbReadADC               4
#define usbReadADCnTimes         5
#define usbReadADCPeriod         6
#define usbReadADCnTimesMS       7
#define usbClearRam              8
#define usbSetRamByte            9
#define usbSetUseCRC             10
#define usbClearUseCRC           11
#define usbReadADCnTimesUS       12
#define usbError                 66

// CCS USB библиотеки
#include <pic18_usb.h>   
#include <usb_desc_hid 8-byte.h>  
#include <usb.c>       

void usb_debug_task(void) {      //Функция отлаживания соединения usb                         
   static int8 last_connected;
   static int8 last_enumerated;
   int8 new_connected;
   int8 new_enumerated;

   new_connected=usb_attached();
   new_enumerated=usb_enumerated();

  // Проверка состояния соединения и передача отчета о соединении по USART
   if (new_connected && !last_connected) {
      printf("\r\n\nUSB connected, waiting for enumaration...");}
   if (!new_connected && last_connected) {
      printf("\r\n\nUSB disconnected, waiting for connection...");}
   if (new_enumerated && !last_enumerated) {
      printf("\r\n\nUSB enumerated by PC/HOST");}
   if (!new_enumerated && last_enumerated) {
      printf("\r\n\nUSB unenumerated by PC/HOST, waiting for enumeration...");}

   last_connected=new_connected;
   last_enumerated=new_enumerated;
}

#INT_RDA   // получение данных из RS232                                    
void serial_isr()                         //функция серии прерываний
{
   int8 uReceive;

   disable_interrupts(GLOBAL);            // отключение глобальных прерываний

   uReceive = fgetc(PC); //fgetc(PC)-ожидание приема символа от РС

   switch (uReceive) {
      case 0x12: {
            if 
         }(fgetc(PC) == 0x34 & fgetc(PC) == 0x56 & fgetc(PC) == 0x78 & fgetc(PC) == 0x90) #asm reset #endasm //если получил нужный символ то делает сброс
         break;
   }

   enable_interrupts(GLOBAL);                // Включение глобальных прервываний 
}

// Алгоритм вычисления циклического кода 
int calc_crc(int oldcrc, int newbyte) {
   int shift_reg, data_bit, sr_lsb, fb_bit, j;
   shift_reg=oldcrc;
   for(j=0; j<8; j++) {   // for each bit
      data_bit = (newbyte >> j) & 0x01;
      sr_lsb = shift_reg & 0x01;
      fb_bit = (data_bit ^ sr_lsb) & 0x01;
      shift_reg = shift_reg >> 1;
      if (fb_bit)
         shift_reg = shift_reg ^ 0x8c;
      }
   return(shift_reg);
}



void main() { //главная функция
   int1 useCRC;
   int8 in_data[8]; //буфер для принимаемых данных
   int8 out_data[8]; //буфер для передаваемых данных
   int8 adcData[theSampleSize];
   int8 theCRC, tempADC;
   int16 n, approxUS, approxMS, period;

//установка режимов работы 
   SETUP_ADC_PORTS(AN0);
   SETUP_ADC(ADC_CLOCK_DIV_64);
   SETUP_TIMER_0(RTCC_INTERNAL|RTCC_DIV_1);
   SETUP_TIMER_1(T1_DISABLED);
   SETUP_TIMER_2(T2_DISABLED, 127, 1);
   SETUP_TIMER_3(T3_INTERNAL | T3_DIV_BY_8);
   SETUP_CCP1(CCP_OFF);
   SETUP_CCP2(CCP_OFF);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);

   usb_init(); //инициализация соединения
   useCRC = true;
   set_adc_channel(0);
   delay_ms(1);

   while (TRUE) {
      usb_task(); // следит за состоянием соединения, при отключеии сбрасывает ЮСБ стек
      usb_debug_task(); //
      if (usb_enumerated()) {
         if (usb_kbhit(1)) {
            usb_get_packet(1, in_data, 8);

//Сбор входных данных для формирования CRC
            if (useCRC) {
               theCRC = 0;
               theCRC = calc_crc(theCRC,in_data[0]);
               theCRC = calc_crc(theCRC,in_data[1]);
               theCRC = calc_crc(theCRC,in_data[2]);
               theCRC = calc_crc(theCRC,in_data[3]);
               theCRC = calc_crc(theCRC,in_data[4]);
               theCRC = calc_crc(theCRC,in_data[5]);
               theCRC = calc_crc(theCRC,in_data[6]);
            }
            else {
               theCRC = in_data[7];
            }

            if (theCRC = in_data[7]) {
               out_data[0] = 255;
               out_data[1] = 255;
               out_data[2] = 255;
               out_data[3] = 255;
               out_data[4] = 255;
               out_data[5] = 255;
               out_data[6] = 255;

               switch (in_data[0]) {
                  case usbReadRam: {
                        if (make16(in_data[1],in_data[2]) <= theSampleSize) {
                           out_data[0] = usbConfirmAction;
                           out_data[1] = usbReadRam;
                           out_data[2] = in_data[1];
                           out_data[3] = in_data[2];
                           out_data[4] = adcData[make16(in_data[1],in_data[2])];
                        }
                        else {
                           out_data[0] = usbError;
                           out_data[1] = usbReadRam;
                           out_data[2] = in_data[1];
                           out_data[3] = in_data[2];
                        }
                     }
                     break;
                  case usbWriteRam: {
                        if (make16(in_data[1],in_data[2]) <= theSampleSize) {
                           adcData[make16(in_data[1],in_data[2])] = in_data[3];
                           out_data[0] = usbConfirmAction;
                           out_data[1] = usbWriteRam;
                           out_data[2] = in_data[1];
                           out_data[3] = in_data[2];
                           out_data[4] = in_data[3];
                        }
                        else {
                           out_data[0] = usbError;
                           out_data[1] = usbWriteRam;
                           out_data[2] = in_data[1];
                           out_data[3] = in_data[2];
                           out_data[4] = in_data[3];
                        }
                     }
                     break;
                  case usbReadADC: {
                        tempADC = READ_ADC();
                        out_data[0] = usbConfirmAction;
                        out_data[1] = usbReadADC;
                        out_data[2] = tempADC;
                     }
                     break;
                  case usbReadADCnTimes: {
                        if (make16(in_data[1],in_data[2]) <= theSampleSize) {
                           set_timer3(0);
                           for (n=0;n<make16(in_data[1],in_data[2]);n++)
                           {
                              adcData[n] = READ_ADC();
                           }
                           period = get_timer3();   
                           out_data[0] = usbConfirmAction;
                           out_data[1] = usbReadADCnTimes;
                           out_data[2] = in_data[1];
                           out_data[3] = in_data[2];
                        }
                        else {
                           out_data[0] = usbError;
                           out_data[1] = usbReadADCnTimes;
                           out_data[2] = in_data[1];
                           out_data[3] = in_data[2];
                        }
                     }
                     break;
                  case usbReadADCPeriod: {
                        out_data[0] = usbConfirmAction;
                        out_data[1] = usbReadADCPeriod;
                        out_data[2] = make8(period,1);
                        out_data[3] = make8(period,0);
                     }
                     break;
                  case usbReadADCnTimesUS: {
                        if (make16(in_data[1],in_data[2]) <= theSampleSize) {
                           approxUS = make16(in_data[3],in_data[4]);
                           for (n=0;n<make16(in_data[1],in_data[2]);n++)
                           {
                              set_timer3(0);
                              adcData[n] = READ_ADC();
                              while (get_timer3() * 2/3 < approxUS);   
                           }
                           out_data[0] = usbConfirmAction;
                           out_data[1] = usbReadADCnTimesUS;
                           out_data[2] = in_data[1];
                           out_data[3] = in_data[2];
                           out_data[4] = in_data[3];
                           out_data[5] = in_data[4];
                        }
                        else {
                           out_data[0] = usbError;
                           out_data[1] = usbReadADCnTimesUS;
                           out_data[2] = in_data[1];
                           out_data[3] = in_data[2];
                           out_data[4] = in_data[3];
                           out_data[5] = in_data[4];
                        }
                     }
                     break;
                  case usbReadADCnTimesMS: {
                        if (make16(in_data[1],in_data[2]) <= theSampleSize) {
                           approxMS = make16(in_data[3],in_data[4]);
                           for (n=0;n<make16(in_data[1],in_data[2]);n++)
                           {
                              set_timer3(0);
                              adcData[n] = READ_ADC();
                              while (get_timer3() * 1/1500 < approxMS);   
                           }
                           out_data[0] = usbConfirmAction;
                           out_data[1] = usbReadADCnTimesMS;
                           out_data[2] = in_data[1];
                           out_data[3] = in_data[2];
                           out_data[4] = in_data[3];
                           out_data[5] = in_data[4];
                        }
                        else {
                           out_data[0] = usbError;
                           out_data[1] = usbReadADCnTimesMS;
                           out_data[2] = in_data[1];
                           out_data[3] = in_data[2];
                           out_data[4] = in_data[3];
                           out_data[5] = in_data[4];
                        }
                     }
                     break;
                  case usbClearRam: {               // очистка памяти
                        for (n=0;n<512;n++)
                        {
                           adcData[n] = 0;
                        }
                        out_data[0] = usbConfirmAction;
                        out_data[1] = usbClearRam;
                     }
                     break;
                  case usbSetRamByte: {
                        for (n=0;n<512;n++)
                        {
                           adcData[n] = in_data[1];
                        }
                        out_data[0] = usbConfirmAction;
                        out_data[1] = usbSetRamByte;
                        out_data[2] = in_data[1];
                     }
                     break;
                  case usbSetUseCRC: {
                        useCRC = true;
                        out_data[0] = usbConfirmAction;
                        out_data[1] = usbSetUseCRC;
                     }
                     break;
                  case usbClearUseCRC: {
                        useCRC = false;
                        out_data[0] = usbConfirmAction;
                        out_data[1] = usbClearUseCRC;
                     }
                     break;
               }
               // Сбор выходных данных для CRC
               if (useCRC) {
                  theCRC = 0;
                  theCRC = calc_crc(theCRC,out_data[0]);
                  theCRC = calc_crc(theCRC,out_data[1]);
                  theCRC = calc_crc(theCRC,out_data[2]);
                  theCRC = calc_crc(theCRC,out_data[3]);
                  theCRC = calc_crc(theCRC,out_data[4]);
                  theCRC = calc_crc(theCRC,out_data[5]);
                  theCRC = calc_crc(theCRC,out_data[6]);
                  out_data[7] = theCRC;
               }

               usb_put_packet(1, out_data, 8, USB_DTS_TOGGLE);  //формирование отправочного пакета
            }

            delay_ms(1);
         }
      }
   }
}


Всё самое непонятное начинается после   switch. В   switch  как я понял с помощью case определяется какая функция выполняется при нажатии определенной кнопки в проге на ПК.  И дальше, например, при выполнении функции usbReadRam возращается какое-то 16 битное число (что за это число???) и прога на МК передает в ПК какие-то данные через out_data[] (что - это за данные?)   И зачем вот это:
out_data[2] = in_data[1];
out_data[3] = in_data[2];
out_data[4] = in_data[3]
Зачем этим буферам присваивать значения у друг друга???

Это сообщение отредактировал(а) micr - 15.4.2012, 14:24
PM MAIL   Вверх
UniBomb
Дата 16.4.2012, 09:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок
***
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 1754
Регистрация: 24.10.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 97



micr, все вот эти вопросы "зачем?" и "что за число?" в общем-то не относятся к незнанию программирования. Ты же смог разобраться в конструкциях и понял что они делают. Но вот зачем - для этого надо разобрать протокол usb. Вещь вообще монструозная, на много-много страниц английского текста. Вот краткий ликбез по usb, изучай. Тогда вопросы отпадут сами собой smile Хотя и появится куча новых...
PM MAIL ICQ Skype   Вверх
micr
Дата 17.4.2012, 06:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 15.4.2012

Репутация: нет
Всего: нет



Цитата(UniBomb @ 16.4.2012,  09:42)
micr, все вот эти вопросы "зачем?" и "что за число?" в общем-то не относятся к незнанию программирования. Ты же смог разобраться в конструкциях и понял что они делают. Но вот зачем - для этого надо разобрать протокол usb. Вещь вообще монструозная, на много-много страниц английского текста. Вот краткий ликбез по usb, изучай. Тогда вопросы отпадут сами собой smile Хотя и появится куча новых...

Спасибо, но ничего полезного я там не нашёл)
PM MAIL   Вверх
UniBomb
Дата 17.4.2012, 08:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок
***
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 1754
Регистрация: 24.10.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 97



micr, значит плохо искал. Там есть фраза "Эта глава должна быть тщательно прочитана" и ей (фразе) стоит поверить  smile 
PM MAIL ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Микроконтроллеры (MCU) и микропроцессоры (MPU)"
PILOT ManiaK
UniBomb Mazzi

На данный раздел помимо Правил форума распространяются текже следующие правила:


  • Прежде чем создать тему воспользуйтесь поиском или посмотрите в faq. Возможно на форуме уже есть ответ на ваш или близкий к вашему вопрос.
  • В заголовке темы в квадратных скобках обозначьте используемое семейство микроконтроллера: [avr],[pic],[arm].
  • При создании темы с вопросом указывайте участок кода с ошибкой, версию компилятора, схемы подключения, fuse биты и прочие данные, которые помогут найти правильный ответ. Для форматирования текста программ используйте кнопку код.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Для флуда, просьб выполнить задание, поиска партнёров или исполнителей существуют свои разделы.
  • Если вы заметили несовместимое с правилами сообщение, то можете уведомить об этом модератора раздела нажав кнопку Репорт у соответствующего сообщения.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, PILOT, ManiaK, UniBomb, Mazzi.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Микроконтроллеры (MCU) и микропроцессоры (MPU) | Следующая тема »


 




[ Время генерации скрипта: 0.0458 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.