|
Помогите найти ошибку в программе. Или глюк АЦП? |
|
|
|
Sep 14 2006, 20:46
|
Знающий
   
Группа: Свой
Сообщений: 559
Регистрация: 6-09-06
Пользователь №: 20 131

|
ПРоблемка у меня...Скорее всего с АЦП. Контроллер - ATMega32, частота кварца 16 МГц Задача такая - по оптическому каналу (лазер и фотодиод) передается байт. В этом же устройстве он принятый байт сравнивается с переданным и если байты одинаковы, возвращается 1. вот код Код #define MUX_STATE (0 << REFS1)|(0 << REFS0) #define ADC_STATE (1 << ADEN)|(0 << ADPS2)|(1 << ADPS1)|(1 <<ADPS0)
int ReadADC(unsigned char ChannelNum) { ADMUX = ChannelNum | MUX_STATE; ADCSRA = (1 << ADSC) | ADC_STATE; while ( (ADCSRA & ( 1 << ADIF))==0); return ADCW; }
send_pack(unsigned char byte) { char *text; int i,x; unsigned char _bit, recieved_byte; for (i=0;i<8;i++) // разбираем байт по битам { _bit=(byte >> i) & 0x01; //присваиваем переменной _bit значение очередного бита переменной byte if (_bit==1) { PORTD |= _BV(PD0); // бит равен 1, включаем лазер glcdFillRect(10,10+i*18,20,20+i*18,RED); }
if (_bit==0) { PORTD &= ~_BV(PD0); // 0, бит равен 0, выключаем лазер glcdFillRect(10,10+i*18,20,20+i*18,WHITE); } glcdWait(1000); //ждем-с...
x=ReadADC(0); запускаем АЦП и измеряем освещенность фотодиода.
sprintf(text," %i ",x); glcdMoveTo(60,10+i*18); glcdPrint(text, 0); if (x<50) // если освещенность низка - bit=0 { glcdFillRect(30,10+i*18,40,20+i*18,WHITE); _bit=0; } if (x>50) // если освещенность достаточна- bit=1 { glcdFillRect(30,10+i*18,40,20+i*18,RED); _bit=1; } recieved_byte |= _bit << i; // склеиваем из полученных битов байт } if (recieved_byte==byte) return 1; return 0;
} Но вот проблема... если в байте чередуются 1 и 0, то данные принимаются с точностью до наоборот. вот вам пример того, что выводится на экран: T- посылаемый бит R- принятый бит L- значение полученное с АЦП Код Для байта 0xFF: Для байта 0xAF: Для байта 0xAF: Для байта 0xFA:
T R L T R L T R L T R L
1 1 512 1 1 514 0 0 11 0 0 11 1 1 511 1 1 513 1 0 11 1 0 11 1 1 509 1 1 512 0 1 515 0 1 508 1 1 510 1 1 512 1 0 11 1 0 11 1 1 512 0 1 512 0 1 515 1 1 508 1 1 511 1 0 12 1 0 12 1 1 507 1 1 511 0 1 537 0 1 512 1 1 506 1 1 511 1 0 13 1 0 13 1 1 508 Небольшой анализ: 1.Подряд идущие биты анализируются нормально. 2.При переключении бита с 1 на 0 или обратно происходит как бы сдвиг, почему-то выводится все наоборот. 3. Первый неправильный "результат" (то есть когда после кучи единиц вдруг оказывается ноль или наоборот) всегда содержит предыдущее значение АЦП. 4. Два одинаковых бита подряд возвращат АЦП к нормальной работе. Комбинации с частотой работы АЦП ничего не дали. VCC, AVCC и AREF соединены одним проводником. P.S. Самое главное - я пишу в WinAVR. До этого аналогичный код был написан мной для CodeVision за полчаса и прекрасно работал...
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 19)
|
Sep 14 2006, 22:21
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата glcdWait(1000); //ждем-с... Что за монстр такой? Не исключено что съеден оптимизатором. Здесь трабл вероятно. Цитата При переключении бита с 1 на 0 или обратно происходит как бы сдвиг, почему-то выводится все наоборот. Не "как бы сдвиг" а именно сдвиг, с отставанием в один бит. Причина - инертность лазера. Глюк в программе - не выдержана требуемая до начала преобразования задержка. Читайте не после изменения, а перед изменением, достоверней будет.
|
|
|
|
|
Sep 15 2006, 05:41
|
    
Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731

