close

 

8051 ASM

;────────────────────────────────
    ;記憶體宣告,宣告各中斷程式存放在記憶體的位址
;────────────────────────────────
        ORG    0H    ;主程式存放位址,從0開始
        AJMP    MAIN    ;跳到主程式段,執行主程式
        ORG    03H    ;外部中斷INT0服務程式存放位址,從03H開始
        AJMP    INT0    ;跳到外部中斷INT0,執行外部中斷0服務程式

;────────────────────────────────
;主程式開始
;────────────────────────────────
;使用副程式有
;    INIT_SERIAL:設定串列埠的初值

MAIN:    ;主程式名稱
    ACALL    INIT_SERIAL        ;設定串列埠的初值
M5:
    NOP
SJMP    M5                ;不做任何事,等待中斷


;────────────────────────────────
;中斷服務程式0開始
;────────────────────────────────
INT0:                        ;外部中斷INT0服務程式名稱
    PUSH    PSW        ;貯存狀態暫存器
;    PUSH    A        ;貯存累加器A,因為這裡用到A
    PUSH    IE        ;貯存中斷致能暫存器
    CLR    EA        ;暫停接受其它中斷
        ACALL   DELAY0_1S     ;延遲0.1秒,避免彈跳
        MOV     R2,#49        ;前置送出的49bytes 0x00

INIT_00H:
    MOV     A,#0        ; 49 bytes = 13ms
    MOV    SBUF,A        ;傳送IR編碼(00H)
    DJNZ    R2,INIT_00H
    MOV     R2,#11        ;傳送11個bytes的00H

INIT_FFH:
        MOV     A,#0FFH        ; 11 bytes = 3ms
        MOV    SBUF,A        ;傳送IR編碼(0FFH)
        DJNZ    R2,INIT_FFH
   
    MOV     R2,#7        ;傳送7次的0x00、0xFF(最後一次不含0xFF)
NEXT_VAL:
    MOV     A,#0        ;設定傳送的值
    MOV     R3,#4        ;1ms on

AT_1MS_ON:
        MOV    SBUF,A    ;傳送IR編碼(00H)
    DJNZ    R3,AT_1MS_ON
    MOV    A,#0FFH
    MOV    R3,#4          ;1ms off
    JMP    FINISH        ;到FINISH處檢查是否為第七次執行

AT_1MS_OFF:
        MOV    SBUF,A    ;傳送IR編碼(FFH)
    DJNZ    R3,AT_1MS_OFF            
    DJNZ    R2,NEXT_VAL
               
FINISH:
    CJNE    R2,#1,AT_1MS_OFF    ;若不是第七次執行,則回到AT_1MS_OFF
    MOV     A,#0
    MOV    SBUF,A            ;送出最後一筆00H
    SETB    EA            ;重新致能中斷
;    POP    A            ;載入原累加器A的值
    POP    PSW            ;載入原狀態暫存器的值
    RETI                ;中斷返回

;────────────────────────────────
;延遲0.1秒副程式
;────────────────────────────────
DELAY0_1S:;副程式名稱
MOV    R1,#250                ;設定迴圈250次,每次500us
A1:                    ;共延遲0.1s
        MOV    R0,#250        ;設定迴圈250次
A0:         DJNZ    R0,A0        ;設定迴圈250次,每次2us
        DJNZ    R1,A1
        RET            ;延遲程式返回

;────────────────────────────────
;串列埠的初始化
;────────────────────────────────
;串列埠的模式設定SCON
;串列埠的傳輸率設定 TMOD  TH1  PCON      TR1
;致能串列中斷 IE

INIT_SERIAL:            ;設定串列埠的初值
MOV    IE,#91H            ;致能串列及外部中斷
MOV    SCON,#40H        ;設定串列模式(一對一、八位元單向傳輸)
                ;設定Baud Rate
MOV    PCON,#80H        ;雙倍率設定
MOV    TMOD,#20H        ;計時模式設定
MOV    TH1,#0FDH        ;計時值設定
SETB    TR1            ;啟動計時器(38000 @ 22M OSC)
RET                ;副程式返回

main.c
   FileName    : main.c
 Title       : Wireless Remote Control for Camera
 Author      : Arthur de Beun
 Created     : 2004 Dec 20
 Last Edit   : 2005 Feb 18, Arthur de Beun
 Company     : Artifex Ltd
 System      : Palm OS 68k

 Description : Pentax Remote Control F Emulator

               (c)2004 Artifex Ltd
 
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.


               How it works:

               Generate this waveform from the IR transmitter LED:
              
                         |||||||||||||          |||      |||      |||      |||      |||      |||      |||
     38kHz --->   |||||||||||||          |||      |||      |||      |||      |||      |||      |||
   modulation  _|||||||||||||_____|||___|||___|||___|||___|||___|||___|||_
              
  duration [ms] |    13     |    3    |1| 1   |1| 1  |1| 1  |1|  1  |1| 1  |1|  1 |1|
   
               The waveform is approximated by setting the baud rate to 38000
               and sending the appropriate characters to the UART. It is not
               exactly right, but it seems to work fine. This method has the
               advantage that the PalmOS API can be used and direct hardware
               access can be avoided.
              
               The actual code to do this is in fv_operate_shutter()
              
               Tested with the following devices:
               Refer readme.txt
                   
               Creator ID 'PRCF' - Pentax Remote Control F

 History     : 0.1 20041222 initial release
               0.2 20041223 added VZ processor to SrmControl if
               0.3 20041224 added OMAP processor to SrmControl if
                            added srmCtlIrDADisable if previously enabled
               0.4 20050117 removed processor selection and now always do
                            srmCtlIrDAEnable and srmCtlRxDisable, also
                            explicitly added 8N1 data mode
              
