找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 531|回复: 3
打印 上一主题 下一主题
收起左侧

MF47大改造与简单上位机编程

[复制链接]
跳转到指定楼层
楼主
  学了一段时间单片机,总想着干点啥,一眼看见那个MF47,欧姆调零容易坏,
修好了没几天又坏了,扔了又可惜。突然脑袋一热,想着给它做一个不用调零的电
路板换上去就一劳永逸了。
  经过不断的尝试与修改,终于有了一个满意的版本,拍个图给大家看看:




从此,我的MF47有了表棒接反报警,超量程报警等功能,灵敏度也提高了,
从20k每伏升级到了200k每伏,电流档满里程从250mV降到了100mV,
原1V档改成了5uA档,取消了2500V插孔和三极管Hfe座,其它和原表对应。
还有了数据输出功能,能接电脑,也能外接1602显示器。
万用表有两种不同的模式,一个是欧姆档测量模式,另一个是电压电流测量模
式。电压电流测量模式时,可以在1602上显示出三个数,分别对应500量程,
250量程和100量程。如果发现用户在测量电阻,则自动显示出电阻阻值,精度
和三位半数字万用表相近,但范围更宽,比如Rx1档,分辨力0.01欧,最大可显
示990.00欧,如果是在Rx10k档,则对应的最大电阻是9.9M欧。测量效果如下:




能达到这样的效果已经很满意了,从此再也不用羡慕MF10和MF63甚至MF18(MF35)。

刚开始装上去发现表针响应慢半拍,毕竟每秒10次的测量速率加上软件积分效应
导致了这样的结果,程序里增加了微分效应才使表针有了“冲”的效果,冲过去
半格后退回到稳定的位置。
  虽然从无源表改成了有源表,耗电量并不大,只有580uA(3.3V),一节700mAh
铁锂电池可以连续使用1000小时,当然还有30分钟自动关机,关机后(OFF档)只有
8uA(3.3V)。外接的1602耗电1.4mA,加起来才2mA(3.3V),能跟随万用表的关闭
而自动关闭。
  有时候可能无法确定万用表是不是在开机状态,我设置了五秒一次的短“嘀”声提醒。
大家还希望这款表添加什么功能呢?欢迎留言。


接下来就是上位机编程了,编一个有用户界面的上位机程序目前对我来说还是有一
定难度的,写一个控制台下的程序则容易了许多,只有“main函数”加“大循环”。
以前写的电阻并联求值小程序,只有控制台界面,算上标点符号也只有15行,贴出来
和大家一起学习最简单的电脑编程:

#include  <stdio.h>
int main(void)
{
  float  x,y,z;
  printf("\n***电阻并联求值小程序***\n\n");
  while(1){
    printf("============分隔线======\n");
    printf("电阻1(可输入小数):");
    scanf("%f",&x);
    printf("\n电阻2(可输入小数):");
    scanf("%f",&y);
    z=(float)(x*y/(x+y));
    printf("\n并联阻值=%g\n\n",z);
    }
}
找一个大家喜欢的编译器编译出来就行了,运行效果如下:

电阻并联求值exe.zip (9.93 KB, 下载次数: 0)

我这个指针万用表是通过串口连接电脑的,比如我电脑上的串口是DAP-link,
相应的驱动程序必须先安装好,然后就是电脑编程了。
  经过多方查找,终于找到了一个简单的串口配置发送和接收示例程序,
此程序配置串口为57600波特率,8位字长,1位停止位,无校验,并通过COM3
发送和接收数据。源码如下,和大家一起学习:

#include <windows.h>
#include <stdio.h>
int main() {
    printf("\n这是一个串口测试程序!\n\n注意串口号是否正确!\n\n");
    printf("请连接串口设备的Rx和Tx,\n\n然后运行此程序\n\n");
    HANDLE hSerial;
    DCB dcbSerialParams = {0};
    COMMTIMEOUTS timeouts = {0};
    // 打开串口,这里改成对应的串口号
    hSerial = CreateFile("\\\\.\\COM3", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hSerial == INVALID_HANDLE_VALUE) {
        fprintf(stderr, "打开串口出错!\n\n请填写正确的串口号后再编译运行!\n");
        getchar();
        return 1;
    }
    // 配置串口参数
    dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
    if (!GetCommState(hSerial, &dcbSerialParams)) {
        fprintf(stderr, "获取串口状态出错\n");
        CloseHandle(hSerial);
        return 1;
    }
    dcbSerialParams.BaudRate = CBR_57600;//波特率
    dcbSerialParams.ByteSize = 8;//8位字长
    dcbSerialParams.StopBits = ONESTOPBIT;//1位停止
    dcbSerialParams.Parity = NOPARITY;//无校验
    if (!SetCommState(hSerial, &dcbSerialParams)) {
        fprintf(stderr, "设置串口状态出错\n");
        CloseHandle(hSerial);
        return 1;
    }
    // 设置超时
    timeouts.ReadIntervalTimeout = 50;
    timeouts.ReadTotalTimeoutConstant = 50;
    timeouts.ReadTotalTimeoutMultiplier = 10;
    timeouts.WriteTotalTimeoutConstant = 50;
    timeouts.WriteTotalTimeoutMultiplier = 10;
    if (!SetCommTimeouts(hSerial, &timeouts)) {
        fprintf(stderr, "设置超时出错\n");
        CloseHandle(hSerial);
        return 1;
    }
    // 发送数据
    unsigned char sendData[] = {0xa1, 0xd2, 0xb3, 0x84, 0x35};
    DWORD bytesWritten;
    if (!WriteFile(hSerial, sendData, sizeof(sendData), &bytesWritten, NULL)) {
        fprintf(stderr, "串口写入出错\n");
        CloseHandle(hSerial);
        return 1;
    }
    printf("发送 %lu 字节\n", bytesWritten);
    // 接收数据
    unsigned char receiveData[256];
    DWORD bytesRead;
    if (!ReadFile(hSerial, receiveData, sizeof(receiveData), &bytesRead, NULL)) {
        fprintf(stderr, "串口接收出错\n");
        CloseHandle(hSerial);
        return 1;
    }
    printf("接收 %lu 字节: ", bytesRead);
    for (DWORD i = 0; i < bytesRead; i++) {
        printf("%02X ", receiveData[ i]);
    }
    printf("\n\n成功接收数据,请关闭此程序!");
    // 关闭串口
    CloseHandle(hSerial);
    getchar();//等待用户查看结果
    return 0;
}
### 代码说明
1. **打开串口**:使用`CreateFile`函数打开串口`COM3`。如果打开失败,程序会输出错误信息并退出。
2. **配置串口参数**:使用`GetCommState`获取当前串口配置,然后设置波特率、字长、停止位和校验位等参数,最后通过`SetCommState`应用这些配置。
3. **设置超时**:通过`SetCommTimeouts`设置串口的读写超时时间。
4. **发送数据**:使用`WriteFile`函数将数组`sendData`中的数据发送到串口。
5. **接收数据**:使用`ReadFile`函数从串口读取数据,并将读取到的数据存储在`receiveData`数组中。
6. **关闭串口**:使用`CloseHandle`关闭串口。
### 编译和运行
在Windows上使用C编译器(如MinGW或Visual Studio)编译该程序,并运行生成的可执行文件。
确保COM3端口已连接并配置正确。
### 注意事项
- 确保COM3端口可用且正确连接。
- 如果COM3端口被其他程序占用,程序将无法打开串口。
- 该程序假设发送和接收的数据量较小,如果需要处理大量数据,可能需要调整缓冲区大小和超时设置。

这个示例程序展示了如何使用Windows API进行基本的串口通信。
根据实际需求,可以进一步扩展和优化该程序。如果将电脑串口
的Rx和Tx连接起来,程序运行的结果是收到了自己发送的数据,
效果图如下:


经过我的几番改进,可以输入串口号和波特率,增加了数据记录到文件的功能,
控制台界面变成了如下的样子:

      

控制台里以文本显示接收到的文字,同时保存数据到电脑上,
程序关闭后可以用记事本打开记录到的数据。

虽然万用表的数据记录功能用处不大,但是过程中能学习到很
多的知识,不是吗?

串口到文本文件.zip (12.13 KB, 下载次数: 0)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏4 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:123917 发表于 2025-3-12 18:03 | 只看该作者
赞,学习了,高手啊
回复

使用道具 举报

板凳
ID:446156 发表于 2025-3-19 17:45 | 只看该作者
能把改造原理图贴出来就更赞了
回复

使用道具 举报

地板
ID:1123082 发表于 2025-4-22 11:11 | 只看该作者
学习了,能把改造原理图贴出来吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表