|
имхо, стОит посмотреть, какой код сгенерился для Код int ReadADC(unsigned char ChannelNum) { ... return ADCW; } , а именно порядок чтения ADCH и ADCL. Т.к. АЦП в данной программе по существу работает однобитовым компаратором (опуская детали, но без потери сути _bit = ADCW>50? 1: 0; кста, в оригинале случай x==50 вообще не обрабатывается  ), то можно сделать так: Код #define MUX_STATE (0 << REFS1)|(0 << REFS0)|(1 << ADLAR) ... uchar ReadADC(unsigned char ChannelNum) { ... return ADCH; }
|
|
|
|
|
Sep 15 2006, 07:16
|
Знающий
   
Группа: Свой
Сообщений: 559
Регистрация: 6-09-06
Пользователь №: 20 131

|
Господа. Я вижу что вы люди квалифицированные, но хотел бы обратить внимание на мой фразу о том, что данный код без проблем работал на CodeVision и многие грабли, на которые мне указывают, пройдены. Цитата Что за монстр такой? Не исключено что съеден оптимизатором. Здесь трабл вероятно.
Причина - инертность лазера. Глюк в программе - не выдержана требуемая до начала преобразования задержка. Какие только задержки я не ставил - и до и после - инертность кк лазера, так и фотодиода исключена. Впрочем, последую вашему совету и всесторонне проверю этот вариант. Ладно, попробую все отладить на проводах. Спасибо за советы.
|
|
|
|
|
Sep 15 2006, 08:34
|
    
Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731

|
Цитата(-=Женек=- @ Sep 15 2006, 11:16)  Господа. Я вижу что вы люди квалифицированные, но хотел бы обратить внимание на мой фразу о том, что данный код без проблем работал на CodeVision и многие грабли, на которые мне указывают, пройдены. Если бы CodeVision и WinAVR генерили одинаковый код, оно и работало бы одинаково. Поэтому я и посоветовал проверить в ассемблерном коде, как читается АЦП и что возвращается из ReadADC. > If the result is left adjusted and no more than 8-bit precision is required, it is sufficient to > read ADCH. Otherwise, ADCL must be read first, then ADCH, to ensure that the content > of the Data Registers belongs to the same conversion.
|
|
|
|
|
Sep 15 2006, 09:04
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Код .... for (i=0;i<8;i++) // разбираем байт по битам { _bit=(byte >> i) & 0x01; //присваиваем переменной _bit значение очередного бита переменной byte ..... Внимательней посмотрите, что здесь происходит. Какому биту равен "_bit" при первой интерации цикла?
|
|
|
|
|
Sep 15 2006, 09:26
|
    
Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731

|
Цитата(aesok @ Sep 15 2006, 13:04)  Код .... for (i=0;i<8;i++) // разбираем байт по битам { _bit=(byte >> i) & 0x01; //присваиваем переменной _bit значение очередного бита переменной byte ..... Внимательней посмотрите, что здесь происходит. Какому биту равен "_bit" при первой интерации цикла? Если не вдаваться в оптимальность кода, то все правильно, не пугайте автора  .
|
|
|
|
|
Sep 15 2006, 09:59
|
Знающий
   
Группа: Свой
Сообщений: 559
Регистрация: 6-09-06
Пользователь №: 20 131

