从下->上 计数器减1 0FEH左移一位 赋予TEMP TEMP取反 TEMP输出到IO地址 延时 计数器==0 计数器=8 返回
四 程序代码
#include
unsigned long int iobase0,iobase1,membase0,membase1,ioadd1=0x60; unsigned char bh; unsigned char bl; int d1=0,m_bit=0x1;
int findPCIcard() //找寻PCI卡的总线号及设备号及功能号 {
26
union REGS regs; regs.h.ah=0xb1;
regs.h.al=0x02; //寻找指定厂商和设备号的PCI卡的位置 regs.x.cx=0x8376;
regs.x.dx=0x10eb; //输入要寻找的厂商号和设备号 regs.x.si=0x00; //输入要寻找的PCI卡索引号 int86(0x1a,®s,®s); //调用指定的X86中断
bl=regs.h.bl; // bh=regs.h.bh; // return(regs.h.ah); //}
int getPCIbase0() //{
union REGS regs; // regs.h.ah=0xb1; // regs.h.al=0x09; // regs.x.di=0x14; //PCI regs.h.bl=bl; // regs.h.bh=bh; // int86(0x1a,®s,®s); // iobase0=regs.x.cx; //CX return(regs.h.ah); //}
int getPCIbase1() {
union REGS regs; // regs.h.ah=0xb1; regs.h.al=0x09;
regs.x.di=0x1c; //PCI regs.h.bl=bl; regs.h.bh=bh;
返回的设备号高5位,低3位为功能号 返回的总线号 返回状态 获得PCI卡的IO0的地址 定义用C语言调用BIOS中断所用的寄存器组合 调用PCI BIOS中断 配置空间用字的方式读入 配置空间中基地址0的地址
要读入配置空间的PCI卡的设备号和功能号 要读入配置空间的PCI卡的总线号 调用指定的X86中断 为返回的IO0的基地址 返回状态 同上 配置空间基地址1的地址 27
int86(0x1a,®s,®s); iobase1=regs.x.cx; return(regs.h.ah); }
int getPCImembase0() {
union REGS regs; //同上 regs.h.ah=0xb1; regs.h.al=0x09;
regs.x.di=0x18; //PCI regs.h.bl=bl; regs.h.bh=bh;
int86(0x1a,®s,®s); membase0=regs.x.cx; return(regs.h.ah); }
int getPCImembase1() {
union REGS regs; // regs.h.ah=0xb1; regs.h.al=0x09;
regs.x.di=0x1a; //PCI regs.h.bl=bl; regs.h.bh=bh;
int86(0x1a,®s,®s); membase1=regs.x.cx; return(regs.h.ah); }
int getPCIIRQ() {
union REGS regs; //
配置空间存储器基地址0的低位地址同上 配置空间存储器基地址0的高位地址 同上
28
regs.h.ah=0xb1; regs.h.al=0x09;
regs.x.di=0x3c; //PCI配置空间中断线的地址 regs.h.bl=bl; regs.h.bh=bh;
int86(0x1a,®s,®s); return(regs.h.cl); } main() {
int err,rio,flagm; int m_k0(); void m_k1(); void m_k2(); void m_k3();
err=findPCIcard(); if (err!=0) {
printf(\ flagm=0; }
err=getPCIbase0();
iobase0=iobase0&0xfffc;
//从PCI配置空间读入的与地址空间有关的数据其bit 0位为1, printf(\//表明此空间为IO空间参与PCI总线地址译码 err=getPCIbase1(); iobase1=iobase1&0xfffc;
printf(\ err=getPCImembase1();
29
err=getPCImembase0();
membase0=membase0+membase1<<16; //左移16位,将高位地址变换成双字中的高位字 printf(\ err=getPCIIRQ();
printf(\//////////////////////////////////////
ioadd1=ioadd1+iobase1; //获取步进电机驱动端口地址 flagm=1;
printf(\选择正、反转或退出 do //主循环 {
rio=inportb(ioadd1); //从IO端口读入数据 rio=rio&0x3; //保留低两位
switch(rio) //判断数据并做相应处理 {
case 0: //为0时LED全亮
flagm=m_k0(); break;
case 1: //为1时LED全部闪烁
m_k1(); break;
case 2: //为2时LED从下到上循环点亮
m_k2(); break;
case 3: //为3时LED从上到下循环点亮
m_k3(); break;
default:
break;
30
}