【TB作品】数据采集器,ATMEGA128单片机,Proteus仿真

实践项目6--数据采集器

一、功能说明

基于AVR单片机设计一2路模拟电压数据采集器,通过RS232与PC进行通信,利用串

口对采样参数进行控制,采样数据发送给PC。

二、具体要求

1、采集两路模拟电压(由电位器产生)。

2、采集结果精确到小数点后一位;

3、通过串口实现与PC通信,制定通信协议,由PC发送通道选择、采样间隔的设置参

数,发送开始采样命令,采样间隔设置为0.5s、0.3s和0.1s三三种。

4、利用发光二极管(LS8-LS1)对当前选择通道和采样间隔进行指示。

5、单片机收到开始采样命令后,开始一次采样过程,以设置的采样间隔从所选择的通

道进行AD转换并存储到单片机内部存储器中,采集50个样本后,停止采样,计算采集电压

的最大和最小值,并将这50个样本值以及极值通过串口发送合PC,数据间以空格为间隔,

数据格式可以为采样二进制数或转换为电压ASCII形式。

6、具有故障检测报警功能;

7、其它。可根据实际情况添加相关功能。

8、其它要求见文件最后说明。

实践项目6--数据采集器设计与实现

一、项目背景与功能说明

本项目基于AVR单片机设计了一款2路模拟电压数据采集器,主要通过RS232与PC进行通信,能够实现以下功能:

  • 采集两路模拟电压数据,并精确到小数点后一位。
  • 通过串口与PC通信,实现采样参数(通道选择、采样间隔)的设置和控制。
  • 采样间隔可以设置为0.5s、0.3s和0.1s三种。
  • 使用发光二极管指示当前选择的通道和采样间隔。
  • 支持故障检测报警功能及其他自定义功能。

二、硬件设计

  • AVR单片机:选择适合的AVR单片机作为主控制器,实现AD转换和串口通信功能。
  • 模拟电路:设计电位器电路生成模拟电压作为输入信号。
  • 串口通信:利用RS232协议与PC进行通信,实现命令和数据的传输。

三、软件设计

  • 主程序逻辑:采用C语言编写主程序,实现采样控制、数据处理和串口通信。
  • 定时器中断:使用定时器中断控制采样间隔,精确触发AD转换和数据采集过程。
  • 数据处理:采集完成后计算并存储采样数据的最大值、最小值,并通过串口发送给PC。

四、实现步骤与关键代码

4.1 主程序指令介绍

主程序主要负责初始化硬件设备,设置串口波特率,配置AD转换器和定时器,并处理串口接收到的命令。

c 复制代码
void main(void) {
   

    // 主循环,处理串口接收到的命令
    while (1) {
        if ((UCSR1A & 0x80) != 0) { // 检查是否有数据接收
            revchar = UDR1; // 读取接收到的数据
            if (revchar == '5') {
                // 设置采样间隔为500ms
                time_tap = 50;
                time1 = 0;
                dijici_caiyang = 0;
                Print_Str("\r\n 500MS  \r\n");
                PORTA |= 0x1C; // 关闭三个LED灯
                PORTA &= ~0x10; // 点亮其中一个
            } else if (revchar == '3') {
                // 设置采样间隔为300ms
                time_tap = 30;
                time1 = 0;
                dijici_caiyang = 0;
                Print_Str("\r\n 300MS  \r\n");
                PORTA |= 0x1C; // 关闭三个LED灯
                PORTA &= ~0x08; // 点亮其中一个
            } else if (revchar == '1') {
                // 设置采样间隔为100ms
                time_tap = 10;
                time1 = 0;
                dijici_caiyang = 0;
                Print_Str("\r\n 100MS  \r\n");
                PORTA |= 0x1C; // 关闭三个LED灯
                PORTA &= ~0x04; // 点亮其中一个
            } else if (revchar == 'O') {
                // 开始采样
                open = 1;
                dijici_caiyang = 0;
                Print_Str("\r\n OPEN  \r\n");
            } else if (revchar == 'A') {
                // 选择通道A
                tongdaoch = 0;
                Print_Str("\r\n tongdao A  \r\n");
                PORTA &= ~0x01; // 打开LED1
                PORTA |= 0x02;  // 关闭LED2
            } else if (revchar == 'B') {
                // 选择通道B
                tongdaoch = 1;
                Print_Str("\r\n tongdao B  \r\n");
                PORTA &= ~0x02; // 打开LED2
                PORTA |= 0x01;  // 关闭LED1
            }
        }
    }
}
4.2 定时器中断程序介绍

定时器中断程序负责在设定的时间间隔内触发AD转换,并将采集到的数据进行处理和存储。

