博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
炎炎夏日需要一个清凉的地 - 自制水冷系统(十一 指尖的思绪之程序篇)
阅读量:5127 次
发布时间:2019-06-13

本文共 21435 字,大约阅读时间需要 71 分钟。

前段时间接手了一个项目,所以DIY的进程有些停滞。实际编写的程序并没有多长时间,得益于Keil这个强大的IDE。能在第一次做51开发的时候,如此顺利的完成代码。

不多说废话了,说明下代码的具体思路。具体思路根据(八 系统设计篇)进行拆分。分为温度显示部分、指示灯、温度获取和继电器操控部分。
LEDDisplay.c            --- 温度显示模块
PilotLamp.c             --- 指示灯控制模块
Temperature.c
12b20Temperature.asm    --- 温度读取模块
Relays.c                --- 继电器控制部分
系统主要控制的指数
1、读取温度的间隔时间
2、在调整温度的时候显示制冷控制温度时间。
3、当达到制冷温度设定值时,关闭或开启控制器一个缓冲量。防止在阀值的时候出现上下跳变问题。
4、控制调整温度的调节范围和调节量
开发中的主要阻力还是来至于温控IC。18B20的时序操作非常严格。如果要自己写调试太耗时间。因此直接从前辈取材,汇编是控制时序是最精确的,在网上找到的很多代码基本也是以汇编为主。我的代码是从杜洋老师已调整好读写时序的汇编代码改编而来。做了些小改动,把温度的精度提高到0.06°C。
另外一个让人抓狂的问题,没能找到根源解决。汇编和C混合开发中,变量的存储地址出现混乱。主程序部分的变量被汇编中的地址操作覆写,导致变量值被冲掉。不知道动了哪根筋,原来木问题后来才有这个问题。  -_-!!哭啊~~ 只能用一个方式规避这个问题,把被覆写变量的地址改为bdata段地址。修改后暂未发现程序中其他变量被覆写的问题。

调试中的效果图

 

贴出第一次写51代码^^。只是软硬结合的这种模式属于第一个。

----------------