******************************************************************************/
#include <PalmOS.h>
#include "main.h"

/* Local Constants */
#define version20 (0x02000000)

/* Globals */

/* Local Function Prototypes */
static UInt16 StartApplication(void);
static void StopApplication(void);
static Boolean MainFormDoCommand(UInt16 command);
static Boolean MainFormHandleEvent(EventPtr event);
static void AppEventLoop(void);
static void fv_operate_shutter(void);

/***********************************************************************
 *
 * FUNCTION:    StartApplication
 *
 * DESCRIPTION: Initialize application.
 *
 * PARAMETERS:  none
 *
 * RETURNED:    0 on success
 *
 ***********************************************************************/
static UInt16 StartApplication (void)
{
  return( 0 );
}

/***********************************************************************
 *
 * FUNCTION:    StopApplication
 *
 * DESCRIPTION:    Close all forms.
 *
 * PARAMETERS:  none
 *
 * RETURNED:    nothing
 *
 ***********************************************************************/
static void StopApplication (void)
{
  FrmCloseAllForms ();
}

/***********************************************************************
 *
 * FUNCTION:    RomVersionCompatible
 *
 * DESCRIPTION: This routine checks that a ROM version meets your
 *              minimum requirement.
 *
 * PARAMETERS:  requiredVersion - minimum rom version required
 *                                (see sysFtrNumROMVersion in SystemMgr.h
 *                                for format)
 *              launchFlags     - flags that indicate if the application
 *                                UI is initialized.
 *
 * RETURNED:    error code or zero if rom is compatible
 *                            
 ***********************************************************************/
static Err RomVersionCompatible (UInt32 requiredVersion, UInt16 launchFlags)
{
  UInt32 romVersion;

  // See if we're on in minimum required version of the ROM or later.
  FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion);
  if (romVersion < requiredVersion)
  {
    if ((launchFlags & (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) ==
        (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp))
    {
      FrmAlert (RomIncompatibleAlert);
       
      // Pilot 1.0 will continuously relaunch this app unless we switch to
      // another safe one.
      if (romVersion < 0x02000000)
        AppLaunchWithCommand(sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL);
    }
    return (sysErrRomIncompatible);
  }
  return (0);
}

/***********************************************************************
 *
 * FUNCTION:    MainFormDoCommand
 *
 * DESCRIPTION: This routine performs the menu command specified.
 *
 * PARAMETERS:  event - a pointer to an EventType structure
 *
 * RETURNED:    true if the command was handled
 *
 ***********************************************************************/
static Boolean MainFormDoCommand (UInt16 command)
{
  Boolean handled = false;

  MenuEraseStatus(0);

  switch (command)
  {
    case MainOptionsAboutCmd:
      FrmAlert(AboutRemoteControlAlert);
      handled = true;
      break;
  }
  return handled;
}

/***********************************************************************
 *
 * FUNCTION:    MainFormHandleEvent
 *
 * DESCRIPTION: This routine is the event handler for the "Main View"
 *
 * PARAMETERS:  event - a pointer to an EventType structure
 *
 * RETURNED:    true if the event has handle and should not be passed
 *              to a higher level handler.
 *
 ***********************************************************************/
static Boolean MainFormHandleEvent (EventPtr event)
{
  FormPtr frm;
  Boolean handled = false;

  switch (event->eType)
  {
    case ctlSelectEvent:
      switch (event->data.ctlSelect.controlID)
      {
        case MainFormShutterButton:
          fv_operate_shutter();
          handled = true;
          break;
               
        default:
          break;
      }
      break;
  
   case menuEvent:
     return MainFormDoCommand(event->data.menu.itemID);
     break;

   case frmUpdateEvent:
     FrmDrawForm (FrmGetActiveForm());
     handled = true;
     break;

   case frmOpenEvent:
     frm = FrmGetActiveForm();
     FrmDrawForm (frm);
     handled = true;
     break;

   case keyDownEvent:
     fv_operate_shutter();
     handled = true;
     break;
  
   default:
     break;
  }
  return (handled);
}

/***********************************************************************
 *
 * FUNCTION:    AppHandleEvent
 *
 * DESCRIPTION: This routine loads form resources and set the event
 *              handler for the form loaded.
 *
 * PARAMETERS:  event  - a pointer to an EventType structure
 *
 * RETURNED:    true if the event has handle and should not be passed
 *              to a higher level handler.
 *
 ***********************************************************************/
