// sample0Dlg.cpp : implementation file // #include "stdafx.h" #include "sample0.h" #include "sample0Dlg.h" #include "ACCES32.H" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define TIMER_ID 0 #define LAPSE 500 //how many milliseconds for the timer /************************************************************* ** These global variables are used by the functions that are common ** to this board. They are also utilized by functions within the dialog box *************************************************************/ unsigned int BASE=0x300; //base address of card unsigned short jumpers; //the jumper settings of the card. Only bits 0-4 should be used. Status information should //be read from the board immediately before use unsigned char adrange; //bits 0-3 are equal to bits 0-3 of the jumpers variable. unsigned char dacBrange; //if this is 0 then DAC1 is set to 0-10 volt range unsigned char dacArange; //if this is 0 then DAC0 is set to 0-10 volt range /************************************************************* ** The following function declarations include some common operations ** for this board. *************************************************************/ unsigned char sbitd(unsigned int data,unsigned char bit); double DAC(unsigned char DACnum,double DACV); void EEPROM_Enable(void); void EEPROM_Disable(void); void EEPROM_Write(unsigned int addr,unsigned int data); unsigned int EEPROM_Read(unsigned int addr); void CAL_ADC(unsigned char M,unsigned char B); void CALWrite(unsigned zAM,unsigned zAB,unsigned zDAM,unsigned zDBM); void doCAL(void); void init(void); double readAD(); ///////////////////////////////////////////////////////////////////////////// // CSample0Dlg dialog CSample0Dlg::CSample0Dlg(CWnd* pParent /*=NULL*/) : CDialog(CSample0Dlg::IDD, pParent) { //{{AFX_DATA_INIT(CSample0Dlg) m_dac0LBL = _T(""); m_dac1LBL = _T(""); //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); dac0out = dac1out = 0; } void CSample0Dlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CSample0Dlg) DDX_Control(pDX, IDC_BUTTON_STOP, m_stopBTN); DDX_Control(pDX, IDC_EDIT_DAC1, m_dac1EDIT); DDX_Control(pDX, IDC_EDIT_DAC0, m_dac0EDIT); DDX_Control(pDX, IDC_EDIT_CHN8, m_chn8EDIT); DDX_Control(pDX, IDC_EDIT_CHN7, m_chn7EDIT); DDX_Control(pDX, IDC_EDIT_CHN6, m_chn6EDIT); DDX_Control(pDX, IDC_EDIT_CHN5, m_chn5EDIT); DDX_Control(pDX, IDC_EDIT_CHN4, m_chn4EDIT); DDX_Control(pDX, IDC_EDIT_CHN3, m_chn3EDIT); DDX_Control(pDX, IDC_EDIT_CHN2, m_chn2EDIT); DDX_Control(pDX, IDC_EDIT_CHN15, m_chn15EDIT); DDX_Control(pDX, IDC_EDIT_CHN14, m_chn14EDIT); DDX_Control(pDX, IDC_EDIT_CHN13, m_chn13EDIT); DDX_Control(pDX, IDC_EDIT_CHN12, m_chn12EDIT); DDX_Control(pDX, IDC_EDIT_CHN11, m_chn11EDIT); DDX_Control(pDX, IDC_EDIT_CHN9, m_chn9EDIT); DDX_Control(pDX, IDC_EDIT_CHN10, m_chn10EDIT); DDX_Control(pDX, IDC_EDIT_CHN1, m_chn1EDIT); DDX_Control(pDX, IDC_EDIT_CHN0, m_chn0EDIT); DDX_Control(pDX, IDC_EDIT_ADDR, m_addrEDIT); DDX_Control(pDX, IDC_BUTTON_BEGIN, m_beginBTN); DDX_Text(pDX, IDC_DAC0_LBL, m_dac0LBL); DDX_Text(pDX, IDC_DAC1_LBL, m_dac1LBL); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CSample0Dlg, CDialog) //{{AFX_MSG_MAP(CSample0Dlg) ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BUTTON_BEGIN, OnButtonBegin) ON_WM_TIMER() ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_DAC0, OnDeltaposSpinDac0) ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_DAC1, OnDeltaposSpinDac1) ON_BN_CLICKED(IDC_BUTTON_STOP, OnButtonStop) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CSample0Dlg message handlers BOOL CSample0Dlg::OnInitDialog() { CDialog::OnInitDialog(); // 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 m_addrEDIT.SetWindowText("300"); m_stopBTN.EnableWindow(false); return TRUE; // return TRUE unless you set the focus to a control } // 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 CSample0Dlg::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 CSample0Dlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } /************************************************************** ** This function performs the following operations: ** 1) Get base address from user. ** 2) initialize global variables and calibrate the card ** 3) Determine DAC ranges and pass them on to the user ** 4) Determine the number of channels and store that value for later use ** 5) Tell the board which channels will be scanned ** 6) Tell the board that conversions will be software driven ** 7) Disable the start button and enable the stop button on the window ** 8) Start the timer *************************************************************/ void CSample0Dlg::OnButtonBegin() { // TODO: Add your control notification handler code here CString addr; char *buf; ////////////////////////////////////////// // 1) Get base address from user. m_addrEDIT.GetWindowText(addr); buf = addr.GetBuffer(5); sscanf(buf, "%x", &BASE); addr.ReleaseBuffer(-1); ///////////////////////////////////////// // 2) initialize global variables and calibrate the card init(); doCAL(); ///////////////////////////////////////// // 3) Determine DAC ranges and pass them on to the user if (dacArange) m_dac0LBL = "DAC 0 output Range is 0 to 5 volts"; else m_dac0LBL = "DAC 0 output Range is 0 to 10 volts"; if (dacBrange) m_dac1LBL = "DAC 1 output Range is 0 to 5 volts"; else m_dac1LBL = "DAC 1 output Range is 0 to 10 volts"; UpdateData(false); //////////////////////////////////////////// // 4) Determine the number of channels and store that value for later use channels = jumpers & 0x01 ? 16 : 8; /////////////////////////////////////////// // 5) Tell the board which channels will be scanned OutPortB(BASE + 0x02, (channels - 1) * 0x10); // bits 0-3 tell the board the start channel and bits 4-7 are the // end channel ////////////////////////////////////////// // 6) Tell the board that conversions will be software driven OutPortB(BASE + 0x01, 0); //reset FIFO OutPortB(BASE + 0x1A, 0x00); //enable software conversion start ///////////////////////////////////////// // 7) Disable the start button and enable the stop button on the window m_beginBTN.EnableWindow(false); m_stopBTN.EnableWindow(true); /////////////////////////////////////// // 8) Start the timer SetTimer(TIMER_ID, LAPSE, NULL); } /**************************************************** ** This function performs the following functions ** 1) stop the timer ** 2) Take 1 reading per channel ** 3) retrieve the readings and display to the window ** 4) Send output to the DACs and display the sent value to the window ** 5) restart the timer ***************************************************/ void CSample0Dlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default //////////////////////////////////////////////////////// // 1) stop the timer KillTimer(TIMER_ID); double reading; char display[10]; ///////////////////////////////////////////////////////// // 2) Take 1 reading per channel for (int count = 0; count < channels; count++) OutPortB(BASE, 0); //////////////////////////////////////////////////////// // 3) retrieve the readings and display to the window // it is possible to create control arrays with VC6, but doing so tends to break the class wizard // and should be attempted only by advanced programmers. So we have to do this the long way reading = readAD(); sprintf(display, "%6f", reading); m_chn0EDIT.SetWindowText(display); reading = readAD(); sprintf(display, "%6f", reading); m_chn1EDIT.SetWindowText(display); reading = readAD(); sprintf(display, "%6f", reading); m_chn2EDIT.SetWindowText(display); reading = readAD(); sprintf(display, "%6f", reading); m_chn3EDIT.SetWindowText(display); reading = readAD(); sprintf(display, "%6f", reading); m_chn4EDIT.SetWindowText(display); reading = readAD(); sprintf(display, "%6f", reading); m_chn5EDIT.SetWindowText(display); reading = readAD(); sprintf(display, "%6f", reading); m_chn6EDIT.SetWindowText(display); reading = readAD(); sprintf(display, "%6f", reading); m_chn7EDIT.SetWindowText(display); if (channels == 16) { reading = readAD(); sprintf(display, "%6f", reading); m_chn8EDIT.SetWindowText(display); reading = readAD(); sprintf(display, "%6f", reading); m_chn9EDIT.SetWindowText(display); reading = readAD(); sprintf(display, "%6f", reading); m_chn10EDIT.SetWindowText(display); reading = readAD(); sprintf(display, "%6f", reading); m_chn11EDIT.SetWindowText(display); reading = readAD(); sprintf(display, "%6f", reading); m_chn12EDIT.SetWindowText(display); reading = readAD(); sprintf(display, "%6f", reading); m_chn13EDIT.SetWindowText(display); reading = readAD(); sprintf(display, "%6f", reading); m_chn14EDIT.SetWindowText(display); reading = readAD(); sprintf(display, "%6f", reading); m_chn15EDIT.SetWindowText(display); } ///////////////////////////////////////////////////////////// //4) Send output to the DACs and display the sent value to the window reading = DAC(0, (dacArange ? .49 * double(dac0out) : .99 * double(dac0out))); sprintf(display, "%6f", reading); m_dac0EDIT.SetWindowText(display); reading = DAC(1, (dacArange ? .49 * double(dac1out) : .99 * double(dac1out))); sprintf(display, "%6f", reading); m_dac1EDIT.SetWindowText(display); /////////////////////////////////////////////////////////////// // 5) restart the timer SetTimer(TIMER_ID, LAPSE, NULL); CDialog::OnTimer(nIDEvent); } /**************************************************** ** This function performs the following functions ** 1) determine if the user clicked the up or down button and adjust the dac multiplier ****************************************************/ void CSample0Dlg::OnDeltaposSpinDac0(NMHDR* pNMHDR, LRESULT* pResult) { NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR; // TODO: Add your control notification handler code here //////////////////////////////////////////////// // 1) determine if the user clicked the up or down button and adjust the dac multiplier //windows sends a negative delta for the up arrow and a positive delta for the down arrow. pNMUpDown->iDelta > 0 ? dac0out-- : dac0out++; if (dac0out > 10) dac0out = 0; else if (dac0out < 0) dac0out = 10; *pResult = 0; } /**************************************************** ** This function performs the following functions ** 1) determine if the user clicked the up or down button and adjust the dac multiplier ****************************************************/ void CSample0Dlg::OnDeltaposSpinDac1(NMHDR* pNMHDR, LRESULT* pResult) { NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR; // TODO: Add your control notification handler code here //////////////////////////////////////////////// // 1) determine if the user clicked the up or down button and adjust the dac multiplier //windows sends a negative delta for the up arrow and a positive delta for the down arrow. pNMUpDown->iDelta > 0 ? dac1out-- : dac1out++; if (dac1out > 10) dac1out = 0; else if (dac1out < 0) dac1out = 10; *pResult = 0; } /**************************************************** ** This function performs the following functions ** 1) Stop the timer ** 2) Disable the stop button and enable the start button ****************************************************/ void CSample0Dlg::OnButtonStop() { // TODO: Add your control notification handler code here ////////////////////////////////////////////////////////// // 1) Stop the timer KillTimer(TIMER_ID); ////////////////////////////////////////////////////////// // 2) Disable the stop button and enable the start button m_beginBTN.EnableWindow(true); m_stopBTN.EnableWindow(false); } //sbitd takes data and bit, then returns 0x81 or 0x01 based on data[bit] unsigned char sbitd(unsigned int data,unsigned char bit) { return (data & (1<>3) & 0x01;//d4,d3 are 5/10 for daca,b dacArange=(jumpers>>4) & 0x01; // CAL(); } // reads the next available value from the FIFO and converts it to volts before returning the reading double readAD() { //scale counts into AD Range Volts unsigned short data; data = InPort(BASE); return (double(data) / 65536.0 - ((adrange&0x02)?0.5:0.0)) //Adjust for polarity jumper * ((adrange&0x04)?10.0:20.0) //Adjust for gain jumper ; }