장비가 정상인지 확인해본다. 연결해 본다.
장비와 컴퓨터가 정상적으로 작동하고 있다.
과제 수행을 해본다.
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;
}
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개가 낭비되기 때문에 나머지는 출력으로 쓸 수 있다.)
'자동제어 > PC 제어' 카테고리의 다른 글
마지막수업 (0) | 2020.08.13 |
---|---|
PC제어프로그램 10일차 (20.07.31) LED 점등 3_2 프로그램 (0) | 2020.07.31 |
PC제어프로그램 8일차 (20.07.24) FND 점등하기 (0) | 2020.07.24 |
PC제어프로그램 7일차 (20.07.14) (0) | 2020.07.14 |
PC제어프로그램 5일차 (20.05.14) - 기본코딩2 (0) | 2020.06.18 |