2011年5月9日 星期一

DIY - PIC:PIC18F4550 USB PIC 端程式 (六十八)

DIY - PICPIC18F4550 USB PIC程式 (十八)

Microchip 18F4550 單片機系列晶片有提供了面向不同客戶群的 DEMO 程式,可以減輕了系統開發人員的負擔,同時縮短了開發週期。

USB Framework 固件網址Microchip Application Libraries v2010-10-19 

程式選用了 USB Device - HID - Custom Demos程式。HID (Human Interface Devices,人機接口設備)是一類的 USB 設備,讓結構的數據,將在設備之間傳輸和主機電腦。在枚舉過程,設備描述信息,它可以接收和發送。USB 通信都是通過中斷來完成的,在 USB 中斷服務程式內,要實現輸入/輸出介面,允許大多數的USB程式在後台完成,電腦主機處理的數據接收從 USB 設備而不需要一個特別設計的設備驅動程序。

USB Device - HID - Custom Demos (目錄下的子目錄) 
└ Generic HID – Firmware 
└ Generic HID - HID DLL - PC Software 
└ Generic HID - PnP Demo - PC Software 
└ Generic HID - Simple Demo - PC Software

USB 程式的設計就是在 Microchip 公司提供的 DEMO 程式的基礎上,進行必要的修改來完成的。

Generic HID – Firmware (子目錄下的文件) 
main.c 
usb_config.c 
usb_descriptors.c 
HardwareProfile - PICDEM FSUSB.c 
USB Device - HID - Simple Custom Demo - C18 - PICDEM FSUSB.mcw 

Microchip (微芯) 提供了一系列的 USB 寄存器,使用這些寄存器可以完成 USB 通信。大多數的 USB 通信都是通過中斷來完成的,在 USB 中斷服務程式內,要實現輸入/輸出介面,允許大多數的 USB 程式在後台完成。從應用的觀點來看,枚舉過程和資料通信的發生好像沒有聯繫。 

在系統主程序 (main.c) 內的 ProcessIO修改, 18F4550 USB 接收到 PC 送來的指令,18F4550 便會作出不同的操作,如 開關 LED、讀 ADC 數值或讀出控鍵狀態。
 
void ProcessIO(void)
{  
    //Blink the LEDs according to the USB device status
    if(blinkStatusValid)
    {
        BlinkUSBStatus();
    }

    // User Application USB tasks
    if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return;
   
    if(!HIDRxHandleBusy(USBOutHandle))     //Check if data was received from the host.
    {  
        switch(ReceivedDataBuffer[0])                //Look at the data the host sent, to see what kind
                                                                                 of application specific command it sent.
        {
            case 0x80:  //Toggle LEDs command
                blinkStatusValid = FALSE;            //Stop blinking the LEDs automatically, going to
                                                                              manually control them now.
                if(mGetLED_1() == mGetLED_2())
                {
                    mLED_1_Toggle();
                    mLED_2_Toggle();
                }
                else
                {
                    if(mGetLED_1())
                    {
                        mLED_2_On();
                    }
                    else
                    {
                        mLED_2_Off();
                    }
                }
               
                break;
            case 0x81:  //Get push button state
                ToSendDataBuffer[0] = 0x81;                //Echo back to the host PC the command we are
                                                                                      fulfilling in the first byte.  In this case, the Get
                                                                                      Pushbutton State command.
                if(sw3 == 1)                            //pushbutton not pressed, pull up resistor on circuit
                                                                   board is pulling the PORT pin high
                {
                    ToSendDataBuffer[1] = 0x01;           
                }
                else        //sw3 must be == 0, pushbutton is pressed and overpowering the pull up resistor
                {
                    ToSendDataBuffer[1] = 0x00;
                }
                if(!HIDTxHandleBusy(USBInHandle))
                {
                    USBInHandle = HIDTxPacket(HID_EP,(BYTE*)&ToSendDataBuffer[0],64);
                }
                break;

            case 0x37:    //Read POT command.  Uses ADC to measure an analog voltage
                                    on one of the ANxx I/O pins, and returns the result to the host
                {
                    WORD_VAL w;

                    if(!HIDTxHandleBusy(USBInHandle))
                    {
                        mInitPOT();
                        w = ReadPOT();    //Use ADC to read the I/O pin voltage.  See the relevant 
                                                           HardwareProfile - xxxxx.h file for the I/O pin that it will measure.
                                                        //Some demo boards, like the PIC18F87J50 FS USB Plug-In
                                                           Module board, do not have a potentiometer (when used stand alone).
                                                        //This function call will still measure the analog voltage on the
                                                           I/O pin however.  To make the demo more interesting, it
                                                        //is suggested that an external adjustable analog voltage should be applied to this pin.
                        ToSendDataBuffer[0] = 0x37;      //Echo back to the host the command we are fulfilling in the first byte.  In this case, the Read POT (analog voltage) command.
                        ToSendDataBuffer[1] = w.v[0];      //Measured analog voltage LSB
                        ToSendDataBuffer[2] = w.v[1];      //Measured analog voltage MSB

                        USBInHandle = HIDTxPacket(HID_EP,(BYTE*)&ToSendDataBuffer[0],64);

        LcdSetLine2();                        // Put cursor on start of line 2
        printf("D=%04i",w);

                    }                   
                }
                break;
        }
        //Re-arm the OUT endpoint for the next packet
        USBOutHandle = HIDRxPacket(HID_EP,(BYTE*)&ReceivedDataBuffer,64);
    }
   
}//end ProcessIO
  ProcessIO 子程式

紅圈是 USB 主要的控制設備
LCD1602 顯示 ADC 的數據

2011 05 09 天氣報告
氣溫:25.7 @ 22:00 
相對濕度:百分之85%  
天氣:天色大致良好


沒有留言:

張貼留言