预览模式: 普通 | 列表

用并口控制BH1415F调频发射芯片

1.并口简介
 
并口使用了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);
 
控制软件界面:

万用板焊接的电路:

分类:Win32&C++ | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 674

驱动编程.4 最简单的NT式驱动程序

//最简单的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中可以看到:
 
分类:Win32&C++ | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 499

驱动编程.3 [转载]WinDBG+VMware=调试内核

原文地址:http://hi.baidu.com/1ian9yu/blog/item/96e29bb357acbfa2d8335a25.html
根据此文,很顺利的完成了源码级调试设置。
 
 

呵呵,搞点突兀的标题而已。其实说的还是如何使用WinDBG和VMware来搭建调试内核的环境而已,这些网上已经有数不清的教程了,不过我喜欢自己亲手写一下。第一,把这个过程写一遍能加深印象,就算以后忘记了也可以有笔记查找,快速想起来。第二、网上的教程很多都是互相抄来抄去,连错误也抄过去了。很典型一个错误就是Baud Rate,前面还写115200,后面就写成了11520了,狂汗!

按照我这篇笔记写的步骤去做,绝对能够成功,并且还能大略地了解到为什么要这样做的原因。第1部分是步骤,如果不想看原因的,直接按部照搬就可以成功。如果还想深入点了解为什么要做这些步骤,这些步骤的含义是什么?那就请继续看第二部分。

第一部分(步骤):

先统一名称,真实的操作系统叫HostOS,在VMware里虚拟的操作系统叫Gues...

查看更多...

分类:Win32&C++ | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 428

驱动编程.2 最简单的“驱动程序”

//SimpleDriver.c,用了C语言
#include
<ntddk.h>
 
VOID SimpleDriverUnload(IN PDRIVER_OBJECT pDriverObject)
{
    KdPrint(("2.SimpleDriverUnload()\n"));
  
//注意KdPrint的格式,是两层括号。
}
 
//驱动程序入口函数,由系统进程(System)调用
//pDriverObject是驱动对象
//pRegistryPath是设备服务键的键名Unicode字符串指针
ULONG DriverEntry (IN PDRIVER_OBJECT pDriverObject,
                   IN PUNICODE_STRING pRegistryPath)
{
    KdPrint(("1.DriverEntry()\n"));
    KdPrint(("1.%S\n",pRegistryPath->Buffer));
   
    //指定卸载routine
    pDriverObject->DriverUnload=SimpleDriverUnload;
 
    return STATUS_SUCCESS;
}
 
编译之后可以使用Compuware DriverStudio提供的DriverMonitor 来加载或卸载。
加载成功后:
1.可以在设备管理的“非即插即用驱动程序”中看到SimpleDriver
2.可以在HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\看到SimpleDriver
3.在www.sysinternals.com出品的Winobj中可以看到SimpleDriver
4.在DDK中提供的Device Tree中可以看到SimpleDriver
 
 关于调试信息的查看:
1.DriverMonitor 可以查看
2.www.sysinternals.com出品Dbgview也可以查看

 

分类:Win32&C++ | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 480