|
Цитата Внимательней посмотрите, что здесь происходит. Какому биту равен "_bit" при первой интерации цикла? Господа, см мой код. На экранчике всякая операция с битами отображается по ходу дела. Цитата if (_bit==1) { PORTD |= _BV(PD0); // бит равен 1, включаем лазер glcdFillRect(10,10+i*18,20,20+i*18,RED); } По поводу отработки ваших советов: 1. Обнуление фотодиода не помогло. Проблема как выяснилось не в оптике, см ниже. 2. Последовательность ADCL и ADCH пока на проверял, сейчас займусь, просто не терпится выложить результаты сюда, дабы не было больше советов проверить оптику и правильность собственно алгоритма анализа битов. 3. Итак... переделал я код под провода. Два варианта: - сигнал по проводу подается на вход порта и анализируется как логический - сигнал по проводу подается на вход АЦП и анализируется полученное цифровое значение. Надо сказать, что я полностью отключил библиотеку LCD, дабы исключить какой-то конфликт, поэтому отображение информации я осуществляю свтодиодами - на моей отладочной плате их у каждого порта по 8 шт. Вот код: Код #include <inttypes.h> #include <stdio.h> #include <avr/io.h> #include <avr/delay.h> #include <avr/iom32.h> #define MUX_STATE (0 << REFS1)|(0 << REFS0) #define ADC_STATE (1 << ADEN)|(1 << ADPS2)|(1 << ADPS1)|(1 <<ADPS0)
int ReadADC(unsigned char ChannelNum) { ADMUX = ChannelNum | MUX_STATE; ADCSRA = (1 << ADSC) | ADC_STATE; while ( (ADCSRA & ( 1 << ADIF))==0); return ADCW; }
send_pack(unsigned char byte) { int i,x,j,b; unsigned char _bit, recieved_byte; for (i=0;i<8;i++) { _bit=(byte >> i) & 0x01; if (_bit==1) PORTD |= _BV(PD0); if (_bit==0) PORTD &= ~_BV(PD0); for (j=0;j<32000;j++) { for (b=0;b<10;b++) {} } //ЧТо-то Я не разобрался пока, как делать задержку в 1 сек функцией _delay_ms. Скучаю по CodeVision )) x=ReadADC(0); for (j=0;j<32000;j++) { for (b=0;b<10;b++) {} } // задержка
if (x>50) // это если испльзуем АЦП //if (PINA & _BV(PA7)) // А это если используем вход порта включенный на прием. { PORTC |= _BV(i); // отображаем текуший бит (ко всем выходам порта С подключены светодиоды) _bit=1; } if (x<51) //if (!(PINA & _BV(PA7))) { PORTC &= ~_BV(i); // отображаем текуший бит (ко всем выходам порта С подключены светодиоды) _bit=0; } for (j=0;j<32000;j++) { for (b=0;b<10;b++) {} } // подождем... recieved_byte |= _bit << i; // Клеим принятый байт... } if (recieved_byte==byte) return 1; return 0; }
void main() { int crc; DDRD |= _BV(PD0); DDRD |= _BV(PD7); DDRC = 0xFF; DDRA &= ~_BV(PA7); PORTD |=_BV(PD0);
crc=send_pack(0xFF); if (crc==1) { PORTD |= _BV(PD7); // если байт передан правильно, то зажигаем светодиод. } if (crc==0) { PORTD &= ~_BV(PD7); }
} Если сигнал подается с выхода одного порта на вход другого и анализируется логически - то все работает. Если же используется АЦП - результат идентичен. раскладки полученных битов даже приводить не буду, см. выше. Еще раз повторяю - данный алгоритм работал на CodeVision. Настройки АЦП те же были... И подскажите ламеру, как АСМовский код посмотреть? Нет его почему то в папке с проектом после компиляции...
|
|
|
|
|
Sep 15 2006, 10:05
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Влияние ADCW (порядка считывания) можно легко устранить. Не думаю что вам нужна 10битная точность АЦП для определения есть/нет сигнала. Настройте АЦП в режиме ADLAR и считывайте только ADCH: Код #define U8 unsigned char #define MUX_STATE (0 << REFS1)|(0 << REFS0)|(1 << ADLAR)
U8 ReadADC(U8 ChannelNum) { ADMUX = ChannelNum | MUX_STATE; ADCSRA = (1 << ADSC) | ADC_STATE; while ( (ADCSRA & ( 1 << ADIF))==0); return ADCH; } также можно выполнять двойное или тройное преобразование, и брать средний результат.
|
|
|
|
|
Sep 15 2006, 11:38
|
Знающий
   
Группа: Свой
Сообщений: 559
Регистрация: 6-09-06
Пользователь №: 20 131

|
ГОСПОДА!!! И правда мистика.....Вот - только что взял свой код и адаптировал его под CodeVision - только лишь синтаксически изменил способ включения/выключения портов. Ну и небольшое отличие в синтаксисе инициализации АЦП. ВСЕ РАБОТАЕТ!!!! Типерь внимание: Я убрал задержки отовсюду, посадил это дело на оптику. Частота чипа - 16 МГц, частота АЦП 125 кГц. Запустил цикл, а в главнои цикле добавил включение диода 5 порта D, если будет хотябы одна ошибка. Колоссальное количество таких операций в секунду. И вот 5 минут у меня девайс работает - ни одной ошибки. ПРостите мне мою глупую просьбу, но посмотрите предыдущий код и этот, для CodeVision - одинаково ли настроены АЦП? просто я уже устал... Код #include <stdio.h> #include <stdlib.h> #include <mega32.h> #include <delay.h>
int crc;
int ReadADC(unsigned char ChannelNum) { ADMUX=ChannelNum| 0x00; // Start the AD conversion ADCSRA|=0x40; // Wait for the AD conversion to complete while ((ADCSRA & 0x10)==0); ADCSRA|=0x10; return ADCW; }
send_pack(unsigned char byte) { int i,x,j,b; unsigned char _bit, recieved_byte; recieved_byte=0x00; PORTC=0x00; for (i=0;i<8;i++) { _bit=(byte >> i) & 0x01; if (_bit==1) { PORTD.0 =1; PORTD.1=0; } if (_bit==0) { PORTD.0 =0; PORTD.1=1; } // delay_ms(200); x=ReadADC(0);
if (x>50) // ýòî åñëè èñïëüçóåì ÀÖÏ // if (PINA.7==1) // À ýòî åñëè èñïîëüçóåì âõîä ïîðòà âêëþ÷åííûé íà ïðèåì. { PORTC |=1<<i;// îòîáðàæàåì òåêóøèé áèò (êî âñåì âûõîäàì ïîðòà Ñ ïîäêëþ÷åíû ñâåòîäèîäû) _bit=1; } if (x<51) // if (PINA.7==0) { PORTC |=0<<i; // îòîáðàæàåì òåêóøèé áèò (êî âñåì âûõîäàì ïîðòà Ñ ïîäêëþ÷åíû ñâåòîäèîäû) _bit=0; }
recieved_byte |= _bit << i; // Êëåèì ïðèíÿòûé áàéò...
} // delay_ms(500); if (recieved_byte==byte) return 1; return 0; }
void main () { DDRD=0xFF; DDRC=0xFF; DDRA.7=1; ADMUX=0x00; ADCSRA=0x87;
while (1) { crc=send_pack(rand()); if (crc==1) { PORTD.7 =1; // åñëè áàéò ïåðåäàí ïðàâèëüíî, òî çàæèãàåì ñâåòîäèîä. } if (crc==0) { PORTD.5 =1; }
} } И честное слово обидно ... что третий день бьюсь и бестолку. Обидно за себя, потому как все эти три дня считал себя недостойным даже звания любителя. А тут бах - и за полчаса сделал... Господа, наверное и у вас есть такое чувство - когда вы над чем-то бьетесь, сколько бы времени это не отнимало - вы всегда чувствуете "вектор" направленный в сторону проблемы и есть ощущение того, что еерешение - это вопрос времени. Но вот когда этого "вектора" нет - проблема действительно оказывается мистической.. Вот еще makefile - гляньте, может здесь собака зарыта... Код # # On command line: # # make all = Make software. # # make clean = Clean out built project files. # # make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). # # make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio # 4.07 or greater). # # make load = Download the hex file to the device, using avrdude. Please # customize the avrdude settings below first! # # make filename.s = Just compile filename.c into the assembler code only # # To rebuild project do "make clean" then "make all". #
# MCU name MCU = atmega32
# Output format. (can be srec, ihex, binary) FORMAT = ihex
# Target file name (without extension). TARGET = nnn
# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. # (Note: 3 is not always the best optimization level. See avr-libc FAQ.) # s seems to be size optimized OPT = 0
SRC = nnn.c
# If there is more than one source file, append them above, or modify and # uncomment the following: #SRC += foo.c bar.c
# You can also wrap lines by appending a backslash to the end of the line: #SRC += baz.c \ #xyzzy.c
# List Assembler source files here. ASRC =
# List any extra directories to look for include files here. # Each directory must be seperated by a space. EXTRAINCDIRS =
# Optional compiler flags. # -g: generate debugging information (for GDB, or for COFF conversion) # -O*: optimization level # -f...: tuning, see gcc manual and avr-libc documentation # -Wall...: warning level # -Wa,...: tell GCC to pass this to the assembler. # -ahlms: create assembler listing
DEBUG_LEVEL=-g WARNINGS=-Wall -Wextra -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare \ -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wunused
CFLAGS = -D GCC_MEGA_AVR -I. \ $(DEBUG_LEVEL) -O$(OPT) \ -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ $(WARNINGS) \ $(patsubst %,-I%,$(EXTRAINCDIRS))
# -Wa,-adhlns=$(<:.c=.lst) \
# Set a "language standard" compiler flag. # Unremark just one line below to set the language standard to use. # gnu99 = C99 + GNU extensions. See GCC manual for more information. #CFLAGS += -std=c89 #CFLAGS += -std=gnu89 #CFLAGS += -std=c99 CFLAGS += -std=gnu99
# Optional assembler flags. # -Wa,...: tell GCC to pass this to the assembler. # -ahlms: create listing # -gstabs: have the assembler create line number information; note that # for use in COFF files, additional information about filenames # and function names needs to be present in the assembler source # files -- see avr-libc docs [FIXME: not yet described there] ASFLAGS = -Wa,-adhlns=$(<:.asm=.lst),-gstabs
# Optional linker flags. # -Wl,...: tell GCC to pass this to linker. # -Map: create map file # --cref: add cross reference to map file LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
# Additional libraries
# Minimalistic printf version #LDFLAGS += -Wl,-u,vfprintf -lprintf_min
# Floating point printf version (requires -lm below) #LDFLAGS += -Wl,-u,vfprintf -lprintf_flt
# -lm = math library LDFLAGS += -lm -L../glcd/. -lglcd
# ---------------------------------------------------------------------------
# Define directories, if needed. DIRAVR = c:/Programme/AVR/Winavr DIRAVRBIN = $(DIRAVR)/bin DIRAVRUTILS = $(DIRAVR)/utils/bin DIRINC = . DIRLIB = $(DIRAVR)/avr/lib
# Define programs and commands. SHELL = sh
CC = avr-gcc
OBJCOPY = avr-objcopy OBJDUMP = avr-objdump SIZE = avr-size
REMOVE = rm -f COPY = cp
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex ELFSIZE = $(SIZE) -A $(TARGET).elf
# Define Messages # English MSG_ERRORS_NONE = Errors: none MSG_BEGIN = -------- begin -------- MSG_END = -------- end -------- MSG_SIZE_BEFORE = Size before: MSG_SIZE_AFTER = Size after: MSG_COFF = Converting to AVR COFF: MSG_EXTENDED_COFF = Converting to AVR Extended COFF: MSG_FLASH = Creating load file for Flash: MSG_EEPROM = Creating load file for EEPROM: MSG_EXTENDED_LISTING = Creating Extended Listing: MSG_SYMBOL_TABLE = Creating Symbol Table: MSG_LINKING = Linking: MSG_COMPILING = Compiling: MSG_ASSEMBLING = Assembling: MSG_CLEANING = Cleaning project:
# Define all object files. OBJ = $(SRC:.c=.o) $(ASRC:.asm=.o)
# Define all listing files. LST = $(ASRC:.asm=.lst) $(SRC:.c=.lst)
# Combine all necessary flags and optional flags. # Add target processor to flags. ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
# Default target. all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ $(TARGET).lss $(TARGET).sym sizeafter finished end
# Eye candy. # AVR Studio 3.x does not check make's exit code but relies on # the following magic strings to be generated by the compile job. begin: @echo @echo $(MSG_BEGIN)
finished: @echo $(MSG_ERRORS_NONE)
end: @echo $(MSG_END) @echo
# Display size of file. sizebefore: @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi
sizeafter: @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi
# Display compiler version information. gccversion : @$(CC) --version
# Convert ELF to COFF for use in debugging / simulating in # AVR Studio or VMLAB. COFFCONVERT=$(OBJCOPY) --debugging \ --change-section-address .data-0x800000 \ --change-section-address .bss-0x800000 \ --change-section-address .noinit-0x800000 \ --change-section-address .eeprom-0x810000
coff: $(TARGET).elf @echo @echo $(MSG_COFF) $(TARGET).cof $(COFFCONVERT) -O coff-avr $< $(TARGET).cof
extcoff: $(TARGET).elf @echo @echo $(MSG_EXTENDED_COFF) $(TARGET).cof $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
# Create final output files (.hex, .eep) from ELF output file. %.hex: %.elf @echo @echo $(MSG_FLASH) $@ $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
%.eep: %.elf @echo @echo $(MSG_EEPROM) $@ -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ --change-section-lma .eeprom=0 -O $(FORMAT) $< $@
# Create extended listing file from ELF output file. %.lss: %.elf @echo @echo $(MSG_EXTENDED_LISTING) $@ $(OBJDUMP) -h -S $< > $@
# Create a symbol table from ELF output file. %.sym: %.elf @echo @echo $(MSG_SYMBOL_TABLE) $@ avr-nm -n $< > $@
# Link: create ELF output file from object files. .SECONDARY : $(TARGET).elf .PRECIOUS : $(OBJ) %.elf: $(OBJ) @echo @echo $(MSG_LINKING) $@ $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)
# Compile: create object files from C source files. %.o : %.c @echo @echo $(MSG_COMPILING) $< $(CC) -c $(ALL_CFLAGS) $< -o $@
# Compile: create assembler files from C source files. %.s : %.c $(CC) -S $(ALL_CFLAGS) $< -o $@
# Assemble: create object files from assembler source files. #%.o : %.S # @echo # @echo $(MSG_ASSEMBLING) $< # $(CC) -c $(ALL_ASFLAGS) $< -o $@
%.o : %.asm @echo @echo $(MSG_ASSEMBLING) $< $(CC) -c $(ALL_ASFLAGS) $< -o $@
# Target: clean project. clean: begin clean_list finished end
clean_list : @echo @echo $(MSG_CLEANING) $(REMOVE) $(TARGET).hex $(REMOVE) $(TARGET).eep $(REMOVE) $(TARGET).obj $(REMOVE) $(TARGET).cof $(REMOVE) $(TARGET).elf $(REMOVE) $(TARGET).map $(REMOVE) $(TARGET).obj $(REMOVE) $(TARGET).a90 $(REMOVE) $(TARGET).sym $(REMOVE) $(TARGET).lnk $(REMOVE) $(TARGET).lss $(REMOVE) $(OBJ) $(REMOVE) $(LST) $(REMOVE) $(SRC:.c=.s) $(REMOVE) $(SRC:.c=.d)
# Automatically generate C source code dependencies. # (Code originally taken from the GNU make user manual and modified # (See README.txt Credits).) # # Note that this will work with sh (bash) and sed that is shipped with WinAVR # (see the SHELL variable defined above). # This may not work with other shells or other seds. # %.d: %.c set -e; $(CC) -MM $(ALL_CFLAGS) $< \ | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ [ -s $@ ] || rm -f $@
# Remove the '-' if you want to see the dependency files generated. include $(SRC:.c=.d)
# you need to erase first before loading the program. # load (program) the software into the eeprom: load: $(TARGET).hex uisp -dlpt=/dev/parport0 --erase -dprog=dapa uisp -dlpt=/dev/parport0 --upload if=$(TARGET).hex -dprog=dapa -v=3 --hash=32
rdfuses: uisp -dlpt=/dev/parport0 -dprog=dapa --rd_fuses @echo " " @echo "Explanation: See page 290 of data sheet"
# use internal RC oscillator 1 Mhz wrfuse1mhz: uisp -dlpt=/dev/parport0 -dprog=dapa --wr_fuse_l=0xe1 # use internal RC oscillator 4 Mhz wrfuse4mhz: uisp -dlpt=/dev/parport0 -dprog=dapa --wr_fuse_l=0xe3 # use internal RC oscillator 8 Mhz wrfuse8mhz: uisp -dlpt=/dev/parport0 -dprog=dapa --wr_fuse_l=0xe4 # use external crystal with internal oscillator wrfuseCrystal: uisp -dlpt=/dev/parport0 -dprog=dapa --wr_fuse_l=0xef uisp -dlpt=/dev/parport0 -dprog=dapa --wr_fuse_h=0xD9
# Listing of phony targets. .PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ clean clean_list program load
|
|
|
|
|
Sep 15 2006, 12:03
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата Но вот когда этого "вектора" нет - проблема действительно оказывается мистической.. Когда вектора нет, возможно три варианта: 1. Заняться чем-то другим. 2. Начать с начала. 3. Прочитать документацию медленно и внимательно. Но у вас imho ситуация гораздо проще. Есть рабочий код и есть не рабочий. Найдите отличия - и задача решена.
|
|
|
|
|
Sep 15 2006, 13:16
|
Знающий
   
Группа: Свой
Сообщений: 559
Регистрация: 6-09-06
Пользователь №: 20 131

|
Все! Проблема решена! Надо было после Код while ( (ADCSRA & ( 1 << ADIF))==0); добавить Код ADCSRA|=0x10; А в главном цикле программы вставить строку Код ADCSRA=0x87; Сейчас буду копаться в даташите, что это означает. Видимо каким-то образом АЦП не сбрасывалось... А теперь все работает. Всем спасибо и извините за беспокойство.
|
|
|
|
|
Sep 15 2006, 14:13
|
    
Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731

|
Если все равно поллинг, то почему флага ADIF, а не ADSC? При опросе ADIF по окончании преобразования его необходимо устанавливать в 1, как Вы сами уже разобрались. ADCSRA=0x87 в цикле вставлять не надо, если Вы не трогаете прескалер ADC и не запрещаете сам ADC в этом цикле. мое хо:  Код #define MUX_STATE (0 << REFS1)|(0 << REFS0)|(1<<ADLAR) #define ADC_STATE (1 << ADEN)|(0 << ADPS2)|(1 << ADPS1)|(1 <<ADPS0)
// somewhere before 1st ADC use ADCSRA = ADC_STATE;
unsigned char ReadADC(unsigned char ChannelNum) { ADMUX = ChannelNum | MUX_STATE; ADCSRA |= 1<<ADSC; while (ADCSRA & (1<<ADSC)) continue; return ADCH; }
send_pack(unsigned char byte) { unsigned char i, received_byte, bit_mask = 1;
received_byte=0x00; PORTC=0x00; for (i=0; i<8; i++) { if(byte & bit_mask) { PORTD.0 = 1; PORTD.1 = 0; } else { PORTD.0 = 0; PORTD.1 = 1; } // delay_ms(200);
received_byte <<= 1; if (ReadADC(0)>50) // if (PINA.7==1) { PORTC |= 1<<i; received_byte |= bit_mask; } else // if (PINA.7==0) { PORTC &= ~(1<<i); } bit_mask <<= 1; } // delay_ms(500); if (recieved_byte==byte) return 1; return 0; } Но на вкус, на цвет ...
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|