急!用STC12C5A60S2同时测温度(DS18B20)和电压(内部AD转换)会出现错误?)

C语言 码拜 8年前 (2017-05-05) 1943次浏览
问题描述:用STC12C5A60S2(LCD1602显示)单独测温度(DS18B20)OK;用STC12C5A60S2(LCD1602显示)测电压OK;但是,当用STC12C5A60S2同时测温度(DS18B20)和电压时电压显示会出现错误
图片传不上去,本人大致说一下,单独显示温度和电压都正常,同时测量温度和电压时温度显示正常,电压显示不正常(烧录后第一次正常,后来变为0.0/)。显示温度和电压输入的引脚并没有复用,不知为什么电压值读不出来。
主要部分代码:

#include <STC12C5A60S2.H>
#include "temp.h"
#include "uart.h"
#include "lcd1602.h"
#include "adc_12c5a.h"
sbit RS485E=P2^0;   //定义485的使能脚
#define uchar unsigned char
#define uint  unsigned int
uchar code Text[10]={"0","1","2","3","4","5","6","7","8","9"};//十进制数组
uchar code Text1[]={" "};//空格
uchar code Text2[]={"."};////小数点
//用来存放要显示的8位数的值
int SendData,volt;
uchar symbol;
//--声明全局函数--//
void Lcd_ReadTemp(int);
void Display();
/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void main()
{
    uchar u1,u2,u3;
    UsartConfiguration();
    AD_init();  
    lcd_config();
    while(1)
	{
      Lcd_ReadTemp(ReadTemp());
      volt=AD_work(7)*100+0.5;//转化为三位整数
      Display();
       }
}
/*******************************************************************************
* 函 数 名         : ReadTemp()
* 函数功能		   : 读取温度
* 输    入         : v
* 输    出         : 无
*******************************************************************************/
void Lcd_ReadTemp(int temp) 	 
{
   	float tp;  
	if(temp< 0)				//当温度值为负数
  	{
        symbol=1;
        temp=temp-1;//原因是读取的温度是实际温度的补码,所以减1,再取反求出原码
		temp=~temp;
		tp=temp;
		temp=tp*0.0625*100+0.5;
  	}
 	else
  	{
		tp=temp;//原因是数据处理有小数点所以将温度赋给一个浮点型变量
		//假如温度是正的那么,那么正数的原码就是补码它本身
		temp=tp*0.0625*100+0.5;
	}
    SendData=temp % 10000 / 10;
}
/*******************************************************************************
* 函 数 名         : Display()
* 函数功能		   : LCD显示温度、电压
* 输    入         : v
* 输    出         : 无
*******************************************************************************/
void Display()
{
    lcd_writecom(0x80);//写入地址位置,0x80第一行,0xc0第二行
    lcdwritedat("T");//TEMP
    lcdwritedat("E");
    lcdwritedat("M");
    lcdwritedat("P");
    lcdwritedat(":");
    if(symbol)
        lcdwritedat("-");  
    if((SendData / 100)>0)
        lcdwritedat("0"+SendData / 100);
    lcdwritedat("0"+SendData % 100 /10); 
    lcdwritedat(".");
    lcdwritedat("0"+SendData % 10); 
    lcdwritedat(0xdf);
    lcdwritedat(0x43);
    
    lcd_writecom(0xc0);//写入地址位置,0x80第一行,0xc0第二行
    lcdwritedat("V");//VOLT
    lcdwritedat("O");
    lcdwritedat("L");
    lcdwritedat("T");
    lcdwritedat(":");
    lcdwritedat("0"+ volt / 100);
    lcdwritedat(".");
    lcdwritedat("0"+ volt % 100 /10); 
    lcdwritedat("0"+ volt % 10); 
    lcdwritedat("V");
}
/*adc_12c5a.c文件*/
//****************************************STC12C5A60S2 AD转换***********************************************//
#include "adc_12c5a.h" 
/*获取AD转换值*/
uint AD_get(uchar 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
    ADC_CONTR&=~0x10; 
    return(ADC_RES*4+ADC_RESL);   //返回AD转换完成的10位数据(16进制)
}
/*进行AD转换*/
float AD_work(uchar channel)
{
    float AD_val;     //定义处理后的数值AD_val为浮点数
    uchar i;
    for(i=0;i<100;i++)
        AD_val+=AD_get(channel); //转换100次求平均值(提高精度)
    AD_val/=100;
    AD_val=(AD_val*4.86)/1024; //AD的参考电压是单片机上的4.86v,所以乘4.86即为实际电压值
    return AD_val;
}
/*延时函数*/
void delay_1ms(uint a) //延时约1ms
{
    uint i;
    while (a--)
        for(i=600;i>0;i--);   //1T单片机i=600,若是12T单片机i=125
}
/*AD转换配置*/
void AD_init()
{
    P1ASF=0xff; //P1口全部作为模拟功能AD使用
    ADC_RES=0;   //清零转换结果寄存器高8位
    ADC_RESL=0; //清零转换结果寄存器低2位
    ADC_CONTR=0x80;//开启AD电源
    delay_1ms(2);   //等待1ms,让AD电源稳定
}
/*"temp.c"文件*/
//***********************************ds18b20测温度***************************************//
#include "temp.h"
void delay_18B20(uint i)
{
    while(i--);
}
 
