02- 模块化编程-001 内置ADC采样与显示

        周末把单片机的开发环境理顺了,开始模块化编程的实践,先从外围模块开始,先从独立的模块,然后构建复杂一些的综合应用,条件所限,以protues的仿真为主。

1、单片机内置ADC采样与显示电路

2、电路原理简介

该电路主要由单片机(PIC16F877A)、74HC573锁存器和四位七段数码管组成,下面是它的工作原理详细介绍:

1. 系统整体结构

  • 单片机 (U1):负责控制整个电路的工作,读取输入信号并控制输出。
  • 锁存器 (U2, U3):使用74HC573作为数据锁存器,可以缓冲单片机发出的数据,确保稳定输出到数码管。
  • 七段数码管:用于显示数字或字母,通过控制相应的段点亮来显示信息。

2. 电源和基础元件

  • 电源:电路通过提供+5V的电源来工作,接地是重要的参考点。
  • 电阻器 (R2, R5, R8, R9, R10):电阻的作用包括偏置电流、限流等,确保整个电路工作在合理范围内。
  • 电容器 (C3):用来滤波,稳定电源电压,减少干扰。

3. 工作流程

  1. 初始化

    • 单片机启动后,进行自检和初始化,配置I/O端口及其他工作参数。
  2. 数据处理

    • 单片机从外部传感器或其他输入源获取数据,并进行处理。
    • 数据经过逻辑运算后,由单片机控制锁存器(74HC573)的使能端(LE)。
  3. 数据锁存

    • 当使能信号(LE)为高时,锁存器将单片机的数据输入锁存,即使得数据输入保持不变。
    • 锁存器的输出将连接至七段数码管相应的段,从而控制其显示。
  4. 显示输出

    • 七段数码管的各个段通过锁存器的输出控制,显示所需的数字或字母。每个数码管的各个段由相应的输出信号控制,形成完整的显示结果。

3、软件代码

//********************************************************************
//*  文件名:main.c
//*  文件描述:基于PIC单片机的数码管显示A/D转换结果程序
//*  编译环境: Windows XP + MPLAB IDE 8.83 + Picc 9.60
//*  编程者: bianjingyuan
//*  编程日期: 2024-10-30
//*  版本号:1.0
//*  修改记录:无
//*  硬件资源分配表:
//*  端口:   RC0 - DUAN
//*           RC1 - WEI
//********************************************************************
#include "pic.h"

// 定义数据引脚
#define DUAN RC0     // 数码管的十位引脚
#define WEI  RC1     // 数码管的位选引脚

// 配置字设置
__CONFIG (0X3B31);

// 函数声明
void delay(unsigned int x); // 延时函数
void display(unsigned char duan, unsigned char wei); // 显示数字
int get_advalue(); // 获取A/D转换值
void inital(); // 初始化系统配置

// 数码管编码表
const char dua_table[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90}; // 不带点数码管编码 0~9
const char ddua_table[] = {0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00, 0x10}; // 带点数码管编码 0~9
const char wei_array[] = {0x01, 0x02, 0x04, 0x08}; // 位选编码

// 中断标志
bit AD_FLAG;

void main()
{
    volatile long int tmp;  // 用于存储A/D转换的临时值
    int advalue;
    unsigned char digits[4]; // 存储千位、百位、十位和个位
	unsigned char i;
    inital();  // 初始化系统
    ADIE = 1;  // 使能A/D中断
    PEIE = 1;  // 使能外围中断
    GIE = 1;   // 使能全局中断
    ADGO = 1;  // 开始A/D转换

    // 等待中断标志AD_FLAG被置位
    while (!AD_FLAG);  // 等待A/D转换完成
    tmp = get_advalue();  // 读取A/D转换结果
    advalue = (tmp * 500) >> 10;  // 将AD值转换为相应值

    // 按位分离,存储到digits数组中
    digits[0] = advalue / 1000;   // 千位
    digits[1] = (advalue / 100) % 10; // 百位
    digits[2] = (advalue / 10) % 10;  // 十位
    digits[3] = advalue % 10;      // 个位

    // 显示结果
    for ( i = 0; i < 4; i++) 
    {
        display(digits[i], i + 1); // 显示各位数
    }       
}

/*********************************************************************
 * 函 数 名: delay
 * 功能描述: 控制延时函数
 * 函数说明: 通过嵌套循环实现延时
 * 调用函数: 无
 * 全局变量: 无
 * 输    入: unsigned int x - 延时循环次数
 * 返    回: 无
 * 设 计 者:bianjingyuan                         日期:2024-10-30
 * 修 改 者:bianjingyuan                         日期:2024-10-30
 * 版    本:
 **********************************************************************/
void delay(unsigned int x)
{
	unsigned char b; 
    while(x--)
    {
        for (b = 0; b < 18; b++);  // 控制延时
    }
}

/*********************************************************************
 * 函 数 名: display
 * 功能描述: 显示数字到数码管
 * 函数说明: 选择带点或不带点的数码管进行显示
 * 调用函数: delay()
 * 全局变量: DUAN, WEI
 * 输    入: unsigned char duan - 数码管要显示的数字
 *           unsigned char wei - 数码管的位选
 * 返    回: 无
 * 设 计 者:bianjingyuan                         日期:2024-10-30
 * 修 改 者:bianjingyuan                         日期:2024-10-30
 * 版    本:
 **********************************************************************/
