我正在用CH365评估板实现读写IO端口的功能,用的是CH365芯片中文手册中提供的“I/O端口应用(上图右边的电路)”方案。其中74LS245的输入端接8个开关,74LS374的输出端接8个LED灯,现在的想法是只要按下8个开关中的任意一个,就马上产生中断,而后中断服务程序读取开关数据,输出到LED灯上。现在的问题是低电平的中断请求信号INT_REQ如何在按下开关时产生??请赐教
电路图已上传[Emot]8[/Emot]
我正在用CH365评估板实现读写IO端口的功能,用的是CH365芯片中文手册中提供的“I/O端口应用(上图右边的电路)”方案。其中74LS245的输入端接8个开关,74LS374的输出端接8个LED灯,现在的想法是只要按下8个开关中的任意一个,就马上产生中断,而后中断服务程序读取开关数据,输出到LED灯上。现在的问题是低电平的中断请求信号INT_REQ如何在按下开关时产生??请赐教
电路图已上传[Emot]8[/Emot]
图没传上
斑竹帮我分析下好吗?我很急
看到了 这个图和中断没关系 这个图的原理是IOP_RD 和IOP_WR 控制74LS139 的译码使能,74LS139将地址译码输出2 路读控制和2 路写控制,经过74LS245 输入缓冲和74LS374 锁存输出,获得2组每组8位缓冲输入和2 组每组8 位锁存输出。也就是按下开关等 是不同的输入输出的读写操作。
我的驱动程序中读写IO端口操作时机是在接收到CH365的中断之后立即进行(也就是以中断方式进行IO与主机的数据交换),是一个循环不断的过程,只要按下开关,就产生一个中断,而后中断程序就读开关状态,再输出到LED上,我的问题是给CH365的这个中断信号怎么产生?不能通过开关的按下产生中断吗??
中断有软件和硬件中断,过程和实现可以参考《CH365 中断功能使用说明》CH365INT.PDF 文档, 在CH365EVT/PUB 中 可从在线下载中 下载CH365EVT.ZIP
《CH365 中断功能使用说明》我也看了,我要产生的是硬件中断,就是给CH365的这个低电平的INT_REQ信号我不知道该如何产生
首先,D3下拉复用引脚59的功能为INT_REQ, 然后根据I/O 空间偏移0F8H,位2设定INTA 中断激活状态,为0无中断,为1有中断。
硬件中断信号现已解决,不知斑竹是否了解winDriver,我用我winDriver写了评估板的驱动程序,但是中断就是不好使啊,程序如下,编译没有错误,不知道有什么其他问题? #include #include #include #include #include "windrvr.h"
/**-----------全局变量---------------*/ HANDLE hWD;//windriver内核句柄 KPTR IO_Base_Addr;//IO空间基地址 int IntCount = 0;//中断次数 WD_INTERRUPT Intrp;//记录中断信息
/**------------------中断处理程序---------------------*/ void ProcessInterrupt(void) { WD_TRANSFER Trans;//传递读写命令的结构体 IntCount++; printf("第%d次中断到来,进入中断处理程序\n",IntCount); /**清除CH365芯片控制寄存器的中断激活状态位*/ Trans.cmdTrans = RP_BYTE; Trans.dwPort = (IO_Base_Addr + 0xf8); WD_Transfer(hWD, &Trans); Trans.Data.Byte &= 0xfb; Trans.cmdTrans = WP_BYTE; WD_Transfer(hWD, &Trans);
/**从开关读入一个字节,输出到LED灯*/ Trans.cmdTrans = RP_BYTE; //从开关读入一个字节 Trans.dwPort = IO_Base_Addr; WD_Transfer(hWD, &Trans); Trans.cmdTrans = WP_BYTE; //输出到LED灯 WD_Transfer(hWD, &Trans); }
DWORD WINAPI wait_interrupt (PVOID pData) { printf ("Waiting for interrupt\n"); for (;;) { WD_IntWait (hWD, &Intrp); if (Intrp.fStopped) break; // WD_IntDisable called by parent ProcessInterrupt();//自定义的中断处理程序 } return 0; } int main() { HANDLE thread_handle; DWORD thread_id; DWORD i=0,IntItem,dwStatus; WD_PCI_SCAN_CARDS pciScan;//记录pci设备扫描信息 WD_PCI_SLOT pciSlot;//记录pci设备插槽信息 WD_PCI_CARD_INFO pciCardInfo;//记录pci板卡信息 WD_PCI_CONFIG_DUMP pciConfig; WD_CARD Card;//记录pci板卡资源信息 WD_CARD_REGISTER cardReg;//登记板卡的结构体 WD_TRANSFER Trans[2];//传递读写命令的结构体
/**-------------初始化-----------------*/ BZERO(pciScan); BZERO(pciCardInfo); BZERO(pciConfig); BZERO(Card); BZERO(cardReg); BZERO(Intrp);
/**-------------WD_Open()--------------*/ hWD=WD_Open(); //打开windriver设备,返回的句柄会被所有的windriver APIs所使用 if (hWD == INVALID_HANDLE_VALUE) { printf("Cannot open WinDriver device\n"); }
/**-----------WD_PciScanCards()-------*/ pciScan.searchId.dwVendorId = 0x4348;//南京沁恒公司提供的Vendor ID pciScan.searchId.dwDeviceId = 0x5049;//南京沁恒公司提供的Device ID WD_PciScanCards(hWD,&pciScan);//查找要访问的PCI插槽上的设备 if (pciScan.dwCards>0) //找到至少一个设备 { pciSlot = pciScan.cardSlot[0]; //使用第一个设备 } else { printf("No matching PCI devices found\n"); } /**------------WD_PciGetCardInfo()----*/ pciCardInfo.pciSlot = pciSlot; WD_PciGetCardInfo(hWD, &pciCardInfo);//枚举该设备的资源 if (pciCardInfo.Card.dwItems!=0) //找到该卡的至少一项资源 { Card = pciCardInfo.Card; } else { printf("Failed fetching PCI card information\n"); }
/**---------------WD_PciConfigDump()---------*/ pciConfig.pciSlot = pciSlot; pciConfig.pBuffer = (&IO_Base_Addr); pciConfig.dwOffset = 0x10;//从配置空间读取IO基地址 pciConfig.dwBytes = sizeof(IO_Base_Addr); pciConfig.fIsRead = TRUE; dwStatus = WD_PciConfigDump(hWD, &pciConfig); if (dwStatus) { printf("WD_PciConfigDump failed\n"); } IO_Base_Addr &= 0xfffffff0;//低四位是无用信息,需要屏蔽
/**-WD_CardRegister() & WD_IntEnable()---------------*/ cardReg.Card = Card; cardReg.fCheckLockOnly = FALSE; for (i=0;i < cardReg.Card.dwItems;i++) { cardReg.Card.Item[i].fNotSharable = TRUE; if (cardReg.Card.Item[i].item == ITEM_INTERRUPT) { IntItem = i; cardReg.Card.Item[i].I.Int.dwOptions =INTERRUPT_LEVEL_SENSITIVE; } } WD_CardRegister(hWD,&cardReg);//向winDriver核心登记硬件板卡,锁定板卡资源 if (cardReg.hCard == 0) { printf("Failed locking device\n"); return FALSE; } else { Intrp.hInterrupt = cardReg.Card.Item[IntItem].I.Int.hInterrupt;//获取板卡中断句柄 Intrp.Cmd = Trans; Intrp.dwCmds = 2; Trans[0].cmdTrans = RP_BYTE; Trans[0].dwPort = (IO_Base_Addr + 0xf8); Trans[1].cmdTrans = WP_BYTE; Trans[1].dwPort = Trans[0].dwPort; Trans[1].Data.Byte = Trans[0].Data.Byte; Intrp.dwOptions = INTERRUPT_LEVEL_SENSITIVE|INTERRUPT_CMD_COPY; WD_IntEnable(hWD, &Intrp); if (!Intrp.fEnableOk) { printf("Failed enabling interrupt\n");//无法开启中断 } printf ("starting interrupt thread\n"); thread_handle = CreateThread (0, 0x1000, wait_interrupt, NULL, 0, &thread_id); WD_IntDisable (hWD, &Intrp); WaitForSingleObject(thread_handle, INFINITE); }
/**-------------WD_CardUnregister()---------------*/ WD_CardUnregister(hWD,&cardReg);//注销板卡
/**------------WD_close()-----------*/ WD_Close(hWD);//关闭winDriver设备
return 0; }