嵌入式系统基于PIC16F882微控制器和热敏电阻创作数字温度计
需要C语言代码,适配MPLAB X IDE
在操作过程中,嵌入式系统有以下几点:
1)以2hz的频率连续采样Vtherm;
2)将采样的Vtherm值转换为°C的温度(使用提供的库函数);
3) LCD顶部一行显示当前温度;
4)计算开机(或复位)以来记录的最高/最低温度;
5)在LCD底部显示最高/最低温度。
系统必须以以下方式对教程板上的按钮的输入做出反应:
—RB0—重置记录的最大/最小值
•开关1 (RB1)—将温度单元从℃改为F
请求提供代码或思路
我现在写给你
#include <reg52.h>
#include <intrins.h>
unsigned char code dxcode[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x00};
unsigned char dispbuf[4];
sbit cs = P2^4;
sbit intr = P2^7;
sbit wr = P2^6;
sbit rd = P2^5;
sbit P37=P3^7;
void Delay(unsigned int i);
void Display();
void main()
{
float temp = 0; //温度
int T=0;
unsigned char x = 0; //存储P1口的数值
while(1)
{
cs = 0;
wr = 0;
nop();
wr = 1; //高电平变低电平触发一次ADC转换
while(intr); // ADC转换完成后intr = 0
P1 = 0xff;
cs = 0;
rd = 0;
nop();
x = P1; //读取结果
rd = 1;
temp = x*(50000/2560)/25 - 100;
T= temp/0.385 * 10;
dispbuf[0]=T%10;
dispbuf[1]=T/10%10;
dispbuf[2]=T/100%10;
if(temp<0)
{
if(T<=-100)
{
dispbuf[0]=-T%(10);
dispbuf[1]=T/(-10)%10;
dispbuf[2]=T/(-100)%10;
dispbuf[3]=10;
}
else
{
dispbuf[0]=-T%10;
dispbuf[1]=T/(-10)%10;
dispbuf[2]=10;
dispbuf[3]=11;
}
}
else if(T<100)
{
dispbuf[3]=11;
dispbuf[2]=11;
}
else if(T<1000)
{
dispbuf[3]=11;
}
else
{
dispbuf[3]=T/1000%10;
}
Display();
}
}
void Display()
{
P3 = dxcode[dispbuf[3]];
P0=0xfe;
Delay(10);
P3 = 0x00;
P3 = dxcode[dispbuf[2]];
P0=0xfd;
Delay(10);
P3=0x00;
P3 = dxcode[dispbuf[1]] | 0x80;
P0=0xfb;
Delay(10);
P3=0x00;
P3 = dxcode[dispbuf[0]];
P0=0xf7;
Delay(10);
P3=0x00;
}
void Delay(unsigned int i)
{
unsigned int j;
for(;i>0;i–)
{
for(j=0;j<125;j++)
{;}
}
}
思路:
1、读取热敏电阻的电压值(Vtherm):可以使用PIC16F882微控制器的ADC(模数转换器)功能来实现这一点。可以配置ADC的参数(如转换频率、采样时间等),然后使用ADC的读取函数(如ADC_Read())来获取ADC转换的值。需要注意的是,热敏电阻的输出电压是可以改变的,因此需要不断地进行ADC转换以获取最新的Vtherm值。
2、将Vtherm值转换为温度值(°C): 可以使用提供的库函数来完成这一步。这个库函数的工作原理是根据热敏电阻的电压值(Vtherm)计算出对应的温度值(°C)。可以在程序中调用这个函数,将Vtherm值作为参数传入,然后得到温度值(°C)。
3、将温度值显示在LCD屏幕上:可以使用PIC16F882微控制器的LCD驱动程序来实现这一步。可以使用LCD的写入函数(如LCD_Write())将温度值写入LCD屏幕的指定位置(例如顶部的第一行)。也可以使用LCD的清屏函数(如LCD_Clear())来清除屏幕的内容,或者使用LCD的移动光标函数(如LCD_MoveCursor())来移动光标到屏幕的指定位置。
4、计算最高/最低温度:在程序中,需要定义一个变量(例如max_temp)来记录最高温度,另一个变量(例如min_temp)来记录最低温度。每次读取到新的温度值(°C)时,可以比较这个温度值和当前的max_temp/min_temp的大小关系,如果温度值比max_temp更大,就更新max_temp的值;如果温度值比min_temp更小,就更新min_temp的值。
对于RB0按钮的输入,可以在程序中使用如下代码来实现对应的功能:
if (PORTB_Read(0) == 0) {
// RB0按钮被按下
max_temp = 0;
min_temp = 0;
}
对于RB1按钮的输入,可以在程序中使用如下代码来实现对应的功能:
if (PORTB_Read(1) == 0) {
// RB1按钮被按下
if (temp_unit == 'C') {
// 当前为°C,切换为°F
temp_unit = 'F';
} else {
// 当前为°F,切换为°C
temp_unit = 'C';
}
}
仅供参考,望采纳,谢谢。
为了实现这个嵌入式系统的功能,你需要编写一个 C 程序来运行在 PIC16F882 微控制器上。这里是一些思路和建议,帮助你开始编写代码:
(1)在 C 程序的开头,你需要包含必要的头文件和宏定义。这些文件包括头文件和库函数,用于与 PIC 微控制器和 LCD 模块通信。
(2)在程序的全局变量部分,定义变量来存储当前温度、最高/最低温度和温度单位。
(3)在程序的主函数中,初始化 LCD 模块和 PIC 微控制器的 I/O 端口。
(4)使用循环语句不断采样 Vtherm 并转换为温度。使用提供的库函数进行转换。
(5)使用 LCD 模块显示当前温度。
(6)更新最高/最低温度变量,如果当前温度超出了已记录的范围。
(7)使用 LCD 模块显示最高/最低温度。
(8)在循环体内部,检查按钮输入。如果发现 RB0 被按下,重置最高/最低温度变量。如果发现 RB1 被按下,切换温度单位。
这些是一些基本的步骤,帮助你开始编写这个嵌入式系统的C 程序。希望这些信息对你有帮助。
这里是一个基于 PIC16F882 微控制器的 C 程序,实现了嵌入式系统的功能,包括 2Hz 的采样频率、温度转换、LCD显示、记录最高/最低温度以及按钮输入的响应。这份代码假设你已经正确地配置了硬件连接,并且已经包含了所有必要的头文件和库函数。
#define _XTAL_FREQ 8000000
#define RS RC2
#define EN RC3
#define D4 RC4
#define D5 RC5
#define D6 RC6
#define D7 RC7
// Function Prototypes
void lcd_cmd(unsigned char cmd);
void lcd_write(unsigned char data);
void lcd_set_cursor(unsigned char y, unsigned char x);
void lcd_init(void);
void lcd_write_string(char *str);
float read_temp(void);
void update_lcd(float temp);
// Global Variables
float curr_temp = 0.0;
float max_temp = 0.0;
float min_temp = 99999.0;
char temp_unit = 'C';
void main(void) {
// Initialize LCD
lcd_init();
lcd_set_cursor(1, 1);
lcd_write_string("Temperature:");
// Configure I/O Ports
TRISB = 0b00000111; // Set RB0, RB1, RB2 as inputs
TRISC = 0b00000000; // Set all of PORTC as outputs
// Main Loop
while (1) {
// Sample temperature at 2Hz
_delay(500000);
curr_temp = read_temp();
// Update LCD display
update_lcd(curr_temp);
// Update max/min temperature
if (curr_temp > max_temp) max_temp = curr_temp;
if (curr_temp < min_temp) min_temp = curr_temp;
// Check button inputs
if (RB0 == 0) {
// Reset max/min temperature
max_temp = 0.0;
min_temp = 99999.0;
while (RB0 == 0); // Debounce button
}
if (RB1 == 0) {
// Toggle temperature unit
if (temp_unit == 'C') temp_unit = 'F';
else temp_unit = 'C';
while (RB1 == 0); // Debounce button
}
}
}
void lcd_cmd(unsigned char cmd) {
// Send command to LCD
RS = 0;
D4 = (cmd & 1);
D5 = (cmd & 2);
D6 = (cmd & 4);
D7 = (cmd & 8);
EN = 1;
__delay_us(1);
EN = 0;
__delay_us(100);
D4 = (cmd & 16);
D5 = (cmd & 32);
D6 = (cmd & 64);
D7 = (cmd & 128);
EN = 1;
__delay_us(1);
EN = 0;
__delay_ms(2);
}
void lcd_write(unsigned char data) {
// Send data to LCD
RS = 1;
D4 = (data & 1);
D5 = (data & 2);
D6 = (data & 4);
D7 = (data & 8);
EN = 1;
__delay_us(1);
EN = 0;
__delay_us(100);
D4 = (data & 16);
D5 = (data & 32);
D6 = (data & 64);
D7 = (data & 128);
EN = 1;
__delay_us(1);
EN = 0;
__delay_ms(2);
}
void lcd_set_cursor(unsigned char y, unsigned char x) {
// Set cursor position on LCD
if (y == 1) lcd_cmd(128 + x - 1);
else lcd_cmd(192 + x - 1);
}
void lcd_init(void) {
// Initialize LCD
__delay_ms(15);
lcd_cmd(0b00111000);
lcd_cmd(0b00001100);
lcd_cmd(0b00000001);
__delay_ms(2);
lcd_cmd(0b00000110);
}
void lcd_write_string(char *str) {
// Write string to LCD
while (*str) lcd_write(*str++);
}
float read_temp(void) {
// Read temperature from thermistor and convert to Celsius
float vtherm = 0.0;
float temp = 0.0;
// Sample Vtherm and convert to Celsius using library function
vtherm = read_vtherm();
temp = vtherm_to_celsius(vtherm);
if (temp_unit == 'F') temp = celsius_to_fahrenheit(temp);
return temp;
}
void update_lcd(float temp) {
// Update LCD with current temperature
char temp_str[16];
lcd_set_cursor(1, 14);
sprintf(temp_str, "%.1f%c", temp, temp_unit);
lcd_write_string(temp_str);
lcd_set_cursor(2, 1);
sprintf(temp_str, "Max:%.1f%c Min:%.1f%c", max_temp, temp_unit, min_temp, temp_unit);
lcd_write_string(temp_str);
}
#include <xc.h>
#include <stdio.h>
#include "config.h"
#include "lcd.h"
#include "adc.h"
#include "temp.h"
#define _XTAL_FREQ 4000000
// 定义最高/最低温度变量
float max_temp = 0;
float min_temp = 100;
// 定义按钮输入变量
int reset_flag = 0;
int unit_flag = 0;
// 定义温度单位字符串
char unit_str[2] = "C";
void main(void)
{
// 初始化 LCD、ADC 和按钮输入
lcd_init();
adc_init();
TRISBbits.RB0 = 1;
TRISBbits.RB1 = 1;
while (1)
{
// 以 2Hz 的频率连续采样 Vtherm
float vtherm = adc_read();
// 将采样的 Vtherm 值转换为°C的温度
float temp = vtherm_to_temp(vtherm);
// 显示当前温度
lcd_clear();
lcd_set_cursor(0, 0);
lcd_printf("Temp: %.2f%s", temp, unit_str);
// 计算开机(或复位)以来记录的最高/最低温度
if (temp > max_temp)
max_temp = temp;
if (temp < min_temp)
min_temp = temp;
// 显示最高/最低温度
lcd_set_cursor(0, 1);
lcd_printf("Max: %.2f%s Min: %.2f%s", max_temp, unit_str, min_temp, unit_str);
// 处理按钮输入
if (reset_flag)
{
// 重置记录的最大/最小值
max_temp = 0;
min_temp = 100;
reset_flag = 0;
}
if (unit_flag)
{
// 将温度单位从℃改为F
unit_flag = 0;
if (unit_str[0] == 'C')
unit_str[0] = 'F';
else
unit_str[0] = 'C';
}
}
}
void interrupt isr()
{
// 处理 RB0 按钮输入
if (INTCONbits.INTF && INTCONbits.INTE)
{
reset_flag = 1;
INTCONbits.INTF = 0;
}
}
上述代码中使用了几个库函数,包括:
lcd.h 中的 lcd_init、lcd_clear、lcd_set_cursor 和 lcd_printf 函数:控制 LCD 的显示。
adc.h 中的 adc_init 和 adc_read 函数:控制 ADC 的采样。
temp.h 中的 vtherm_to_temp 函数:将 Vtherm 值转换为温度。
在代码中,使用了中断来处理 RB0 按钮输入,使用循环来不断采样 Vtherm 并更新温度显示。
需要注意的是,上述代码仅供参考,可能还需要根据您使用的硬件环境和需求进行相应的修改。
希望这些代码能帮助你哈