winio 写SPD

ww506772362 2013-10-16 01:32:14
最近在研究winio 修改gpio ,可能熟悉的程度不够吧!望那位大虾指点下。
BYTE ReadSPD(DWORD Base, int nOffset,BYTE DeviceID)
{
DWORD statusSMBUS;
SetPortVal(Base + 4,DeviceID+1, 1);//偏移字节
GetPortVal(Base, &statusSMBUS, 1);//获取smbus状态
while (!(statusSMBUS & 0x42))
{
GetPortVal(Base, &statusSMBUS, 1);
}
GetPortVal(Base, &statusSMBUS, 1);
SetPortVal(Base, statusSMBUS & 0xBF, 1);
GetPortVal(Base, &statusSMBUS, 1);
while(statusSMBUS & 2)
GetPortVal(Base, &statusSMBUS, 1);
GetPortVal(Base, &statusSMBUS, 1);
SetPortVal(Base + 3, nOffset, 1);
SetPortVal(Base + 2, 0x48, 1);
GetPortVal(Base, &statusSMBUS, 1);
while(statusSMBUS & 1)
GetPortVal(Base, &statusSMBUS, 1);
GetPortVal(Base + 5, &statusSMBUS, 1);//读写都是加5
if ((nOffset + 1) % 16 == 0)
printf("\n");
return statusSMBUS & 0xFF;
}

读取数据正确但是写数据就是写不进去望指点

void WriteSPD(DWORD Base, int nOffset,BYTE DeviceID,int nValue)
{
DWORD statusSMBUS;
SetPortVal(Base + 4,DeviceID, 1);//查找Device地址-----选择设备1 读 0是写
GetPortVal(Base, &statusSMBUS, 1);//获取smbus状态
while (!(statusSMBUS & 0x42))
{
GetPortVal(Base, &statusSMBUS, 1);
}
GetPortVal(Base, &statusSMBUS, 1);
SetPortVal(Base, statusSMBUS & 0xBF, 1);
GetPortVal(Base, &statusSMBUS, 1);
while(statusSMBUS & 2)
GetPortVal(Base, &statusSMBUS, 1);
GetPortVal(Base, &statusSMBUS, 1);
SetPortVal(Base + 3, nOffset, 1);//选择索引

SetPortVal(Base + 5, nValue, 1);//读写都是加5
GetPortVal(Base, &statusSMBUS, 1);
while(statusSMBUS & 1)
GetPortVal(Base, &statusSMBUS, 1);

SetPortVal(Base + 2, 0x48, 1);//s
}
...全文
11472 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
yanguowusheng68 2014-05-14
  • 打赏
  • 举报
回复
您好,请问您是怎样利用winio实现对端口的读取操作的,能不能发下邮箱:evolain@126.com
cptang 2013-10-31
  • 打赏
  • 举报
回复
还没结贴? :-)
cptang 2013-10-19
  • 打赏
  • 举报
回复
引用 13 楼 ww506772362 的回复:
谢谢!可能我描述有点问题我其实我是要修改显卡的spd 信息到达固屏效果。
这个就没法 帮忙了 这是你程序设计的事情 我只是解决你的读写问题。
ww506772362 2013-10-19
  • 打赏
  • 举报
回复
谢谢!可能我描述有点问题我其实我是要修改显卡的spd 信息到达固屏效果。
cptang 2013-10-19
  • 打赏
  • 举报
回复


已发
查收!
cptang 2013-10-19
  • 打赏
  • 举报
回复
引用 10 楼 ww506772362 的回复:
非常感谢!但是问题依然存在。
回头我给你写个demo 你试试效果如何。
ww506772362 2013-10-19
  • 打赏
  • 举报
回复
非常感谢!但是问题依然存在。
cptang 2013-10-16
  • 打赏
  • 举报
回复
貌似这个视频卡的读写都需要两个字节吧。 GetPortVal(Base, &statusSMBUS, 1);//此处的1应该改为2吧? SetPortVal(Base, statusSMBUS & 0xBF, 1);//此处的1应该改为2吧?
cptang 2013-10-16
  • 打赏
  • 举报
回复
已发 查收。
ww506772362 2013-10-16
  • 打赏
  • 举报
回复
非常感谢!qq 506772362
cptang 2013-10-16
  • 打赏
  • 举报
回复
winio的dll为静态调用。 你实在想用winio,可以参考我以下代码。

