PIC A/D 转换问题

发布于 2024-10-07 12:12:06 字数 2529 浏览 10 评论 0原文

我正在尝试使用 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() 使用 OpenADC() API 方法:

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)时,当我向 PIC 供电时,它会立即闪烁。也许我使用了错误的端口?我实际上正在传递 AN9 作为读取端口?或者阈值可能是错误的?我怎样才能找到正确的值?谢谢

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

I am trying to read analogic signal for a sort of mouse with a pic18f14k50 controller. Here the simple circuit: http://dl.dropbox.com/u/14663091/schematiconew.pdf . I have to read analogic signal from AN9 circuit port. Main function reads from the port, and blinks 30 time if threshold is reached:

 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

I used two method to read from the AN9 port, myReadADC() that uses OpenADC() API method:

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
}

and myReadADC2(), that implements manual read from the port.

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; 

}

Both cases doesn't works, i touch (sending analogic signal) port AN9 but when I set high threshold (~50) led don't blinks, with low threshold (~0) it blinks immidiatly when i provide power to the PIC. Maybe i'm using wrong port? I'm actually passing AN9 as reading port? Or maybe threshold is wrong? How can i found the right value? Thank you

Here the MPLAB C18 Apis http://dl.dropbox.com/u/14663091/API%20microchip%20C18.pdf .

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

娇纵 2024-10-14 12:12:06

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

iRet += (ADRESH << 8);

我总是喜欢先将其保存为临时变量,或者在向上移动之前显式转换值 ADRESH :

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

这样我确信在向上移动时这些位不会丢失,这让我很痛苦前。

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

Regarding function myReadADC2(): you need to switch ANSEL and ANSELH configs as RC7/AN9 is configured in bit 1 of ANSELH. Also call me paranoid but for the line

iRet += (ADRESH << 8);

I always like to either save it a temporary variable first or cast explicitly the value ADRESH before shifting it up:

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

That way I know for sure the bits won't get lost when shifting up which has bitten me before.

Regarding function myReadADC():
OpenADC() only takes two parameters. I presume that bitfield in the third parameter field is for the analog enable (ADRESH/ADRES). I'm assuming that's handled by SetChanADC() but you may have to set ADRESH/ADRES manually. It may help to set a breakpoint in the debugger and stop after configuration is complete to make sure your registers are set appropriatley.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文