c 复制代码
// 定时器0中断服务程序
#pragma interrupt_handler TIMER0_ISR:17
void TIMER0_ISR(void) {
    TCNT0 = 183; // 设置定时器初值,实现10ms定时
    cnt++;

    if (cnt >= 50) { // 每500ms处理一次数据
        cnt = 0;
        // 读取并转换ADC值
        ADC_Value = ADC_read(0);
        jiancev1 = convert(ADC_Value);
        ADC_Value = ADC_read(1);
        jiancev2 = convert(ADC_Value);
        // 判断电压是否低于0.2V
        if (jiancev1 < 20 || jiancev2 < 20) {
            PORTA &= ~0x20; // 打开蜂鸣器
        } else {
            PORTA |= 0x20;  // 关闭蜂鸣器
        }
    }

    // 检查是否开始采样并处理采样数据
    if (open == 1 && time_tap != 0) {
        time1++;
        if (time1 == time_tap) { // 到达设定的采样间隔
            time1 = 0;
            // 采集通道0的数据并存储
            ADC_Value = ADC_read(0);
            voltage = convert(ADC_Value) / 10;
            ADC0BUFFER[dijici_caiyang] = voltage;
            // 采集通道1的数据并存储
            ADC_Value = ADC_read(1);
            voltage = convert(ADC_Value) / 10;
            ADC1BUFFER[dijici_caiyang] = voltage;
            dijici_caiyang++; // 采样次数加1

            // 打印采样次数
            sprintf(buffer, "start %d\r\n", (int)dijici_caiyang);
            Print_Str(buffer);

            if (dijici_caiyang == 50) { // 完成50次采样
                // 计算通道0的最大值和最小值
                ADC0BUFFER[50] = 0;
                ADC0BUFFER[51] = 50;
                for (char i = 0; i < 50; i++) {
                    if (ADC0BUFFER[50] < ADC0BUFFER[i]) {
                        ADC0BUFFER[50] = ADC0BUFFER[i];
                    }
                    if (ADC0BUFFER[51] > ADC0BUFFER[i]) {
                        ADC0BUFFER[51] = ADC0BUFFER[i];
                    }
                }
                // 计算通道1的最大值和最小值
                ADC1BUFFER[50] = 0;
                ADC1BUFFER[51] = 50;
                for (char i = 0; i < 50; i++) {
                    if (ADC1BUFFER[50] < ADC1BUFFER[i]) {
                        ADC1BUFFER[50] = ADC1BUFFER[i];
                    }
                    if (ADC1BUFFER[51] > ADC1BUFFER[i]) {
                        ADC1BUFFER[51] = ADC1BUFFER[i];
                    }
                }
                //

 打印最大值和最小值
                Print_Str("\r\nA通道采样50次完成\r\n");
                sprintf(buffer, "0max=%d\r\n", (int)ADC0BUFFER[50]);
                Print_Str(buffer);
                sprintf(buffer, "0min=%d\r\n", (int)ADC0BUFFER[51]);
                Print_Str(buffer);
                sprintf(buffer, "1max=%d\r\n", (int)ADC1BUFFER[50]);
                Print_Str(buffer);
                sprintf(buffer, "1min=%d\r\n", (int)ADC1BUFFER[51]);
                Print_Str(buffer);
                // 停止采样
                open = 0;
                dijici_caiyang = 0;
            }
        }
    }
}

五、项目总结与展望

通过本项目的设计与实现,成功搭建了一款功能完善的模拟电压数据采集器,实现了基本的数据采集、处理和通信功能。未来可以进一步优化硬件电路设计、增强故障检测功能,并提升数据传输效率和稳定性。

资源:

https://docs.qq.com/sheet/DUEdqZ2lmbmR6UVdU?u=bdf8eeb84961492ba2b62f7bfee641ea&tab=BB08J2
相关推荐
番茄灭世神9 小时前
利用STM32的定时器输出PWM方波
stm32·单片机·嵌入式硬件
人才程序员10 小时前
【51单片机入门】速通定时器
c语言·c++·单片机·嵌入式硬件·mcu·51单片机·proteus
XD74297163613 小时前
【TB作品】步进电机控制器,ATMEGA16单片机,Proteus仿真
单片机·proteus·仿真·步进电机·atmega16
南耿先生13 小时前
我在高职教STM32——LCD液晶显示(1)
stm32·单片机·嵌入式硬件
xiaoyaoyou.xyz13 小时前
嵌入式UI开发-lvgl+wsl2+vscode系列:5、事件(Events)
单片机·ui·lvgl
qq_4148260013 小时前
云上MongoDB常见索引问题及最优索引规则大全
数据库·mongodb
yueqingll13 小时前
011、MongoDB副本集数据同步机制深度解析
数据库·mongodb
莫邪博客14 小时前
【STM32修改串口波特率】
stm32·单片机·嵌入式硬件
电气_空空15 小时前
基于单片机技术的按键扫描电路分析
单片机·嵌入式硬件·毕业设计·毕设
XD74297163615 小时前
【TB作品】密码锁,数码管,ATMEGA16单片机,Proteus仿真
单片机·proteus·密码锁