📄 demo365.c
字号:
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
//#include <setupapi.h>
#include <winioctl.h>
#include "CH365DLL.H"
#pragma comment(lib,"CH365DLL.LIB")
mPCH365_IO_REG mIoBase; // I/O基址
mPCH365_MEM_REG mMemBase; //存储器基地址
ULONG mIntLine; // 中断号
int Device_Number; //选择设备号
void A15_A8Test(UCHAR data);
void IoTest(UCHAR mByte);
void MemoryTest(UCHAR mByte,PUCHAR temp);
void IntTest();
void I2cTest(UCHAR Byte);
void Select();
//中断服务子程序
void CALLBACK InterruptEvent( void )
{
UCHAR mByte;
// 该中断服务程序属于应用层程序,当中断频率高于每秒100000次以上或者系统较忙时有可能丢失中断.
// 在进入应用层的中断服务之前,CH365的WDM硬件中断服务程序会先执行中断命令,而中断命令属于系统级程序,不会丢失中断.
// 所以中断频率较高时,建议使用中断命令或者重新写一个专用的WDM驱动
// printf不支持重入,所以不宜用在中断服务程序中
printf( "\n### Interrupt Event ###\n" );
printf( "### CH365mReadIoByte: addr=0x02, data " );
if ( CH365mReadIoByte(Device_Number, & mIoBase -> mCh365IoPort[2], &mByte ) == FALSE ) printf( " ERROR " );
printf( "= %02X \n", mByte );
}
void main()
{
printf("*****Copyright (C) W.ch 2003.08 ");
// 需要使用DLL则需要先加载
printf( "*** Load DLL: CH365DLL.DLL \n" );
if ( LoadLibrary( "CH365DLL.DLL" ) == NULL ) return; // 加载DLL失败,可能未安装到系统中
//选择打开365设备
printf("***请输入要选择的365的设备号(0、1...)\n");
scanf("%d",&Device_Number);
//OPEN DEVICE 打开存储器和中断
printf( "*** CH365mOpenDevice: I/O port, Memory,Interrupt\n" );
if ( CH365mOpenDevice(Device_Number, TRUE, TRUE ) == INVALID_HANDLE_VALUE ) return;
// 通过DLL来调用版本号
printf( "*** CH365GetDrvVersion " );
printf( "= %02X \n", CH365GetDrvVersion() );
// 通过DLL来调用系统自动分配的I/O基地址
printf( "*** CH365mGetIoBaseAddr " );
if ( CH365mGetIoBaseAddr( Device_Number,&mIoBase ) == FALSE ) printf( " ERROR " );
printf( "= %08X \n", mIoBase );
// 通过DLL来调用系统自动分配的存储器基地址
printf( "***CH365mGetMemBaseAddr ");
if (CH365mGetMemBaseAddr(Device_Number,&mMemBase) ==FALSE) printf("ERROR");
printf("=%08X\n",mMemBase);
/* 如果需要用到中断,自动检测CH365所用的中断号 */
printf( "*** CH365mSetIntLine: AUTO " );
if ( CH365mSetIntLine(Device_Number, mCH365_INT_LINE_AUTO ) == FALSE ) printf( " ERROR \n" );
else printf( "= OK \n" );
//调用中断号
printf( "*** CH365mGetIntLine " );
if ( CH365mGetIntLine(Device_Number, &mIntLine ) == FALSE ) printf( " ERROR " );
printf( "= %08X \n", mIntLine );
/***中断命令设定,CH365的WDM驱动程序中支持两条中断预处理命令 **/
/**通过使用CH365mWriteIntCommand( // 写入中断命令缓冲区 **/
/** ULONG iIndex, // 指定CH365设备序号 **/
/** mPWIN32_COMMAND iCommand, // 指向作为中断命令的命令结构 **/
/** ULONG iCmdIndex ) // 中断命令序号,为1或者2 **/
/**假定在系统响应中断时设定A0-A15的状态为0x08000,可以撤消外部电路的中断请求 **/
if ( mIntLine )// 已经启用中断
{
mWIN32_COMMAND mCommand;
printf( "***CH365mWriteIntCommand " );
mCommand.mFunction = mFuncWriteIoWord; //发送I/O口写字命令,命令代码,该命令在硬件中断时由驱动程序执行
mCommand.mAddress = & mIoBase ->mCh365MemAddr; //设定A0-A15的地址寄存器,操作地址
mCommand.mLength = 2; //数据长度设定,操作数据长度,以字节计算
mCommand.mBuffer[0] = 0x00; //要写的数据
mCommand.mBuffer[1] = 0x80; // A15=1,假定:在外部电路的中断逻辑上,将A15置为高电平可以撤消中断
if ( CH365mWriteIntCommand(Device_Number, &mCommand, 1 ) == FALSE ) printf( " ERROR ");
printf( "*** CH365SetIntRoutine " );
if ( CH365mSetIntRoutine(Device_Number, InterruptEvent ) == FALSE ) printf( " ERROR " );
printf( "= OK \n" );
}
//开始选择和调用测试
Select();
}
void Select()
{
char inputr; // 输入一个选择号
UCHAR a;
PUCHAR temp1=&a;
printf(" *******请输入测试的端口*******\n");
printf("0.退出程序 1.A15-A8的输出测试\n");
printf("2.D7-D0的输出测试 3.存储器测试\n");
printf("4.中断测试 5.I2C设备测试\n");
do{
inputr=getchar();
switch(inputr)
{
case '0':
// 关闭CH365设备,如果不继续使用CH365则必须关闭设备,就象读写完硬盘中的数据文件后要关闭一样
printf( "*** CH365mCloseDevice \n" );
CH365mCloseDevice(Device_Number);
printf( "\nExit.\n" );
exit(0); //退出
case '1':
printf("***请输入数据作为A15-A8的输出测试\n ");
scanf("%x",&a); //得到一个字符
A15_A8Test(a); //调用函数
break;
case '2':
printf("***请输入数据作为D0-D7的输入输出测试\n");
scanf("%x",&a); //得到一个字符
IoTest(a); //调用函数
break;
case '3':
printf("***请输入数据作为存储器的输入输出测试\n");
scanf("%x",&a);
MemoryTest(a,temp1);
break;
case '4':
printf("***进入中断测试\n");
IntTest();
break;
case '5':
printf("***请输入数据作为I2C的输入输出测试\n");
scanf("%02x",&a);
I2cTest(a);
}
}
while(1);
}
// 向I/O空间的A15-A8地址设定单元写入数据
// 因为A15-A0地址设定寄存器必须以字为单位进行读写,
// 所以应该使用CH365WriteIoWord,或者使用DLL提供的CH365SetA15_A8
void A15_A8Test(UCHAR data)
{
printf( "*** CH365mSetA15_A8: data=0x XX " );
if ( CH365mSetA15_A8(Device_Number, data ) == FALSE ) printf( " ERROR " );
printf( "= OK \n" );
Select(); //重新调用输出测试
}
// 从I/O端口的偏移地址写入一个字节的数据
void IoTest(UCHAR mByte)
{
printf( "*** CH365mWriteIoByte: addr=0x XX, data " );
if ( CH365mWriteIoByte(Device_Number, &mIoBase -> mCh365IoPort[0x00], mByte ) == FALSE ) printf( " ERROR " );
printf( "= %02X \n", mByte );
if ( CH365mReadIoByte(Device_Number, &mIoBase -> mCh365IoPort[0x00], &mByte ) == FALSE ) printf( " ERROR " );
printf("= %02X \n", mByte);
Select(); //重新调用输出测试
}
// 从MEM端口的偏移地址写入和读出一个字节的数据
void MemoryTest(UCHAR mByte,PUCHAR temp)
{
printf("***CH365mWriteMemByte: addr=0x XX, data");
if ( CH365mWriteMemByte(Device_Number,&mMemBase ->mCh365MemPort[0x22], mByte ) ==FALSE) printf("ERROR");
printf("= %02X\n",mByte) ;
mByte+=5;
printf("***CH365mWriteMemByte: addr=0x XX, data");
if ( CH365mWriteMemByte(Device_Number,&mMemBase ->mCh365MemPort[0x23], mByte ) ==FALSE) printf("ERROR");
printf("= %02X\n",mByte) ;
printf("***CH365mReadMemByte: addr=0x XX,data");
if (CH365mReadMemByte(Device_Number,&mMemBase ->mCh365MemPort[0x40], temp) == FALSE) printf("ERROR");
printf("= %02X\n",*temp);
printf("***CH365mReadMemByte: addr=0x XX,data");
if (CH365mReadMemByte(Device_Number,&mMemBase ->mCh365MemPort[0x41], temp) == FALSE) printf("ERROR");
printf("= %02X\n",*temp);
Select();
}
//中断测试
void IntTest()
{
printf("请置SYS_EX为低电平,则InterruptEvent将被调用,按任意键后退出");
getch();
CH365mSetA15_A8(Device_Number, 0x00 ); /* 将A15恢复为低电平,从而允许下次中断测试 */
}
//I2C设备测试
void I2cTest(UCHAR Byte)
{
// 从I2C接口所挂接的24C0X中读取一个字节的数据, 0x50是24C0X的7位设备地址,该24C0X的A2-A1-A0均接地
printf("***CH365mWriteI2C:addr=1,data");
if(CH365mWriteI2C(Device_Number, 0x50, 0x01,Byte )==FALSE) printf("ERROR");
printf("= %02X\n",Byte) ;
printf("ADDR= %02X\n",&Byte) ;
// 对于EEPROM 24C01A/24C02/24C04/24C08/24C16在写操作后应该延时10毫秒,确保EEPROM擦写周期
CH365DelayUS( 12000 ); // 延时12000微秒, 即12毫秒
// Sleep(10); // 软件延时误差较大,所以使用CH365的DLL提供的硬件延时,在Windows下的多任务切换有可能导致硬件延时增加
Byte+=4;
printf("***CH365mWriteI2C:addr=5,data");
if(CH365mWriteI2C(Device_Number, 0x50, 0x05,Byte )==FALSE) printf("ERROR");
printf("= %02X\n",Byte) ;
printf("ADDR= %02X\n",&Byte) ;
// 对于EEPROM 24C01A/24C02/24C04/24C08/24C16在写操作后应该延时10毫秒,确保EEPROM擦写周期
CH365DelayUS( 12000 ); // 延时12000微秒, 即12毫秒
// Sleep(10);
printf("***CH365mReadI2C:addr=1,data");
if(CH365mReadI2C(Device_Number, 0x50, 0x01,&Byte)==FALSE) printf("ERROR");
printf("= %02X\n",Byte);
printf("ADDR= %02X\n",&Byte) ;
printf("***CH365mReadI2C:addr=5,data");
if(CH365mReadI2C(Device_Number, 0x50, 0x05,&Byte)==FALSE) printf("ERROR");
printf("= %02X\n",Byte);
printf("ADDR= %02X\n",&Byte) ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -