본문 바로가기

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

PC제어프로그램 9일차 (20.07.30) LED 점등하기(LED3)

반응형

 

장비가 정상인지 확인해본다. 연결해 본다. 

장비와 컴퓨터가 정상적으로 작동하고 있다.

 


과제 수행을 해본다.

 

LED6개를 점등하는 프로그램을 새로 만든다.

 

// LED1_0730_10Dlg.cpp : implementation file

#include "stdafx.h"
#include "LED1_0730_10.h"
#include "LED1_0730_10Dlg.h"

//#include "windows.h"
#include "string"
//#include "vector"
//#include "iostream"
//#define ENABLE_TRACE

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

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

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

unsigned char flag=0;
unsigned char RunThread=0;

// 변수선언
int supf, supb;
int led0,led1,led2,led3,led4,led5,led;
int stp,cm,a,b,c,d,e,i,j,sum,sup;
int stage,act;
int bs1,bs2,bs3,bs4;


/////////////////////////////////////////////////////////////////////////////
// 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()

/////////////////////////////////////////////////////////////////////////////
// CLED1_0730_10Dlg dialog

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

void CLED1_0730_10Dlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CLED1_0730_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);
	DDX_Check(pDX, IDC_CHECK5, m_led4);
	DDX_Check(pDX, IDC_CHECK6, m_led5);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CLED1_0730_10Dlg, CDialog)
	//{{AFX_MSG_MAP(CLED1_0730_10Dlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_SHOWWINDOW()
	ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
	ON_BN_CLICKED(IDC_CHECK1, OnCheck1)
	ON_BN_CLICKED(IDC_CHECK2, OnCheck2)
	ON_BN_CLICKED(IDC_CHECK3, OnCheck3)
	ON_BN_CLICKED(IDC_CHECK4, OnCheck4)
	ON_BN_CLICKED(IDC_CHECK5, OnCheck5)
	ON_BN_CLICKED(IDC_CHECK6, OnCheck6)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CLED1_0730_10Dlg message handlers

BOOL CLED1_0730_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
	
	// TODO: Add extra initialization here
	// 사용자 입력
	if(InitDrv()<0) return -1;		// USB 포트 정의
	if(USBDrvInit()<0) return -1;	// USB 포트 정의

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

void CLED1_0730_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 CLED1_0730_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 CLED1_0730_10Dlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CLED1_0730_10Dlg::OnShowWindow(BOOL bShow, UINT nStatus) 
{
	CDialog::OnShowWindow(bShow, nStatus);
	if(RunThread==0)
		AfxBeginThread(Z, NULL); //AfxBeginThread()로 쓰레드 생성
	// TODO: Add your message handler code here
}

void CLED1_0730_10Dlg::OnButton1() // 수동구동 
{
	if(1)									// 자동 실행된다.
		led=led0+led1+led2+led3+led4+led5;	// led는 모두 합한다.
}

void CLED1_0730_10Dlg::OnCheck1() // LED0
{
	OutputDebugString(_T("Console Test----------CLed1_1Dlg::OnCheck1 \n"));
	if(m_led0==FALSE) led0=1;				// m_led0는 초기에 설정할 때 우리가 입력한 데이터이다.
	else if(m_led0==TRUE) led0=0;
	UpdateData(TRUE);
}

void CLED1_0730_10Dlg::OnCheck2()  // LED1
{
	OutputDebugString(_T("Console Test----------CLed1_1Dlg::OnCheck2 \n"));
	if(m_led1==FALSE) led1=2;				
	else if(m_led1==TRUE) led1=0;
	UpdateData(TRUE);
}

void CLED1_0730_10Dlg::OnCheck3()  // LED2
{
	OutputDebugString(_T("Console Test----------CLed1_1Dlg::OnCheck3 \n"));
	if(m_led2==FALSE) led2=4;				
	else if(m_led2==TRUE) led2=0;
	UpdateData(TRUE);
}

void CLED1_0730_10Dlg::OnCheck4()  // LED3
{
	OutputDebugString(_T("Console Test----------CLed1_1Dlg::OnCheck4 \n"));
	if(m_led3==FALSE) led3=8;
	else if(m_led3==TRUE) led3=0;
	UpdateData(TRUE);
}

void CLED1_0730_10Dlg::OnCheck5()  // LED4
{
	OutputDebugString(_T("Console Test----------CLed1_1Dlg::OnCheck5 \n"));
	if(m_led4==FALSE) led4=16;
	else if(m_led4==TRUE) led4=0;
	UpdateData(TRUE);
}

void CLED1_0730_10Dlg::OnCheck6()  // LED5
{
	OutputDebugString(_T("Console Test----------CLed1_1Dlg::OnCheck6 \n"));
	if(m_led5==FALSE) led5=32;
	else if(m_led5==TRUE) led5=0;
	UpdateData(TRUE);
}

UINT Z(LPVOID lPARAM)
{
	RunThread=1;
	flag=1;
	OutputDebugString(_T("Console Test----------UINT Z() \n"));
	do{
		if(1)
		{
			// 8255의 c포트로 led값을 출력(송신)해라.
			// 현재 8255의 c포트의 1~6에는 led가 연결되어 있다.
			Outputb(PPI_C,led);
			Sleep(500);			// led가 점등되는 시간이 0.5초 만큼 해라.
		}
	}while(1); 		// 무한 반복으로 실행해라. => 유지시간을 0.5초를 안주어도 된다.
	RunThread=0;
	return 0;
}

 

 

 

 

LED3.zip
2.19MB

 


PROGRAM 설명 

 

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개가 낭비되기 때문에 나머지는 출력으로 쓸 수 있다.)

 

 

 

 


 

01_LED1_2020_07_24.mp4
3.47MB

 

04_LED1_2020_07_24.mp4
8.05MB
02_LED1_2020_07_24.mp4
4.52MB