void display(unsigned char duan, unsigned char wei)
{
    if (wei == 2)
        PORTB = ddua_table[duan];  // 显示带点数码管
    else
        PORTB = dua_table[duan];    // 显示不带点数码管 

    DUAN = 1;                  // 使能DUA
    DUAN = 0;                  // 关闭DUA

    PORTB = wei_array[wei - 1]; // 设置当前位选
    WEI = 1;                  // 使能WEI
    WEI = 0;                  // 关闭WEI

    delay(40);                // 延时
    PORTB = 0;                // 关闭数码管显示
    WEI = 1;                  // 使能WEI
    WEI = 0;                  // 关闭WEI
}

/*********************************************************************
 * 函 数 名: get_advalue
 * 功能描述: 读取A/D转换结果
 * 函数说明: 从高位和低位合并读取A/D值
 * 调用函数: 无
 * 全局变量: AD_FLAG
 * 输    入: 无
 * 返    回: int - 返回读取的A/D值
 * 设 计 者:bianjingyuan                         日期:2024-10-30
 * 修 改 者:bianjingyuan                         日期:2024-10-30
 * 版    本:
 **********************************************************************/
int get_advalue()
{
    unsigned char low;
    int temp;

    temp = ADRESH;            // 读取高位
    low = ADRESL;             // 读取低位
    AD_FLAG = 0;              // 清除A/D标志
    return (temp << 8) | low; // 返回合并的A/D值
}

/*********************************************************************
 * 函 数 名: get_ad
 * 功能描述: A/D转换中断服务程序
 * 函数说明: 检查A/D中断标志并清除标志
 * 调用函数: 无
 * 全局变量: AD_FLAG
 * 输    入: 无
 * 返    回: 无
 * 设 计 者:bianjingyuan                         日期:2024-10-30
 * 修 改 者:bianjingyuan                         日期:2024-10-30
 * 版    本:
 **********************************************************************/
void interrupt get_ad()
{
    if (ADIF)  // 检查A/D中断标志
    {    
        ADIF = 0;  // 清除中断标志
        AD_FLAG = 1;  // 设置A/D标志
    }
}

/*********************************************************************
 * 函 数 名: inital
 * 功能描述: 初始化系统设置
 * 函数说明: 设置各个端口的输入输出状态等初始化操作
 * 调用函数: 无
 * 全局变量: 无
 * 输    入: 无
 * 返    回: 无
 * 设 计 者:bianjingyuan                         日期:2024-10-30
 * 修 改 者:bianjingyuan                         日期:2024-10-30
 * 版    本:
 **********************************************************************/
void inital()
{
    TRISA |= 0x01;  // 设置RA0为输入
    TRISB = 0x00;    // 设置PORTB为输出
    TRISC = 0x00;    // 设置PORTC为输出
    PORTB = 0;       // 清空PORTB
    PORTC = 0;       // 清空PORTC   
    INTCON = 0;      // 清除中断控制寄存器
    PIE1 = 0;        // 清除外部中断
    ADCON1 = 0x8E;   // 配置ADC参考电压和通道
    ADCON0 = 0x41;   // 使能A/D转换
}

4、代码解析

        该程序的主要功能是基于PIC单片机进行A/D转换,并将转换结果通过数码管显示出来。代码实现了以下主要功能:

  1. 初始化PIC单片机的相关外设和端口。
  2. 通过A/D转换功能采集模拟量输入。
  3. 执行A/D转换操作,并在转换完成后通过中断获取转换结果。
  4. 将A/D转换的结果进行数值处理,转换为实际数值。
  5. 将处理后的数值分离为千位、百位、十位和个位,通过数码管显示出来。

软件流程图:

+------------------------+
|        Start              |
+------------------------+
          |
+------------------------+
|      Initialize        |
+------------------------+
          |
+------------------------+
| Enable A/D Interrupts  |
+------------------------+
          |
+------------------------+
|    Start A/D Convert   |
+------------------------+
          |
+------------------------+
|    Wait for A/D Flag   |
+------------------------+
          |
+------------------------+
|       Read A/D Result  |
+------------------------+
          |
+------------------------+
|  Convert Result to Digits |
+------------------------+
          |
+------------------------+
|     Display on 7-Seg   |
+------------------------+
          |
+------------------------+
|        End             |
+------------------------+
 

5、硬件资源分配表

序号单片机引脚功能定义字符串替代定义功能内容备注
1RC0DUAN-数码管的十位引脚连接数码管
2RC1WEI-数码管的位选引脚连接数码管
3PORTB--数码管显示数据总线连接数码管输出

        基于上述硬件资源分配表,该程序实现了以下主要功能:

  1. 通过A/D转换采集模拟量。
  2. 将A/D转换结果转换为实际数值。
  3. 通过数码管显示转换后的数值。

6、仿真运行结果

 

 

 

 

下一篇的相关资料:

时钟芯片DS1302及其在数据记录中的应用.pdf

https://pan.baidu.com/s/1uEe3L3PMw6rt3lIgTAqL0A?pwd=88c8 

DS1302时钟.ppt

百度网盘 请输入提取码

基于STC89C52单片机DS1302时钟芯片定时开关的设计与仿真.pdf

 百度网盘 请输入提取码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值