标题:
单片机控制实现ADC TLC549一路模拟电压采集程序Proteus仿真
[打印本页]
作者:
norlike
时间:
2023-7-8 20:57
标题:
单片机控制实现ADC TLC549一路模拟电压采集程序Proteus仿真
使用proteus进行仿真:运用单片机(AT89C52、STM32、MSP430等)控制实现一路模拟电压采集(ADC)
需实现以下功能:
1、电压测量范围0~5V
2、设置电压上限4.5V,超过上限电压红色LED灯警示、蜂鸣器警示1S;
3、设置电压下限0.5V,低于下限电压黄色LED灯警示、蜂鸣器警示1S;
4、显示实时测量电压值、上下限电压值,将采集到的电压数据显示在LCD1602液晶屏的第一行中间位置,上下限电压值显示在LCD1602液晶屏的第二行位置;
5、将学号后两位显示在液晶屏的右下角;
6、AD芯片选型:ADC0804,TLC549等。
在附件里还有一个可以自己计算可调的上下限电压的python代码。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
51hei.gif
(112.05 KB, 下载次数: 25)
下载附件
2023-7-9 00:29 上传
1.png
(38.41 KB, 下载次数: 28)
下载附件
2023-7-8 22:56 上传
单片机源程序如下:
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit fengmingqi = P1^0; // 蜂鸣器引脚定义
sbit LED_red = P1^6; // 红色LED报警引脚定义
sbit LED_yellow = P1^7; // 黄色LED报警引脚定义
sbit RS = P2^0; // LCD控制引脚定义
sbit RW = P2^1; // LCD控制引脚定义
sbit E = P2^2; // LCD控制引脚定义
sbit TLC549_CLK = P2^3; // TLC549时钟引脚定义
sbit TLC549_CS = P2^4; // TLC549片选引脚定义
sbit TLC549_DO = P2^5; // TLC549数据引脚定义
uchar volt_h = 0xBF, volt_l = 0x68; // 设置电压上下限 4.5V 0.5V
unsigned char s1[] = "21"; // 显示学号字符串
unsigned char s2[] = "2.05V 3.75V"; // 显示电压上下限字符串
void delayms(uchar ms)
{
uchar i;
while (ms--)
for (i = 0; i < 123; i++); // 延时函数,以毫秒为单位
}
void delayus(uchar us)
{
while (us--); // 延时函数,以微秒为单位
}
void w_com(uchar com)
{
RS = 0; // RS=0表示选择指令寄存器
RW = 0; // RW=0表示写,RW=1表示读
E = 1; // 使能端
P0 = com; // 指令代码从P0口送出
E = 0; // 下降沿执行
delayms(1);
}
void w_dat(uchar dat)
{
RS = 1; // RS=1表示选择数据寄存器
RW = 0;
E = 1;
P0 = dat; // 数据从P0口送出
E = 0; // 下降沿执行
delayms(1);
}
void lcd_ini(void)
{
delayms(10);
w_com(0x38); // 功能设置:8位口2行
delayms(10);
w_com(0x0C); // 显示设置:开显示,关光标,无闪烁
delayms(10);
w_com(0x06); // 输入模式:右移一格,地址加1
delayms(10);
w_com(0x01); // 清显示
delayms(10);
w_com(0x38); // 功能设置:8位口2行
delayms(10);
}
uchar TLC549_ADC(void)
{
uchar i, temp;
TLC549_CLK = 0;
TLC549_CS = 0;
for (i = 0; i < 8; i++)
{
temp <<= 1;
temp |= TLC549_DO;
TLC549_CLK = 1;
TLC549_CLK = 0;
}
TLC549_CS = 1;
delayus(20);
return temp;
}
void main(void)
{
uint temp, d, i = 0, j = 0;
uchar digit1, digit2, digit3; // 个位数和小数点后两位数的变量
lcd_ini();
w_com(0xC1); // 第二行显示电压上下限
while (s2[j] != '\0')
{
w_dat(s2[j]);
j++;
}
w_com(0xCE); // 第二行第14列显示学号
while (s1[i] != '\0')
{
w_dat(s1[i]);
i++;
}
while (1)
{
temp = TLC549_ADC();
d = temp * 1.96; // 基准电压5V转换为电压值
digit1 = d %1000 / 100; // 计算个位数
digit2 = d %100 / 10; // 计算小数点后第一位
digit3 = d %10; // 计算小数点后第二位
w_com(0x84);
w_dat(digit1 + 0x30); // 显示电压值个位
w_dat('.'); // 显示小数点
w_dat(digit2 + 0x30); // 显示电压值小数点后第一位
w_dat(digit3 + 0x30); // 显示电压值小数点后第二位
w_dat('V');
if(temp<=volt_l&&temp>=0x00) //低于下限电压,黄色LED亮蜂鸣器响
{
LED_red=1;
LED_yellow =0; //黄色灯示警
fengmingqi=0; //蜂鸣器示警
delayms(1000);
fengmingqi=1;
delayms(1000);
}
else if(temp<volt_h&&temp>volt_l) //正常电压
{
LED_red =1;
LED_yellow =1;
fengmingqi=1;
delayms(1000);
}
else //高于上限电压,红色LED亮蜂鸣器报警
{
LED_red =0; //红色灯示警
LED_yellow=1;
fengmingqi=0; //蜂鸣器示警
delayms(1000);
fengmingqi=1;
delayms(1000);
}
}
}
复制代码
python代码:
V_min = 0.0 # 最小电压值
V_max = 5.0 # 最大电压值
hex_min = 0x00 # 最小十六进制值
hex_max = 0xFF # 最大十六进制值
# 输入电压范围
V_range_min = float(input("请输入电压范围的最小值(范围在{}之间):".format(V_min)))
V_range_max = float(input("请输入电压范围的最大值(范围在{}之间):".format(V_max)))
# 计算电压范围对应的相对位置
relative_position_min = (V_range_min - V_min) / (V_max - V_min)
relative_position_max = (V_range_max - V_min) / (V_max - V_min)
# 计算十六进制范围
hex_range_min = int(relative_position_min * (hex_max - hex_min) + hex_min)
hex_range_max = int(relative_position_max * (hex_max - hex_min) + hex_min)
# 分解十六进制范围的最小值和最大值为高位和低位
volt_h_min = (hex_range_min >> 8) & 0xFF # 最小值的高位
volt_l_min = hex_range_min & 0xFF # 最小值的低位
volt_h_max = (hex_range_max >> 8) & 0xFF # 最大值的高位
volt_l_max = hex_range_max & 0xFF # 最大值的低位
# 输出结果
print("最小电压值的十六进制表示:volt_h = 0x{:02X}, volt_l = 0x{:02X}".format(volt_h_min, volt_l_min))
print("最大电压值的十六进制表示:volt_h = 0x{:02X}, volt_l = 0x{:02X}".format(volt_h_max, volt_l_max))
#最后你只要把输出的结果选择volt_l的值就可以写入就可以了
复制代码
Keil代码与Proteus仿真下载:
仿真程序.7z
(60.3 KB, 下载次数: 23)
2023-7-9 00:28 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1