一、简介:
LPC2124,一款由NXP(前身为飞利浦半导体)精心打造的微控制器,以其ARM7TDMI-S内核为核心,展现出卓越的性能与低功耗特性,加之其紧凑的封装和丰富的外设,使其成为嵌入式系统设计的理想之选。在构建基于LPC2124的温度模糊控制系统时,Proteus软件成为了一名得力的助手,它能够协助设计师进行电路的构思与仿真,确保系统的稳定与高效。
量程自动切换数字电压表,这是一款电子测量领域的精密仪器,它如同一位智慧的测量大师,能够根据输入电压的特性,自动选择最适宜的测量范围(量程),以确保每一次测量都能提供最为精确的读数。在实验室的严谨、工业的精密以及教育的严谨中,这款电压表都是不可或缺的工具,它能够精准地测量直流或交流电压,为科研与生产提供坚实的数据支持。
二、基于LPC2124的温度模糊控制系统设计思路:
基于LPC2124的温度模糊控制系统使用了特定的寄存器配置和函数调用来初始化系统,并执行一些特定的操作。下面是对这段代码的设计思路
2.1 寄存器配置
PINSEL0
和PINSEL1
是用于配置引脚功能的寄存器。PINSEL0=0x00020000;
可能是在配置某个引脚为特定的功能,例如作为外设的片选信号。PINSEL1=0x00000000;
可能是在将其他引脚配置为默认的GPIO功能。IO0DIR=0x00cfffff;
设置了一组GPIO引脚的方向为输出。这里的0x00cfffff
是一个掩码,指定了哪些位对应的引脚应该被设置为输出。IO0CLR=0xeff;
清零了一组GPIO引脚的输出状态。这里的0xeff
也是一个掩码,指定了哪些位对应的引脚应该被清零。
2.2 初始化函数
TargetInit();
是一个自定义的初始化函数,用于初始化目标系统(可能是某个特定的硬件平台)。这个函数可能包括了时钟配置、外设初始化、中断设置等。
2.3 显示函数
ShowByte(0x80,0);
和ShowByte(0xc0,0);
是调用了一个名为ShowByte
的函数,用于显示两个字节的数据。这里的参数0x80
和0xc0
可能是要显示的数据,而第二个参数0
可能是显示的位置或者其他配置参数。
2.4 模糊逻辑函数
fuzzy();
是一个模糊逻辑函数,用于执行模糊逻辑控制。模糊逻辑是一种处理不确定性和模糊性的方法,常用于控制系统中。
2.5 返回值
return(0);
表示主函数正常结束。
2.6 设计思路总结
设计思路是首先配置硬件平台,包括引脚功能和GPIO方向,然后调用初始化函数对系统进行初始化。接着,它通过调用 `ShowByte` 函数来显示一些数据,并执行模糊逻辑控制。最后,主函数正常结束。
三、量程自动切换数字电压表设计思路:
3.1 工作原理
量程自动切换数字电压表的核心组件包括:
- 模数转换器(ADC):将输入的模拟电压信号转换为数字信号。
- 微处理器或微控制器:处理ADC的输出,并根据测量值自动选择最佳量程。
- 多量程输入电路:包括多个分压电阻网络,每个网络对应一个特定的测量范围。
-
显示器:通常是一个LCD或LED显示屏,用于显示测量结果。
当输入电压被施加到电压表时,微处理器会根据ADC的输出值判断当前量程是否合适。如果测量值超出了当前量程的范围,微处理器会切换到更高的量程。如果测量值远低于当前量程的下限,微处理器会切换到更低的量程以提高测量精度。
3.2 特点
- 自动量程切换:无需用户手动选择量程,简化了操作过程。
- 高精度:通过自动选择最佳量程,可以确保测量的高精度。
- 易用性:用户只需连接被测电压,电压表即可自动完成测量。
- 多功能:除了测量电压,许多自动量程数字电压表还具有测量电流、电阻、频率等其他参数的能力。
3.3 应用
- 电子维修:用于检测电路中的电压问题。
- 实验室研究:在科学实验中精确测量电压。
- 工业自动化:在生产线上监控电压水平。
- 教育:在电子工程教学中作为教学工具。
这段代码是为8051单片机设计的,用于读取ADC(模数转换器)的输出并将其显示在4位数码管上。下面是设计思路的概述:
3.4 硬件接口定义:
- 通过
sbit
关键字定义了与ADC和数码管控制相关的I/O引脚,如ST
、OE
、EOC
、CLK
、ADD_A
、ADD_B
、ADD_C
、D0
、D1
、D2
、D3
和P17
。 - 定义了两个开关
s1
和s2
,用于选择不同的电压范围(0.5V或10V)。
3.5 定时器初始化:
TimeInitial()
函数用于初始化定时器1,设置其工作在模式1(16位定时器),并开启定时器中断。
3.6 延时函数:
Delay()
函数提供了一个简单的软件延时,用于数码管显示的稳定。
3.7 数码管显示函数:
Display()
函数负责将dispbuf
数组中的数字转换为数码管显示的段码,并通过控制位选信号来选择哪个数码管显示。- 根据
m
的值,决定是否在第二位或第三位数码管上显示小数点。
3.8 主函数:
- 在
main()
函数中,首先初始化定时器和ADC选择输入端。 - 进入无限循环,通过控制
ST
、OE
信号来启动ADC转换并读取转换结果。 - 根据
s1
和s2
的状态以及ADC的输出值,调整电压范围和m
的值。 - 计算转换后的电压值,并将其分解为4位数字存储在
dispbuf
中。 - 调用
Display()
函数显示电压值。
3.9 定时器中断服务函数:
-
t1()
中断服务函数用于定时翻转CLK
信号,为ADC提供时钟信号。整体设计思路是通过ADC读取模拟电压值,根据选择的电压范围(0.5V或10V)进行转换,并将转换后的电压值显示在4位数码管上。通过定时器中断来提供ADC所需的时钟信号,确保ADC能够正常工作。数码管的显示通过软件控制位选和段选信号来实现。
四、基于LPC2124的温度模糊控制系统硬件初始化和定义
用于控制一个LCD显示器,并且可能与一个模数转换器(ADC)接口,用于读取模拟信号并将其转换为数字值。
-
#include "config.h"
:这行代码引入了名为config.h
的头文件,该头文件包含了一些配置信息或者定义了一些常量和宏。 -
#define
语句定义了一些常量,这些常量是用于控制LCD显示器的引脚配置,例如rs
、rw
、en
可能分别代表寄存器选择、读写控制和使能信号。 -
uint8 e, ec;
和fp32 ectemp, prelevel, etemp;
:这些变量是用于模糊逻辑控制系统的输入和输出变量。uint8
是8位无符号整数,fp32
是32位浮点数。 -
uint8 fuzzycode[21][11]
:这是一个二维数组,用于存储模糊逻辑控制系统的规则表。每一行代表一条规则,每一列代表该规则在不同输入值下的输出强度。 -
uint8 BCD[7];
:这个数组用于存储BCD码(二进制编码的十进制数),用于LCD显示器的数字显示。 -
uint32 ADC_Data;
:这个变量用于存储从ADC读取的数字数据。 -
void ShowInt(uint8 addr, uint16 num);
和void ShowByte(uint8 addr, uint16 num);
:这两个函数是用于在LCD显示器上显示整数和字节数据。 -
uint32 AD_Convert(void);
:这个函数是用于执行模数转换,将模拟信号转换为数字值。
#include "config.h"
#define rs (1<<9)
#define rw (1<<10)
#define en (1<<11)
#define busy (1<<7)
#define ke 2
#define kec 2.5
uint8 e,ec;
fp32 ectemp,prelevel,etemp;
uint8 temp=0;
uint8 fuzzycode[21][11]=
{
{5,5,5,5,5,5,4,3,2,1,1},
{5,5,5,5,5,5,4,2,2,1,1},
{5,5,5,5,5,5,4,2,2,1,1},
{5,5,5,5,5,5,4,2,1,1,1},
{5,5,5,5,5,5,4,2,1,1,1},
{5,5,5,5,5,5,4,2,1,1,1},
{5,5,5,4,4,4,3,2,1,1,1},
{5,5,5,4,4,4,3,2,1,1,1},
{5,5,4,4,4,3,2,2,1,0,0},
{5,5,4,4,3,2,1,1,1,0,0},
{4,4,3,3,2,1,1,1,0,0,0},
{3,3,2,2,1,1,1,0,0,0,0},
{2,2,2,2,1,1,1,0,0,0,0},
{2,2,2,1,1,0,0,0,0,0,0},
{2,2,2,1,1,0,0,0,0,0,0},
{1,1,1,1,1,0,0,0,0,0,0},
{1,1,1,1,1,0,0,0,0,0,0},
{1,1,1,1,1,0,0,0,0,0,0},
{1,1,1,1,1,0,0,0,0,0,0},
{1,1,1,1,1,0,0,0,0,0,0},
{1,1,1,1,1,0,0,0,0,0,0}
};
uint8 BCD[7]; //十位二进制的显示码分别是千百十个位的显示
uint32 ADC_Data;
void ShowInt(uint8 addr,uint16 num);
void ShowByte(uint8 addr,uint16 num);
uint32 AD_Convert(void) ;
五、其他相关函数定义:
列出了多个函数声明,这些函数是用于实现模糊逻辑控制和脉宽调制(PWM)输出。下面是对这些函数的一般性解释:
-
void fuzzy(void);
:这个函数是用于实现模糊逻辑控制算法。模糊逻辑控制是一种基于模糊集合论和模糊逻辑的控制方法,它允许系统处理不精确的输入,并产生模糊的输出,这些输出通常会被转换为精确的控制信号。 -
void PWM0(void);
到void PWM5(void);
:这些函数是用于生成不同通道的脉宽调制信号。脉宽调制是一种调制技术,通过改变信号的脉冲宽度来控制模拟电路的平均电压。在嵌入式系统中,PWM常用于控制电机速度、LED亮度、电源转换等。
每个PWM函数负责配置和控制一个特定的PWM输出通道。例如,void PWM0(void);
负责配置和控制第一个PWM输出通道,而 void PWM1(void);
则负责第二个通道,以此类推。
在这些函数中,会包含以下操作:
- 配置定时器/计数器以生成PWM信号。
- 设置PWM的频率和占空比。
- 启动或停止PWM输出。
- 根据需要调整PWM的参数。
void fuzzy(void); void PWM0(void); void PWM1(void); void PWM2(void); void PWM3(void); void PWM4(void); void PWM5(void);
六、主函数:
它包含了几个关键操作,主要用于配置硬件接口、初始化设备,并执行一些基本的功能。下面是对代码中关键部分的解释:
-
PINSEL0 和 PINSEL1 寄存器配置:
- 这些寄存器通常用于选择微控制器引脚的功能。例如,
PINSEL0=0x00020000;
是将某个特定的引脚配置为某种特殊功能(如外部中断、定时器输入、UART接口等),而不是默认的GPIO(通用输入输出)功能。 PINSEL1=0x00000000;
表示将相关引脚保持在默认功能,通常是GPIO。
- 这些寄存器通常用于选择微控制器引脚的功能。例如,
-
IO0DIR 寄存器配置:
IO0DIR=0x00cfffff;
用于设置GPIO端口的方向。在这个例子中,某些位被设置为1
,表示这些引脚被配置为输出。具体哪些引脚被设置为输出,取决于具体的位模式。
-
IO0CLR 寄存器使用:
IO0CLR=0xeff;
用于清除(或说置低)指定的GPIO引脚。这通常用于初始化阶段,确保输出引脚处于已知状态,比如LED灯在程序开始时保持熄灭状态。
-
TargetInit() 函数调用:
- 这个函数调用看起来是用于目标设备的初始化。具体做了什么,需要查看
TargetInit
函数的实现。它包括系统时钟设置、中断系统配置、外设初始化等。
- 这个函数调用看起来是用于目标设备的初始化。具体做了什么,需要查看
-
ShowByte 函数调用:
ShowByte(0x80,0);
和ShowByte(0xc0,0);
函数调用用于在某种显示设备上显示数据或者控制某些输出。具体的参数0x80
和0xc0
代表要显示或控制的数据,而0
可能表示目标位置或设备。
-
fuzzy 函数调用:
fuzzy();
根据函数名“fuzzy”,它与模糊逻辑或模糊控制有关,但这只是一个猜测。
-
return(0);:
-
程序的最后返回0,表示程序正常结束。在嵌入式系统中,
main
函数结束并不意味着设备停止工作,设备可能继续运行其他循环或中断服务程序。这段代码的具体功能和目的依赖于它所用的硬件平台和外围设备,以及
TargetInit
、ShowByte
和fuzzy
等函数的具体实现。段int main(void) { PINSEL0=0x00020000; PINSEL1=0x00000000; IO0DIR=0x00cfffff; //设置为输出 IO0CLR=0xeff; TargetInit(); ShowByte(0x80,0); ShowByte(0xc0,0); fuzzy(); return(0); }
七、量程自动切换数字电压表硬件接口定义:
-
7.1 头文件和预处理指令
#include<reg52.h>
: 这个头文件包含了8052单片机的寄存器定义,用于访问单片机的特殊功能寄存器。
7.2 全局变量和常量定义
unsigned char code dispbitcode[]
: 这是一个数组,存储了数码管显示0-9的段码。每个数字对应的段码是一个8位的二进制数,用于控制数码管的各个段亮灭。unsigned char dispbuf[4]
: 这个数组用于存储要显示在数码管上的4位数字。unsigned int i, j, getdata, temp, temp1
: 这些是无符号整型变量,用于存储中间计算结果或计数。unsigned char count, d, m
: 这些是无符号字符型变量,用于计数或存储状态。
7.3 特殊功能寄存器位定义
sbit ST=P2^4, OE=P2^5, EOC=P2^6, CLK=P2^7
: 这些定义了与ADC控制相关的特殊功能寄存器位。ST
用于启动ADC转换,OE
用于输出使能,EOC
是转换结束的标志,CLK
提供时钟信号。sbit ADD_A=P3^4, ADD_B=P3^5, ADD_C=P3^6
: 这些定义了选择ADC输入通道的控制位。sbit D0=P2^0, D1=P2^1, D2=P2^2, D3=P2^3
: 这些定义了控制数码管位选的控制位。sbit P17=P1^7
: 这个定义用于控制数码管小数点的显示。sbit s1=P3^2, s2=P3^3
: 这两个定义了两个开关的状态,用于选择不同的电压范围。
7.4 宏定义
#define _v0_5 {s1=1;s2=0;}
: 这个宏定义了一个动作,当调用_v0_5
时,s1
置为1,s2
置为0,可能用于选择0.5V的电压范围。#define _v10 {s1=0;s2=1;}
: 这个宏定义了另一个动作,当调用_v10
时,s1
置为0,s2
置为1,可能用于选择10V的电压范围。
7.5 变量m
-
unsigned char m
: 这个变量没有初始化,可能在后续的代码中用于存储某个状态或计算结果。这段代码是为8051系列单片机设计的,用于读取ADC的输出并将其显示在4位数码管上。它通过控制不同的I/O引脚来实现ADC的启动、读取和数码管的显示。代码中还定义了两个宏,用于根据外部开关的状态选择不同的电压范围进行ADC转换。
#include<reg52.h>
unsigned char code dispbitcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char dispbuf[4];
unsigned int i;
unsigned int j;
unsigned int getdata;
unsigned int temp;
unsigned int temp1;
unsigned char count;
unsigned char d;
sbit ST=P2^4;
sbit OE=P2^5;
sbit EOC=P2^6;
sbit CLK=P2^7;
sbit ADD_A=P3^4; //选择AD的输入端
sbit ADD_B=P3^5;
sbit ADD_C=P3^6;
sbit D0=P2^0; //数码管的位控制端
sbit D1=P2^1;
sbit D2=P2^2;
sbit D3=P2^3;
sbit P17=P1^7; //确定小数点的位置
sbit s1=P3^2;
sbit s2=P3^3;
#define _v0_5 {s1=1;s2=0;}
#define _v10 {s1=0;s2=1;}
unsigned char m;
八、相关函数介绍:
这段代码包含了三个函数:`TimeInitial`, `Delay`, 和 `Display`。每个函数都有特定的功能,用于8051单片机的时间控制和数码管显示。下面是对这些函数的详细介绍:
8.1 函数 TimeInitial()
这个函数用于初始化定时器1(Timer 1)的模式和计数值。
TMOD=0x10;
:设置定时器模式寄存器,0x10
表示定时器1工作在模式2(自动重装载模式)。TH1=(65536-200)/256;
和TL1=(65536-200)%256;
:这两行代码设置定时器1的初值,用于产生定时中断。这里的200是计数值,65536是16位定时器的最大值。EA=1;
:全局中断使能。ET1=1;
:定时器1中断使能。TR1=1;
:启动定时器1。
8.2 函数 Delay(unsigned int i)
这个函数用于创建一个简单的延时,参数i
表示延时的长度。
- 循环结构:外层循环控制延时次数,内层循环提供额外的延时长度。这种延时方法依赖于处理器的执行速度,因此并不精确。
8.3 函数 Display()
这个函数用于控制数码管的显示。
P1=dispbitcode[dispbuf[3]];
:设置P1端口的值为dispbuf[3]
对应的段码,用于显示第四位数字。D0=0; D1=1; D2=1; D3=1;
:通过设置这些控制位,选择激活第一个数码管。Delay(10);
:调用延时函数,保持当前显示状态一段时间。P1=0x00;
:清除显示,准备下一个数字的显示。- 接下来的代码块重复上述逻辑,用于显示第三位、第二位和第一位数字。
if(m==2)
和if(m==10)
:这两个条件判断用于控制小数点的显示,当变量m
等于特定值时,激活小数点。
void TimeInitial();
void Delay(unsigned int i);
void TimeInitial()
{
TMOD=0x10;
TH1=(65536-200)/256;
TL1=(65536-200)%256;
EA=1;
ET1=1;
TR1=1;
}
void Delay(unsigned int i)
{
unsigned int j;
for(;i>0;i--)
{
for(j=0;j<125;j++)
{;}
}
}
void Display()
{
P1=dispbitcode[dispbuf[3]];
D0=0;
D1=1;
D2=1;
D3=1;
Delay(10);
P1=0x00;
P1=dispbitcode[dispbuf[2]];
if(m==2)
{
P17=1;
}
D0=1;
D1=0;
D2=1;
D3=1;
Delay(10);
P1=0x00;
P1=dispbitcode[dispbuf[1]];
if(m==10)
{
P17=1;
}
D0=1;
D1=1;
D2=0;
D3=1;
Delay(10);
P1=0x00;
P1=dispbitcode[dispbuf[0]];
D0=1;
D1=1;
D2=1;
D3=0;
Delay(10);
P1=0x00;
}
这段代码通过控制数码管的各个段和位选择,实现了数字的动态显示。每个数字显示一段时间后清除,然后显示下一个数字,从而在视觉上形成连续显示的效果。
九、仿真电路设计
微控制器选择:
- 寄存器配置(如PINSEL0、PINSEL1等),选择合适的微控制器。例如,如果是基于ARM架构的微控制器,可能是LPC系列等。
外围设备和接口:
- 确定代码中涉及的外围设备,如显示设备(由
ShowByte
函数推测),以及需要控制的其他设备(如LED灯、传感器等)。 - 设计必要的接口电路,例如电阻、晶体管、继电器等,以适配微控制器的电压和电流要求。
电源管理:
- 设计电源管理电路,确保微控制器和所有外围设备都能获得稳定的电源供应。可能需要考虑线性稳压器或开关稳压器,以及电源滤波和保护电路。
信号处理:
- 如果涉及模拟信号的采集或输出,设计适当的信号调理电路,如放大、滤波、隔离等。
仿真软件选择:
- 使用如Proteus、Multisim等电路仿真软件来设计和测试电路。这些软件可以帮助验证电路设计的正确性,并模拟微控制器与外围设备的交互。
编程和调试:
- 在仿真环境中加载和运行您的代码,观察微控制器的行为是否符合预期。
- 使用调试工具(如JTAG、SWD接口)进行程序调试,确保程序逻辑正确无误。
安全和可靠性考虑:
- 设计时考虑电路的安全性和可靠性,包括过电压、过电流保护,以及电路的物理布局,以减少噪声和干扰。
十、总电路
LPC2124电路设计
量程自动切换数字电压表电路设计
七、运行效果
整体运行效果
数据显示
达到设定温度风扇停止
其他待测效果
6.8 显示模块和待测电压
十一、总结
针对上述项目,我们能够汲取的知识精华包括:
-
嵌入式系统编程:
- 学习如何使用C语言编写嵌入式系统程序,包括寄存器级别的硬件控制,如GPIO配置、外设初始化等。
-
微控制器硬件知识:
- 了解微控制器的基本架构,包括引脚功能选择(PINSEL)、IO方向控制(IO0DIR)、IO状态控制(IO0CLR)等。
-
硬件接口设计:
- 学习如何设计硬件接口电路,包括电源管理、信号处理、外围设备连接等。
-
仿真和调试技术:
- 掌握使用电路仿真软件(如Proteus、Multisim)进行电路设计和测试的方法。
- 学习使用调试工具(如JTAG、SWD)进行程序调试和硬件验证。
-
项目管理和实施:
- 学习如何规划和实施一个嵌入式系统项目,包括需求分析、设计、实现、测试和优化等阶段。
-
软件与硬件的协同工作:
- 理解软件程序如何与硬件设备协同工作,以及如何通过编程控制硬件行为。
-
问题解决和故障排除:
- 在项目实施过程中,学习如何识别和解决硬件和软件问题,以及如何进行故障排除。
通过这个项目,可以获得从理论到实践的全面学习经验,不仅提升编程技能,还能加深对嵌入式系统硬件和软件协同工作的理解。这对于电子工程、计算机工程、自动化控制等领域的学生和专业人士来说,都是非常宝贵的学习机会。
评论(0)
您还未登录,请登录后发表或查看评论