gxg0000 发表于 2024-7-13 13:49:06

驱动

本帖最后由 gxg0000 于 2024-7-13 13:46 编辑

闲暇无事,翻出多年前的飞凌2440嵌入式单片机,将其改成多功能仪表,其中有一中短波扫频仪功能,也算是废物利用吧。
扫频仪采用WINCE5.0系统运行,以下扫频仪流驱动程序,程序带注释,仅供参考!

开机界面


扫频仪全貌


扫频仪工作界面


扫频仪探头



// SWEEP.cpp : 定义 DLL 应用程序的入口点。
//
#include "stdafx.h"
#define REG_TYPE DWORD
#include <ceddk.h>
#include <s3c2440a_ioport.h>
#include <s3c2440a_adc.h>
#include <s3c2440a_base_regs.h>
#define DLLAPI extern "C" __declspec(dllexport)        //指定C编译器编译
static volatile S3C2440A_IOPORT_REG*v_pIOPregs;       // S3C2440x GPIO registers
static volatile S3C2440A_ADC_REG*v_pADCPregs;       // S3C2440x ADC registers
//IO控制DDS引脚定义
#define ad9850_w_clk_clr                v_pIOPregs->GPGDAT &=~ (1 <<7)                //GPG7口接ad9850的w_clk脚
#define ad9850_w_clk_set        v_pIOPregs->GPGDAT |= (1 << 7)
#define ad9850_fq_up_clr                v_pIOPregs->GPGDAT &=~ (1 << 5)                //GPG5口接ad9850的fu_ud脚
#define ad9850_fq_up_set        v_pIOPregs->GPGDAT |= (1 << 5)
#define ad9850_bit_data_clr                v_pIOPregs->GPGDAT &=~ (1 << 2)        //GPG2口接ad9850的data脚
#define ad9850_bit_data_set        v_pIOPregs->GPGDAT |= (1 << 2)
#define ad9850_rest_clr                v_pIOPregs->GPEDAT &=~ (1 << 12)                        //GPE12口接ad9850的reset脚
#define ad9850_rest_set        v_pIOPregs->GPEDAT |= (1 << 12)
//
bool flag=true;               //读写标记
unsigned int f_start =441750;        //扫描开始频率
unsigned int step=150;                //步进
unsigned int delay=1;                //采样速度1快2慢
unsigned int ad_channel=1;//AD通道
unsigned int adc;
unsigned int Array1;
unsigned int Array2;
HANDLE hand;        //AD线程句柄
DWORD WINAPI ADThread();        //AD线程函数