void Init_DS18B20(void)
{
    uchar x=0;
    DQ = 1;          //DQ复位
    delay_18B20(80); //稍做延时
    DQ = 0;          //单片机将DQ拉低
    delay_18B20(800); //精确延时 大于 480us
    DQ = 1;          //拉高总线
    delay_18B20(140);
    x=DQ;  
    delay_18B20(200);
}
 
uchar ReadOneChar(void)
{
    uchar i=0;
    uchar dat = 0;
    for (i=8;i>0;i--)
    {
        DQ = 0; // 给脉冲信号
        dat>>=1;
        DQ = 1; // 给脉冲信号
        if(DQ)
        dat|=0x80;
        delay_18B20(40);     //40
    }
   return(dat);
}
 
void WriteOneChar(uchar dat)
{
   uchar i=0;
   for (i=8; i>0; i--)
   {
    DQ = 0;
    DQ = dat&0x01;
    delay_18B20(50); //50
    DQ = 1;
    dat>>=1;
    }
}
uint ReadTemp(void)
{
    uchar a=0;
    uchar b=0;
    uint temp_value=0;
    Init_DS18B20();
    WriteOneChar(0xCC);    
    WriteOneChar(0x44); 
    delay_18B20(1000);     
    Init_DS18B20();
    WriteOneChar(0xCC); 
    WriteOneChar(0xBE); 
    delay_18B20(1000);
    a=ReadOneChar();    //读取温度值低位
    b=ReadOneChar();      //读取温度值高位
    temp_value = b<<8;
    temp_value |= a;
    return temp_value;
       
}
/*附上两个.h文件*/
#ifndef __LCD1602_H_
#define __LCD1602_H_
//--重定义关键词--//
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint 
#define uint unsigned int
#endif
#define LCD_DAT P0
sbit LCD_EN=P2^7;
sbit LCD_WR=P2^5;
sbit LCD_RS=P2^6;
void lcd_writecom(uchar com);/*lcd1602写入指令*/
void lcdwritedat(uchar dat);/*lcd1602写入数据*/
void lcd_config();/*lcd1602配置初始化*/
#endif
#ifndef __ADC_12C5A_H_
#define __ADC_12C5A_H_
#include <STC12C5A60S2.H>
#include "intrins.h"
//--重定义关键词--//
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint 
#define uint unsigned int
#endif
//--声明全局函数--//
void AD_init();
void delay_1ms(uint a);
float AD_work(uchar channel);
uint AD_get(uchar channel);
#endif

其中lcd1602的配置文件省略可以不用看,没什么问题。
ds18b20的数据输出接P3^7/WR,输入电压接的是P1^7/ADC7。是程序的问题还是引脚复用的冲突还是。?
请各位高手帮看看怎么回事,跪谢!

解决方案

100

个人经验:delay或sleep的时间加大再试试。

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明急!用STC12C5A60S2同时测温度(DS18B20)和电压(内部AD转换)会出现错误?)
喜欢 (0)
[1034331897@qq.com]
分享 (0)