|  | roboforum.ruТехнический форум по робототехнике. |  | 
PWM1_Init(5000);PWM1_Set_Duty (192);unsigned short current_duty, old_duty, current_duty1, old_duty1;
void InitMain() {
  ANSEL  = 0;                         // Configure AN pins as digital I/O
  ANSELH = 0;
  PORTA = 255;
  TRISA = 255;                        // configure PORTA pins as input
  PORTB = 0;                          // set PORTB to 0
  TRISB = 0;                          // designate PORTB pins as output
  PORTC = 0;                          // set PORTC to 0
  TRISC = 0;                          // designate PORTC pins as output
  PWM1_Init(5000);                    // Initialize PWM1 module at 5KHz
  PWM2_Init(5000);                    // Initialize PWM2 module at 5KHz
}
void main() {
  InitMain();
  current_duty  = 16;                 // initial value for current_duty
  current_duty1 = 16;                 // initial value for current_duty1
  PWM1_Start();                       // start PWM1
  PWM2_Start();                       // start PWM2
  PWM1_Set_Duty(current_duty);        // Set current duty for PWM1
  PWM2_Set_Duty(current_duty1);       // Set current duty for PWM2
  while (1) {                         // endless loop
    if (RA0_bit) {                    // button on RA0 pressed
      Delay_ms(40);
      current_duty++;                 // increment current_duty
      PWM1_Set_Duty(current_duty);
     }
    if (RA1_bit) {                    // button on RA1 pressed
      Delay_ms(40);
      current_duty--;                 // decrement current_duty
      PWM1_Set_Duty(current_duty);
     }
    if (RA2_bit) {                    // button on RA2 pressed
      Delay_ms(40);
      current_duty1++;                // increment current_duty1
      PWM2_Set_Duty(current_duty1);
     }
    if (RA3_bit) {                    // button on RA3 pressed
      Delay_ms(40);
      current_duty1--;                // decrement current_duty1
      PWM2_Set_Duty(current_duty1);
     }
    Delay_ms(5);                      // slow down change pace a little
  }
}
char data1[6];
char data2[6];
int x;
unsigned i;
void main()
{
Lcd_Init(&PORTD);      
Lcd_Cmd(LCD_CURSOR_OFF); //курсор жки выключен
Lcd_Out(1,1,"ADC=");           
Lcd_Out(2,1,"servo=");      
TRISC.F5 =0;    //инициализация серв на трех портах
TRISB.F4 =0;
TRISB.F5 =0;
 while(1)
      {
ANSEL=0xFF;          //PORTA назначаем анлоговым
TRISA=0xFF;          //PORTA назначаем входом
ADCON0=0b11001101;           //режим: RC_Mode (11) ANALOG1(0011) GO(0) ADON(1)
ADCON0.GO=1;          //запуск цикла аналогово-цифрового преобразователя
      while(ADCON0.GO);     // ожидание завершения преобразования
        {
       x=(ADRESH*4)+(ADRESL/64);  // расчет полученных данных
       WordToStr(x,data1);      //преобразуем Х для вывода на экран
       Lcd_Out(1,12,data1);  // выводим на экран
       Delay_ms(100);           // в течении 100 миллисекунд
      i=(1900/100)*(x/(1023/100));   // пропорция для зависимости частоты АЦП и импульсов для сервы 
      i=i+500;                      // прибавляем 500 чтобы самое маленькое значение для сервы было не менее 500 (500 - это крайнее левое положение, правое 2400)
      i=i/1000;        // делим на 1000 для перевода микросекунд в миллисекунды, потому что функция Vdelay_ms(i); работает только с миллисекундами. Хотя этот момент я сам не очень понимаю. 
                            // Если мы задаем i от 500-2400 то почему бы Vdelay_ms(i); не принимать их за миллисекунды? Впрочем если на 1000 не делить - то работать вообще не будет...
      WordToStr(i,data2);
      Lcd_Out(2,12,data2);    
      Delay_ms(100);          
ANSEL=0x00;
ANSELH=0x00;
PORTC.F5=1;          //команды работать соответствующим выходам
PORTB.F5=1;
PORTB.F4=1;
Vdelay_ms(i);    
PORTC.F5=0;
PORTB.F5=0;
PORTB.F4=0;
delay_ms(20);     // самое интересное, что если убрать эту строчку программа будет работать абсолютно также, и серва будет точно также колбаситься...
         }
       }
}

