问题描述:用STC12C5A60S2(LCD1602显示)单独测温度(DS18B20)OK;用STC12C5A60S2(LCD1602显示)测电压OK;但是,当用STC12C5A60S2同时测温度(DS18B20)和电压时电压显示会出现错误。
图片传不上去,本人大致说一下,单独显示温度和电压都正常,同时测量温度和电压时温度显示正常,电压显示不正常(烧录后第一次正常,后来变为0.0/)。显示温度和电压输入的引脚并没有复用,不知为什么电压值读不出来。
主要部分代码:
图片传不上去,本人大致说一下,单独显示温度和电压都正常,同时测量温度和电压时温度显示正常,电压显示不正常(烧录后第一次正常,后来变为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的时间加大再试试。