본문 바로가기

자동제어(PLC,PC,로봇) & 전장설계 & CNC/PC 제어

PC제어프로그램 10일차 (20.07.31) LED 점등 3_2 프로그램

반응형

LED 점등 3 PROGRAM 설명 

이전 시간에 했던 LED점등 3 프로그램의 중요 로직을 설명한다.

 

 

UINT Z(LPVOID lParam) 
{ 
    RunThread=1; 
    flag=1; 
    do{ 
        if(stage==1)        // 초기동작 조건 (초기동작이라면 ...)
        { 
            Outputb(PPI_C, led); // led의 값(0부터4까지)을 8255보드의 C포트(PC)로 보내서 점등 할 것을 결정해준다.
            Sleep(500);             // 0.5초 동안 유지시킨다.
            first=1;                  // 초기동작 후 기본동작 조건 
        } // stage==1
        else if(stage==2)   // 기본동작 조건 (기본동작이라면...)
        { 
            if(first==1)       // 초기동작 완료 조건 
            { 
                for(i=0;i<=3;i++) 
                { 
                    Outputb(PPI_C,aled[i]); 
                    Sleep(500); 
                    if(stage==4) { goto end;  } 
                    Outputb(PPI_C,0); 
               } 
           } 
        }  // stage==2
        else if(stage==4)   // 동작종료 조건
        { 
            end: 
            Outputb(PPI_C,0); 
        } // stage==4
   }while(flag); 
   RunThread=0; 
   return 0; 
}

 

8255보드에는 유저가 쓸수 있는 포트가 3개(A,B,C)가 있다.

PA0~PA7, PB0~PB7, PC0~PC7

 

PLC의 입출력 단자는 10개를 사용한다면 10개를 통으로 쓴다.

동일한 단자인데 입력과 출력 동시에 쓸 수 있는 단자가 없다.

그런데 조건의 세팅에 따라 입력/출력을 바꿔서 사용할 수 있을 것 같다.

 

PC제어에서는 동일한 포트를 입력과 출력으로 사용할 수 있다.

 

PA, PB는 입력 또는 출력으로 사용가능

PC는 4비트씩 쪼개서 입력 또는 출력으로 사용가능

(최대한 활용도를 높이기 위해서이다. 예-입력이 3개라면 5개가 낭비되기 때문에 나머지는 출력으로 쓸 수 있다.)

 


LED3_2 프로그램(B)

- 초기동작 버튼을 누르기 전에는 LED가 수동구동 되지 않고

- 초기동작 버튼을 누른 후에 LED의 수동구동가능

- 기본동작 버튼을 누르면 LED01, 12, 23, 01, 12, 23, ... 순으로 왕복 점등

- 동작 종료 버은을 누르면 종료

- 파일명 : LED3_0731_10

 

 

 

// LED3_0731_10Dlg.cpp : implementation file

#include "stdafx.h"
#include "LED3_0731_10.h"
#include "LED3_0731_10Dlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// 사용자 입력 start
#include <MPSDriver.h>
#define PPI_A 0x00	// PPIBoard 조건
#define PPI_B 0x01
#define PPI_C 0x02
#define PPI_CR 0x03

UINT Z(LPVOID lParam);	// 쓰레드를 구동하기 위한 사용자 지정함수 선언.

unsigned char flag=0;
unsigned char RunThread=0;
unsigned char aled[3]={3,6,12};

// 변수선언 
int supf,supb;
int led0,led1,led2,led3,led4,led5,led6,led7,led;
int stp,cm;
int a,b,c,d,e,i,j,sum,sup;
int stage,act,first; // stage : 동작구분
int bs1,bs2,bs3,bs4;
// 사용자 입력 end
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CLED3_0731_10Dlg dialog

CLED3_0731_10Dlg::CLED3_0731_10Dlg(CWnd* pParent /*=NULL*/)
	: CDialog(CLED3_0731_10Dlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CLED3_0731_10Dlg)
	m_led0 = FALSE;
	m_led1 = FALSE;
	m_led2 = FALSE;
	m_led3 = FALSE;
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CLED3_0731_10Dlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CLED3_0731_10Dlg)
	DDX_Check(pDX, IDC_CHECK1, m_led0);
	DDX_Check(pDX, IDC_CHECK2, m_led1);
	DDX_Check(pDX, IDC_CHECK3, m_led2);
	DDX_Check(pDX, IDC_CHECK4, m_led3);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CLED3_0731_10Dlg, CDialog)
	//{{AFX_MSG_MAP(CLED3_0731_10Dlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_SHOWWINDOW()
	ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
	ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
	ON_BN_CLICKED(IDC_BUTTON3, OnButton3)
	ON_BN_CLICKED(IDC_BUTTON4, OnButton4)
	ON_BN_CLICKED(IDC_CHECK1, OnCheck1)
	ON_BN_CLICKED(IDC_CHECK2, OnCheck2)
	ON_BN_CLICKED(IDC_CHECK3, OnCheck3)
	ON_BN_CLICKED(IDC_CHECK4, OnCheck4)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CLED3_0731_10Dlg message handlers

