STC单片机测8路NTC测温度
来源:互联网 发布:javascript实战 pdf 编辑:程序博客网 时间:2024/05/17 21:10
1. 单片机型号:STC15F2K32S2,NTC电阻,内部自带ADC检测ADC,
2. 怎么样把ADC值转为温度是最容易让大家不知从何下手,有查表等思路,但是我自己分析的不是查表,查表速度慢,单片机内存也只有那么大,我选择的方法是ADC值和温度直接联系,我下午特意去奶茶店找了一点冰块,来测了几十个点的温度,然后建立ADC值与温度的关系,参考温度是胜利万用表的温度。
注意:这个地方测ADC值不要测一段连续的温度的ADC值(要分点测试比如,16,18,20等 ),相信你有更好的办法,我测高温度是用热水测得,低温度是在奶茶店找的冰测得。
3.我们用的分析软件是新建 Excel 表
注意:这个数据曲线不是随便乱选的,你测了那么多点,你要看经过的点最多的,当然不可能是性线关系,这个要根据你自己的数据去分析,你公式出来了,然后用C语言可以把这个每一个温度的ADC值算出来,然后用NTC电阻测几个温度对比一下我们得出来公式的。我的参考温度还是是胜利万用表测出来的温度。
如以上还有不懂的,可以加我QQ:2681075556
/* ***************************************************** */// 工 程 : my// 文件名 : main.c// 处理器 : STC// 编译环境 : Keil4 C51 // 系统时钟 : 内部自带22.1184MHZ// 版 本: V1.0 // 生成日期: 2017-005-02 // 修改日期: // 简单描述 : 八路NTC温度// 开发人才 :Made in Liu Ren fu(大白菜)/* ***************************************************** */#include <STC15F2K60S2.H>#include "adc.h"#include "lcd12864.h"#include "uart.h"#include "math.h"#include "key.h"/******************全局变量***********************/u16 tab[8]={0};//存储ADC值float ADC_Value[8]={0};//存储温度u8 L_num[8]={15,15,15,15,15,15,15,15}; //设置低报警温度值,默认u8 H_num[8]={40,40,40,40,40,40,40,40}; //设置高报警温度值/************************************************/sbit OE1_573 = P2^7;sbit OE2_573 = P4^6;sbit OE3_573 = P4^5;//========================================================================// 函数: void IO_Inti()// 描述: 初始化IO// 参数: ch:选择要转换的ADC通道//========================================================================void IO_Inti(){P0M1=0;P0M0=0XFF;P1M1 = 0Xff;P1M0 = 0X00;P2M1=0;P2M0=0;P3M1=0;P3M0=0;P4M1=0;P4M0=0;P5M1=0;P5M0=0;}//========================================================================// 函数: float Get_Temperature(u8 ch)// 描述: (log(y)-log(635.69))/-0.029=x// 参数: ch:选择要转换的ADC通道//========================================================================float Get_Temperature(u8 ch){ const float XS = 635.69; u16 ADC_V=0; float temp = Get_ADC10bitResult(ch); temp = log(temp); temp -= log(XS); temp /= -0.029; return temp;}//========================================================================// 函数: int filter(u8 ch) // 描述: 软件滤波// 参数: ch滤波值//========================================================================#define N 12 int filter(u8 ch) { float sum = 0;u8 count=0;for(count=0;count<N;count++) { sum += Get_Temperature(ch); _nop_(); _nop_(); _nop_(); } return (int)(sum/N); }//========================================================================// 函数: void UART_Test()// 描述: 数据读取与串口测试// 参数: 无//========================================================================void UART_Test(){ tab[0]=Get_ADC10bitResult(0); //读取通道0的ADC值ADC_Value[0] = (float)filter(0); //读取通道0的温度tab[1]=Get_ADC10bitResult(1); //读取通道1的ADC值ADC_Value[1] = (float)filter(1); //读取通道1的温度tab[2]=Get_ADC10bitResult(2); //读取通道2的ADC值ADC_Value[2] = (float)filter(2); //读取通道2的温度tab[3]=Get_ADC10bitResult(3); //读取通道3的ADC值ADC_Value[3] = (float)filter(3); //读取通道3的温度tab[4]=Get_ADC10bitResult(4); //读取通道4的ADC值ADC_Value[4] = (float)filter(4); //读取通道4的温度tab[5]=Get_ADC10bitResult(5); //读取通道5的ADC值ADC_Value[5] = (float)filter(5); //读取通道5的温度tab[6]=Get_ADC10bitResult(6);//读取通道6的ADC值ADC_Value[6] = (float)filter(6); //读取通道6的温度 tab[7]=Get_ADC10bitResult(7); //读取通道7的ADC值ADC_Value[7] = (float)filter(7); //读取通道7的温度//发送串口监控显示//printf("通道0的AD值%d\n",tab[0]);//printf("通道0的温度值%f℃\n",ADC_Value[0]);//printf("通道1的AD值%d\n",tab[1]);//printf("通道1的温度值%f℃\n",ADC_Value[1]);//printf("通道2的AD值%d\n",tab[2]);//printf("通道2的温度值%f℃\n",ADC_Value[2]);//printf("通道3的AD值%d\n",tab[3]);//printf("通道3的温度值%f℃\n",ADC_Value[3]);//printf("通道4的AD值%d\n",tab[4]);//printf("通道4的温度值%f℃\n",ADC_Value[4]);//printf("通道5的AD值%d\n",tab[5]);//printf("通道5的温度值%f℃\n",ADC_Value[5]);//printf("通道6的AD值%d\n",tab[6]);//printf("通道6的温度值%f℃\n",ADC_Value[6]);//printf("通道7的AD值%d\n",tab[7]);//printf("通道7的温度值%f℃\n\n\n",ADC_Value[7]);}void Timer0Init(void)//1000微秒@22.1184MHz{AUXR &= 0x7F;//定时器时钟12T模式TMOD &= 0xF0;//设置定时器模式TL0 = 0xCD;//设置定时初值TH0 = 0xF8;//设置定时初值TR0 = 0;//定时器0关闭计时ET0 = 1;//打开定时器0中断EA = 1; //打开总中断}//========================================================================// 函数: void Timer1Init(void)// 描述: 定时器1初始化// 参数: 无//========================================================================void Timer1Init(void)//1000微秒@22.1184MHz{AUXR &= 0xBF;//定时器时钟12T模式TMOD &= 0x0F;//设置定时器模式TL1 = 0xCD;//设置定时初值TH1 = 0xF8;//设置定时初值TF1 = 0;//清除TF1标志TR1 = 0;//定时器1开始计时ET1 = 1;//打开定时器0中断EA = 1; //打开总中断}//========================================================================// 函数: void Dis_play(u8 x,u8 y,u8 dat)// 描述: LCD12864显示数据// 参数: 无//========================================================================void Dis_play(u8 x,u8 y,u8 dat){ u8 ge=0,shi=0; //用于显示个,十位 ge = dat%10; //取各位 shi = dat/10; //取十位 Single_Data(x,y,shi);//发送十位显示 Write_data(ge+'0'); //发送个位显示 _nop_();_nop_();}//========================================================================// 函数: display_start()// 描述: LCD12864显示数据// 参数: 无//========================================================================void display_start(){LCD_PutString(0,1,"ch0: ℃ch4: ℃");//温度显示界面 LCD_PutString(0,2,"ch1: ℃ch5: ℃"); LCD_PutString(0,3,"ch2: ℃ch6: ℃"); LCD_PutString(0,4,"ch3: ℃ch7: ℃");}//========================================================================// 函数: empty_inti()// 描述: LCD12864清空显示数据// 参数: 无//========================================================================void empty_inti(){ LCD_PutString(0,1,"0:开1:开2:开3:开");//清空LCD12864显示 LCD_PutString(0,2,"4:开5:开6:开7:开"); LCD_PutString(0,3," "); LCD_PutString(0,4," ");}//========================================================================// 函数: Control_KEY()// 描述: 设置温度报警// 参数: 无//========================================================================void Control_KEY(){ static u8 flag_1=0;//用于设置那一路温度标志位 if(SW1 == 0)//判断是否有按键按下 { DelayMS(1);//延时消抖 if(SW1 == 0)//判断是否有按键按下 { while(!SW1);//松手检测 flag_1++; switch(flag_1) { case 1: TR1 = 0; TR0 = 1; LCD_PutString(0,1,"0: -- 4: -- "); LCD_PutString(0,2,"1: -- 5: -- "); LCD_PutString(0,3,"2: -- 6: -- "); LCD_PutString(0,4,"3: -- 7: -- "); break; // case 2: LCD_PutString(0,1,"0: 设 4: -- ");//设置0通道 break; case 3: LCD_PutString(0,1,"0: -- 4: -- "); //设置1通道LCD_PutString(0,2,"1: 设 5: -- "); break; case 4: LCD_PutString(0,2,"1: -- 5: -- ");//设置2通道LCD_PutString(0,3,"2: 设 6: -- "); break; case 5: LCD_PutString(0,3,"2: -- 6: -- ");//设置3通道LCD_PutString(0,4,"3: 设 7: -- "); break; case 6: LCD_PutString(0,4,"3: -- 7: -- ");//设置4通道LCD_PutString(0,1,"0: -- 4: 设 "); break; case 7: LCD_PutString(0,1,"0: -- 4: -- ");//设置5通道LCD_PutString(0,2,"1: -- 5: 设 "); break; case 8: LCD_PutString(0,2,"1: -- 5: -- ");//设置6通道LCD_PutString(0,3,"2: -- 6: 设 "); break; case 9: LCD_PutString(0,3,"2: -- 6: -- ");//设置7通道LCD_PutString(0,4,"3: -- 7: 设 "); break; case 10: TR0 = 0; TR1 = 1; break; default:break; } if(flag_1 == 10) flag_1=0; } } /////////////////////////////////////////// if((SW2 == 0) && (flag_1 > 1))//判断高报警位按键与是否可以设置温度 { DelayMS(2);//延时消抖 if((SW2 == 0) && (flag_1 > 1))//判断高报警位按键与是否可以设置温度 { while(!SW2);//松手检测 switch(flag_1) { case 2:H_num[0]++;if(H_num[0]==99){ H_num[0]=30;}break;case 3:H_num[1]++;if(H_num[1]==99){ H_num[1]=30;}break;case 4:H_num[2]++;if(H_num[2]==99){ H_num[2]=30;}break;case 5:H_num[3]++;if(H_num[3]==99){ H_num[3]=30;}break;case 6:H_num[4]++;if(H_num[4]==99){ H_num[4]=30;}break; case 7:H_num[5]++;if(H_num[5]==99){ H_num[5]=30;}break;case 8:H_num[6]++;if(H_num[6]==99){ H_num[6]=30;}break;case 9:H_num[7]++;if(H_num[7]==99){ H_num[7]=30;}break;default:break; } }} ///////////////////////////////////////if((SW3 == 0) && (flag_1 > 1))//判断低报警位按键与是否可以设置温度 { DelayMS(2);//延时消抖 if((SW3 == 0) && (flag_1 > 1))//判断低报警位按键与是否可以设置温度 { while(!SW3); //松手检测 switch(flag_1) { case 2:L_num[0]--;if(L_num[0]==0){ L_num[0]=30;}break;case 3:L_num[1]--;if(L_num[1]==0){ L_num[1]=30;}break;case 4:L_num[2]--;if(L_num[2]==0){ L_num[2]=30;}break;case 5:L_num[3]--;if(L_num[3]==0){ L_num[3]=30;}break;case 6:L_num[4]--;if(L_num[4]==0){ L_num[4]=30;}break; case 7:L_num[5]--;if(L_num[5]==0){ L_num[5]=30;}break;case 8:L_num[6]--;if(L_num[6]==0){ L_num[6]=30;}break;case 9:L_num[7]--;if(L_num[7]==0){ L_num[7]=30;}break;default:break; } } }///////////////////////////// if(SW4 == 0)//判断是否有按键按下 { DelayMS(1);//延时消抖 if(SW4 == 0)//判断是否有按键按下 { while(!SW1);//松手检测 TR1=1; } }}void main(){IO_Inti();//IO初始化LCD_inti();//初始化LCD12864Timer1Init();//初始化定时器1Timer0Init();//初始化定时器0UART_init();//初始化串口 AD_Inti();//ADC初始化while(1){ Control_KEY();//按键检测 UART_Test();//ADC读取 if((L_num[0] >= ADC_Value[0])) //温度少于设定低温度是加热水 { OE1_573 = 1;//打开573使能端 OE2_573 = 0;//573使关闭能端 P0 = 0xef; } if((H_num[0] <= ADC_Value[0])) //温度大于设定高温度是加冷水 { OE1_573 = 0;//打开573使能端 OE2_573 = 1;//573使关闭能端 P0 = 0xef; }}}void tm0() interrupt 1{ static u16 flag=0; flag++; if(flag>=300) { flag=0; Dis_play(3,1,L_num[0]); //报警值显示 Dis_play(3,2,L_num[1]); Dis_play(3,3,L_num[2]); Dis_play(3,4,L_num[3]); Dis_play(7,1,L_num[4]); Dis_play(7,2,L_num[5]); Dis_play(7,3,L_num[6]); Dis_play(7,4,L_num[7]); Dis_play(1,1,H_num[0]); Dis_play(1,2,H_num[1]); Dis_play(1,3,H_num[2]); Dis_play(1,4,H_num[3]); Dis_play(5,1,H_num[4]); Dis_play(5,2,H_num[5]); Dis_play(5,3,H_num[6]); Dis_play(5,4,H_num[7]); }}void tm1() interrupt 3{ static u16 flag=0;flag++;if(flag>=300)//10ms{ flag = 0;display_start();Dis_play(2,1,(u8)ADC_Value[0]);//温度显示Dis_play(2,2,(u8)ADC_Value[1]);Dis_play(2,3,(u8)ADC_Value[2]);Dis_play(2,4,(u8)ADC_Value[3]);Dis_play(6,1,(u8)ADC_Value[4]);Dis_play(6,2,(u8)ADC_Value[5]);Dis_play(6,3,(u8)ADC_Value[6]);Dis_play(6,4,(u8)ADC_Value[7]);}}
#ifndef __ADC_H_#define __ADC_H_#include "config.h"#include "lcd12864.h"#include <STC15F2K60S2.H>#include "intrins.h"#include "uart.h"#include <stdio.h> // 为使用KEIL自带的库函数printf而加入#define ADC_POWER 0x80 //ADC电源控制位#define ADC_FLAG 0x10 //ADC完成标志#define ADC_START 0x08 //ADC起始控制位#define ADC_SPEEDLL 0x00 //540个时钟#define ADC_SPEEDL 0x20 //360个时钟#define ADC_SPEEDH 0x40 //180个时钟#define ADC_SPEEDHH 0x60 //90个时钟void AD_Inti(void);u16 Get_ADC10bitResult(u8 channel);#endif#include "adc.h"void AD_Inti(void){ADC_RESL=0;//清除结果寄存器ADC_RES=0;//清除结果寄存器ADC_CONTR &= 0x10;//清除转换完成标志位P1ASF = 0xff; //P1做ADC ADC_CONTR = 0xE0; //90T, ADC power on _nop_(); _nop_(); _nop_(); _nop_();}//========================================================================// 函数: u16 Get_ADC10bitResult(u8 channel)// 描述: 查询法读一次ADC结果.// 参数: channel: 选择要转换的ADC.// 返回: 10位ADC结果.// 版本: V1.0, 2012-10-22//========================================================================u16 Get_ADC10bitResult(u8 channel) //channel = 0~7{u16 AD_v = 0; ADC_RES = 0; ADC_RESL = 0; ADC_CONTR = (ADC_CONTR & 0xe0) | 0x08 | channel; //start the ADC _nop_(); _nop_(); _nop_(); _nop_(); while((ADC_CONTR & 0x10) == 0) ; //wait for ADC finish ADC_CONTR &= ~0x10; //清除ADC结束标志AD_v = ((u16)ADC_RES << 2) | (ADC_RESL & 3); return (AD_v);}
0 0
- STC单片机测8路NTC测温度
- ntc 测温 单片机 C语言 查表 温度系数表 计算公式
- STC单片机timer2捕获模式测频率
- 51单片机 DS18B20 (测温度 读取序列号 温度警报)
- Arduino 负温度系数热敏电阻(NTC)测温
- STC单片机的延时
- STC单片机波特率计算
- STC单片机遭遇
- STC单片机EEPROM读写
- STC单片机 DS1302
- STC单片机程序-按键
- STC单片机编程知识点
- STC单片机学习----ADC
- STC 单片机深入学习
- STC单片机跑马灯
- STC单片机知识点
- STC单片机常用型号
- STC单片机单片机模块化总结
- Spring各jar包详解
- java 多线程加锁-锁住了什么?
- Bootstrap常用的导航栏
- 高斯滤波器
- 学习淘淘商城第五十一课(搜索功能切换到集群)
- STC单片机测8路NTC测温度
- hdu2571-递推的思考-递推的逻辑
- pthread-消费者/生产者模型实现
- 为什么继承
- 单例模式的八种写法
- 01-端口映射作用
- js获取url及url参数的方法
- Spring Anotation
- matlab中使用libsvm