static Boolean AppHandleEvent( EventPtr eventP)
{
  UInt16 formId;
  FormPtr frmP;

  if (eventP->eType == frmLoadEvent)
  {
    // Load the form resource.
    formId = eventP->data.frmLoad.formID;
    frmP = FrmInitForm(formId);
    FrmSetActiveForm(frmP);

    // Set the event handler for the form.  The handler of the currently
    // active form is called by FrmHandleEvent each time is receives an
    // event.
    switch (formId)
    {
      case MainForm:
        FrmSetEventHandler(frmP, MainFormHandleEvent);
        break;

      default:
        ErrNonFatalDisplay("Invalid Form Load Event");
        break;
    }
    return true;
  }
  return false;
}

/***********************************************************************
 *
 * FUNCTION:    AppEventLoop
 *
 * DESCRIPTION: This routine is the event loop for the application. 
 *
 * PARAMETERS:  nothing
 *
 * RETURNED:    nothing
 *
 ***********************************************************************/
static void AppEventLoop(void)
{
  UInt16 error;
  EventType event;

  do
  {
    EvtGetEvent(&event, evtWaitForever);
    if (! SysHandleEvent(&event))
      if (! MenuHandleEvent(0, &event, &error))
        if (! AppHandleEvent(&event))
          FrmDispatchEvent(&event);

  // Check the heaps after each event
  #if EMULATION_LEVEL != EMULATION_NONE
  MemHeapCheck(0);
  MemHeapCheck(1);
  #endif

  } while (event.eType != appStopEvent);
}

/***********************************************************************
 *
 * FUNCTION:    PilotMain
 *
 * DESCRIPTION: This is the main entry point for the application
 *
 * PARAMETERS:  nothing
 *
 * RETURNED:    0
 *
 ***********************************************************************/
 
UInt32 PilotMain (UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags)
{
  UInt16 error;

  error = RomVersionCompatible (version20, launchFlags);
  if (error) return (error);

  if ( cmd == sysAppLaunchCmdNormalLaunch )
  {
    error = StartApplication ();
    if (error) return (error);

    FrmGotoForm (MainForm);

    AppEventLoop ();
    StopApplication ();
  }
  return (0);
}

static void fv_operate_shutter(void)
{
  UInt16 portId;
  UInt32 flags;
  UInt16 flagsSize = sizeof(flags);
  Err err;
  Char msg[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00,                                           // 49 bytes = 13ms
                0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                0xFF, 0xFF, 0xFF,                               // 11 bytes = 3ms
                0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, // 1} 1ms on, 1ms off
                0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, // 2} 1ms on, 1ms off
                0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, // 3} 1ms on, 1ms off
                0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, // 4} 1ms on, 1ms off
                0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, // 5} 1ms on, 1ms off
                0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, // 6) 1ms on, 1ms off
                0x00, 0x00, 0x00, 0x00,                         // 7) 1ms on
                0x00};
  UInt32 value;

 
  err = FtrGet(sysFileCSerialMgr, sysFtrNewSerialPresent, &value);
  if ((err == 0) && (value !=0)) // use new Serial Manager
  {
    err = SrmOpen(serPortIrPort /* port */, 38000 /* baud */, &portId);
    if (err)
    {
      FrmAlert(CantOpenIRPortAlert);
    }
    else
    {
      flags = srmSettingsFlagBitsPerChar8 | srmSettingsFlagStopBits1;
      SrmControl(portId, srmCtlSetFlags, &flags, &flagsSize);
      SrmControl(portId, srmCtlIrDAEnable, NULL, 0); // enable IR on single UART device and VZ
      SrmControl(portId, srmCtlRxDisable, NULL, 0);
      SrmSend(portId, msg, 112, &err);               // 112 @ 38k, 113 @ 38k4
      SrmSendWait(portId);
      err = SrmClose(portId);
    }
  }
  else // old Serial Manager warning, don't bother supporting it
  {
    FrmAlert(OldSerialManagerAlert);
  }
 
}

 

Filename main.h
  /******************************************************************************

 FileName    : main.h
 Title       : Wireless Remote Control for Camera
 Author      : Arthur de Beun
 Created     : 2004 Dec 20
 Last Edit   : 2005 Feb 18, Arthur de Beun
 Company     : Artifex Ltd
 System      : Palm OS 68k

 Description : Pentax Remote Control F Emulator

               (c)2004 Artifex Ltd

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
******************************************************************************/
// Main View
#define MainForm                    1000
#define MainFormShutterButton        1001

// Alerts
#define CantOpenIRPortAlert         1000
#define RomIncompatibleAlert        1001
#define AboutRemoteControlAlert     1002
#define OldSerialManagerAlert       1003

// Menus
#define MainFormMenuBar                1000

// Menu commands
#define MainOptionsAboutCmd            10
arrow
arrow
    全站熱搜

    haman77 發表在 痞客邦 留言(0) 人氣()