x=(ADRESH*4)+(ADRESL/64); // вычисление частоты процессора

Zeus писал(а)::)).
2. Процедура VDelay_Advanced_ms (изначально предназначена для генерации милисекунд)
Prototype - void VDelay_Advanced_ms(unsigned time_in_ms, unsigned Current_Fosc_kHz);
Description Creates a software delay in duration of time_in_ms milliseconds (a variable), for a given oscillator frequency. Generated delay is not as precise as the delay created by Delay_ms.
Программная задержка в "реальных" "time_in_ms" милисекунах, которая привязана к частоте кварца.
Example pause = 1000;
fosc = 10000; (Частоту вводим в килогерцах, т.е. 10МГц/1000=10000 кГц)
VDelay_Advanced_ms(pause, fosc); // Generates approximately one second pause, for a oscillator frequency of 10 MHz
unsigned = 0...65535, так что максимум типа 65,535 МГц.
Так что четкие и правильные микросекунды этой процедурой не получить.
При кварце 10МГц можно конечно ввести 50000, тогда при time_in_ms = 1 может быть задержка будет 0,2 мс или 200 мкс...
Zeus писал(а): При кварце 10МГц можно конечно ввести 50000, тогда при time_in_ms = 1 может быть задержка будет 0,2 мс или 200 мкс...

- скорее всего так, типа занижаем тактовую частоту, а реально он на 10 МГц шпарит, может быть и так... я ошибочно увеличил в 5 раз.При кварце 10МГц нужно ввести 2000
в пару ADRESH и ADRESL записывается результат анлогово-цифрового преобразования и для того чтобы использовать полученные данные мы их вычисляем

Да это я понимаю, комментарий то написан "x=(ADRESH*4)+(ADRESL/64); // вычисление частоты процессора"
вот и спрашиваю причем здесь вычиление частоты процессора, когда вычисляешь данные с АЦП?

ANSEL=0xFF;          //PORTA назначаем анлоговымANSEL=0x00;
ANSELH=0x00;



Zeus писал(а):я что-то не пойму, у тебя какой контроллер - PIC16F877?
 
 Zeus писал(а):вот сижу листаю даташит и не могу найти там никакого регистра
- Код: Выделить всё • Развернуть
ANSEL=0xFF; //PORTA назначаем анлоговым
и вот эти тоже:
- Код: Выделить всё • Развернуть
ANSEL=0x00;
ANSELH=0x00;
в этих контроллерах вроде ADCON0 и ADCON1 только есть и ADRESH с ADRESL соответственно.
Регистр ADCON0 используется для настройки работы модуля АЦП, а с помощью регистра ADCON1 устанавливаются какие входы микроконтроллера будут использоваться модулем АЦП и в каком режиме (аналоговый или цмфровой порт вводаввывода).
Если у тебя действительно PIC16F877, то перечитай раздел 11 (модуль АЦП) даташита.
да ты не спеши все сделаешь и разберешься
 
 Zeus писал(а):можно узнать, а зачем вообще такая формула сложная: x=(ADRESH*4)+(ADRESL/64)
зачем ADRESH умножать на 4, а ADRESL делить на 64 и потом все это складывать?

 только как обычно времени очень мало свободного - сегодня только с Сызрани вернулся.
 только как обычно времени очень мало свободного - сегодня только с Сызрани вернулся.Помимо вышеприведенных микроконтроллеров, Microchip продолжает выпуск "устаревших" семейств (PIC16F627A/628A/648A, PIC16F72/73/74/76/77, PIC16F737/747/767/777, PIC16F818/819, PIC16F84(A), PIC16F87/88, PIC16F87x/87xA). Следует обратить внимание, что в большинстве случаев возможно и целесообразно осуществить переход к более новому семейству, обеспечивающему ту же функциональность, что позволит значительно сэкономить


Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0