1.并口简介
并口标准:http://www.fapo.com/1284int.htm
 
并口使用了3个8位的端口寄存器,分别是(默认状态下):
数据寄存器:端口0x378+0,用于输出数据,Bit0-Bit7,针脚2-9
状态寄存器:端口0x378+1,用于输入数据,Bit3-Bit7,针脚15、13、12、10、11(反相)
控制寄存器:端口0x378+2,用于输出数据,Bit0-Bit3,针脚1(反相)、14、16(反相)、17(反相)
2.并口与BH1415F模块的连接
并口的输出不足以驱动BH1415F,这里使用三极管作为驱动(信号被反相了,编程时需要注意),电路图如下:


3.并口编程
这里采用http://www.internals.com出品的WinIO库来操作端口。
编程步骤:
//初始化WinIO
InitializeWinIo();
 
//操作数据端口
BOOL SetData(IN BYTE byteData )
{
    return ::SetPortVal(0x378,byteData,1);
}
 
//读取状态端口
BOOL GetStatus(OUT PDWORD lpStatus )
{
    return ::GetPortVal(0x378+1,lpStatus,1);
}
 
//操作控制端口
BOOL SetControl(IN BYTE byteControl )
{
    //并口Bit0,2,3相位是反的
    byteControl ^= 0x01;
    byteControl ^= 0x02;
    byteControl ^= 0x08;
    return ::SetPortVal(0x378+2,byteControl,1);
}
 
//释放WinIO
ShutdownWinIo();
4.控制BH1415F
点击这里下载BH1415Fdatasheethttp://www.pira.cz/pdf/bh1415f.pdf
a.频率计算程序:
int CalcFrequncy(double fMhz,BOOL bStero)
{
    int d1_d10=(int)(fMhz*10);//bit0-bit10
    int nData=d1_d10;
 
    if (bStero){
        nData|=18432;//0b 01 00 1 000 0000 0000
    }
    else{
        nData|=16384;//0b 01 00 0 000 0000 0000
    }
    return nData;
}
 
b.控制数据写入芯片,根据时序图写出控制程序:


//bit 1, 并口01:BH1415Chip Enable
//bit 2, 并口14:BH1415Clock
//bit 3, 并口16:BH1415Data
//bit 4, 并口17:BH1415MutingH=Mute on,L=Mute Off
MUTE(0);
 
CE(1);
for (int i=0;i<=15;i++)
{
    int bit=(nData>>i) & 0x01;
   
    DATA(bit);
    CLK(1);
    CLK(0);
}
 
CE(0);
 
控制软件界面:

万用板焊接的电路:


本文链接地址: 用并口控制BH1415F调频发射芯片
https://blog.qingfengju.com/index.asp?id=189

分类:Win32/C++ 查看次数:18451 发布时间:2009/12/31 23:23:39

//最简单的NT式驱动程序
//A Simple kernel-mode driver.
 
extern "C"
{
    #include <ntddk.h>
};
 
//设备扩展:其实是自己定义的附加信息
struct DEVICE_EXTENSION
{
    PDEVICE_OBJECT pDevObj;
    UNICODE_STRING ustr_SymbolicLinkName;
};
 
VOID SimpleDriver_Unload(IN PDRIVER_OBJECT pDriverObject)
{
    //遍历设备链,删除设备,删除符号链接
    //设备链是个普通链表
    PDEVICE_OBJECT pDevObj=pDriverObject->DeviceObject;
    while(pDevObj!=NULL)
    {
        DEVICE_EXTENSION* pDevExt=(DEVICE_EXTENSION*)(pDevObj->DeviceExtension);
        IoDeleteSymbolicLink(&(pDevExt->ustr_SymbolicLinkName));
        IoDeleteDevice(pDevExt->pDevObj);
 
        pDevObj=pDevObj->NextDevice;
    }
 
    KdPrint(("2.SimpleDriver_Unload()\n"));
}
 
 
extern "C" NTSTATUS DriverEntry(
                     IN PDRIVER_OBJECT  pDriverObject,
                     IN PUNICODE_STRING pRegistryPath)
{
   
    //指定卸载(此处的卸载是指此驱动程序停止运行时)例程
    KdPrint(("1.SimpleDriver DriverEntry()\n"));
    pDriverObject->DriverUnload=SimpleDriver_Unload;
 
    //初始化设备名称
    //格式为:\Device\DeviceName
    UNICODE_STRING ustr_DevName;
    RtlInitUnicodeString(&ustr_DevName,L"\\Device\\SimpleDriver_Device0");
                             
    //主动创建设备
    PDEVICE_OBJECT pDevObj;
    NTSTATUS status=IoCreateDevice(
        pDriverObject,
        sizeof(DEVICE_EXTENSION),
        &ustr_DevName,
        FILE_DEVICE_UNKNOWN,
        0,
        TRUE,
        &pDevObj);
          
    if (NT_SUCCESS(status)){
        KdPrint(("1.1.IoCreateDevice() OK\n"));
    }
    else{
        KdPrint(("1.1.IoCreateDevice() Failed\n"));
        return status;
    }
 
    //设置设备扩展信息(根据需要,保存各种附加信息)
    //DEVICE_EXTENSION是自己定义的结构体
    DEVICE_EXTENSION* pDevExt=(DEVICE_EXTENSION*)(pDevObj->DeviceExtension);
    pDevExt->pDevObj=pDevObj;
 
    //初始化链接名称字符串
    //格式为:\??\SymbolicLinkName
    UNICODE_STRING ustr_SymbolicLinkName;
    RtlInitUnicodeString(&ustr_SymbolicLinkName,L"\\??\\SimpleDriver_Device0");
   
    //创建符号链接
    status=IoCreateSymbolicLink(&ustr_SymbolicLinkName,&ustr_DevName);
    if (NT_SUCCESS(status)){
        KdPrint(("1.2.IoCreateSymbolicLink() OK\n"));
        pDevExt->ustr_SymbolicLinkName=ustr_SymbolicLinkName;
    }
    else{
        KdPrint(("1.2.IoCreateSymbolicLink() Failed\n"));
        return status;
    }
 
    return STATUS_SUCCESS;
}
 
用DriverMonitor加载后,在DeviceTree中可以看到:
 

本文链接地址: 驱动编程.4 最简单的NT式驱动程序
https://blog.qingfengju.com/index.asp?id=188

分类:Win32/C++ 查看次数:9282 发布时间:2009/12/22 14:47:51