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

Александр К.

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

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

  • Посещение

Весь контент Александр К.


  1. Ещё разок помогите, пожалуйста. Тот же компилятор. signed char k_corr=25 ; int t_gor=1369,t_gor_nev; unsigned int t_pper=6893; В формуле t_gor_nev=t_gor-(((long)t_pper*k_corr+90)/180); происходит переполнение за счёт t_pper*k_corr. Как исправить?
  2. Спасибо. Вечером проверю, что в этом регистре.
  3. Запутался с таймером. Помогите. CodeVisionAVR, Mega 16. Нужно: 250 кГц, Normal top, прерывание по переполнению и по Comp.A, Comp.B. На выводы ничего не выводить, с выводов не прерываться. CodeVision даёт такую настройку: /[code]/ Timer/Counter 1 initialization // Clock source: System Clock // Clock value: 250,000 kHz // Mode: Normal top=FFFFh // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer 1 Overflow Interrupt: On // Input Capture Interrupt: Off // Compare A Match Interrupt: On // Compare B Match Interrupt: On TCCR1A=0x00; TCCR1B=0x03; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; [/code] и также [code]// Timer 1 overflow interrupt service routine interrupt [TIM1_OVF] void timer1_ovf_isr(void) { // Place your code here } // Timer 1 output compare A interrupt service routine interrupt [TIM1_COMPA] void timer1_compa_isr(void) { // Place your code here } // Timer 1 output compare B interrupt service routine interrupt [TIM1_COMPB] void timer1_compb_isr(void) { // Place your code here } [/code] Проблема: прерывание по переполнению есть, а двух других нет. Значения OCR1A, OCR1B в программе меняются на ненулевые. Где моя ошибка?
  4. По описанию CodeVision это вроде допускается - не указывать длинну. Сам должен подсчитать :) .
  5. Если массив определить вот так: unsigned int t_zub_i[], то в него ничего не пишется (или пишется непонятно что), хотя и ошибок при компиляции никаких не показывается. Обошёл просто: unsigned int t_zub_i[96]. Т.е. при явном задании числа элементов массива всё заработало.
  6. Я нашёл, где косяк. CodeVisionAVR не может выполнить такой код: while((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=0x1234; } Разумеется, сообщений об ошибках нет. Т.е. индекс массива не может быть задан как переменная? Или элементы массива по одиночке нельзя переопределять? Как это можно обойти?
  7. В чём извращение? Прерывание на каждый такт нужны временно, в дальнейшем прерывания планируются на такты 1,5,10,11,19,20,25,26,29. Иначе завёл бы сигнал на INT0. Качество сигнала очень хорошее + стоит компаратор с гистерезисом. Вы хотите сказать, что TCNT0 получится перезаписывать каждый такт, а OCR0 нет? Кстати, перепаять один провод - не проблема.
  8. Таймер тактируется внешним сигналом - примерно каждые 2мс. Прерывание - на каждый такт. Индекс у меня - глобальная переменная - он используется и в другом месте. К нему претензий нет. Может, взять Mega 164? Там вроде два регистра сравнения, будет две функции прерывания - поочерёдно. Дорого только ...
  9. i_zub проходит один цикл изменения от 0 до заданного и больше не обнуляется.
  10. Эта: case 29: ... OCR0=1; TCNT0=0; ... На п.1. Какая разница? Если можно, поясните. Это как? И где завершается период - при начале следующего? Может, в этом проблема?
  11. Как побороть? Есть такое: char i_zub=0; Вполне успевает.
  12. Есть потребность непрерывно перезаписывать в Меге 16 OCRO. Можно ли это делать? Дело в том, что на практике запись идёт с ошибками. // Timer 0 output compare interrupt service routine interrupt [TIM0_COMP] void timer0_comp_isr(void) { if ((!PINB.3) && (!flag_s_eep)) { flag_s=1; // Разрешение записи PORTD.5=0; // Индикация записи - включить СД } if(!flag_start) { flag_start=1; TCNT1=0; TCNT0=0; OCR0=1; t_zub=0; return; } if(!flag_zub1) // Поиск 1-го зуба { t_zub0=t_zub; t_zub=TCNT1; TCNT1=0; if((t_zub > (t_zub0 + (t_zub0>>1))) && (t_zub0)) { flag_zub1=1; t_zub4=0; OCR0=5; } else TCNT0=0; return; } switch (OCR0) { case 1: t_zub1=TCNT1; t_zub0=t_zub; t_zub=t_zub1-t_zub29; if(t_zub < (t_zub0 + (t_zub0>>1))) { //PORTD.5=0; // Индикация потери синхронизации } //else PORTD.5=1; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=1; t_zub_i[i_zub++]=t_zub; } OCR0=2; break; case 2: t_zub2=TCNT1; t_zub=t_zub2-t_zub1; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=2; t_zub_i[i_zub++]=t_zub; } OCR0=3; break; case 3: t_zub3=TCNT1; t_zub=t_zub3-t_zub2; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=3; t_zub_i[i_zub++]=t_zub; } OCR0=4; break; case 4: t_zub4=TCNT1; t_zub=t_zub4-t_zub3; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=4; t_zub_i[i_zub++]=t_zub; } OCR0=5; break; case 5: t_zub5=TCNT1; TCNT1=0; t_zub=t_zub5-t_zub4; if((t_zub5)&&(t_zub4)) // При t_zub4=0 нет данных { // о времени полуоборота n=7500000/t_zub5; if(n > 600) flag_pusk=1; // Запуск двигателя произведён. flag_pper=1; } if((i_zub < i_zub_max) && (flag_s) && (t_zub4)) { t_zub_i[i_zub++]=5; t_zub_i[i_zub++]=t_zub; } OCR0=6; break; case 6: t_zub6=TCNT1; t_zub=t_zub6; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=6; t_zub_i[i_zub++]=t_zub; } OCR0=7; break; case 7: t_zub7=TCNT1; t_zub=t_zub7-t_zub6; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=7; t_zub_i[i_zub++]=t_zub; } OCR0=8; break; case 8: t_zub8=TCNT1; t_zub=t_zub8-t_zub7; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=8; t_zub_i[i_zub++]=t_zub; } OCR0=9; break; case 9: t_zub9=TCNT1; t_zub=t_zub9-t_zub8; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=9; t_zub_i[i_zub++]=t_zub; } OCR0=10; break; case 10: t_zub10=TCNT1; t_zub=t_zub10-t_zub9; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=10; t_zub_i[i_zub++]=t_zub; } OCR0=11; break; case 11: t_zub11=TCNT1; t_zub=t_zub11-t_zub10; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=11; t_zub_i[i_zub++]=t_zub; } OCR0=12; break; case 12: t_zub12=TCNT1; t_zub=t_zub12-t_zub11; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=12; t_zub_i[i_zub++]=t_zub; } OCR0=13; break; case 13: t_zub13=TCNT1; t_zub=t_zub13-t_zub12; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=13; t_zub_i[i_zub++]=t_zub; } OCR0=14; break; case 14: t_zub14=TCNT1; t_zub=t_zub14-t_zub13; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=14; t_zub_i[i_zub++]=t_zub; } OCR0=15; break; case 15: t_zub15=TCNT1; t_zub=t_zub15-t_zub14; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=15; t_zub_i[i_zub++]=t_zub; } OCR0=16; break; case 16: t_zub16=TCNT1; t_zub=t_zub16-t_zub15; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=16; t_zub_i[i_zub++]=t_zub; } OCR0=17; break; case 17: t_zub17=TCNT1; t_zub=t_zub17-t_zub16; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=17; t_zub_i[i_zub++]=t_zub; } OCR0=18; break; case 18: t_zub18=TCNT1; t_zub=t_zub18-t_zub17; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=18; t_zub_i[i_zub++]=t_zub; } OCR0=19; break; case 19: t_zub19=TCNT1; t_zub=t_zub19-t_zub18; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=19; t_zub_i[i_zub++]=t_zub; } OCR0=20; break; case 20: t_zub20=TCNT1; TCNT1=0; t_zub=t_zub20-t_zub19; if(t_zub20) n=7500000/t_zub20; if(n > 600) flag_pusk=1; // Запуск двигателя произведён. flag_pper=1; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=20; t_zub_i[i_zub++]=t_zub; } OCR0=21; break; case 21: t_zub21=TCNT1; t_zub=t_zub21; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=21; t_zub_i[i_zub++]=t_zub; } OCR0=22; break; case 22: t_zub22=TCNT1; t_zub=t_zub22-t_zub21; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=22; t_zub_i[i_zub++]=t_zub; } OCR0=23; break; case 23: t_zub23=TCNT1; t_zub=t_zub23-t_zub22; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=23; t_zub_i[i_zub++]=t_zub; } OCR0=24; break; case 24: t_zub24=TCNT1; t_zub=t_zub24-t_zub23; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=24; t_zub_i[i_zub++]=t_zub; } OCR0=25; break; case 25: t_zub25=TCNT1; t_zub=t_zub25-t_zub24; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=25; t_zub_i[i_zub++]=t_zub; } OCR0=26; break; case 26: t_zub26=TCNT1; t_zub=t_zub26-t_zub25; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=26; t_zub_i[i_zub++]=t_zub; } OCR0=27; break; case 27: t_zub27=TCNT1; t_zub=t_zub27-t_zub26; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=27; t_zub_i[i_zub++]=t_zub; } OCR0=28; break; case 28: t_zub28=TCNT1; t_zub=t_zub28-t_zub27; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=28; t_zub_i[i_zub++]=t_zub; } OCR0=29; break; case 29: t_zub29=TCNT1; t_zub=t_zub29-t_zub28; if((i_zub < i_zub_max) && (flag_s)) { t_zub_i[i_zub++]=29; t_zub_i[i_zub++]=t_zub; } OCR0=1; TCNT0=0; break; } //Скобка switch } Фрагмент массива t_zub_i : 001D 0A0A 0022 C44F 0003 01AD 0003 01A7 0004 01A0 0005 0359... В этом массиве нечётные "слова" должны увеличиваться на единицу до 29 включительно, затем опять начинаться с единицы. Но в реальности этого гарантированно нет. Почему?
  13. Работает. Спасибо. Нужно результат работы программы разместить в eeprom в виде нескольких массивов так, чтобы знать, где что. Массив поэлементно как записать? Версия 2.03.4 Standard. Goodefine, попробую.
  14. Теперь другая ошибка: Error: a value of type 'const int' can't be assigned to an entity of type 'eeprom unsigned int *' В строках point=eeprom_const_adr1 и point=eeprom_const_adr2; В англицком я не силён ...
  15. Так не получается. Ошибка: Error: ...: missing '(' В строчке const eeprom_const_adr1=0x10;
  16. Нужно записывать данные в eeprom AVR по конкретным адресам, используя CodeVisionAVR. #include <mega16.h> eeprom unsigned int *point; void main(void) { } Нужно задать значение point, а затем по этому адресу записать данные. Как это пишется?
  17. Убрал лишнее из прерывания. И при #pragma savereg- работает. Был неправ. Спасибо за помощь.
  18. В регистрах. Но их (регистров) больше, чем переменных. И все переменные - глобальные. Пересечений нет. Вот фрагмент на асемблере. После остановки симулятора указатель показывает на адрес 180. +00000172: E7AA LDI R26,0x7A Load immediate +00000173: E0B0 LDI R27,0x00 Load immediate +00000174: 91EC LD R30,X Load indirect +00000175: E0F0 LDI R31,0x00 Load immediate +00000176: 64E0 ORI R30,0x40 Logical OR with immediate +00000177: 93EC ST X,R30 Store indirect +00000178: 9508 RET Subroutine return +00000179: 91E9 LD R30,Y+ Load indirect and postincrement +0000017A: 91F9 LD R31,Y+ Load indirect and postincrement +0000017B: 9630 ADIW R30,0x00 Add immediate to word +0000017C: F039 BREQ PC+0x08 Branch if equal +0000017D: EA80 LDI R24,0xA0 Load immediate +0000017E: E09F LDI R25,0x0F Load immediate +0000017F: 9701 SBIW R24,0x01 Subtract immediate from word +00000180: F7F1 BRNE PC-0x01 Branch if not equal +00000181: 95A8 WDR Watchdog reset +00000182: 9731 SBIW R30,0x01 Subtract immediate from word +00000183: F7C9 BRNE PC-0x06 Branch if not equal +00000184: 9508 RET Subroutine return +00000185: 95F1 NEG R31 Two's complement +00000186: 95E1 NEG R30 Two's complement +00000187: 40F0 SBCI R31,0x00 Subtract immediate with carry +00000188: 9508 RET Subroutine return +00000189: 2400 CLR R0 Clear Register Я в этом не понимаю ... Конкретный косяк не видно? Очень хочется не сохранять все РОН при прерывании.
  19. Спасибо. Посмотрел по ссылке, но не понял - почему нельзя использовать штатную команду? Я в прерывании регистры не использую, все переменные - глобальные. И почему ж нельзя? Глюк CV? ----------------------------------------------------------------------------------------------------------- Исправил и проверил. Всё нормально. Ещё раз спасибо. Вопрос остался ...
  20. /***************************************************** This program was produced by the CodeWizardAVR V2.03.4 Standard Automatic Program Generator © Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l. http://www.hpinfotech.com Project : Подсос С АЦП и без таймеров Version : 3-5 Date : 30.09.2009 Author : Company : Comments: Пропущенный участок работает в железе без проблем. Chip type : ATmega164 Program type : Application Clock frequency : 16.000000 MHz Memory model : Small External RAM size : 0 Data Stack size : 256 *****************************************************/ #pragma savereg- // Выключить автоматическое сохранение регистров #include <mega164.h> #include <delay.h> #define start_ADC ADCSRA|=(1<<6);// Запуск АЦП #define ADC_VREF_TYPE 0x60 char i=0,j_tec=0,j_max=130,t_i=0,adc_data=0,i_adc_buf,k; //i - номер фазы коммутации обмоток ШД //j-tec - текущее положение ротора ШД 0<=j_tec<=j_max //j-max - максимальное число полушагов ротора //t_i - период коммутации фаз (0-16ms,130-8,193-4,224-2,239-1) //i_adc_buf - номер в буфере АЦП signed char j=0; //j=1 пр. часовой,j=-1 по часовой,иначе - координата. char step[]={16,80,64,96,32,160,128,144};// комбинации фаз char adc_buf[3]={0,0,0};// Кольцевой буфер для усреднения АЦП void SW_step(void) { if (i==7)i=0; else ++i; PORTA=step[i]; } void SSW_step(void) {if (i==0)i=7; else --i; PORTA=step[i]; } void poworot (void) { if (j==-1)goto L0; if (j!=1)goto L3; if (j_tec==j_max)return; L1: SSW_step(); j_tec++; return; L0: if (j_tec==0) { return; } L2: SW_step(); j_tec--; return; L3: if(j<0) { return; } if(j>j_tec) goto L1; if(j<j_tec) goto L2; } // ADC interrupt service routine interrupt [ADC_INT] void adc_isr(void) { unsigned char adc_data; // Read the 8 most significant bits // of the AD conversion result // Place your code here adc_data=ADCH; adc_data=(adc_data>>1); // j не больше 127 if(adc_data==1) adc_data=0;// j==1 исключается - особенность функции poworot if(i_adc_buf>=2) i_adc_buf=0; else ++i_adc_buf; j=(adc_buf[0]+adc_buf[1]+adc_buf[2]+adc_data)/4; //рекурсия adc_buf[i_adc_buf]=j; } // Declare your global variables here void main(void) { // Declare your local variables here // Input/Output Ports initialization // Port A initialization // Func7=Out Func6=Out Func5=Out Func4=Out Func3=In Func2=In Func1=In Func0=Out // State7=0 State6=0 State5=0 State4=0 State3=T State2=T State1=T State0=0 PORTA=0x00; DDRA=0xF1; // Port B initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTB=0x00; DDRB=0x00; // Port C initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTC=0x00; DDRC=0x00; // Port D initialization // Func7=Out Func6=Out Func5=Out Func4=In Func3=In Func2=In Func1=In Func0=In // State7=0 State6=0 State5=0 State4=T State3=T State2=T State1=T State0=T PORTD=0x00; DDRD=0xE0; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: Timer 0 Stopped // Mode: Normal top=FFh // OC0A output: Disconnected // OC0B output: Disconnected TCCR0A=0x00; TCCR0B=0x00; TCNT0=0x00; OCR0A=0x00; OCR0B=0x00; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: Timer 1 Stopped // Mode: Normal top=FFFFh // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer 1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // Timer/Counter 2 initialization // Clock source: System Clock // Clock value: Timer 2 Stopped // Mode: Normal top=FFh // OC2A output: Disconnected // OC2B output: Disconnected ASSR=0x00; TCCR2A=0x00; TCCR2B=0x00; TCNT2=0x00; OCR2A=0x00; OCR2B=0x00; // External Interrupt(s) initialization // INT0: Off // INT1: Off // INT2: Off // Interrupt on any change on pins PCINT0-7: Off // Interrupt on any change on pins PCINT8-15: Off // Interrupt on any change on pins PCINT16-23: Off // Interrupt on any change on pins PCINT24-31: Off EICRA=0x00; EIMSK=0x00; PCICR=0x00; // Timer/Counter 0 Interrupt(s) initialization TIMSK0=0x00; // Timer/Counter 1 Interrupt(s) initialization TIMSK1=0x00; // Timer/Counter 2 Interrupt(s) initialization TIMSK2=0x00; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; ADCSRB=0x00; // ADC initialization // ADC Clock frequency: 125.000 kHz // ADC Voltage Reference: AVCC pin // ADC Auto Trigger Source: None // Only the 8 most significant bits of // the AD conversion result are used // Digital input buffers on ADC0: Off, ADC1: Off, ADC2: Off, ADC3: Off // ADC4: Off, ADC5: Off, ADC6: Off, ADC7: Off DIDR0=0xFF; ADMUX=ADC_VREF_TYPE & 0xff; ADCSRA=0x8F; goto L11; k=0; j=1; while(j_tec!=125) { poworot(); delay_ms(2); } delay_ms(2000); j=-1; while(j_tec!=20) { poworot(); delay_ms(50); } delay_ms(2000); j=70; while(k<200) { poworot(); delay_ms(1); k++; } delay_ms(2000); L11: #asm("sei") // Разрешить прерывания ADMUX=1;// Первый канал АЦП start_ADC; while (1) { poworot(); delay_ms(2); start_ADC; } }
  21. Как на этом движке дать вложение? Или дать программу текстом?
×
×
  • Создать...