#include "winio.h"
//------------------------------变量定义区---------------------------------------------
bool     winIoInitOK ;
//------------------------------函数预定义---------------------------------------------
unsigned char (*inportb)(unsigned short) ;
void (*outportb)(unsigned short, unsigned char) ;
//--------------------------------固定函数定义区-------------------------------------------
unsigned char inportb9x(unsigned short int port)
{
    unsigned long value = 0;
    GetPortVal(port, &value, 1);
    return value;
}
//---------------------------------------------------------------------------
void outportb9x(unsigned short port, unsigned char value)
{
    SetPortVal(port, value, 1);
}
//---------------------------------------------------------------------------
unsigned char inportbNT(unsigned short port)
{
    asm mov dx, port;
    asm in al, dx;
    return _AL;
}
//---------------------------------------------------------------------------
void outportbNT(unsigned short port, unsigned char  value)
{
    asm mov dx, port;
    asm mov al, value;
    asm out dx,al;
}
//---------------------------------------------------------------------------
void InitWinIo(void)
{
    OSVERSIONINFO osVer = {sizeof(OSVERSIONINFO)};
    GetVersionEx(&osVer);

    if(osVer.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
    {
        inportb = inportb9x;
        outportb = outportb9x;
    }
    else
    {            
        inportb = inportbNT;
        outportb = outportbNT;
    }

    winIoInitOK = InitializeWinIo() ;
    if(!winIoInitOK)
        MessageBox(0,"端口初始化失败,请重启计算机","系统初始化错误", MB_OK|MB_ICONSTOP);
}
//---------------------------------------------------------------------------
cptang 2013-10-16
  • 打赏
  • 举报
回复
以下代码是我以前的,cb6环境。 能读就能写吧。以下代码以前测试通过的。 你为什么不用官方提供的dll呢?不过我没用官方提供的dll,也没用winio 给我留个email,我给你发一个底层驱动吧。用我那个驱动试试。

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "main.h"
#include <Inifiles.hpp>
const unsigned int GPIO_BASE_ADDR  =	0x500  ;
const unsigned int GPO0	           =	12     ;
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "RzButton"
#pragma link "RzTray"
#pragma link "fcStatusBar"
#pragma link "_GClass"
#pragma link "AbLED"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    statusInt = 0 ;

    TIniFile *iniFile;
    try
    {
        iniFile = new TIniFile(ExtractFilePath(Application->ExeName) + "Config.ini");
        statusInt = iniFile->ReadString("CurrentGPIOValue","GPIOValue","0").ToIntDef(0) ;

    }
    __finally
    {
        delete iniFile;
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::RzBitBtn2Click(TObject *Sender)
{
    statusInt = 0 ;
    SetGPOStatus() ;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::RzBitBtn1Click(TObject *Sender)
{
    statusInt = 1 ;
    SetGPOStatus() ;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SetGPOStatus()
{
    PortValue =  IOPort1->PortD[GPIO_BASE_ADDR + 0x0C];

    if(statusInt)
       PortValue |= 1 << GPO0;              //视频通道
    else
       PortValue &= ~(1 << GPO0);            //数据通道

    IOPort1->PortD[GPIO_BASE_ADDR + 0x0C] = PortValue ;

    TIniFile *iniFile;
    iniFile = new TIniFile(ExtractFilePath(Application->ExeName) + "Config.ini");
    iniFile->WriteString("CurrentGPIOValue","GPIOValue",IntToStr(statusInt)) ;
    delete iniFile;

    RzBitBtn2->Enabled = statusInt ;
    RzBitBtn1->Enabled = !statusInt ;

    AbLED1->Checked = !statusInt ;
    AbLED2->Checked = statusInt ;
}
//---------------------------------------------------------------------------  
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
    SetGPOStatus() ;
}
//---------------------------------------------------------------------------
ww506772362 2013-10-16
  • 打赏
  • 举报
回复
非常感谢 cptang 的回复,但是我查了下资料。因为在window下访问寄存器,只能用winio去处理。我现在读取数据时对的,就是写不进去不知道是为什么。
cptang 2013-10-16
  • 打赏
  • 举报
回复


// GpioDemoDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "GpioDemo.h"
#include "GpioDemoDlg.h"
#include "afxdialogex.h"

#include <windows.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include "kbsp.h"
#include <io.h>       //_access()
#include "afx.h"


#pragma comment(lib,"libkcn_bsp.lib")

#define GPIO_BASE_ADDR	0x500
#define GPO0		12
void SetGPOStatus(BOOL level);

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

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

	// 对话框数据
	enum { IDD = IDD_ABOUTBOX };

protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

	// 实现
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CGpioDemoDlg 对话框




CGpioDemoDlg::CGpioDemoDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CGpioDemoDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CGpioDemoDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CGpioDemoDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON1, &CGpioDemoDlg::OnBnClickedButton1)
END_MESSAGE_MAP()


// CGpioDemoDlg 消息处理程序

BOOL CGpioDemoDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

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

	// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标


	// TODO: 在此添加额外的初始化代码
	
	
	kbsp_init();
	CString FileName = "./Config.ini";

	if(!_access(FileName, 0))    //0,Existence only
	{
		int GPIOValue=2;
		GPIOValue= GetPrivateProfileIntA("CurrentGPIOValue","GPIOValue",3,FileName);
		if(GPIOValue)
			SetGPOStatus(1);
		else
			SetGPOStatus(0);
	}
	else
	{
		::AfxMessageBox("Cann't find Log file: Config.ini");
	}

	kbsp_done();

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

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

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CGpioDemoDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		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;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CGpioDemoDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}



void CGpioDemoDlg::OnBnClickedButton1()
{
	// TODO: 在此添加控件通知处理程序代码

	kbsp_init();
	CString FileName = "./Config.ini";

	if(!_access(FileName, 0))    //0,Existence only
	{
		int GPIOValue=2;
		GPIOValue= GetPrivateProfileIntA("CurrentGPIOValue","GPIOValue",3,FileName);
		if(GPIOValue)
		{
			SetGPOStatus(0);
			WritePrivateProfileString("CurrentGPIOValue","GPIOValue","0",FileName);
		}
		else
		{
			SetGPOStatus(1);
			WritePrivateProfileString("CurrentGPIOValue","GPIOValue","1",FileName);
		}
	}
	else
	{
		::AfxMessageBox("Cann't find Log file: Config.ini");
	}

	kbsp_done();

}

void SetGPOStatus(BOOL level)
{

	ULONG PortValue;	

	PortValue = _inpd(GPIO_BASE_ADDR + 0x0C);

	if(level)
	{
		PortValue |= 1 << GPO0;
	}
	else
	{
		PortValue &= ~(1 << GPO0);
	}

	_outpd(GPIO_BASE_ADDR + 0x0C,PortValue);
}
cptang 2013-10-16
  • 打赏
  • 举报
回复
官方其实提供了一个vc的demo 你直接使用就可以了 无需用winio
cptang 2013-10-16
  • 打赏
  • 举报
回复
楼主这个程序貌似改自官方demo啊 视频通道切换操作。

552

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 茶馆
社区管理员
  • 茶馆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