DoubleCooling.c
1 #include 
2 3 #include "Pins.h" 4 #include "LEDDisplay.h" 5 #include "Temperature.h" 6 #include "Relays.h" 7 #include "PilotLamp.h" 8 9 #define uchar unsigned char 10 #define uint unsigned int 11 12 // 获取温度的时间间隔 13 #define TEMPGETCOUNT 5000 // 温度读取间隔, 500ms 读一次温度,即1秒读2次温度。 14 #define CHANGINGCOUNT 20000 // 温度调控状态时会显示调控温度值,最长显示时间。 15 #define CRITICALCOUNTDOWN 5 // 温度下临界跳变阀值 16 #define CRITICALCOUNTUP 5 // 温度上临界跳变阀值 17 #define CRITICALCOUNTERR 3 // 温度错误,3次关闭 18 #define DEFAULTCRITICALTEMP 2500 // 默认跳变温度 25°C 19 #define VALIDTEMPERATURE_MAX 3000 // 最大有效温度 30°C 20 #define VALIDTEMPERATURE_MIN 2000 // 最小有效温度 20°C 21 #define TEMPERATURESPET 50 // 0.5 °C 温度调整步长 22 23 24 #define COOL_POWERALL 0xFF // 全力运行 25 #define COOL_MALAISE 0x00 // 萎靡~~~~~ 哇咔咔~~~ 26 27 #define KEYPRESS_LONG 200 // 按键长按计数,如一只按住不放 28 #define KEYPRESS_SHORT 15 // 短按计数 29 30 31 #define FOSC 1843200L 32 #define T1MS (65536-FOSC/12/1000) // 计时器工作频率 12T状态 33 34 35 uint CriticalTempVal; // 临界温度,跳变温度 36 uint RealTempVal; // 当前温度,获取一定次数时都 37 uint ChangeCount; // 临界切换计数 38 39 uchar RelayVal; // 继电器状态控制位 从右到左 0x03(0000 0011) 那么第一第二个继电器打开。 40 // 指示灯状态 41 // 第一位 继电器工作状态,灯亮工作状态,灯灭停止制冷 42 // 第二位 是否为自动模式 43 // 第三位 温控器故障 44 // 0000 0111 45 uchar DirectLamp; 46 uchar bdata WorkStatus; 47 sbit InCritical = WorkStatus ^ 0; // 临界状态 48 sbit InWorking = WorkStatus ^ 1; // 工作状态 49 sbit InAuto = WorkStatus ^ 2; // 自动模式 50 sbit InHandOn = WorkStatus ^ 3; // 手动打开状态 51 sbit CanReadTemp = WorkStatus ^ 4; // 是否允许读取温度 52 sbit InInitTemp = WorkStatus ^ 5; // 温度读取是否在初始状态,解决第一次读取出现85°C的问题 53 sbit InChangingTemp = WorkStatus ^ 6; // 在温度调整中 54 55 56 // 温度读取时间间隔,减少18B20的读取次数, 57 // 目的是为数码管能获得比较高的刷新频率,提高显示亮度。 58 // 每次读取会有固定占用时间,能看出每次读取会有变暗的闪烁情况。 59 uint TempTimerSpace; 60 61 uint TempChangingStatusSpace; // 温度调控状态中 62 63 void Init(void); 64 bit CanUpdateTemp(void); 65 void UpdateTemperature(void); 66 void ReadTemperature(void); 67 void UpdateStatus(void); 68 void InitTimer(void); 69 void SearchKeys(void); 70 71 unsigned int GetCriticalTemperature(void); 72 //void SaveCriticalTemperature(unsigned int); 73 74 75 // 按键 76 // 18 K3 17 K4 16 K5 77 sbit Key_Mode = P1 ^ 1; 78 sbit Key_CTDown = P1 ^ 0; 79 sbit Key_CTUp = P0 ^ 0; 80 81 //enum KeyType (TNone=0, KTMode=1, KTCTDown=2, KTCTUp=4); 82 83 uchar KeyCount; 84 uchar KeyTypeVal; 85 86 #define KEYTYPE_NONE 0 // 没有按键使用 87 #define KEYTYPE_MODE 1 // 按下模式切换状态 88 #define KEYTYPE_CTDOWN 2 // 按下温度切换状态 89 #define KEYTYPE_CTUP 4 // 按下温度切换状态 90 91 92 void main() 93 { 94 Init(); 95 while(1){ 96 if (CanReadTemp) 97 ReadTemperature(); 98 99 SearchKeys(); 100 UpdateStatus(); 101 UpdateRelays(RelayVal);102 103 if (!InChangingTemp)104 DisplayTemperature(RealTempVal);105 else 106 DisplayTemperature(CriticalTempVal);107 108 DisplayPilotLamp(DirectLamp);109 }110 }111 112 void Init(void){113 WorkStatus = 0x00;114 InAuto = 1; // 默认自动模式115 116 KeyCount = 0;117 KeyTypeVal = KEYTYPE_NONE;118 RealTempVal = DEFAULTCRITICALTEMP; 119 CriticalTempVal = GetCriticalTemperature();120 121 InitTimer();122 InitPilotLamp();123 InitView();124 InitTemperature();125 InitRealys();126 }127 128 void SearchKeys(void){129 // 模式切换130 if (Key_Mode == 0){131 KeyTypeVal = KEYTYPE_MODE;132 KeyCount++;133 }134 135 // 温控温度136 if (Key_CTDown == 0) {137 KeyTypeVal = KEYTYPE_CTDOWN;138 KeyCount ++;139 140 // 长按状态141 if (KeyCount > KEYPRESS_LONG) {142 KeyCount = 0;143 if (CriticalTempVal > VALIDTEMPERATURE_MIN) {144 TempChangingStatusSpace = CHANGINGCOUNT; 145 CriticalTempVal -= TEMPERATURESPET;146 }147 }148 }149 150 // 温控温度151 if (Key_CTUp == 0) {152 KeyTypeVal = KEYTYPE_CTUP;153 KeyCount ++;154 155 // 长按状态156 if (KeyCount > KEYPRESS_LONG) {157 KeyCount = 0;158 if (CriticalTempVal < VALIDTEMPERATURE_MAX){159 TempChangingStatusSpace = CHANGINGCOUNT; 160 CriticalTempVal += TEMPERATURESPET;161 }162 }163 }164 165 if (KeyCount > KEYPRESS_SHORT){166 if (Key_Mode == 1 && KeyTypeVal == KEYTYPE_MODE){167 KeyTypeVal = KEYTYPE_NONE;168 KeyCount = 0;169 if (InAuto){170 InAuto = 0;171 InHandOn = 1;172 }173 else {174 if (InHandOn) 175 InHandOn = 0;176 else177 InAuto = 1;178 }179 }180 181 if (Key_CTDown == 1 && KeyTypeVal == KEYTYPE_CTDOWN){182 KeyTypeVal = KEYTYPE_NONE;183 KeyCount = 0;184 if (CriticalTempVal > VALIDTEMPERATURE_MIN) {185 CriticalTempVal -= TEMPERATURESPET;186 TempChangingStatusSpace = CHANGINGCOUNT; 187 }188 }189 190 if (Key_CTUp == 1 && KeyTypeVal == KEYTYPE_CTUP){191 KeyTypeVal = KEYTYPE_NONE;192 KeyCount = 0;193 if (CriticalTempVal < VALIDTEMPERATURE_MAX) {194 TempChangingStatusSpace = CHANGINGCOUNT; 195 CriticalTempVal += TEMPERATURESPET;196 }197 }198 }199 }200 201 202 void ReadTemperature(void){203 unsigned int Val;204 205 Val = GetTemperature(); 206 207 // 18B20有个特殊问题,第一次读取会出现 85°C208 if (InInitTemp && Val == 8500){209 CanReadTemp = 1; 210 return;211 }212 213 RealTempVal = Val;214 CanReadTemp = 0;215 InInitTemp = 0;216 //217 // 对于临界温度,需要特殊处理。218 // 防止温控在临界时频繁跳变,当在临界一侧温度超缓冲量时才允许跳转模式。219 // 当温控探头无效时优先处理220 //221 // 如果温控探头被拔出,再次插入的时候会出现 85°C的错误情况222 // 只要温度读取错误,那么就认为温控探头是被拔出状态。223 //224 if (RealTempVal == VAL_ERRTEMPERATURE){225 InInitTemp = 1;226 if (InCritical)227 ChangeCount--;228 else {229 InCritical = 1;230 ChangeCount = CRITICALCOUNTERR;231 }232 }233 else if (InWorking) {234 if (RealTempVal < CriticalTempVal){235 if (InCritical)236 ChangeCount--;237 else {238 InCritical = 1;239 ChangeCount = CRITICALCOUNTDOWN;240 }241 }242 else {243 InCritical = 0;244 ChangeCount = 0;245 }246 }247 else {248 if (RealTempVal > CriticalTempVal){249 if (InCritical)250 ChangeCount --;251 else {252 InCritical = 1;253 ChangeCount = CRITICALCOUNTUP;254 }255 }256 else {257 InCritical = 0;258 ChangeCount = 0;259 }260 }261 262 }263 264 265 void InitTimer(void){266 // 使用定时器1作为时间计数267 TMOD = 0x01; 268 TL0 = T1MS;269 TH0 = T1MS >> 8; 270 TR0 = 1; 271 ET0 = 1; 272 EA = 1; 273 274 CanReadTemp = 0;275 TempTimerSpace = TEMPGETCOUNT; // 第一次温度读取276 InInitTemp = 1; // 温度处于初始状态,解决85°C问题277 TempChangingStatusSpace = 0; // 不在调温状态278 }279 280 281 void UpdateStatus(void){282 //283 // 温控临界跳变, 缓冲计数为零时跳变284 // 285 // 286 if (InCritical && !ChangeCount){287 InCritical = 0;288 if ((RealTempVal != VAL_ERRTEMPERATURE) && (RealTempVal > CriticalTempVal))289 InWorking = 1;290 else 291 InWorking = 0; 292 }293 294 // 是否在调温状态295 if (TempChangingStatusSpace) 296 InChangingTemp = 1;297 else 298 InChangingTemp = 0;299 300 // 301 // 温控状态和手工状态302 // 温控状态时根据是否工作状态判断,手动模式下通过是否强行开启判断继电器模式303 // 304 if((InAuto && InWorking) || (!InAuto && InHandOn)) 305 RelayVal = COOL_POWERALL; 306 else307 RelayVal = COOL_MALAISE; 308 309 // 工作状态信息更新310 311 if (RelayVal > 0)312 DirectLamp = 1;313 else314 DirectLamp = 0;315 316 if (InAuto)317 DirectLamp |= 0x02; 318 }319 320 321 unsigned int GetCriticalTemperature(void){322 //todo : 这里的值需要从EEPROM中获取323 return (DEFAULTCRITICALTEMP);324 }325 /*326 void SaveCriticalTemperature(unsigned int Val){327 //todo : 保存临界温度到EEPROM,防止停电丢失数据 328 }329 */330 331 void time0(void) interrupt 1{332 // 时钟333 TL0 = T1MS;334 TH0 = T1MS >> 8; 335 TempTimerSpace--;336 if (!TempTimerSpace){337 CanReadTemp = 1;338 TempTimerSpace = TEMPGETCOUNT;339 }340 341 if (TempChangingStatusSpace) 342 TempChangingStatusSpace--;343 }
LEDDisplay.c
1 #include 
2 3 #include "LEDDisplay.h" 4 #include "Temperature.h" 5 #include "Pins.h" 6 7 8 #define Delay_REF 12 //设置每一个点显示的时间长度(1~20) 9 #define LED_PWDDEFAULT 9 // LED的调光值 1~9 10 11 #define DT_P2M0SET 0x00 // 0000 0000 12 #define DT_P2M1SET 0x00 // 0000 0000 13 #define DT_P0M0SET 0xf0 // 1111 0000 14 #define DT_P0M1SET 0x00 // 0000 0000 15 16 17 // 数码管 18 // 12 ~ 9 19 sbit DT_COM1 = P0 ^ 4; 20 sbit DT_COM2 = P0 ^ 5; 21 sbit DT_COM3 = P0 ^ 6; 22 sbit DT_COM4 = P0 ^ 7; 23 // 8 ~ 1 24 sbit DT_DpyA = P2 ^ 0; 25 sbit DT_DpyB = P2 ^ 1; 26 sbit DT_DpyC = P2 ^ 2; 27 sbit DT_DpyD = P2 ^ 3; 28 sbit DT_DpyE = P2 ^ 4; 29 sbit DT_DpyF = P2 ^ 5; 30 sbit DT_DpyG = P2 ^ 6; 31 sbit DT_DpyDP = P2 ^ 7; 32 sfr DT_Dpy = 0xA0; // P2 33 34 35 void Delay (unsigned int); 36 void Dis_Off (void); 37 void displayHH1 (unsigned char); 38 void displayHH2 (unsigned char); 39 void displayHH3 (unsigned char); 40 void displayHH4 (unsigned char); 41 42 43 44 data unsigned char Led_PWM; // 调光 1 ~ 9 45 46 unsigned char code NumData[]={ 47 //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, (None) E, R 48 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, 0x00, 0x79, 0x77 49 }; 50 unsigned int Sec = 0; 51 52 53 void InitView(void){ 54 P0M0 = DT_P0M0SET; 55 P0M1 = DT_P0M1SET; 56 P2M0 = DT_P2M0SET; 57 P2M1 = DT_P2M1SET; 58 //Dis_Off(); 59 Led_PWM = LED_PWDDEFAULT; 60 } 61 62 void DisplayTemperature(unsigned int t){ 63 // 无效温度显示 ERR 字样 64 if (t != VAL_ERRTEMPERATURE){ 65 displayHH4(NumData[t / 1000]); 66 displayHH3(NumData[t / 100 % 10] + 0x80); 67 displayHH2(NumData[t / 10 % 10]); 68 displayHH1(NumData[t % 10]); 69 } 70 else { 71 // 无效温度显示 ERR 字样 72 //displayHH4(NumData[10]); 73 displayHH3(NumData[11]); 74 displayHH2(NumData[12]); 75 displayHH1(NumData[12]); 76 } 77 } 78 79 80 81 void Delay (unsigned int count){ 82 unsigned int i; 83 while( count-- != 0){ 84 for(i = 0; i < Delay_REF; i++); 85 } 86 } 87 88 void Dis_Off (void){ 89 DT_COM1 = 0; 90 DT_COM2 = 0; 91 DT_COM3 = 0; 92 DT_COM4 = 0; 93 94 DT_Dpy = 0xFF; 95 /* 96 DT_DpyA = 1; 97 DT_DpyB = 1; 98 DT_DpyC = 1; 99 DT_DpyD = 1;100 DT_DpyE = 1;101 DT_DpyF = 1;102 DT_DpyG = 1;103 DT_DpyG = 1;104 */105 Delay(10-Led_PWM); 106 }107 108 void displayHH1 (unsigned char d){ 109 if(d & 0x01){110 DT_COM1 = 1;DT_DpyA = 0;} Delay(Led_PWM); Dis_Off();111 112 if(d & 0x02){113 DT_COM1 = 1;DT_DpyB = 0;} Delay(Led_PWM); Dis_Off();114 115 if(d & 0x04){116 DT_COM1 = 1;DT_DpyC = 0;} Delay(Led_PWM); Dis_Off();117 118 if(d & 0x08){119 DT_COM1 = 1;DT_DpyD = 0;}Delay(Led_PWM);Dis_Off();120 121 if(d & 0x10){122 DT_COM1 = 1;DT_DpyE = 0;}Delay(Led_PWM);Dis_Off();123 124 if(d & 0x20){125 DT_COM1 = 1;DT_DpyF = 0;}Delay(Led_PWM);Dis_Off();126 127 if(d & 0x40){128 DT_COM1 = 1;DT_DpyG = 0;}Delay(Led_PWM);Dis_Off();129 130 if(d & 0x80){131 DT_COM1 = 1;DT_DpyDP = 0;}Delay(Led_PWM);Dis_Off();132 } 133 134 void displayHH2 (unsigned char d){135 if(d & 0x01){136 DT_COM2 = 1;DT_DpyA = 0;}Delay(Led_PWM);Dis_Off();137 138 if(d & 0x02){139 DT_COM2 = 1;DT_DpyB = 0;}Delay(Led_PWM);Dis_Off();140 141 if(d & 0x04){142 DT_COM2 = 1;DT_DpyC = 0;}Delay(Led_PWM);Dis_Off();143 144 if(d & 0x08){145 DT_COM2 = 1;DT_DpyD = 0;}Delay(Led_PWM);Dis_Off();146 147 if(d & 0x10){148 DT_COM2 = 1;DT_DpyE = 0;}Delay(Led_PWM);Dis_Off();149 150 if(d & 0x20){151 DT_COM2 = 1;DT_DpyF = 0;}Delay(Led_PWM);Dis_Off();152 153 if(d & 0x40){154 DT_COM2 = 1;DT_DpyG = 0;}Delay(Led_PWM);Dis_Off();155 156 if(d & 0x80){157 DT_COM2 = 1;DT_DpyDP = 0;}Delay(Led_PWM);Dis_Off();158 } 159 160 void displayHH3 (unsigned char d){161 if(d & 0x01){162 DT_COM3 = 1;DT_DpyA = 0;}Delay(Led_PWM);Dis_Off();163 164 if(d & 0x02){165 DT_COM3 = 1;DT_DpyB = 0;}Delay(Led_PWM);Dis_Off();166 167 if(d & 0x04){168 DT_COM3 = 1;DT_DpyC = 0;}Delay(Led_PWM);Dis_Off();169 170 if(d & 0x08){171 DT_COM3 = 1;DT_DpyD = 0;}Delay(Led_PWM);Dis_Off();172 173 if(d & 0x10){174 DT_COM3 = 1;DT_DpyE = 0;}Delay(Led_PWM);Dis_Off();175 176 if(d & 0x20){177 DT_COM3 = 1;DT_DpyF = 0;}Delay(Led_PWM);Dis_Off();178 179 if(d & 0x40){180 DT_COM3 = 1;DT_DpyG = 0;}Delay(Led_PWM);Dis_Off();181 182 if(d & 0x80){183 DT_COM3 = 1;DT_DpyDP = 0;}Delay(Led_PWM);Dis_Off();184 } 185 186 void displayHH4 (unsigned char d){187 if(d & 0x01){188 DT_COM4 = 1;DT_DpyA = 0;}Delay(Led_PWM);Dis_Off();189 190 if(d & 0x02){191 DT_COM4 = 1;DT_DpyB = 0;}Delay(Led_PWM);Dis_Off();192 193 if(d & 0x04){194 DT_COM4 = 1;DT_DpyC = 0;}Delay(Led_PWM);Dis_Off();195 196 if(d & 0x08){197 DT_COM4 = 1;DT_DpyD = 0;}Delay(Led_PWM);Dis_Off();198 199 if(d & 0x10){200 DT_COM4 = 1;DT_DpyE = 0;}Delay(Led_PWM);Dis_Off();201 202 if(d & 0x20){203 DT_COM4 = 1;DT_DpyF = 0;}Delay(Led_PWM);Dis_Off();204 205 if(d & 0x40){206 DT_COM4 = 1;DT_DpyG = 0;}Delay(Led_PWM);Dis_Off();207 208 if(d & 0x80){209 DT_COM4 = 1;DT_DpyDP = 0;}Delay(Led_PWM);Dis_Off();210 }
PilotLamp.c
1 #include 
2 3 #include "PilotLamp.h" 4 5 // LED 指示灯 6 sbit Lamp_Work = P0 ^ 1; // 继电器工作状态亮 7 sbit Lamp_Auto = P0 ^ 2; // 温控模式 8 sbit Lamp_Hand = P0 ^ 3; // 手控模式 9 10 11 void InitPilotLamp(void){12 }13 14 void DisplayPilotLamp(unsigned char Val){15 // 指示灯状态 16 // 第一位 继电器工作状态,灯亮工作状态,灯灭停止制冷 17 // 第二位 是否为自动模式18 // 第三位 温控器故障19 if (Val & 0x01)20 Lamp_Work = 1;21 else 22 Lamp_Work = 0;23 24 if (Val & 0x02)25 Lamp_Auto = 1;26 else27 Lamp_Auto = 0;28 29 Lamp_Hand = ~Lamp_Auto;30 31 }
Relays.c
1 #include 
2 3 #include "Relays.h" 4 #include "Pins.h" 5 6 7 sbit RelayCool1 = P1 ^ 3; 8 sbit RelayCool2 = P1 ^ 4; 9 10 11 void InitRealys(void){}12 13 void UpdateRelays(unsigned char Val){14 // 例:值 0x03 (0000 0011)15 // 开启第一、第二 继电器 16 if (Val){17 RelayCool1 = 0;18 RelayCool2 = 0;19 }20 else {21 RelayCool1 = 1;22 RelayCool2 = 1;23 }24 }
18b20Temperature.asm
1 DSSP  SEGMENT  CODE    ;程序段  2   3 PUBLIC  GetTemperature      ;入口地址,跳转到DL标号处执行汇编程序  GetTemperature  4   5 RSEG  DSSP              ;程序段  6   7 IN           EQU     0CBH  ; P5.3 引脚地址  8 FLAG1     EQU   05H   ;DS18B20器件存在标志  9 TTL       EQU   07H   ;温度读出值(高位在TTL-1中,低位在TTL中) 10 ;TTL_H     EQU   06H   ;温度读出值(高位在TTL-1中,低位在TTL中) 11  12  13 ; 这是DS18B20复位初始化子程序 14 INIT_1820: 15     SETB IN 16     NOP 17     CLR IN 18     ;主机发出延时537微秒的复位低脉冲 19     MOV R1,#18;#3 20 TSR1: 21     MOV R0,#107 22     DJNZ R0,$ 23     DJNZ R1,TSR1 24     SETB IN;然后拉高数据线 25     NOP 26     NOP 27     NOP 28     NOP;12倍 29     NOP 30     NOP 31     NOP 32     NOP 33     NOP 34     NOP 35     NOP 36     NOP 37     NOP 38     NOP 39     NOP 40     NOP 41     NOP 42     NOP 43     NOP 44     NOP 45     NOP 46     NOP 47     NOP 48     NOP 49     NOP 50     NOP 51     NOP 52     NOP 53     NOP 54     NOP 55     NOP 56     NOP 57     NOP 58     NOP 59     NOP 60     NOP 61     NOP 62     NOP 63     NOP 64     MOV R0,#0DEH;#25H 65 TSR2: 66     JNB IN,TSR3;等待DS18B20回应 67     DJNZ R0,TSR2 68     LJMP TSR4 ; 延时 69 TSR3: 70     SETB FLAG1 ; 置标志位,表示DS1820存在 71     LJMP TSR5 72 TSR4: 73     CLR FLAG1 ; 清标志位,表示DS1820不存在 74     LJMP TSR7 75 TSR5: 76     MOV R7,#6 77 TSR6: 78     MOV R0,#117 79     DJNZ R0,$ ; 时序要求延时一段时间 */ 80     DJNZ R7,TSR6 ; 时序要求延时一段时间 */ 81 TSR7: 82     SETB IN 83     RET 84  85 GetTemperature:   86 DS1820PRO: 87     ;这里通过调用显示子程序实现延时一段时间,等待AD转换结束,12位的话750微秒 88     SETB IN 89     LCALL INIT_1820;先复位DS18B20 90     JB FLAG1,TSS2 91     jmp BCD33 ; 判断DS1820是否存在?若DS18B20不存在则返回 92 TSS2: 93     MOV A,#0CCH     ; 跳过ROM匹配 94     LCALL WRITE_1820 95     MOV A,#44H         ; 发出温度转换命令 96     LCALL WRITE_1820 97     CALL  DL1MS  98     SETB IN 99     LCALL INIT_1820    ;准备读温度前先复位100     MOV A,#0CCH     ; 跳过ROM匹配101     LCALL WRITE_1820102     MOV A,#0BEH     ; 发出读温度命令103     LCALL WRITE_1820104     LCALL READ_18200; 将读出的温度数据保存到35H/36H 105     106 107 BCD33: 108     JB FLAG1,BCD44109     mov R6, #080H110     mov R7,#00H111     JMP TORET112     113 BCD44:114 115       ;温度转换程序:精确到:0.06 ;116       ; 小数温度查表获取。117       MOV    DPTR,#TABB118     MOV A, TTL119       ANL A,#0FH120       MOVC A,@A+DPTR121       MOV R3, A;122       ; 整数温度转换123       MOV A,TTL124     MOV B,TTL-1125     MOV C,B.0126     RRC A127     MOV C,B.1128     RRC A129     MOV C,B.2130     RRC A131     MOV C,B.3132     RRC A133       ; 拼接整数位和小数位温度  整数*100 + 小数位值134       MOV B, #100135       MUL AB136     MOV    R4,B         ;保存积的高8位137     ADD    A,R3         ;138     MOV    R7,A139     CLR    A140     ADDC A,R4         ;加上进位,141     MOV    R6,A    142 143 144 TORET:145     RET146     147     148 ;--------------------------------写DS18B20的子程序(有具体的时序要求)149 WRITE_1820:150     MOV R2,#8;一共8位数据151     CLR C152 WR1:153     CLR IN154     MOV R3,#36;#6155     DJNZ R3,$156     RRC A157     MOV IN,C158     MOV R3,#192;#23159     DJNZ R3,$160     SETB IN161     NOP162     NOP163     NOP164     NOP165     NOP166     NOP167     NOP168     NOP169     NOP170     NOP171     NOP172     NOP173     DJNZ R2,WR1174     SETB IN175     RET176 177 ;-----------------------------读DS18B20的程序,从DS18B20中读出两个字节的温度数据 178 READ_18200:179     MOV R4,#2 ; 将温度高位和低位从DS18B20中读出180     MOV R1,#TTL ; 低位存入29H(TEMPER_L),高位存入28H(TEMPER_H)181 RE00:182     MOV R2,#8;数据一共有8位183 RE01:184     CLR C185     SETB IN186     NOP187     NOP188     NOP189     NOP190     NOP191     NOP192     NOP193     NOP194     NOP195     NOP196     NOP197     NOP198     NOP199     NOP200     NOP201     NOP202     NOP203     NOP204     NOP205     NOP206     NOP207     NOP208     NOP209     NOP210     NOP211     NOP212     CLR IN213     NOP214     NOP215     NOP216     NOP217     NOP218     NOP219     NOP220     NOP221     NOP222     NOP223     NOP224     NOP225     NOP226     NOP227     NOP228     NOP229     NOP230     NOP231     NOP232     NOP233     NOP234     NOP235     NOP236     NOP237     NOP238     NOP239     NOP240     NOP241     NOP242     NOP243     NOP244     NOP245     NOP246     NOP247     NOP248     NOP249     NOP250     NOP251     NOP252     SETB IN253     MOV R3,#54;#9254 RE10: 255     DJNZ R3,RE10256     MOV C,IN257     MOV R3,#138;#23258 RE20: 259     DJNZ R3,RE20260     RRC A261     DJNZ R2,RE01262     MOV @R1,A263     DEC R1264     DJNZ R4,RE00265     RET266 267 DL1MS:268     MOV R7,#6269 DL1MS2:270     MOV R6,#255271      DJNZ R6,$272      DJNZ R7,DL1MS2273     RET 274     275 TABB:   276     ; 小数位温度0~F的查表值,18B20的最小温控精度 0.0625, 只保留两位小数277     278     DB    00H, 06H, 0CH, 12H, 19H, 1FH, 25H, 2BH, 32H  279     DB  56H, 3EH, 44H, 4BH, 51H, 57H, 5DH 280     281 282 END

 

 

 

 

 

 

转载于:https://www.cnblogs.com/gleam/archive/2012/08/10/2631516.html

你可能感兴趣的文章
typeof与instanceof的区别
查看>>
网站搭建(一)
查看>>
SDWebImage源码解读之SDWebImageDownloaderOperation
查看>>
elastaticsearch
查看>>
postgreSQL 简单命令操作
查看>>
Spring JDBCTemplate
查看>>
Radon变换——MATLAB
查看>>
第五章笔记
查看>>
Iroha and a Grid AtCoder - 1974(思维水题)
查看>>
gzip
查看>>
转负二进制(个人模版)
查看>>
LintCode-Backpack
查看>>
查询数据库锁
查看>>
[LeetCode] Palindrome Number
查看>>
我对于脚本程序的理解——百度轻应用有感
查看>>
SQL更新某列包含XX的所有值
查看>>
网易味央第二座猪场落户江西 面积超过3300亩
查看>>
面试时被问到的问题
查看>>
spring 事务管理
查看>>
VS2008 去掉msvcr90的依赖
查看>>