找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 150|回复: 0
打印 上一主题 下一主题
收起左侧

Arduino LM35测量温度

[复制链接]
跳转到指定楼层
楼主
用Arduino多功能扩展板,LM35温度传感器模块测量温度,不需外接线,将LM35模块有字面向前(数码管方向),三个脚按顺序插入图中三个插孔中。



Arduino源程序如下:
  1. // LM35温度传感器 + 4位数码管显示(74HC595驱动)

  2. // 引脚定义
  3. #define LM35_PIN A4          // LM35连接到模拟引脚A4
  4. int latchPin = 4;           // 74HC595锁存引脚
  5. int clockPin = 7;           // 74HC595时钟引脚
  6. int dataPin = 8;            // 74HC595数据引脚

  7. // 数码管段选表(0-9,共阴数码管)
  8. // 格式:dp,g,f,e,d,c,b,a
  9. unsigned char segTable[] = {
  10.   0xC0, // 0: 1100 0000
  11.   0xF9, // 1: 1111 1001
  12.   0xA4, // 2: 1010 0100
  13.   0xB0, // 3: 1011 0000
  14.   0x99, // 4: 1001 1001
  15.   0x92, // 5: 1001 0010
  16.   0x82, // 6: 1000 0010
  17.   0xF8, // 7: 1111 1000
  18.   0x80, // 8: 1000 0000
  19.   0x90, // 9: 1001 0000
  20.   0xFF  // 空白显示
  21. };

  22. // 数码管位选表(4位共阴数码管)
  23. // 每个位选码选中一位数码管(低电平有效)
  24. unsigned char digitSelect[] = {
  25.   0xF1, // 1111 0001 - 选中第1位(最左边)
  26.   0xF2, // 1111 0010 - 选中第2位
  27.   0xF4, // 1111 0100 - 选中第3位
  28.   0xF8  // 1111 1000 - 选中第4位(最右边)
  29. };

  30. // 显示缓冲区
  31. unsigned char displayBuffer[] = {0, 0, 0, 0};

  32. // 温度变量
  33. float temperature = 0.0;

  34. // 时间变量
  35. unsigned long lastTempRead = 0;
  36. const unsigned long tempReadInterval = 1000; // 1秒读取一次温度

  37. void setup() {
  38.   Serial.begin(9600);       // 初始化串口
  39.   
  40.   // 设置74HC595引脚为输出
  41.   pinMode(latchPin, OUTPUT);
  42.   pinMode(clockPin, OUTPUT);
  43.   pinMode(dataPin, OUTPUT);
  44.   
  45.   // 设置LM35引脚为输入
  46.   pinMode(LM35_PIN, INPUT);
  47.   
  48.   // 初始显示"----"
  49.   for (int i = 0; i < 4; i++) {
  50.     displayBuffer[i] = 10; // 10对应空白
  51.   }
  52.   
  53.   Serial.println("LM35温度传感器 - 4位数码管显示");
  54.   Serial.println("初始化完成...");
  55. }

  56. // 读取LM35温度
  57. float readLM35Temperature() {
  58.   // 读取模拟值
  59.   int sensorValue = analogRead(LM35_PIN);
  60.   
  61.   // 转换为电压(假设参考电压为5V)
  62.   float voltage = sensorValue * (5.0 / 1023.0);
  63.   
  64.   // LM35每10mV对应1°C,所以电压*100得到温度
  65.   float temp = voltage * 100.0;
  66.   
  67.   return temp;
  68. }

  69. // 更新显示缓冲区
  70. void updateDisplayBuffer(float temp) {
  71.   // 确保温度在合理范围内
  72.   if (temp < 0) temp = 0;
  73.   if (temp > 99.9) temp = 99.9;
  74.   
  75.   // 将温度值乘以10转换为整数,便于分离各位数字
  76.   int tempInt = (int)(temp * 10);
  77.   
  78.   // 分离各位数字
  79.   int tens = tempInt / 100;              // 十位
  80.   int ones = (tempInt % 100) / 10;       // 个位
  81.   int tenths = tempInt % 10;             // 十分位
  82.   
  83.   // 更新显示缓冲区
  84.   if (tens == 0) {
  85.     displayBuffer[0] = 10;  // 十位为0时显示空白
  86.   } else {
  87.     displayBuffer[0] = tens;  // 显示十位
  88.   }
  89.   
  90.   displayBuffer[1] = ones;      // 显示个位(带小数点)
  91.   displayBuffer[2] = tenths;    // 显示十分位
  92.   
  93.   // 第4位显示"C"表示摄氏度(这里用8表示,但实际会特殊处理)
  94.   displayBuffer[3] = 12;  // 特殊值,在显示函数中会转换为"C"
  95. }

  96. // 数码管显示函数
  97. void displayDigits() {
  98.   // 循环显示4位数码管
  99.   for (int i = 0; i < 4; i++) {
  100.     digitalWrite(latchPin, LOW);  // 准备发送数据
  101.    
  102.     // 获取当前位的段选码
  103.     unsigned char segCode;
  104.    
  105.     if (i == 3) {
  106.       // 第4位显示摄氏度符号"C"(段码:1100 0110 = 0xC6)
  107.       segCode = 0xC6;
  108.     } else {
  109.       segCode = segTable[displayBuffer[i]];
  110.       
  111.       // 如果是第1位(个位),添加小数点
  112.       if (i == 1 && displayBuffer[i] != 10) {
  113.         segCode &= 0x7F;  // 清除最高位(dp位),使其显示小数点
  114.       }
  115.     }
  116.    
  117.     // 发送段选数据
  118.     shiftOut(dataPin, clockPin, MSBFIRST, segCode);
  119.    
  120.     // 发送位选数据
  121.     shiftOut(dataPin, clockPin, MSBFIRST, digitSelect[i]);
  122.    
  123.     digitalWrite(latchPin, HIGH);  // 锁存数据,更新显示
  124.    
  125.     // 短暂延时,实现动态扫描
  126.     delay(1);
  127.   }
  128. }

  129. void loop() {
  130.   unsigned long currentMillis = millis();
  131.   
  132.   // 定期读取温度
  133.   if (currentMillis - lastTempRead >= tempReadInterval) {
  134.     lastTempRead = currentMillis;
  135.    
  136.     // 读取温度
  137.     temperature = readLM35Temperature();
  138.    
  139.     // 更新显示缓冲区
  140.     updateDisplayBuffer(temperature);
  141.    
  142.     // 串口输出
  143.     Serial.print("温度: ");
  144.     Serial.print(temperature, 1);  // 显示1位小数
  145.     Serial.println(" °C");
  146.   }
  147.   
  148.   // 持续刷新数码管显示
  149.   // 每50ms刷新20次,确保稳定显示
  150.   static unsigned long lastDisplayTime = 0;
  151.   if (currentMillis - lastDisplayTime >= 50) {
  152.     lastDisplayTime = currentMillis;
  153.    
  154.     // 显示20次(约40ms)
  155.     for (int i = 0; i < 20; i++) {
  156.       displayDigits();
  157.     }
  158.   }
  159. }

  160. /*
  161. 硬件连接说明:

  162. 1. LM35连接:
  163.    VCC -> Arduino 5V
  164.    OUT -> Arduino A4
  165.    GND -> Arduino GND

  166. 2. 74HC595连接(两个芯片级联):
  167.    第一个74HC595(控制段选):
  168.      DS (14脚) -> Arduino 8
  169.      SH_CP (11脚) -> Arduino 7
  170.      ST_CP (12脚) -> Arduino 4
  171.      MR (10脚) -> VCC
  172.      OE (13脚) -> GND
  173.      Q0-Q7 -> 数码管段选引脚(a,b,c,d,e,f,g,dp)

  174.    第二个74HC595(控制位选):
  175.      DS (14脚) -> 第一个74HC595的Q7' (9脚)
  176.      SH_CP (11脚) -> Arduino 7(与第一个共用)
  177.      ST_CP (12脚) -> Arduino 4(与第一个共用)
  178.      MR (10脚) -> VCC
  179.      OE (13脚) -> GND
  180.      Q0-Q3 -> 数码管位选引脚(COM1-COM4)

  181. 3. 4位共阴数码管:
  182.    段选引脚(a-g,dp) -> 第一个74HC595的Q0-Q7
  183.    公共阴极(COM1-COM4) -> 第二个74HC595的Q0-Q3

  184. 注意:
  185. 1. 段选引脚需要串联220Ω限流电阻
  186. 2. 确保74HC595的VCC(16脚)接5V,GND(8脚)接GND
  187. 3. 数码管是共阴极,所以位选低电平时该位数码管被选中

  188. 显示格式:
  189. 第1位:十位温度(如果为0则显示空白)
  190. 第2位:个位温度(带小数点)
  191. 第3位:十分位温度
  192. 第4位:摄氏度符号"C"
  193. 示例:25.6°C 显示为 "25.6C"
  194. */

  195. // 如果需要显示负温度,可以使用以下扩展代码:
  196. /*
  197. // 在segTable数组中添加负号
  198. unsigned char segTable[] = {
  199.   // ... 原有的0-9和空白
  200.   0xBF, // 负号 (-): 1011 1111
  201. };

  202. // 修改updateDisplayBuffer函数:
  203. void updateDisplayBuffer(float temp) {
  204.   if (temp < 0) {
  205.     // 显示负号
  206.     temp = -temp;
  207.     if (temp > 99.9) temp = 99.9;
  208.    
  209.     int tempInt = (int)(temp * 10);
  210.     int ones = (tempInt % 100) / 10;
  211.     int tenths = tempInt % 10;
  212.    
  213.     displayBuffer[0] = 11;  // 负号
  214.     displayBuffer[1] = ones;
  215.     displayBuffer[2] = tenths;
  216.     displayBuffer[3] = 12;  // "C"
  217.   } else {
  218.     // 正温度显示逻辑(保持不变)
  219.     if (temp > 99.9) temp = 99.9;
  220.    
  221.     int tempInt = (int)(temp * 10);
  222.     int tens = tempInt / 100;
  223.     int ones = (tempInt % 100) / 10;
  224.     int tenths = tempInt % 10;
  225.    
  226.     if (tens == 0) {
  227.       displayBuffer[0] = 10;  // 空白
  228.     } else {
  229.       displayBuffer[0] = tens;
  230.     }
  231.    
  232.     displayBuffer[1] = ones;
  233.     displayBuffer[2] = tenths;
  234.     displayBuffer[3] = 12;  // "C"
  235.   }
  236. }
  237. */
复制代码


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表