BOOL CLED3_0731_10Dlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	/////////////////////////////////////////////////////////////////////////////
    // 사용자 입력 start
	if(InitDrv()<0) return-1;		// USB 포트정의
	if(USBDrvInit()<0) return-1;// USB 포트정의

	Outputb(PPI_CR,0x90);				// 8255 초기설정 A:입력, B:출력, C:출력
    // 사용자 입력 end
    /////////////////////////////////////////////////////////////////////////////
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CLED3_0731_10Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CLED3_0731_10Dlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CLED3_0731_10Dlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CLED3_0731_10Dlg::OnShowWindow(BOOL bShow, UINT nStatus) 
{
	CDialog::OnShowWindow(bShow, nStatus);
	
	// TODO: Add your message handler code here
	if(RunThread==0)
		AfxBeginThread(Z,NULL);	
}

void CLED3_0731_10Dlg::OnButton1() // 수동구동
{
		if(1)
			led=led0+led1+led2+led3;
		if(stage!=1) MessageBox("'초기동작' 버튼을 먼저 눌러야 작동합니다.");
}

void CLED3_0731_10Dlg::OnButton2() // 초기동작
{
	stage=1;
}

void CLED3_0731_10Dlg::OnButton3() // 기본동작
{
	if(stage!=1) MessageBox("'초기동작' 버튼을 먼저 눌러야 작동합니다.");
	stage=2;
}

void CLED3_0731_10Dlg::OnButton4() // 동작종료
{
	if(stage!=1) MessageBox("'초기동작' 버튼을 누르고 \n다른 버튼을 눌러야합니다. ");
	//if(stage==4) {CheckDigButton(IDC_CHECK1, FALSE);}
	stage=4;	
}

void CLED3_0731_10Dlg::OnCheck1() // led0 
{
	if(m_led0==FALSE) led0=1;
	else if(m_led0==TRUE) led0=0;
	UpdateData(TRUE);
}

void CLED3_0731_10Dlg::OnCheck2()  // led1
{
	if(m_led1==FALSE) led1=2;
	else if(m_led1==TRUE) led1=0;
	UpdateData(TRUE);
}

void CLED3_0731_10Dlg::OnCheck3()  // led2
{
	if(m_led2==FALSE) led2=4;
	else if(m_led2==TRUE) led2=0;
	UpdateData(TRUE);
}

void CLED3_0731_10Dlg::OnCheck4()  // led3
{
	if(m_led3==FALSE) led3=8;
	else if(m_led3==TRUE) led3=0;
	UpdateData(TRUE);
}

UINT Z(LPVOID lParam)
{
	RunThread=1;
	flag=1;
	do{
		if(stage==1)	// 초기동작이라면 ...
		{
			Outputb(PPI_C,led); //led의 값을 PPI_C포트로 출력을 하라. led값은 모두 더한 값이다.
			Sleep(500);	// 우리 눈에 안보이기 때문에 보이게 하기 위해
			first=1;	// 초기동작 후 기본동작 조건 | first에 값을 넣는 이유는 first가 1인가에 따라 일을 하기 위해서다. 
		}
		else if(stage==2)	// 기본동작이라면...
		{
			if(first==1)	  // 초기동작 완료 조건
			{
				for(i=0;i<=2;i++)
				{
					// aled[4]={1+2,2+4,4+8}; 순차적으로 붉을 밝히고
					Outputb(PPI_C,aled[i]); // 3(6,12) 값이 C포트의 0(1,2,3)번에 들어간다. 
					Sleep(500);

					if(stage==4){ goto end; } // 동작종료 버튼을 눌렀을때 | 패트롤(돌고 있는데 눌르는 것)
					Outputb(PPI_C,0);					// 점등 후 0.5초 후에 소등하고 바로 점등하게 된다.
				}
			} // if end
		}
		else if(stage==4)
		{
			end:  // go to end로 오는 목적지이다.
			Outputb(PPI_C,0);
		}
	}while(flag);

	RunThread=0;
	return 0;
}