Перейти к содержанию
    

the_last_dreamer

Участник
  • Постов

    22
  • Зарегистрирован

  • Посещение

Весь контент the_last_dreamer


  1. Проблема решилась путем замены SetupDiGetClassDevs на SetupDiGetClassDevsA
  2. Пишу программу для обмена данными с hid устройствами. #include <Windows.h> #include <stdio.h> #include <iostream> #include <conio.h> using namespace std; #define DIGCF_PRESENT 0x00000002 //-------Hid.dll functions prototypes------- //HidD_Hello is a pointer that points at the function which accepts two parameters (PCHAR and ULONG) //and returns result of ULONG type typedef ULONG (WINAPI *PHidD_Hello)(PCHAR, ULONG); typedef void (WINAPI *PHidD_GetHidGuid)(LPGUID); PHidD_Hello HidD_Hello; PHidD_GetHidGuid HidD_GetHidGuid; //-------SetupApi.dll functions prototypes-------- typedef PVOID HDEVINFO; typedef HDEVINFO (WINAPI *PSetupDiGetClassDevs)(const GUID*, PCTSTR, HWND, DWORD); PSetupDiGetClassDevs SetupDiGetClassDevs; void main(int argc, char *argv[]) { //Load hid.dll HMODULE HidDllDescriptor=LoadLibrary((LPCTSTR)"hid.dll"); if (HidDllDescriptor==NULL) { cout << "Error #" << GetLastError() << ". Can't load hid.dll." << endl; } else { cout << "hid.dll have been loaded successfully" << endl; char HidDllAdress[50]; if (GetModuleFileName(HidDllDescriptor,(LPSTR)HidDllAdress,50)==0) { cout << "Can't get full path to hid.dll. Error # " << GetLastError() << endl; } else { cout << "hid.dll adress is " << HidDllAdress <<endl; //Get entry points of HID.dll functions HidD_Hello=(PHidD_Hello)GetProcAddress((HMODULE)HidDllDescriptor, "HidD_Hello"); HidD_GetHidGuid=(PHidD_GetHidGuid)GetProcAddress((HMODULE)HidDllDescriptor, "HidD_GetHidGuid"); } } //Load setupapi.dll HMODULE SetupApiDllDescriptor=LoadLibrary((LPCSTR)"setupapi.dll"); if (SetupApiDllDescriptor==NULL) { cout << "Can't load setupapi.dll. Error # " << GetLastError() << endl; } else { cout << "setupapi.dll have been loaded successfully" << endl; char SetupApiDllAdress[50]; if (GetModuleFileName(SetupApiDllDescriptor,(LPSTR)SetupApiDllAdress,50)==0) { cout << "Can't get full path to setupapi.dll. Error # " << GetLastError << endl; } else { cout << "Setupapi.dll adress is " << SetupApiDllAdress << endl; //Get entry points of setupapi.dll functions SetupDiGetClassDevs=(PSetupDiGetClassDevs)GetProcAddress((HMODULE)SetupApiDllDes criptor,"SetupDiGetClassDevs"); } } GUID HidGuid; HidD_GetHidGuid(&HidGuid); typedef struct _HIDD_ATTRIBUTES { ULONG Size; // = sizeof (struct _HIDD_ATTRIBUTES) USHORT VendorID; USHORT ProductID; USHORT VersionNumber; } HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES; HDEVINFO hHidInfo; hHidInfo=SetupDiGetClassDevs(&HidGuid,NULL,NULL,DIGCF_PRESENT); //Здесь появляется ошибка! if (hHidInfo==INVALID_HANDLE_VALUE) { cout << "Can't build a list of HIDs. Error " << GetLastError << endl; } else { cout << "List of HIDs have been built" << endl; } //Unload hid and setupapi libraries FreeLibrary(HidDllDescriptor); FreeLibrary(SetupApiDllDescriptor); cin.get(); }; Компилируется без ошибок и предупреждений, но при запуске выдает ошибку: Необработанное исключение в "0x00000000" в "hid1.exe": 0xC0000005: Нарушение прав доступа при чтении "0x00000000". Погуглив, я узнал, что это связано с разыменованием пустого указателя PVOID, каким по-сути является hHidInfo. Замена куска кода HDEVINFO hHidInfo; hHidInfo=SetupDiGetClassDevs(&HidGuid,NULL,NULL,DIGCF_PRESENT); на DWORD *hHidInfo; hHidInfo=(DWORD *)SetupDiGetClassDevs(&HidGuid,NULL,NULL,DIGCF_PRESENT); не помогла решить проблему. Как и в случае замены HDEVINFO на char *, word *, void *. Помогите, пожалуйста, разобраться с этой ошибкой.
  3. Завалялся электродвигатель без каких-либо опознавательных надписей, кажется, еще советский. Щеток нет. У статора 4 обмотки. Наружу выходят 2 провода. Подскажите, пожалуйста, что это за электродвигатель? И подскажите за одно, как его включать. Мне кажется, что асинхронный... Спасибо. P.S. Еще есть его фотографии. Но они не хотят загружаются :( Если получится, то выложу
  4. Для того чтобы микроконтроллер самостоятельно определял "фазу" и "ноль" решил добавить еще одну схему для определения момента перехода через "0" сетевого напряжения. Предполагается, что сигналы будут поступать на два входа INT0 и INT1 микроконтроллера. На том входе, который подключен к фазе, сигнал будет периодически изменяться с лог. 1 на лог. 0. На другом же входе, подключенном к "нулю", уровень напряжения будет постоянно оставаться равным "0". Такое дополнение позволит избежать поиска фазы. Будет ли такое решение верным, в том смысле будет ли работать схема так как предполагается? Спасибо.
  5. Спаял заново всю схему с использованием предложенной rezident'ом схемы защиты ножки микроконтроллера http://electronix.ru/forum/index.php?act=A...st&id=48569 Переписал код прошивки. Получился он, кстати, раза в 3 меньше, чем первая версия. Да уж все гениальное - просто :) В общем, спаял я все это дело, прошил и включил. И... лампочка загорелась :08: Дабы не спалить стабилизатор напряжения и симистор, т.к. на них радиаторы не цеплял (хотя тепла на них по моим прикидкам должно выделяться не много 2 и 1 Вт соответственно), решил я включить схемку на пару секунд. После второго включения на пару секунд она еще работала, а на третий раз уже нет :crying: На этот раз ничего, на первый взгляд, не сгорело B) Да и вся схема была холодная. Нашел информацию о проверке тестером электронных компонентов. Мультиметром пытаюсь обнаружить неисправность. Все резисторы, кажется, в порядке. Подозрение вызывает стабилитрон в схеме защиты входа МК. Его сопротивление в прямом направлении около 10кОм, в обратном около 16кОм. Как вы думаете, может ли схема не функционаровать должным образом из-за неисправности стабилитрона? Если я правильно понимаю, то, в принцепе, схема должна работать если стабилитрон вообще удалить. Все наладилось - вилку не той стороной в разетку вставил
  6. Сейчас я не вспомню точные технические характеристики. Производительность около 2 м3/ч, мощность около 400Вт, питается переменным током 220В. Симистор который использован в схеме, согласно спецификации, пропускает ток до 8А. Думаю, такого симистора достаточно.
  7. Скорее даже не электродвигатель, а погружной насос.
  8. Теперь понимаю :) Если Вам не трудно подскажите какой мощности должен быть резистор R1 на этой схеме? http://electronix.ru/forum/index.php?act=A...st&id=48569 По моим подсчетам получается что мощность R1 равна 220^2/1000=48,2 Вт. Не многовато ли?
  9. Можно еще уточнить по поводу этой схемы? http://electronix.ru/forum/index.php?act=a...st&id=20626 Если верить протеусу, то напряжение подаваемое на вход МК будет периодически изменяться от -0,5 до 5,5В. С чем это связано? Разве оно не должно изменяться в диапазоне 0-5В? И еще вопрос по поводу резистора R2 сопротивлением 10кОм. Какова его функция? Только ограничение тока, проходящего через микроконтроллер?
  10. А можете немного по-подробнее рассказать? Это пробная схема. В дальнейшем хочу подключить вместо лампочки электродвигатель.
  11. Можно ли использовать оптосиммистор с датчиком перехода через 0 (например, MOC3041), чтобы "не изобретать велосипед"? Если в цепь включить такой оптосимистор, то симистор будет открываться всякий раз, когда сетевое напряжение переходит через 0 и при условии, что на оптосимистор будет подано напряжение с ножки микроконтроллера? И еще один вопрос. Какова должна быть мощность резистора в снабберной цепи?
  12. Всем спасибо за помощь! Буду исправлять схему. Еще вернусь :)
  13. А на выходе диодного моста получется же напряжение величина которого описывается функцией U=|sin(wt)|? Оно же изменяется во времени, следовательно действующее напряжение не будет величиной постоянной. А вольтметр показывает постоянную величину. Или может быть у меня вольтметр особенный... На входе АЦП напряжение периодически возрастает, достигая максимального значения 5В, затем убывает, достигая 0. МК фиксирует тот момент, когда напряжение уменьшалось, а затем начало возрастать. Хотя, может быть, я не понимаю назначение диодного моста... Спасибо, Александр
  14. Решил я сделать устройство для управления мощными устройствами на микроконтроллере. Собрал схему по материалам, которые нашел в гугле, написал программу для МК, отладил устройство в протеусе. Кажется все работает. Прошил микроконтроллер, включил в сеть и... устройство не заработало. Точнее заработало, но не так как я ожидал того (лампа накаливания успела зажечься буквально на долю секунды, причем не на полную мощнность, а только нить накала покраснела и погасла). Последующие попытки включить устройство были напрасны. Но стабилизатор напряжения и микроконтроллер нагрелись хорошо. На ощупь (естественно после отключения от сети) градусов 70 :crying: Ребята, помогите, пожалуйста, разобраться что не так с этой схемой (рисунок прилагается ниже). Краткое описание схемы. Основной проблемой для меня было определить момент перехода через ноль сетевого напряжения. Для определения нуля использую АЦП МК. Напряжение со второй вторичной обмотки трансформатора после диодного моста (около 9В) попадает на переменный резистор, с которого на МК поступает пульсирующее напряжение с амплитудой около 5В. Как только МК регистрирует рост напряжения, он посылает импульс длительностью 50 мкс на вывод PD0. Использую симистор MAC9ng (ну или использовал(. Первую вторичную обмотку использую для получения стабилизированного напряжения для питания схемы. Стабилизатор 78M05 (5В, 500мА). И еще несколько детских вопросов: 1. Земля - это же отрицательный вывод источника питания? 2. Если вольтметр показывает напряжение 4,9В (и предполагается, что напряжение пульсирующее) это амплитудное значение напряжение или среднее? 3. Напряжение на вторичной обмотке трансформатора совпадает по фазе с напряжением на первичной обмотке? 4. Если на кварцевый резонатор подать напряжение 18В, он перестанет работать? Заранее благодарю за помощь :)
  15. Кажется проблема разрешилась - поместил в одну папку файл .elf программы и файл проекта Proteus'а :)
  16. Возникла ещё такая проблема. Хотелось бы отладить программу в Proteus. Прочитал, что для того чтобы можно было отлаживать программу пошагово и при этом видеть текст программы нужно в МК загрузить файл .cof или .elf, а не .hex. Создаю файл .cof с помощью команды make extcoff. Загружаю его в МК, после запуска в окне AVR Source Code - U1 текст программы не отображается. Но есть надпись No source line at PC adress. При загрузке .cof файла, созданного в codevisionavr, код программы отображается. Можно перейти на CVAVR, но все-таки хотелось бы разобраться в WinAVR :)
  17. Спасибо, Сергей Борщ! В регистр теперь записывается то число что нужно.
  18. Извините за беспокойство, но она все-таки не работает :( Приведу более толковый текст программы: #include <avr/io.h> #include <avr/interrupt.h> #include <math.h> /****************************************************************** Здесь еще есть обработчики прерываний при переполнении таймеров, дополнительные процедуры и т.д. и т.п. Их текст не привожу, чтобы не усложнять чтение программы. ******************************************************************/ volatile unsigned int OCR1AMaxValue=9900; volatile unsigned char ADCresult=255; ISR(ADC_vect) { //Запись в переменную ADCresult значения АЦ преобразования ADCresult=ADCH; //Запись в регистр OCR1A целого выражения OCR1A=floor(ADCresult/255*OCR1AMaxValue); //Ошибка в этой строке, как мне кажется //Начать новое преобразование ADCSRA|=(1<<ADSC); } int main (void) { SREG=1<<7; //Установка вывода OC1A при совпадении значений регистров OCR1A и TCNT1 TCCR1A|=(1<<COM1A1)|(1<<COM1A0); //Включение АЦП. Разрешение прерываний от АЦП. //Предделитель частоты - 32 ADCSRA|=(1<<ADEN)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS0); //Выбор опорного напряжения. Выбор аналогового входа ADMUX|=(1<<REFS0)|(1<<MUX0); //Левостороннее выравнивание ADMUX|=(1<<ADLAR); //Начать первое преобразование ADCSRA|=(1<<ADSC); while (1) { //Без этой строки похоже тоже не обойтись. Компилятор выбрасывает пустой цикл из программы char i=1; } return (0); } МК выполняет аналогово-цифровое преобразование. В регистр OCR1A необходимо записать целое число значение которого вычисляется по формуле: floor(OCR1AMaxValue*ADCResult/255). При отладке в Avr Studio происходит следующее (может все слишком подробно описано, но я уже начинаю думать, что я что-то не так делаю в отладчике): 1. В функции main установка битов в регистрах АЦП проходит правильно. 2. После того как программа входит в бесконечный цикл ввожу в регистр ADCH произвольное значение. Например, 64. 3. Устанавливаю breakpoint при входе в обработчик прерываний от АЦП. 4. Нажимаю F5. 5. Программа входит в тело процедуры ISR(ADC_vect). 6. Нажимаю F11. 7. Программа присваивает переменной ADCresult значение 64. 8. Нажимаю F11, когда курсор находится в строке OCR1A=floor(ADCresult/255*OCR1AMaxValue). 9. И в этот момент курсор перескакивает в бесконечный цикл, на строку char i=1. В окне watch значения переменной ADCresult=Not In Scope. 10. Нажимаю F11. Курсор возвращается в обработчик прерывания в строк ADCSRA|=(1<<ADSC). В окне watch ADCresult=64. Но в OCR1A все нули, хотя должно быть 64/255*9900=2484. 11. Далее выполнение программы идет нормально - ожидаем новое прерывание от АЦП. При его возникновении история повторяется. Компилировал при OPT = 0. Если я правильно понимаю, то компилятор вообще ничего не должен оптимизировать? Может быть я не понял что-то в предыдущих ответах... WinAVR у меня 20090313. Может быть в нем причина? Может ли данная ситуация быть просто глюком AVRStudio, а в реальном устройстве работать правильно? Подскажите, пожалуйста, в чем ошибка.
  19. >ну дык посмотрите ассемблерные листинги. К сожалению, ассемблер не знаю, хотя разобраться в нем и надо бы. >а если выполнить присвоение перед выполнением функции? поменять опции оптимизатора? компилировал при уровне оптимизации 0. Не помогло :( >Объявите tmpVar как volatile, сказав тем компилятору, что он не имеет права предполагать что-то по поводу видимости этой переменной из внешнего по отношению к программе мира, и наслаждайтесь. Большое спасибо за совет. Работает :08:
  20. Доброго времени суток! Имеется такой простенький код: #include <avr/io.h> #include <math.h> double b=15.485; double tmpVar; int main (void) { tmpVar = floor(b); //берем целую часть от 15.485, т.е. 15 while (1) { char i=1; } return (0); } Компилируется нормально. Олаживаю в avr studio. При выполнении команды tmpVar = floor(b) переменной tmpVar должно быть присвоено значение 15, но вместо этого выполнение передается в цикл, и в окне Watch в качестве значения переменной tmpVar появляется "Not in Scope", а на следующем шаге обратно из цикла и при этом в окне watch появляется значение переменной tmpVar равное 15. И далее выполнение программы продолжается правильно. Похожая программа написанная в codeVision AVR в avr studio работает корректно. Такой код работает правильно: #include <avr/io.h> #include <math.h> double tmpVar; int main (void) { tmpVar = floor(15.485); while (1) { char i=1; } return (0); } Подскажите, пожалуйста, в чем может быть ошибка.
×
×
  • Создать...