Новичок
Профиль
Группа: Участник
Сообщений: 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
|