Проблемы с PIC A / D преобразованием - PullRequest
1 голос
/ 13 декабря 2010

Я пытаюсь прочитать аналоговый сигнал для мыши с контроллером pic18f14k50.Вот простая схема: http://dl.dropbox.com/u/14663091/schematiconew.pdf.Я должен прочитать аналоговый сигнал от порта схемы AN9.Основная функция читает данные из порта и мигает 30 раз при достижении порога:

 void main(void) {
      InitializeSystem();

      #if defined(USB_INTERRUPT)
         USBDeviceAttach();
     #endif

     while(1) {

             if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) continue;

      if(!HIDTxHandleBusy(lastTransmission))
      {
       int readed = myReadADC2(); //Here i tried both myReadADC2() or myReadADC1()
       if(readed>40) { //If read threshold > 40, blink led 30 times
        int i;
        for(i=0; i<30; i++) {
         Delay1KTCYx(0);
         mLED_1_On();
         Delay1KTCYx(0);
         mLED_1_Off();
        }
              }
              lastTransmission = HIDTxPacket(HID_EP, (BYTE*)hid_report_in, 0x03);


     }//end while
 }//end main

Я использовал два метода для чтения с порта AN9, myReadADC (), который использует метод API OpenADC ():

int myReadADC(void) {
   #define ADC_REF_VDD_VDD_X 0b11110011                      
   OpenADC(ADC_FOSC_RC & ADC_RIGHT_JUST & ADC_12_TAD, ADC_CH9 & ADC_INT_OFF, ADC_REF_VDD_VDD_X & ADC_REF_VDD_VSS, 0b00000010); // channel 9
   SetChanADC(ADC_CH9);
   ConvertADC();                 // Start conversion
   while(BusyADC());             // Wait for completion
   return ReadADC();           // Read result
}

и myReadADC2 (), которые реализуют чтение вручную из порта.

int myReadADC2() {

  int iRet;
  OSCCON=0x70;         // Select 16 MHz internal clock
  ANSEL = 0b00000010;  // Set PORT AN9 to analog input
  ANSELH = 0;          // Set other PORTS as Digital I/O
  /* Init ADC */
  ADCON0=0b00100101;   // ADC port channel 9 (AN9), Enable ADC
  ADCON1=0b00000000;   // Use Internal Voltage Reference (Vdd and Vss)
  ADCON2=0b10101011;   // Right justify result, 12 TAD, Select the FRC for 16 MHz
  iRet=100;


  ADCON0bits.GO=1;
  while (ADCON0bits.GO);   // Wait conversion done
  iRet=ADRESL;           // Get the 8 bit LSB result
  iRet += (ADRESH << 8); // Get the 2 bit MSB result
  return iDelay; 

}

В обоих случаях не работает, я касаюсь (отправка аналогового сигнала) порта AN9, но когда я устанавливаю высокий порог(~ 50) светодиод не мигает, с низким порогом (~ 0) он мигает, когда я подаю питание на ПИК.Может быть, я использую неправильный порт?Я на самом деле передаю AN9 в качестве порта чтения?А может порог неправильный?Как я могу найти правильное значение?Спасибо

Здесь MPLAB C18 Apis http://dl.dropbox.com/u/14663091/API%20microchip%20C18.pdf.

1 Ответ

1 голос
/ 14 декабря 2010

Относительно функции myReadADC2 (): вам необходимо переключить конфигурации ANSEL и ANSELH, так как RC7 / AN9 сконфигурирован в бите 1 ANSELH.Также назовите меня параноиком, но для строки

iRet += (ADRESH << 8);

Я всегда хотел бы сначала сохранить ее во временную переменную или явно привести значение ADRESH, прежде чем сдвинуть его вверх:

iRet += (((UINT) ADRESH) << 8);

Таким образомЯ точно знаю, что биты не будут потеряны при переходе вверх, который укусил меня раньше.

Относительно функции myReadADC (): OpenADC () принимает только два параметра.Я предполагаю, что битовое поле в третьем поле параметра предназначено для аналогового разрешения (ADRESH / ADRES).Я предполагаю, что это обрабатывается SetChanADC (), но вам, возможно, придется установить ADRESH / ADRES вручную.Это может помочь установить точку останова в отладчике и остановиться после завершения настройки, чтобы убедиться, что ваши регистры установлены соответствующим образом.

...