用并口控制BH1415F调频发射芯片
作者:淡月清风 日期:2009-12-31
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
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脚:接BH1415的Chip Enable
//bit 2, 并口14脚:接BH1415的Clock
//bit 3, 并口16脚:接BH1415的Data
//bit 4, 并口17脚:接BH1415的Muting,H=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);
控制软件界面:
万用板焊接的电路:
驱动编程.4 最简单的NT式驱动程序
作者:淡月清风 日期:2009-12-22
//最简单的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;
}
驱动编程.3 [转载]WinDBG+VMware=调试内核
作者:淡月清风 日期:2009-12-21
原文地址:http://hi.baidu.com/1ian9yu/blog/item/96e29bb357acbfa2d8335a25.html
根据此文,很顺利的完成了源码级调试设置。
呵呵,搞点突兀的标题而已。其实说的还是如何使用WinDBG和VMware来搭建调试内核的环境而已,这些网上已经有数不清的教程了,不过我喜欢自己亲手写一下。第一,把这个过程写一遍能加深印象,就算以后忘记了也可以有笔记查找,快速想起来。第二、网上的教程很多都是互相抄来抄去,连错误也抄过去了。很典型一个错误就是Baud Rate,前面还写115200,后面就写成了11520了,狂汗!
按照我这篇笔记写的步骤去做,绝对能够成功,并且还能大略地了解到为什么要这样做的原因。第1部分是步骤,如果不想看原因的,直接按部照搬就可以成功。如果还想深入点了解为什么要做这些步骤,这些步骤的含义是什么?那就请继续看第二部分。
第一部分(步骤):
先统一名称,真实的操作系统叫HostOS,在VMware里虚拟的操作系统叫Gues...
驱动编程.2 最简单的“驱动程序”
作者:淡月清风 日期:2009-12-20
//SimpleDriver.c,用了C语言
#include <ntddk.h>
#include <ntddk.h>
VOID SimpleDriverUnload(IN PDRIVER_OBJECT pDriverObject)
{
KdPrint(("2.SimpleDriverUnload()\n"));
//注意KdPrint的格式,是两层括号。
//注意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.可以在设备管理的“非即插即用驱动程序”中看到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也可以查看
1.DriverMonitor 可以查看
2.www.sysinternals.com出品Dbgview也可以查看






