找回密码
 立即注册

QQ登录

只需一步,快速开始

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

新人求助~~温度传感器跟单片机的连接和单片机与PC机的连接

[复制链接]
跳转到指定楼层
楼主
ID:118291 发表于 2016-5-4 09:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本人正在做温度检测系统,现在需要温度传感器和单片机连接中的AD转换模块和单片机与PC机连接时的串口通讯模块的C语言程序,哪位大神能帮帮忙?万分感谢~
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:82765 发表于 2016-5-4 10:47 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

板凳
ID:117677 发表于 2016-5-4 14:25 | 只看该作者
我有那个程序 好使的

回复

使用道具 举报

地板
ID:117677 发表于 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);
//}
回复

使用道具 举报

5#
ID:117677 发表于 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;
}


回复

使用道具 举报

6#
ID:117677 发表于 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;     //返回温度值

}

回复

使用道具 举报

7#
ID:118291 发表于 2016-5-5 09:28 | 只看该作者
cjjcjj1 发表于 2016-5-4 10:47
你好!温度传感器是18B20吗?原理图有了吗?显示是液晶还是数码管?程序可以完成

显示是在PC机的LabVIEW软件里显示的
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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