/*-------------------------------------------------------------/
函数名称:        Delay_us
功能描述:        延时函数
传    参:        n*1微秒
返 回 值:        无
--------------------------------------------------------------*/
void Delay_us(unsigned int n)
{
    volatile unsigned int i,j;
    for(i = 0; i < n; i++)
        for(j = 0; j < 78; j++);
}
/*-------------------------------------------------------------/
函数名称:        ad9850_reset_serial
功能描述:        ad9850复位(串口模式)
传    参:无
返 回 值:无
--------------------------------------------------------------*/
void ad9850_reset_serial()
{
        ad9850_w_clk_clr;
        ad9850_fq_up_clr;
        ad9850_rest_clr;        //rest信号
        ad9850_rest_set;
        Delay_us(1);
        ad9850_rest_clr;
        ad9850_w_clk_clr;        //w_clk信号
        ad9850_w_clk_set;
        Delay_us(1);
        ad9850_w_clk_clr;
        ad9850_fq_up_clr;        //fu_ud信号
        ad9850_fq_up_set;
        Delay_us(1);
        ad9850_fq_up_clr;
}
/*-------------------------------------------------------------/
函数名称:        ad9850_w
功能描述:        向ad9850串口写1字节函数
传    参:w
返 回 值:无
--------------------------------------------------------------*/
void ad9850_w(BYTE w)
{
        for(unsigned char i=0;i<8;i++)
        {
                (((w>>i)&1)==1)?(ad9850_bit_data_set):(ad9850_bit_data_clr);
                ad9850_w_clk_set;
                Delay_us(1);
                ad9850_w_clk_clr;
        }
}
/*-------------------------------------------------------------/
函数名称:        ad9850_wr_serial
功能描述:        向ad9850中写命令与数据(串口)
传    参:w0,frequence
返 回 值:无
--------------------------------------------------------------*/
void ad9850_wr_serial(BYTE w0,unsigned int frequence)
{
        unsigned int y=(unsigned int)(frequence*34.35973836);
        ad9850_w(y);                //写w4数据
        ad9850_w(y>>8);        //写w3数据
        ad9850_w(y>>16);        //写w2数据
        ad9850_w(y>>24);        //写w1数据
        ad9850_w(w0);        //写w0数据
        ad9850_fq_up_set;        //移入始能
        Delay_us(1);
        ad9850_fq_up_clr;
}
/*-------------------------------------------------------------/
函数名称:        ADC
功能描述:        单次模数转换函数
传    参:无
返 回 值:10位有效
--------------------------------------------------------------*/
UINT32 ADC()
{
        v_pADCPregs-> ADCCON |= 0x1;        // 开始转换
        while (        (v_pADCPregs-> ADCCON) & (1<<0));        //检测开始位是否为低电平
        while(!((v_pADCPregs-> ADCCON) & (1<<15)));        //检测转换是否完毕标志位
        return ((v_pADCPregs->ADCDAT0) & 0x3ff);
}
/*-------------------------------------------------------------/
函数名称:        ADC_DigitalFilter_1
功能描述:        模数转换+数字滤波函数(32次AD)
传    参:无
返 回 值:10位有效
--------------------------------------------------------------*/
UINT32 ADC_DigitalFilter_1()
{
        v_pADCPregs-> ADCDLY = 10;        // ADC开始延时寄存器(延时时间最小)                                                        
        for (unsigned int j=0; j<32; j++)       {Array1=ADC();}
        v_pADCPregs-> ADCDLY = 20000;                //ADC开始延时寄存器(恢复默认,否则要影响触摸屏)
        qsort(Array1,32,4,comp);
        unsigned int        add=0;
        for (unsigned int j=0; j<16; j++) {add+=Array1;}
        return add>>4;
}
/*-------------------------------------------------------------/
函数名称:        ADC_DigitalFilter_2
功能描述:        模数转换+数字滤波函数(64次AD)
传    参:无
返 回 值:10位有效
--------------------------------------------------------------*/
UINT32 ADC_DigitalFilter_2()
{
        v_pADCPregs-> ADCDLY = 10;                               
        for (unsigned int j=0; j<64; j++) {Array2=ADC();}
        v_pADCPregs-> ADCDLY = 20000;       
        qsort(Array2,64,4,comp);
        unsigned int        add=0;
        for (unsigned int j=0; j<32; j++) {add+=Array2;}
        return add>>5;
}
//-----------------------------------------------------------------------------
//----------------------DllMain入口--------------------------------
BOOL APIENTRY DllMain( HANDLE hModule, DWORDul_reason_for_call, LPVOID lpReserved)
{
    switch ( ul_reason_for_call )
    {
      case DLL_PROCESS_ATTACH:
                        RETAILMSG(1, (_T("SEW_PROCESS_ATTACH\r\n")));        //DisableThreadLibraryCalls((HMODULE) hModule);
      break;
      case DLL_PROCESS_DETACH:
                        RETAILMSG(1, (_T("SEW_PROCESS_DETACH\r\n")));
      break;
    }
        return true;
}
//-----------------------------------------------------------------------------
//-------------init-init-init-init-init-init-init-------------------
DLLAPI DWORD SWE_Init(LPCTSTR pContext)
{
    RETAILMSG(1,(TEXT("***SWE_init\r\n")));
        //IO寄存器地址映射
    v_pIOPregs = (volatile S3C2440A_IOPORT_REG *)VirtualAlloc(0, sizeof(S3C2440A_IOPORT_REG), MEM_RESERVE,PAGE_NOACCESS);//为v_pIOPregs变量分配虚拟空间
        if (v_pIOPregs == NULL)
    {
      ERRORMSG(1,(_T("SWE_InitAddrIO: VirtualAlloc failed!\r\n"))); //分配虚拟空间不成功
      return 0;
    }
    if (!VirtualCopy((PVOID)v_pIOPregs, (PVOID)(S3C2440A_BASE_REG_PA_IOPORT>>8) , sizeof(S3C2440A_IOPORT_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE))//把v_pIOPregs虚拟空间映射到物理内存
    {
      ERRORMSG(1,(_T("SWE_InitAddrIO: VirtualCopy failed!\r\n")));
      VirtualFree((PVOID) v_pIOPregs, 0, MEM_RELEASE); //释放虚拟空间
      v_pIOPregs = NULL;
      return 0;
    }
        //ADC寄存器地址映射
    v_pADCPregs = (volatile S3C2440A_ADC_REG *)VirtualAlloc(0, sizeof(S3C2440A_ADC_REG), MEM_RESERVE,PAGE_NOACCESS);
    if (v_pADCPregs == NULL) //分配虚拟空间不成功
        {
                ERRORMSG(1,(TEXT("SWE_InitAddrADC: VirtualAlloc failed!\r\n")));
                return 0;
        }
        if(!VirtualCopy((PVOID)v_pADCPregs, (PVOID)(S3C2440A_BASE_REG_PA_ADC>>8) , sizeof(S3C2440A_ADC_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE))//把虚拟空间与物理空间绑定
        {
                ERRORMSG(1,(TEXT("SWE_InitAddrADC: VirtualCopy failed!\r\n")));
                VirtualFree((PVOID) v_pADCPregs, 0, MEM_RELEASE); //释放虚拟空间
                v_pADCPregs = NULL;
                return 0;
        }
        return 1;
}
//-----------------------------------------------------------------------------
//-------------Deinit-DeinitDeinit-DeinitDein------------
DLLAPI BOOL SWE_Deinit(DWORD hDeviceContext)
{
        RETAILMSG(1,(TEXT("***SWE_Deinit\r\n")));
   
        if(v_pIOPregs)
        {
                VirtualFree((PVOID) v_pIOPregs, 0, MEM_RELEASE); /*释放虚拟空间*/   
                v_pIOPregs = NULL;
        }       
        if(v_pADCPregs)
        {
                VirtualFree((PVOID) v_pADCPregs, 0, MEM_RELEASE); /*释放虚拟空间*/   
                v_pADCPregs = NULL;
        }
        return true;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DLLAPI DWORD SWE_Open(DWORD hDeviceContext,DWORD AccessCode,DWORD ShareMode)
{
    //设置GPG7:GPG5:GPG2:GPE12:端口输出
        v_pIOPregs->GPGCON &=~ (1<< 15);        //设置GPG7输出(15:14位)
        v_pIOPregs->GPGCON |= (1<< 14);       
        v_pIOPregs->GPGCON &=~ (1<< 11);        //设置GPG5输出(11:10位)
        v_pIOPregs->GPGCON |= (1<< 10);       
        v_pIOPregs->GPGCON &=~ (1<< 5);                //设置GPG2输出(5:4位)
        v_pIOPregs->GPGCON |= (1<< 4);       
        v_pIOPregs->GPECON &=~ (1<< 25);        //设置GPE12输出(25:24位)
        v_pIOPregs->GPECON |= (1<< 24);       
        //设置放电端口
        v_pIOPregs->GPBCON &=~ (1<< 15);        //设置GPG7输入(15:14位)
        v_pIOPregs->GPBCON &=~ (1<< 14);
        v_pIOPregs->GPBUP |= (1<< 7);                                //取消GPB7端口上拉电阻
        //创建AD线程
    hand = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ADThread,NULL,0,NULL);                                                               
        // 设置线程的优先级低于触控屏
        if( !CeSetThreadPriority(hand, 130))
        {
                RETAILMSG(1,(TEXT("SWE: Failed setting Thread Priority.\r\n")));
                return 0;
        }
        RETAILMSG(1,(TEXT("***SWE_OPEN\r\n")));
        return (1);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DLLAPI BOOL SWE_Close(DWORD hOpenContext)
{
        RETAILMSG(1,(TEXT("***SWE_Close\r\n")));
    TerminateThread(hand,-1); //在线程外终止一个线程,用于强制终止线程(终止线程句柄,退出码)
    CloseHandle(hand); //关闭AD转换线程句柄
        v_pIOPregs->GPGCON &=~ (1<< 15);        //设置GPG7输入(15:14位)
        v_pIOPregs->GPGCON &=~ (1<< 14);       
        v_pIOPregs->GPGCON &=~ (1<< 11);        //设置GPG5输入(11:10位)
        v_pIOPregs->GPGCON &=~ (1<< 10);       
        v_pIOPregs->GPGCON &=~ (1<< 5);                //设置GPG2输入(5:4位)
        v_pIOPregs->GPGCON &=~ (1<< 4);       
        v_pIOPregs->GPECON &=~ (1<< 25);        //设置GPE12输入(25:24位)
        v_pIOPregs->GPECON &=~ (1<< 24);       
        return (true);
}
//-----------------------------------------------------------------------------
//----------IO-IO-IO-IO-IO-IO-IO-IO-IO-IO-IO-------------
DLLAPI BOOL SWE_IOControl(DWORD hOpenContext, //DRV_Open()返回的设备打开上下文
                                                  DWORD dwCode,       //要发送的控制码(应用程序发往驱动控制命令,握手约定)
                                                  PBYTE pBufIn,       //输入,指向输入缓冲区的指针   
                                                  DWORD dwLenIn,      //输入缓冲区的长度   
                                                  PDWORD pBufOut,      //输出,指向输出缓冲区的指针(将指针由BYTE型改成DWORD型)   
                                                  DWORD dwLenOut,   //输出缓冲区的长度   
                                                  PDWORD pdwActualOut)//输出,设备实际输出字符数   
{
        dwLenIn=16;   //输入缓冲区的长度
        dwLenOut=310;   //输出缓冲区的长度
        unsigned int data =0;       
        f_start=0;
        step=0;
        delay=0;
        ad_channel=0;
        for(unsigned char i=0; i<16; i++)
        {
                data=*pBufIn;
                if(i<4) f_start += data<<(8*i);
                else if(i<8) step += data<<(8*(i-4));
                else if(i<12) delay += data<<(8*(i-8));
                else if(i<16) ad_channel += data<<(8*(i-12));
                pBufIn++;
        }
        memcpy(pBufOut, adc,1240);        //数组拷贝到*pBufOut(310*4字节)
        flag=true;        //设立AD转换标记,在线程内完成采集
        RETAILMSG(1,(TEXT("***SWE_IOControl\n")));
        return true;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DLLAPI DWORD SWE_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count)
{
           RETAILMSG(1,(TEXT("***SWE_Read\n")));
    return 1;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DLLAPI DWORD SWE_Write(DWORD hOpenContext, LPCVOID pBuffer, DWORD Count)
{
    RETAILMSG(1,(TEXT("***SWE_Write\n")));
    return 1;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DLLAPI DWORD SWE_Seek(DWORD hOpenContext,long Amount,DWORD Type)
{
    DWORD dwRet = 0;
    RETAILMSG(1,(TEXT("***SWE_Seek\n")));
    return dwRet;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DLLAPI void SWE_PowerDown(DWORD hDeviceContext)
{
    RETAILMSG(1,(TEXT("***SWE_PowerDown\n")));
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DLLAPI void SWE_PowerUp(DWORD hDeviceContext)
{
    RETAILMSG(1,(TEXT("***SWE_PowerUp\n")));
}
//-----------------------------------------------------------------------------
//--------------------------AD线程---------------------------------------
DWORD WINAPI ADThread()
{
    RETAILMSG(1,(_T("ADThread++\r\n")));
        HWND hwnd;
        if(!(hwnd = FindWindow(NULL,_T("扫频仪"))))        //获取窗口句柄
        {RETAILMSG(1,(TEXT("Get handle failure\n")));}
        int time1=0;        //设置电池电压发回窗口控制循环时间
        while (1)
        {
                if(flag==true)//查询读/写标记
                {
                        DWORD dstart=GetTickCount();
                        v_pADCPregs-> ADCCON = (1 << 14) | (98 << 6) | (ad_channel << 3);         //AD初始化(D14="1"分频有效, D13:6=98分频系数1Mhz()10us,建立通道号
                        for (unsigned int i=0; i<310; i++)        // =1,等待310次转化完成
                        {                               
                                if((step!=0)|(i==0))                        //步进=0, DDS频率修改第1次, 以后for循环内不修改DDS频率
                                {
                                        ad9850_reset_serial();
                                        ad9850_wr_serial(0x0, f_start+i*step);        //向ad9850中写命令与数据(串口)
                                }       
                                Sleep(1);//线程阻塞1ms
                                if(delay==1)
                                        adc=ADC_DigitalFilter_1();               
                                else                       
                                        adc=ADC_DigitalFilter_2();                       
                        }
                        RETAILMSG(1,(TEXT("time= %dms\n"), (GetTickCount() - dstart)));        //计数310次AD转换运行时间并显示
                        //向ad9850写入扫描初始频率
                        ad9850_wr_serial(0x0, f_start);
                        //ch3通道电池电压监控
                        time1=0;
                        v_pADCPregs-> ADCCON = (1 << 14) | (98 << 6) | (3 << 3);
                       int UV =ADC_DigitalFilter_1();       
                        flag=false;
                        if(hwnd != NULL)
                        {
                                if (!(PostMessage(hwnd, 310, 0,UV)))        //将测量值发送到应用程序窗口
                                        {RETAILMSG(1,(TEXT("Messaging failure\n")));}
                        }
                }
                else
                {
                        time1++;
                        if(time1==100)
                        {
                                time1=0;
                                int UV =ADC_DigitalFilter_1();       
                                flag=false;
                                if(hwnd != NULL)
                                {
                                        if (!(PostMessage(hwnd, 3700, 0,UV)))        //将电池电压发送到应用程序窗口
                                                {RETAILMSG(1,(TEXT("Messaging failure\n")));}
                                }
                        }
                        else Sleep(10);       
                }
        }
        return true;
}


程序编译后生成SWEEP.dll驱动。




补充内容 (2024-7-13 16:56):
不小心排序回调函数删了,补上
/******排序回调函数******/
int comp(const void * p1,const void * p2)
{
        int n1 = *((const int *)p1);
        int n2 = *((const int *)p2);
        return n1 < n2 ?-1:(n1 > n2?1:0);
}

补充内容 (2024-7-25 15:37):
谢谢老师们加分鼓励!

gxg0000 发表于 2024-7-25 15:17:10

本帖最后由 gxg0000 于 2024-7-25 15:19 编辑

窗口应用程序C#书写,有注释,仅供参考!

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
using System.Drawing.Imaging;
using 琴键开关;
using System.Diagnostics;


namespace 扫频仪
{
    public partial class Form1 : Form
    {
      public Form1()
      {
            InitializeComponent();
      }
      public const int GWL_WNDPROC = (-4); //nIndex的参数:为窗口过程设定一个新的地址
      public IntPtr OldProc = IntPtr.Zero;
       //API声明,将消息信息传送给指定的窗口过程
      private extern static int CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hwnd, uint msg, uint wParam, int lParam);
       //API声明,改变指定窗口的属性
      public static extern IntPtr SetWindowLong(IntPtr hwnd, int nIndex, IntPtr dwNewLong);
      public delegate int WndProcHandler(IntPtr hwnd, uint msg, uint wParam, int lParam);//定义委托(Delegate)的类型函数
      WndProcHandler myproc = null; //声明委托类型对象

      int hd; //声明流驱动设备句柄
      int hDrv; //声明打开设备句柄
      bool button1_state=true;
      bool loop1= true;   //数据刷新标记
      bool loop2 = false;//图形上显示带宽标记
      int dwCode; //控制码
      uint dstart = 0;

      public const int OPEN_EXISTING = 3;
      public const int INVALID_HANDLE_VALUE = -1;
      public const int GENERIC_READ = -0;
      public const int GENERIC_WRITE = 0x40000000;

      public static uint[] pBuffIn1 = new uint; //声明写入数组
      public static byte[] pBuffIn2 = new byte;
      public static uint[] pBufOut1 = new uint;//声明读出数组
      public static uint[] pBufOut2 = new uint;
      uint[] f1 = { 455000, 465000, 4000000, 8000000, 10700000, 12000000, 16000000, 20000000, 24000000, 30000000 };
      uint[] f2 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 100 };
      KeySwitch keySwitch5;
      KeySwitch keySwitch6;
      KeySwitch keySwitch7;

      
      public static extern uint GetTickCount();
      
      public static extern int CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode, int lpSecurityAttributes, int dwCreationDisposition, int dwFLagsAndAttributes, int hTemplateFile);
      
      public static extern bool WriteFile(int hFile, byte[] lpBuffer, int nNumberOfBytesToWrite, byte[] pNumberOfBytesWritten, int lpOverlapped);
      
      public static extern bool ReadFile(int hFile, byte[] lpBuffer, int nNumberOfBytesToRead, byte[] lpNumberOfBytesRead, int lpOverlapped);
      
      public static extern int DeviceIoControl(int hDevice, int dwIoControlCode, uint[] lpInBuffer, int nInBufferSize, uint[] lpOutBuffer, int nOutBufferSize, IntPtr lpBytesReturned, int lpOverlapped);
      
      public static extern bool CloseHandle(int hObject);
       //加载流驱动
      public static extern int ActivateDeviceEx(string lpszDevKey, IntPtr lpRegEnts, UInt32 cRegEnts, IntPtr dwParam);
       //卸载流
      public static extern bool DeactivateDevice(int hDevice);
      
      Pen p1 = new Pen(Color.LimeGreen, 1); //创建画笔p1(色,像数)
      Pen p2 = new Pen(Color.DimGray, 1);
      Pen p3 = new Pen(Color.FromArgb(30, 30, 30), 1);
      Brush brush1= new SolidBrush(Color.Brown);

      Bitmap tup1; Graphics g1; //画曲线
      Bitmap tup2; Graphics g2; //画网格和坐标
      
      Thread ThreadAd;
      /// <summary>
      /// 画显示电池电压图形
      /// </summary>
      /// <param name="level">电量等级</param>
      private void UV(int level)
      {
            if (level > 715) //欠压7.18V时对应AD值715
            {
                level = (level - 715) / 17 + 1;
                level = (level > 4) ? 4 : level;   //限幅
            }
            else
            {
                level = 0;
            }
            Bitmap tup3; Graphics g3; //画电池图形
            tup3 = new Bitmap(22, 14); g3 = Graphics.FromImage(tup3);
            Brush brush2 = new SolidBrush(Color.Gray);
            g3.DrawRectangle(new Pen(Color.FromArgb(50, 50, 50), 1), 0, 4, 2, 5);
            g3.DrawRectangle(new Pen(Color.FromArgb(50, 50, 50), 1), 2, 2, 19, 9);
            g3.FillRectangle(brush2, 20 - 4 * level, 4, 4 * level, 6);
            pictureBox2.Image = tup3;
            g3.Dispose();
      }
      /// <summary>
      /// 频率显示格式化
      /// </summary>
      /// <param name="f">频率</param>
      /// <param name="str1">返回频率值</param>
      /// <param name="str2">返回频率单位</param>
      private void Freq_Format(int f, out string str1, out string str2)
      {
            string length1 = f.ToString();
            if (length1.Length < 4) { str1 = length1; str2 = "Hz"; }
            else if (length1.Length == 4) { str1 = length1.Insert(1, "."); str2 = "KHz"; }
            else if (length1.Length == 5) { str1 = length1.Insert(2, ".").Remove(5, 1); str2 = "KHz"; }
            else if (length1.Length == 6) { str1 = length1.Insert(3, ".").Remove(5, 2); str2 = "KHz"; }
            else if (length1.Length == 7) { str1 = length1.Insert(1, ".").Remove(5, 3); str2 = "MHz"; }
            else if (length1.Length == 8) { str1 = length1.Insert(2, ".").Remove(5, 4); str2 = "MHz"; }
            else { str1 = "0"; str2 = "0"; }
      }
      /// <summary>
      /// 图像提亮函数
      /// </summary>
      /// <param name="sur">源图像</param>
      /// <param name="light">背景图像提亮(=0亮度不变、正数亮度增加、负数亮度降低</param>
      /// <returns></returns>
      private Bitmap ImageLight(Bitmap sur, int light)
      {
            if (light == 0) { return sur; }
            Bitmap tempCur = (Bitmap)sur.Clone(); //创建临时背景位图副本
            BitmapData bmpData1 = tempCur.LockBits(new Rectangle(0, 0, tempCur.Width, tempCur.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            int stride = bmpData1.Stride; //背景图像扫描宽度
            byte[] Data1 = new byte; //背景图像数组
            Marshal.Copy(bmpData1.Scan0, Data1, 0, stride * tempCur.Height);//读取背景图像数据(拷贝到托管数组)
            for (int i = 0; i < tempCur.Height; i++) //高内循环
            {
                for (int j = 0; j < tempCur.Width; j++) //行内循环
                {
                  int m = i * stride + j * 3;
                  int b = Data1 + light;
                  int g = Data1 + light;
                  int r = Data1 + light;
                  if (light > 0)
                  {
                        b = b > 255 ? 255 : b;
                        g = g > 255 ? 255 : g;
                        r = r > 255 ? 255 : r;
                  }
                  else if (light < 0)
                  {
                        b = b < 0 ? 0 : b;
                        g = g < 0 ? 0 : g;
                        r = r < 0 ? 0 : r;
                  }
                  Data1 = (byte)b;
                  Data1 = (byte)g;
                  Data1 = (byte)r;
                }
            }
            Marshal.Copy(Data1, 0, bmpData1.Scan0, stride * tempCur.Height); //将数据写入图像(拷贝到bmpData1)                                                   
            tempCur.UnlockBits(bmpData1);
            return tempCur;
      }
      /// <summary>
      /// 生成窗口上固定的字符串
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      private void Form1_Paint(object sender, PaintEventArgs e)
      {
            Graphics g3 = e.Graphics;
            Font font = new Font("Arial", 9f, FontStyle.Regular);
            Brush brush = new SolidBrush(Color.DimGray);
            //画显示图形区矩形框
            g3.DrawRectangle(p2, 21, 19, 311, 217);
            //y轴刻度字符串生成
            g3.DrawString("电压(V)", font, brush, 1, 4);
            g3.DrawString("3", font, brush, 1, 18);
            g3.DrawString("2.5", font, brush, 1, 51);
            g3.DrawString("2", font, brush, 1, 87);
            g3.DrawString("1.5", font, brush, 1, 123);
            g3.DrawString("1", font, brush, 1, 159);
            g3.DrawString("0.5", font, brush, 1, 195);
            g3.DrawString("0", font, brush, 1, 227);
            //频率轴刻度字符串生成
            g3.DrawString("0", font, brush, 19, 238);
            g3.DrawString("1", font, brush, 51, 238);
            g3.DrawString("2", font, brush, 82, 238);
            g3.DrawString("3", font, brush, 113, 238);
            g3.DrawString("4", font, brush, 144, 238);
            g3.DrawString("5", font, brush, 175, 238);
            g3.DrawString("6", font, brush, 206, 238);
            g3.DrawString("7", font, brush, 237, 238);
            g3.DrawString("8", font, brush, 268, 238);
            g3.DrawString("9", font, brush, 299, 238);
            g3.DrawString("10", font, brush, 326, 238);
            //
            //g3.DrawString("gxg0000", font, brush, 1, 252);
            g3.DrawString("扫描频率", font, brush, 142, 252);
            //
            g3.FillRectangle(new SolidBrush(Color.DarkKhaki), 340, 0, 138, 98);
            g3.DrawString("谐振频率", font, new SolidBrush(Color.DarkRed), 342, 5);
            g3.DrawLine(new Pen(Color.MediumOrchid, 2), 346, 49, 472, 49);
            g3.DrawString("峰值电压     V", font, new SolidBrush(Color.Indigo), 342, 55);
            //
            g3.FillRectangle(new SolidBrush(Color.YellowGreen), 340, 100, 138, 82);
            g3.DrawString("带宽", font, new SolidBrush(Color.Purple), 342+24, 103);
            g3.DrawString("下边频", font, new SolidBrush(Color.Purple), 342+12, 119);
            g3.DrawString("上边频", font, new SolidBrush(Color.Purple), 342+12, 135);
            g3.DrawString("Q值", font, new SolidBrush(Color.Purple), 342+30, 151);
            g3.DrawString("矩形系数", font, new SolidBrush(Color.Purple), 342, 167);
            //
            g3.FillRectangle(new SolidBrush(Color.LightSeaGreen), 340, 184, 138, 51);
            g3.DrawString("开始频率", font, new SolidBrush(Color.Navy), 342, 188);
            g3.DrawString("步进", font, new SolidBrush(Color.Navy), 342+24, 203);
            g3.DrawString("终止频率", font, new SolidBrush(Color.Navy), 342, 218);
      }
      private void Form1_Load(System.Object sender, System.EventArgs e) //初始化
      {
            Cursor.Hide();
            this.Width = 480;
            this.Height = 267;
            label18.Width = 1;   //竖线
            label18.Height = 216 - 12;
            label18.Top = 20;
            label18.Left = 22;
            label18.Visible = false;
            label19.Width = 310 - 32; //横向
            label19.Height = 1;
            label19.Top = 20;
            label19.Left = 22 + 32;
            label19.Visible = false;

            label31.Width = 32;    //频率刻度
            label31.Height = 12;
            label31.Top = 20 - 12 + 216;
            label31.Left = 22;
            label31.Visible = false;
            label32.Width = 32;    //增益刻度
            label32.Height = 12;
            label32.Top = 20;
            label32.Left = 22;
            label32.Visible = false;
            hd = ActivateDeviceEx("\\Drivers\\SWEEP", IntPtr.Zero, 0, IntPtr.Zero); //加载驱动
            hDrv = CreateFile("SWE1:", GENERIC_READ + GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
            if (INVALID_HANDLE_VALUE == hDrv)   //获得句柄hDrv,句柄=-1,说明设备未打开
            { MessageBox.Show("不能打开SWE1"); }
            tup1 = new Bitmap(310, 216); g1 = Graphics.FromImage(tup1);
            tup2 = new Bitmap(310, 216); g2 = Graphics.FromImage(tup2);
            dwCode = 0; //控制码
            pBuffIn1 = 441750;    //扫描开始频率
            pBuffIn1 = 155;   //步进
            pBuffIn1 = 1; //AD转换增加延时1ms
            pBuffIn1 = 1; //AD转换选择1通道
            label2.Text = "0";
            label3.Text = "0";
            label4.Text = "0 Hz";
            label5.Text = "0 Hz";
            label6.Text = "0 Hz";
            label8.Text = "";
            //生成预置频率控件
            keySwitch5 = new KeySwitch();
            keySwitch5.SwichValue = 2;
            keySwitch5.Left = 1;
            keySwitch5.Top = 17;
            keySwitch5.SwichText = new string[] { "455KHz", "465KHz", "4MHz", "8MHz", "10.7MHz", "12MHz", "16MHz", "20MHz", "24MHz", "手动"};
            this.panel1.Controls.Add(keySwitch5); //添加到控件集合
            this.keySwitch5.MouseDown += new KeySwitch.MouseDownEventHandler(this.keySwitch5_MouseDown);
            //生成扫频范围控件
            keySwitch6 = new KeySwitch();
            keySwitch6.SwichValue = 5;
            keySwitch6.Left = 62;
            keySwitch6.Top = 17;
            keySwitch6.SwichText = new string[] { "±1%", "±2%", "±3%", "±4%", "±5%", "±6%", "±7%", "±8%", "±9%", "手动" };
            this.panel1.Controls.Add(keySwitch6); //添加到控件集合
            this.keySwitch6.MouseDown += new KeySwitch.MouseDownEventHandler(this.keySwitch6_MouseDown);
            //生成AD转换通道号控件            
            keySwitch7 = new KeySwitch();
            keySwitch7.SwichNumber = 2;
            keySwitch7.Left = 123;
            keySwitch7.Top = 17;
            keySwitch7.Height = 50;
            keySwitch7.SwichText = new string[] { "ch1", "ch2" };
            this.panel1.Controls.Add(keySwitch7); //添加到控件集合
            //生成显示速度切换控件
            //keySwitch4 = new KeySwitch();
            //keySwitch4.SwichNumber = 2;
            //keySwitch4.Left = 184;
            //keySwitch4.Top = 17;
            //keySwitch4.Height = 50;
            //keySwitch4.SwichText = new string[] { "快", "慢" };
            //this.panel1.Controls.Add(keySwitch4); //添加到控件集合
            //
            ThreadAd = new Thread(myTask); //创建读取电压采集数据的线程
            ThreadAd.Start(); //启动线程
      }

待续



gxg0000 发表于 2024-7-25 15:20:56

/// <summary>
      /// 截获驱动程序发出完成电压采集的消息
      /// </summary>
      /// <param name="e"></param>
      protected override void OnHandleCreated(EventArgs e) //引发事件时,会通过委托调用事件处理程序
      {
            base.OnHandleCreated(e);
            myproc = new WndProcHandler(MyWndProc);
            OldProc = SetWindowLong(Handle, GWL_WNDPROC, Marshal.GetFunctionPointerForDelegate(myproc));
      }
      int MyWndProc(IntPtr hwnd, uint msg, uint wParam, int lParam)
      {
            if (msg == 310)
            {
                loop1 = true;
                UV(lParam); //显示电池电量(频率扫描状态)
            }
            else if (msg == 3700)
            {
                UV(lParam); //显示电池电量(暂停状态)
            }
            return CallWindowProc(OldProc, hwnd, msg, wParam, lParam);
      }

      private void myTask() //数据接收及界面显示方法(多线程)
      {
            this.Invoke(new EventHandler(myTask_Drawing)); //委托调用画界面图形方法
            while (true)
            {
               this.Invoke(new EventHandler(myTask_Show)); //委托调用接收数据和显示方法
            }
      }
      private void myTask_Drawing(object sender, EventArgs e)//被调用画界面图形方法
      {
            for (int i = 31; i < 310; i += 31)
            {
                g2.DrawLine(p3, i, 0, i, 217); //画垂直格子线,间距31
            }
            for (int i = 36; i < 216; i += 36)
            {
                g2.DrawLine(p3, 0, i, 310, i); //画水平格子线,间距31
            }
            pictureBox1.Image = tup2;
      }
      private void myTask_Show(object sender, EventArgs e)//被调用接收数据和显示方法
      {
            if (pBuffIn1 == 1)
                label17.Text = "快";
            else
                label17.Text = "慢";
            if (loop1&(!button1_state) == true)
            {
                label14.Text = (GetTickCount() - dstart).ToString() + "ms";//显示一次循环时间
                dstart = GetTickCount();
                if (DeviceIoControl(hDrv, dwCode, pBuffIn1, 16, pBufOut1, 1, IntPtr.Zero, 0) == 0)
                {
                  MessageBox.Show("读写SWE1出错");
                }
                for (int i = 0; i < 310; i++)
                {
                  pBufOut2 = pBufOut1;//复制副本
                }
                Array.Sort(pBufOut2); //副本排序
                uint Umax = pBufOut2;
                int fs = Array.IndexOf<uint>(pBufOut1, Umax, 0);//索引中心频率位置
                //搜索增益下降-3dB时的带宽(可用于计算Q值等...)
               int fL = fs;
               while ((fL != 0) && (Convert.ToInt32(pBufOut1) > (Convert.ToInt32(pBufOut2) * 0.708)))
                { fL--; } //搜索中心频率左边下降-3dB频率
               int fH = fs;
               while ((fH != 309) && (Convert.ToInt32(pBufOut1) > (Convert.ToInt32(pBufOut2) * 0.708)))
                { fH++; } //搜索中心频率右边下降-3dB频率
               int BW_3dB = 0;
               if ((fL == 0) | (fH == 309)) { BW_3dB = 0; }//未搜索到+-3dB处频率
               else { BW_3dB = fH - fL; }//计算-3dB带宽
                int b1 = Convert.ToInt32(label9.Text.Replace(",", "").Replace(" Hz", ""));   //开始频率
                int b2 = Convert.ToInt32(label10.Text.Replace(",", "").Replace(" Hz", ""));//步进         
                int fs_peak = b1 + fs * b2;   //谐振峰频率
                string s1 = "0";
                string s2 = "0";
                Freq_Format(fs_peak,out s1, out s2);
                label2.Text = s1;
                label1.Text = s2; //显示谐振频率
                uint u1 = (Umax > 930) ? 930 : Umax;
                label3.Text = String.Format("{0:N}", u1 * 3.3 / 1023); //显示谐振峰电压(限幅3V)
                label4.Text = String.Format("{0:N}", BW_3dB * b2).Replace(".00", "") + " Hz";//显示带宽
                label5.Text = String.Format("{0:N}", b1 + fL * b2).Replace(".00", "") + " Hz";//显示下边频
                label6.Text = String.Format("{0:N}", b1 + fH * b2).Replace(".00", "") + " Hz";//显示上边频
                //搜索增益下降-20dB时的带宽(与3dB带宽配合计算通道矩形系数)
                int BW_20dB = 0;
                int fL_20dB = fs;
                while ((fL_20dB != 0) && (Convert.ToInt32(pBufOut1) > (Convert.ToInt32(pBufOut2) * 0.1)))
                { fL_20dB--; } //搜索中心频率左边下降-20dB频率
                int fH_20dB = fs;
                while ((fH_20dB != 309) && (Convert.ToInt32(pBufOut1) > (Convert.ToInt32(pBufOut2) * 0.1)))
                { fH_20dB++; } //搜索中心频率右边下降-20dB频率
                if ((fL_20dB == 0) | (fH_20dB == 309)) { BW_20dB = 0; } //未搜索到+-20dB处频率
                else { BW_20dB = fH_20dB - fL_20dB; }//计算-20dB带宽
                if (BW_3dB * b2 == 0) { label7.Text = "0"; }
                else { label7.Text = String.Format("{0:N}", (b1 + fs * b2) / (BW_3dB*b2)).Replace(".00", ""); } //显示Q值
                //计算矩形系数
                if ((BW_3dB != 0) & (BW_20dB != 0))//-3dB带宽或-20dB带宽=0,不计算矩形系数
                {
                  label8.Text = String.Format("{0:N}", 1.0 * BW_3dB / BW_20dB);    //显示矩形系数
                }
                else { label8.Text = ""; }
                //下面是在这块内存画布上绘图(先在内存上画好图形,然后在刷新屏幕,降低屏闪)
                g1.Clear(Color.Black); //清除内存绘图区
                g1.DrawImage(tup2, new Rectangle(0, 0, 310, 216), new Rectangle(0, 0, 310, 216), GraphicsUnit.Pixel); //将tup2图像复制到tup1中
                int y = 0;
                List<Point> points = new List<Point>();//存直线连接的点
                for (int i = 0; i < 310; i++)
                {
                  y = Convert.ToInt32(pBufOut1 * 216 / 930); //电压倍率调整(=3*1023/3.3v)
                  points.Add(new Point(i, 215 - y));
                }
                g1.DrawLines(p1, points.ToArray());
                //显示带宽
                if (checkBox1.Checked== true)
                {
                  int width3 = Convert.ToInt32(pBufOut1 * 216 / 930);//图形宽度
                  if ((BW_3dB != 0) & (width3 != 0))
                  {
                        Bitmap tup3 = new Bitmap(BW_3dB, width3);
                        Graphics g3 = Graphics.FromImage(tup3);
                        g3.DrawImage(tup1, 0, 0, new Rectangle((int)fL + 1, 216 - (int)(pBufOut1 * 216 / 930), BW_3dB, (int)(pBufOut1 * 216 / 930)), GraphicsUnit.Pixel);
                        tup3 = ImageLight(tup3, 35); //带宽显示处提高亮度
                        g1.DrawImage(tup3, (int)fL + 1, 216 - (int)(pBufOut1 * 216 / 930));
                        g3.Dispose();
                     }
                }               
                pictureBox1.Image = tup1; //将内存画布画到图片框中
                g1.Dispose(); //释放资源
                g2.Dispose();
                loop1 = false;
            }
            else
                System.Threading.Thread.Sleep(10);
      }

      private void button1_Click(object sender, EventArgs e) //启动扫描
      {
            if (button1_state == true)
            {
                button1.Text = "暂停";
                button1_state = false;
                button3.Enabled = false;
            }
            else
            {
                button1.Text = "启动";
                button1_state = true;
                button3.Enabled = true;
            }
      }
      private void button2_Click(object sender, EventArgs e) //退出
      {
            Cursor.Show();
            ThreadAd.Abort();//终止线程
            CloseHandle(hDrv); //关闭设备
            DeactivateDevice(hd); //卸载驱动
            this.Close();
      }
      /// <summary>
      /// 打开设置界面
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      private void button3_Click(object sender, EventArgs e)
      {
            if (button3.Text == "设置")
            {
                button3.Text = "返回";
                panel1.Visible = true;
                panel1.Top = 0;
                panel1.Left = 0;
                button1.Enabled = false;
                button2.Enabled = false;
            }
            else
            {
                button3.Text = "设置";
                panel1.Visible = false;
                button1.Enabled = true;
                button2.Enabled = true;
                dwCode = 0; //控制码
                pBuffIn1 = Convert.ToUInt32(label9.Text.Replace(",", "").Replace(" Hz", ""));   //扫描开始频率
                pBuffIn1 = Convert.ToUInt32(label10.Text.Replace(",", "").Replace(" Hz", ""));//步进
                //pBuffIn1 = (uint)(keySwitch4.SwichValue); //AD转换增加延时
                pBuffIn1 = (uint)(keySwitch7.SwichValue); //AD转换选择通道号(ch0通道用于电池电压检测)
            }
      }
      #region 扫频预置
      
      /// <summary>
      /// 频率预置函数
      /// </summary>
      private void settings()
      {
            UInt64 freq = f1;
            if (keySwitch6.SwichValue != 10)
            {
                label24.Text = String.Format("{0:N}", freq * (100 - f2) / 100).Replace(".00", " Hz");
                label26.Text = String.Format("{0:N}", freq * 2 * f2 / 31000).Replace(".00", " Hz");
                label28.Text = String.Format("{0:N}", freq * (100 + f2) / 100).Replace(".00", " Hz");
            }
            else
            {
                label24.Text = String.Format("{0:N}", freq * (1000 - f2) / 1000).Replace(".00", " Hz");
                label26.Text = String.Format("{0:N}", freq * 2 * f2 / 310000).Replace(".00", " Hz");
                label28.Text = String.Format("{0:N}", freq * (1000 + f2) / 1000).Replace(".00", " Hz");
            }
      }
      /// <summary>
      /// 扫频频率预置
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      private void keySwitch5_MouseDown(object sender, MouseEventArgs e)
      {
            if (keySwitch5.SwichValue == 10)
            {
                panel2.Visible = true;//打开数字按键盘
                label20.Text = f1.ToString();
                label20.Visible = true;
                label21.Text = "Hz";
                label22.Visible = false;
                keySwitch6.Enabled = false;
                button4.Visible = false;
            }
            else
            {
                panel2.Visible = false;//隐藏数字按键盘
                keySwitch6.Enabled = true;
                settings();
                button4.Visible = true;
            }
      }
      /// <summary>
      /// 扫频范围预置
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      private void keySwitch6_MouseDown(object sender, MouseEventArgs e)
      {
            if (keySwitch6.SwichValue == 10)
            {
                panel2.Visible = true;//打开数字按键盘
                label22.Text = f2.ToString();
                label22.Visible = true;
                label21.Text = "‰";
                label20.Visible = false;
                keySwitch5.Enabled = false;
                button4.Visible = false;
            }
            else
            {
                panel2.Visible = false ;//隐藏数字按键盘
                keySwitch5.Enabled = true;
                settings();
                button4.Visible = true;
            }
      }
      /// <summary>
      /// 预置置入
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      private void button4_Click(object sender, EventArgs e)
      {
            label9.Text = label24.Text;
            label10.Text = label26.Text;
            label11.Text = label28.Text;
            if (keySwitch5.SwichValue != 10)
                label13.Text = keySwitch5.SwichText; //预置扫描中心频率显示
            else
            {
                string s1 = "0";
                string s2 = "0";
                Freq_Format(Convert.ToInt32(label20.Text.Replace(",", "")), out s1, out s2);//手动扫描中心频率显示
                label13.Text = s1+s2;
            }
      }

      #endregion


待续

gxg0000 发表于 2024-7-25 15:21:57

    #region 数字小键盘

      /// <summary>
      /// 确认
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      private void button15_Click(object sender, EventArgs e)
      {
            if (label21.Text == "Hz")
                if (label20.Text != "") { f1 = Convert.ToUInt32(label20.Text); }
                else
                {
                  MessageBox.Show("频率预置不能为空");
                  return;
                }
                else
                if (label22.Text != "") { f2 = Convert.ToUInt32(label22.Text); }
                else
                {
                  MessageBox.Show("频率范围预置不能为空");
                  return;
                }
            settings();
            keySwitch5.Enabled = true;
            keySwitch6.Enabled = true;
            panel2.Visible = false;
            button4.Visible = true;
      }
      /// <summary>
      /// 删除
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      private void button14_Click(object sender, EventArgs e)
      {
            int data = 0;
            if (label21.Text == "Hz")
            {
                data=label20.Text.Length;
                if (data != 0)
                label20.Text = label20.Text.Remove(data - 1, 1);
            }
            else
            {
                data = label22.Text.Length;
                if (data != 0)
                label22.Text = label22.Text.Remove(data - 1, 1);
            }
      }
      
      /// <summary>
      /// 数字键盘处理函数
      /// </summary>
      /// <param name="digit"></param>
      private void keyboard(stringdigit)
      {
            uint data = 0;
            if (label21.Text == "Hz") //频率处理
            {
                if (label20.Text == "")
                  data = Convert.ToUInt32(digit);
                else
                  data = Convert.ToUInt32(label20.Text) * 10 + Convert.ToUInt32(digit);
                if (data < 40000000) //频率设置限幅
                  label20.Text += digit;
                else
                  MessageBox.Show("频率预置超过40MHz");
            }
            else //%处理
            {
                if (label22.Text == "")
                  data = Convert.ToUInt32(digit);
                else
                  data = Convert.ToUInt32(label22.Text) * 10 + Convert.ToUInt32(digit);
                if (data < 1000) //频率范围‰设置限幅
                  label22.Text += digit;
                else
                  MessageBox.Show("扫频范围预置超过1000‰");
            }
      }
      /// <summary>
      /// 数字键盘0-9事件
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      private void button16_Click(object sender, EventArgs e)
      {
            keyboard("0");
      }

      private void button5_Click(object sender, EventArgs e)
      {
            keyboard("1");
      }

      private void button6_Click(object sender, EventArgs e)
      {
            keyboard("2");
      }

      private void button7_Click(object sender, EventArgs e)
      {
            keyboard("3");
      }

      private void button8_Click(object sender, EventArgs e)
      {
            keyboard("4");
      }

      private void button10_Click(object sender, EventArgs e)
      {
            keyboard("5");
      }

      private void button9_Click(object sender, EventArgs e)
      {
            keyboard("6");
      }

      private void button11_Click(object sender, EventArgs e)
      {
            keyboard("7");
      }

      private void button13_Click(object sender, EventArgs e)
      {
            keyboard("8");
      }

      private void button12_Click(object sender, EventArgs e)
      {
            keyboard("9");
      }

      #endregion

      private void pictureBox1_Click(object sender, EventArgs e)
      {
            if (loop2 == false) { loop2 = true; } //显示带宽标记
            else { loop2 = false; }
      }
      /// <summary>
      /// 十字线
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
      {
            int x = e.X;//获取鼠标的竖直坐标,并将十字星焦点向左上方偏移1个像数
            int y = 0;
            if (e.X < 310)
                y = Convert.ToInt32(pBufOut1 * 216 / 930);   //横线位置(跟踪曲线的高度=3*1023/3.3v)
            else
                y = Convert.ToInt32(pBufOut1 * 216 / 930);
            label18.Left = x + 22;    //十字线竖线         
            label19.Top = 20 + (216 - y);   //十字线横线
            ///刻度
            if (x < 16) { label31.Left = 23; } //16=32/2
            else if (x > 294) { label31.Left = 300; }    //294=310-32/2
            else { label31.Left = x + 22-16; }
            if (y < 6) { label32.Top = 224; }
            else if (y > 210) { label32.Top = 20; } //210=216-12/2
            else { label32.Top = 14 + (216 - y); }
            ///刻度值
            string s1 = "0";
            string s2 = "0";
            int b1 = Convert.ToInt32(label9.Text.Replace(",", "").Replace(" Hz", ""));   //开始频率
            int b2 = Convert.ToInt32(label10.Text.Replace(",", "").Replace(" Hz", ""));//步进         
            int f = b1 + e.X * b2;   //频率
            Freq_Format(f, out s1, out s2);
            label31.Text = String.Format("{0:0}",s1);
            label15.Text = "(" + s2 + ")";
            label32.Text = String.Format("{0:0.00}", 3.0 * y / 216);
            //显示十字线
            label18.Visible = true;
            label19.Visible = true;
            label31.Visible = true;
            label32.Visible = true;
            if (checkBox2.Checked == false)//勾选十字线光标常量
            {
                timer1.Interval = 3000;   //设置自动关闭十字线光标时间
                timer1.Enabled = true;
            }
      }
      /// <summary>
      /// 隐藏十字线
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      private void timer1_Tick(object sender, EventArgs e)
      {
            label18.Visible = false;
            label19.Visible = false;
            label31.Visible = false;
            label32.Visible = false;
            timer1.Enabled = false;
      }
      /// <summary>
      /// 带宽单选
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      private void checkBox1_Click(object sender, EventArgs e)
      {
            this.Focus();
      }
      /// <summary>
      /// 光标单选
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      private void checkBox2_Click(object sender, EventArgs e)
      {
            this.Focus();
            if (checkBox2.Checked == true)    //显示十字线光标
            {
                label18.Visible = true;
                label19.Visible = true;
                label31.Visible = true;
                label32.Visible = true;
                timer1.Enabled = false;
            }
            else       //隐藏十字线光标
            {
                label18.Visible = false;
                label19.Visible = false;
                label31.Visible = false;
                label32.Visible = false;
            }
      }
      /// <summary>
      /// 采样速度单选
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      private void checkBox3_Click(object sender, EventArgs e)
      {
            this.Focus();
            pBuffIn1 = (uint)(checkBox3.Checked ? 2 : 1);//显示速度快1,慢2
      }

      private void button17_Click(object sender, EventArgs e)
      {
            Process.Start("\\ResidentFlash\\扫频仪\\扫频仪使用说明.txt", "");
      }

    }
}


完!


页: [1]
查看完整版本: 驱动