PIC A / D转换问题

时间:2010-12-13 14:07:22

标签: c microcontroller pic threshold analog-digital-converter

我正在尝试使用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端口读取使用OpenADC()API方法的myReadADC():

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)时,LED不闪烁,低阈值(~0)当我向电源提供电源时,它会立即闪烁图片。也许我使用错误的端口?我实际上是通过AN9作为阅读端口?或者可能是门槛错了?我怎样才能找到合适的价值?谢谢

这里是MPLAB C18 Apis http://dl.dropbox.com/u/14663091/API%20microchip%20C18.pdf

1 个答案:

答案 0 :(得分:1)

关于函数myReadADC2():,您需要切换ANSEL和ANSELH配置,因为在ANSELH的第1位配置了RC7 / AN9。也叫我偏执,但为行

iRet += (ADRESH << 8);

我总是喜欢先将它保存为临时变量,或者在转移它之前明确地转换值ADRESH:

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

这样我就确切地知道这些位不会在向上移动时丢失,这已经让我感到困惑。

关于函数myReadADC(): OpenADC()只接受两个参数。我假设第三个参数字段中的位域用于模拟使能(ADRESH / ADRES)。我假设由SetChanADC()处理,但您可能必须手动设置ADRESH / ADRES。可能有助于在调试器中设置断点并在配置完成后停止以确保您的寄存器设置为appropriatley。