标题:
新人求助~~温度传感器跟单片机的连接和单片机与PC机的连接
[打印本页]
作者:
chen。chen
时间:
2016-5-4 09:41
标题:
新人求助~~温度传感器跟单片机的连接和单片机与PC机的连接
本人正在做温度检测系统,现在需要温度传感器和单片机连接中的AD转换模块和单片机与PC机连接时的串口通讯模块的C语言程序,哪位大神能帮帮忙?万分感谢~
作者:
cjjcjj1
时间:
2016-5-4 10:47
提示:
作者被禁止或删除 内容自动屏蔽
作者:
东木和孟婆
时间:
2016-5-4 14:25
我有那个程序 好使的
作者:
东木和孟婆
时间:
2016-5-4 14:27
/***********************************************************
程序功能:STC12C5A60S2自带ADC采集电压信号+DS18B20温度传感器+LCD1602液晶显示
MCU型号: STC12C5A60S2
晶振频率:11.0892MHz
整理时间:2012年4月25号
************************************************************/
#include"STC12c5a60s2.h" //头文件在STC公司主页上下载
#include "intrins.h"
//sfr P4 = 0XC0;
//sfr ADC_CONTR = 0XBC;
//sfr ADC_RES = 0XBD;
sfr ADC_LOW2 = 0XBE;
//sfr P1ASF = 0X9D;
typedef unsigned char BYTE;
typedef unsigned int WORD;
#include "1602.h"
#include "DS18B20.h"
#define ADC_POWER 0X80
#define ADC_FLAG 0X10
#define ADC_START 0X08
#define ADC_SPEEDLL 0X00
#define ADC_SPEEDL 0X20
#define ADC_SPEEDH 0X40
#define ADC_SPEEDHH 0X60
unsigned char vr[17],vl[14];
unsigned int V1,V3;
void InitADC();
void Delay(WORD n);
WORD GetADCResult(BYTE ch);
void DisplayADCResult(int num);
void DisplayTemperature(int num);
unsigned char temp;
char qian=0,bai=0,shi=0,ge=0;
BYTE ly_dis[4];//定义显示缓冲区
unsigned int AD_get(unsigned char channel)
{
ADC_CONTR=0x88|channel; //开启AD转换1000 1000 即POWER SPEED1 SPEED0 ADC_FLAG ADC_START CHS2 CHS1 CHS0
_nop_(); _nop_(); _nop_(); _nop_();//要经过4个CPU时钟的延时,其值才能够保证被设置进ADC_CONTR 寄存器
while(!(ADC_CONTR&0x10)); //等待转换完成
ADC_CONTR&=0xe7; //关闭AD转换,ADC_FLAG位由软件清0
return(ADC_RES*4+ADC_RESL); //返回AD转换完成的10位数据(16进制)
}
float AD_work(unsigned char channel)
{
float AD_val; //定义处理后的数值AD_val为浮点数
unsigned char i;
for(i=0;i<10;i++)
AD_val+=AD_get(channel); //转换10次求平均值(提高精度)
AD_val/=10;
AD_val=(AD_val*5)/1024; //AD的参考电压是单片机上的5v,所以乘5即为实际电压值
return AD_val;
}
void UsartConfiguration() //工作方式一 计数器工作方式2 波特率4800
{
SCON=0X50;
TMOD=0X20;
PCON=0X80;
TH1=0XF3;
TL1=0XF3;
TR1=1;
}
void chuankou_send(int num);//串口初始化 不加int型参数串口不好用
void main()
{
WORD i=0;
float tt;
int ltemp;
LCDInit();
UsartConfiguration();
DisplayListChar(0, 0, "Temp:");
while(1)
{
if(i==0)
tmpchange(); //温度转换
if(i==100)
{
tt=tmp()*0.0625; //得到真实十进制温度值,因为DS18B20
//可以精确到0.0625度,所以读回数据的最低位代表的是0.0625度。
ltemp=tt*10+0.5; //放大十倍,这样做的目的将小数点后第一位也转换为可显示数字,同时进行一个四舍五入操作。
if(ltemp<0)
{ //判断第一位显示整数还是负号
ly_dis[0]=0xbf;
ltemp=0-ltemp;
}
else
ly_dis[0]=ltemp/1000;//显示百位值
ltemp=ltemp%1000;
ly_dis[1]=ltemp/100; //显示温度十位值
ltemp=ltemp%100;
ly_dis[2]=ltemp/10; //显示温度个位值
ly_dis[3]=ltemp%10; //显示小数点后一位
}
i++;
if(i==150)
{
DisplayADCResult(0);
i=0;
}
DisplayTemperature(6); //调用显示
// chuankou_send(0);
}
}
void DisplayADCResult(int num)
{
V1=AD_work(6)*10000; //采集上电位器的AD数据,保留4位小数
V3=AD_work(5)*10000; //采集下电位器的AD数据,保留4位小数
vr[7]=V1%10+'0'; vr[6]=V1/10%10+'0'; vr[5]=V1/100%10+'0';
vr[4]=V1/1000%10+'0'; vr[3]='.'; vr[2]=V1/10000%10+'0';
vr[1]=':'; vr[0]='X';
vr[16]=V3%10+'0'; vr[15]=V3/10%10+'0'; vr[14]=V3/100%10+'0';
vr[13]=V3/1000%10+'0'; vr[12]='.'; vr[11]=V3/10000%10+'0';
vr[10]=':'; vr[9]='S'; vr[8]=' ';
//DisplayOneChar(0,1,vr[0]);
DisplayOneChar(1,1,vr[1]);
// SBUF=vr[1];
// while(!TI);
// TI=0;
DisplayOneChar(2,1,vr[2]);
// SBUF=vr[2];
// while(!TI);
// TI=0;
DisplayOneChar(3,1,vr[3]);
// SBUF=vr[3];
// while(!TI);
// TI=0;
DisplayOneChar(4,1,vr[4]);
// SBUF=vr[4];
// while(!TI);
// TI=0;
DisplayOneChar(5,1,vr[5]);
// SBUF=vr[5];
// while(!TI);
// TI=0;
DisplayOneChar(6,1,vr[6]);
// SBUF=vr[6];
// while(!TI);
// TI=0;
DisplayOneChar(7,1,vr[7]);
// SBUF=vr[7];
// while(!TI);
// TI=0;
DisplayOneChar(8,1,vr[9]);
// SBUF=vr[9];
// while(!TI);
// TI=0;
DisplayOneChar(9,1,vr[10]);
// SBUF=vr[10];
// while(!TI);
// TI=0;
DisplayOneChar(10,1,vr[11]);
// SBUF=vr[11];
// while(!TI);
// TI=0;
DisplayOneChar(11,1,vr[12]);
// SBUF=vr[12];
// while(!TI);
// TI=0;
DisplayOneChar(12,1,vr[13]);
// SBUF=vr[13];
// while(!TI);
// TI=0;
DisplayOneChar(13,1,vr[14]);
// SBUF=vr[14];
// while(!TI);
// TI=0;
DisplayOneChar(14,1,vr[15]);
// SBUF=vr[15];
// while(!TI);
// TI=0;
DisplayOneChar(15,1,vr[16]);
// SBUF=vr[16];
// while(!TI);
// TI=0;
DisplayOneChar(16,1,vr[0]);
// SBUF=vr[0];
// while(!TI);
// TI=0;
//DisplayOneChar();
// qian=GetADCResult(Channel)/1000;
// bai=GetADCResult(Channel)%1000/100;
// shi=GetADCResult(Channel)%1000%100/10;
// ge=GetADCResult(Channel)%10;
// if(0==qian)
// DisplayOneChar(5,1,' ');
// else
// DisplayOneChar(5,1,table[qian]);
//
// if(0==bai&&0==qian)
// DisplayOneChar(6,1,' ');
// else
// DisplayOneChar(6,1,table[bai]);
//
// DisplayOneChar(7,1,table[shi]);
// DisplayOneChar(8,1,table[ge]);
//
// DisplayOneChar(9, 1, 'v');
//
}
void DisplayTemperature(int num) //温度加串口
{
if(0==ly_dis[0])
DisplayOneChar(5, 0, ' ');
else
DisplayOneChar(5, 0, table[ly_dis[0]]);
SBUF='T';
while(!TI);
TI=0;
SBUF=':';
while(!TI);
TI=0;
DisplayOneChar(6, 0, table[ly_dis[1]]);
SBUF=table[ly_dis[1]];
while(!TI);
TI=0;
DisplayOneChar(7, 0, table[ly_dis[2]]);
SBUF=table[ly_dis[2]];
while(!TI);
TI=0;
DisplayOneChar(8, 0,'.');
SBUF='.';
while(!TI);
TI=0;
DisplayOneChar(9, 0, table[ly_dis[3]]);
SBUF=table[ly_dis[3]];
while(!TI);
TI=0;
DisplayOneChar(10, 0, 0xdf);
DisplayOneChar(11, 0, 'C');
SBUF=' ';
while(!TI);
TI=0;
SBUF='\n';
while(!TI);
TI=0;
// Delay(2); //延时后刷新数据过慢 所以注释掉
}
WORD GetADCResult(BYTE ch)
{
ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ch|ADC_START;
_nop_();
_nop_();
_nop_();
_nop_();
while(!(ADC_CONTR&ADC_FLAG));
ADC_CONTR&=~ADC_FLAG;
return ADC_RES*4+ADC_LOW2;
}
void InitADC()
{
P1ASF = 0XFF;
ADC_RES = 0;
ADC_CONTR = ADC_POWER|ADC_SPEEDLL;
Delay(2);
}
void Delay(WORD t)
{
WORD x;
while(t--)
{
x = 5000;
while(x--);
}
}
//void chuankou_send(int num) 不好用
//{
// SBUF='T';
// while(!TI);
// TI=0;
// SBUF=':';
// while(!TI);
// TI=0;
// SBUF=table[ly_dis[1]];
// while(!TI);
// TI=0;
// SBUF=table[ly_dis[2]];
// while(!TI);
// TI=0;
// SBUF='.';
// while(!TI);
// TI=0;
// SBUF=table[ly_dis[3]];
// while(!TI);
// TI=0;
//// SBUF=vr[1];
//// while(!TI);
//// TI=0;
//// SBUF=vr[2];
//// while(!TI);
//// TI=0;
//// SBUF=vr[3];
//// while(!TI);
//// TI=0;
//// SBUF=vr[4];
//// while(!TI);
//// TI=0;
//// SBUF=vr[5];
//// while(!TI);
//// TI=0;
//// SBUF=vr[6];
//// while(!TI);
//// TI=0;
//// SBUF=vr[7];
//// while(!TI);
//// TI=0;
//// SBUF=vr[8];
//// while(!TI);
//// TI=0;
//// SBUF='S';
//// while(!TI);
//// TI=0;
//// SBUF=vr[10];
//// while(!TI);
//// TI=0;
//// SBUF=vr[11];
//// while(!TI);
//// TI=0;
//// SBUF=vr[12];
//// while(!TI);
//// TI=0;
//// SBUF=vr[13];
//// while(!TI);
//// TI=0;
//// SBUF=vr[14];
//// while(!TI);
//// TI=0;
//// SBUF=vr[15];
//// while(!TI);
//// TI=0;
//// SBUF=vr[16];
//// while(!TI);
//// TI=0;
//// SBUF=vr[0];
//// while(!TI);
//// TI=0;
// SBUF='\n';
// while(!TI);
// TI=0;
// Delay(2);
//}
作者:
东木和孟婆
时间:
2016-5-4 14:27
sbit LCD_RS=P2^6;//定义引脚
sbit LCD_RW=P2^5;
sbit LCD_E=P2^7;
#define LCD_Data P0
/********宏定义***********************************************************/
#define Busy 0x80 //用于检测LCD状态字中的Busy标识
/********数据定义*************************************************************/
code BYTE table[]={48,49,50,51,52,53,54,55,56,57}; //0_9 ascii码的数字
/********函数声明*************************************************************/
void WriteDataLCD(BYTE WR_DATA); //写数据
void WriteCommandLCD(BYTE WCLCD); //写命令
void WriteCommandLCD1(BYTE WCLCD); //写命令
void busy_check(void); //读状态
void LCDInit(void); //初始化
void DisplayOneChar(BYTE X, BYTE Y, BYTE DData); //相应坐标显示字节内容
void DisplayListChar(BYTE X, BYTE Y, BYTE code *DData); //相应坐标开始显示一串内容
//void delay1MS(uint t)
//{
// uint i,j;
// for(i=0;i<t;i++)
// for(j=0;j<935;j++);
//}
/*初始化*/
void LCDInit(void)
{
WriteCommandLCD(0x38);//不检测忙信号
WriteCommandLCD(0x08); //关闭显示
WriteCommandLCD(0x01); //显示清屏
WriteCommandLCD(0x06); //显示光标移动设置
WriteCommandLCD(0x0C); //显示开及光标设置
}
/*按指定位置显示一串字符*/
void DisplayListChar(BYTE X, BYTE Y, BYTE code *DData)
{
BYTE ListLength;
ListLength = 0;
X &= 0xF;
Y &= 0x1; //限制X不能大于15,Y不能大于1
while (DData[ListLength]>=0x20)
{ //若到达字串尾则退出
if (X <= 0xF){ //X坐标应小于0xF
DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
ListLength++;
X++;
}
}
}
/*按指定位置显示一个字符*/
void DisplayOneChar(BYTE X, BYTE Y, BYTE DData)
{
X &= 0xF;
Y &= 0x1; //限制X不能大于15,Y不能大于1
if (Y)
X |= 0x40; //当要显示第二行时地址码+0x40;
X |= 0x80; //算出指令码
WriteCommandLCD(X); //发送地址码
WriteDataLCD(DData);
}
/***********写指令********************************************************/
void WriteCommandLCD(BYTE WCLCD)
{
busy_check();
LCD_Data = WCLCD;
LCD_RS = 0;
LCD_RW = 0;
LCD_E = 1;
LCD_E = 0;
}
/***********写数据********************************************************/
void WriteDataLCD(BYTE WR_DATA)
{
busy_check(); //检测忙
LCD_Data = WR_DATA;
LCD_RS = 1;
LCD_RW = 0;
LCD_E = 1;
LCD_E = 0;
}
//检测忙信号
void busy_check(void)
{
LCD_Data = 0xFF;
LCD_E = 0;
LCD_RS = 0;
LCD_RW = 1;
LCD_E = 1;
while (LCD_Data & Busy);
LCD_E = 0;
}
作者:
东木和孟婆
时间:
2016-5-4 14:28
/********IO引脚定义***********************************************************/
sbit DS=P2^4; //定义DS18B20接口
/*************延时子函数 *******************************************/
void delayb(WORD count)
{
WORD i;
while(count)
{
i=200;
while(i>0)
i--;
count--;
}
}
/*************DS18B20初始化*******************************************/
void dsreset(void)
{
WORD i;
DS=0;
// i=103;
i=1000;
while(i>0)i--;
DS=1;
// i=4;
i=40;
while(i>0)i--;
}
/*************读一位*************************************************/
bit tmpreadbit(void)
{
WORD i;
bit dat;
DS=0;
i++; //小延时一下
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
DS=1;
i++;i++;
dat=DS;
// i=8;
i=96;
while(i>0)i--;
return (dat);
}
/*************读一个字节*************************************************/
BYTE tmpread(void)
{
BYTE i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tmpreadbit();
dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好//一个字节在DAT里
}
return(dat); //将一个字节数据返回
}
/*************写一个字节*************************************************/
void tmpwritebyte(BYTE dat)
{
WORD i;
BYTE j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) // 写1部分
{
DS=0;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
DS=1;
// i=8;
i=96;
while(i>0)i--;
}
else
{
DS=0; //写0部分
// i=8;
i=96;
while(i>0)i--;
DS=1;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
i++;i++;
}
}
}
/***********发送温度转换命令***********************************************/
void tmpchange(void)
{
dsreset(); //初始化DS18B20
delayb(1); //延时
tmpwritebyte(0xcc); // 跳过序列号命令
tmpwritebyte(0x44); //发送温度转换命令
}
/***********获得温度*******************************************************/
int tmp()
{
int temp;
BYTE a,b;
dsreset();
delayb(1);
tmpwritebyte(0xcc);
tmpwritebyte(0xbe); //发送读取数据命令
a=tmpread(); //连续读两个字节数据
b=tmpread();
temp=b;
temp<<=8;
temp=temp|a; //两字节合成一个整型变量。
return temp; //返回温度值
}
作者:
chen。chen
时间:
2016-5-5 09:28
cjjcjj1 发表于 2016-5-4 10:47
你好!温度传感器是18B20吗?原理图有了吗?显示是液晶还是数码管?程序可以完成
显示是在PC机的LabVIEW软件里显示的
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1