8051仿真讀取18B20溫度,DS1307時鐘,顯示在1602液晶。同時每分鐘一次將溫度和電阻模擬的ADC值記入24C02 EEPROM。通過串口顯示全部數值,并每分鐘一次輸出24C02全部存儲數值。程序用MikroC8051編寫,使用了自帶的onewire和soft i2c庫。仿真串口輸出已經映射到虛擬串口1,可以用YSPD虛擬串口軟件加串口助手查看。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.png (19.9 KB, 下載次數: 53)
下載附件
2020-5-1 13:46 上傳
單片機源程序如下:
- /*
- * Project name:
- OneWire (Interfacing the DS1820 temperature sensor - all versions)
- * Copyright:
- (c) Mikroelektronika, 2013.
- * Revision History:
- 20101129:
- - initial release (SZ)
- * Description:
- This code demonstrates one-wire communication with temperature sensor
- DS18x20 connected to P3.7 pin.
- MCU reads temperature from the sensor and sends it on the UART.
- The display format of the temperature is 'xxx.xxxx癈'. To obtain correct
- results, the 18x20's temperature resolution has to be adjusted (constant
- TEMP_RESOLUTION).
- * Test configuration:
- MCU: AT89S8252
-
-
- Oscillator: External oscillator 11.0592MHz
- Ext. Modules: -
- SW: mikroC PRO for 8051
- * NOTES:
- - also, pull-up P3.7
- - UART: SW11.1 and SW11.3 - ON
- */
- extern void AT24C02_Write1Byte(char AT24C02_Address,char AT24C02_1Byte);
- extern char AT24C02_Read1Byte(char AT24C02_Address);
- extern void Display_24C02(void);
- extern unsigned char ReadADC8591(unsigned char Channel);
- unsigned char AT24C02Address = 0;
- unsigned char LightVolt; unsigned char Volt[4];
- char seconds, minutes, hours, date, month; // Global date/time variables
- unsigned int year;
- unsigned int RTCModuleAddress, YearOffset; // RTC chip description variables
- //unsigned int i;
- //#define PCF8583 // Uncomment this line if you use PCF8583 RTC chip (mE RTC extra board)
- #define DS1307 // Uncomment this line if you use DS1307 RTC chip (mE RTC2 extra board)
- // Software I2C connections
- sbit Soft_I2C_Scl at P2_0_bit;
- sbit Soft_I2C_Sda at P2_1_bit;
- // End Software I2C connections
- // Lcd module connections
- sbit LCD_RS at P2_2_bit;
- sbit LCD_EN at P2_3_bit;
- sbit LCD_D4 at P2_4_bit;
- sbit LCD_D5 at P2_5_bit;
- sbit LCD_D6 at P2_6_bit;
- sbit LCD_D7 at P2_7_bit;
- // End Lcd module connections
- // OneWire pinout
- sbit OW_Bit at P3.B7;
- // end OneWire definition
- // Set TEMP_RESOLUTION to the corresponding resolution of used DS18x20 sensor:
- // 18S20: 9 (default setting; can be 9,10,11,or 12)
- // 18B20: 12
- const unsigned short TEMP_RESOLUTION = 12;
- char *text = "000.0000";
- unsigned char temp1; unsigned char temp2;unsigned int temp;
- const char character[] = {7,5,7,0,0,0,0,0};
- void CustomChar(char pos_row, char pos_char) {
- char i;
- Lcd_Cmd(64);
- for (i = 0; i<=7; i++) Lcd_Chr_CP(character[i]);
- Lcd_Cmd(_LCD_RETURN_HOME);
- Lcd_Chr(pos_row, pos_char, 0);
- }
- void Display_Temperature(unsigned int temp2write) {
- const unsigned short RES_SHIFT =TEMP_RESOLUTION - 8 ;
- char temp_whole;
- unsigned int temp_fraction;
- // check if temperature is negative
- if (temp2write > 0x0900) {
- text[0] = '-';
- temp2write = ~temp2write+1;
- }
- else
- {text[0] = ' ';}
-
- // extract temp_whole
- temp_whole = temp2write >> RES_SHIFT ;
- // convert temp_whole to characters
- if (temp_whole/100)
- {text[0] = '1';}
- //else
- //{text[0] = '0';}
- text[1] = (temp_whole/10)%10 + 48; // Extract tens digit
- text[2] = temp_whole%10 + 48; // Extract ones digit
- // extract temp_fraction and convert it to unsigned int
- temp_fraction = temp2write << (4-RES_SHIFT);
- temp_fraction &= 0x000F;
- temp_fraction *= 625;
- // convert temp_fraction to characters
- text[4] = temp_fraction/1000 + 48; // Extract thousands digit
- text[5] = (temp_fraction/100)%10 + 48; // Extract hundreds digit
- text[6] = (temp_fraction/10)%10 + 48; // Extract tens digit
- text[7] = temp_fraction%10 + 48; // Extract ones digit
- // send temperature to UART
- UART1_Write_Text("Temp: ");
- UART1_Write_Text(text);
- UART1_Write('"'); // degree sign
- UART1_Write('C'); // celsius
- UART1_Write(13); // CR
- UART1_Write(10); // LF
- Lcd_Out(1, 6, text);
-
- if (seconds==0)
- {
- AT24C02_Write1Byte(minutes,temp_whole);
- }
-
- }
- //------------------ Performs project-wide init
- void Init_Main() {
- #ifdef PCF8583
- RTCModuleAddress = 0xA0;
- YearOffset = 2008;
- #endif
- #ifdef DS1307
- RTCModuleAddress = 0xD0;
- YearOffset = 2000;
- #endif
- Soft_I2C_Init(); // Initialize Soft I2C communication
- Lcd_Init(); // Initialize LCD
- Lcd_Cmd(_LCD_CLEAR); // Clear LCD display
- Lcd_Cmd(_LCD_CURSOR_OFF); // Turn cursor off
- //LCD_Out(1,1,"Date:"); // Prepare and output static text on LCD
- //Lcd_Chr(1,8,':');
- //Lcd_Chr(1,11,':');
- LCD_Out(2,1,"Time:");
- Lcd_Chr(2,8,':');
- Lcd_Chr(2,11,':');
- }
- //--------------------- Reads time and date information from PCF8583 RTC
- void Read_Time_PCF8583() {
- char byte_read;
- Soft_I2C_Start(); // Issue start signal
- Soft_I2C_Write(RTCModuleAddress); // RTC module address + write (R#/W = 0)
- Soft_I2C_Write(2); // Start from seconds byte
- Soft_I2C_Start(); // Issue repeated start signal
- Soft_I2C_Write(RTCModuleAddress+1); // RTC module address + read (R#/W = 1)
- byte_read = Soft_I2C_Read(1); // Read seconds byte
- seconds = ((byte_read & 0xF0) >> 4)*10 + (byte_read & 0x0F); // Transform seconds
- byte_read = Soft_I2C_Read(1); // Read minutes byte
- minutes = ((byte_read & 0xF0) >> 4)*10 + (byte_read & 0x0F); // Transform minutes
- byte_read = Soft_I2C_Read(1); // Read hours byte
- hours = ((byte_read & 0xF0) >> 4)*10 + (byte_read & 0x0F); // Transform hours
- if ( (byte_read.B7) && (byte_read.B6) ) // 12h format && PM flag
- hours = hours + 12;
- byte_read = Soft_I2C_Read(1); // Read year/date byte
- year = YearOffset + ((byte_read & 0xC0) >> 6); // Transform year
- date = ((byte_read & 0x30) >> 4)*10 + (byte_read & 0x0F); // Transform date
- byte_read = Soft_I2C_Read(0); // Read weekday/month byte
- month = ((byte_read & 0x10) >> 4)*10 + (byte_read & 0x0F); // Transform month
- Soft_I2C_Stop(); // Issue stop signal
- }
- //--------------------- Reads time and date information from DS1307 RTC
- void Read_Time_DS1307() {
- char byte_read;
- char i;
- Soft_I2C_Start(); // Issue start signal
- Soft_I2C_Write(RTCModuleAddress); // RTC module address + write (R#/W = 0)
- Soft_I2C_Write(0); // Start from seconds byte
- Soft_I2C_Start(); // Issue repeated start signal
- Soft_I2C_Write(RTCModuleAddress+1); // RTC module address + read (R#/W = 1)
- byte_read = Soft_I2C_Read(1); // Read seconds byte
- seconds = ((byte_read & 0x70) >> 4)*10 + (byte_read & 0x0F); // Transform seconds
- byte_read = Soft_I2C_Read(1); // Read minutes byte
- minutes = ((byte_read & 0x70) >> 4)*10 + (byte_read & 0x0F); // Transform minutes
- byte_read = Soft_I2C_Read(1); // Read hours byte
- if (byte_read.B6) { // 12h format
- hours = ((byte_read & 0x10) >> 4)*10 + (byte_read & 0x0F); // Transform hours
- if (byte_read.B5) // PM flag
- hours = hours + 12;
- }
- else
- hours = ((byte_read & 0x30) >> 4)*10 + (byte_read & 0x0F); // Transform hours
- byte_read = Soft_I2C_Read(1); // Read weekday byte
- byte_read = Soft_I2C_Read(1); // Read date byte
- date = ((byte_read & 0x30) >> 4)*10 + (byte_read & 0x0F); // Transform date
- byte_read = Soft_I2C_Read(1); // Read month byte
- month = ((byte_read & 0x10) >> 4)*10 + (byte_read & 0x0F); // Transform month
- byte_read = Soft_I2C_Read(0); // Read year byte
- year = YearOffset + ((byte_read & 0xF0) >> 4)*10 + (byte_read & 0x0F); // Transform year
- //for (i =1; i<=10 ;i++)
- //{byte_read=Soft_I2C_Read(1);}
- Soft_I2C_Stop(); // Issue stop signal
- }
- //--------------------- Reads time and date information from RTC
- void Read_Time() {
- #ifdef PCF8583
- Read_Time_PCF8583();
- #endif
- #ifdef DS1307
- Read_Time_DS1307();
- #endif
- }
- //-------------------- Output values to LCD
- void Display_Time() {
- //char year1[8];char month1[4];char date1[4];char hours1[4];char minutes1[4];char seconds1[4];
-
- Lcd_Chr(2, 6, (hours / 10) + 48);
- Lcd_Chr(2, 7, (hours % 10) + 48);
- Lcd_Chr(2, 9, (minutes / 10) + 48);
- Lcd_Chr(2,10, (minutes % 10) + 48);
- Lcd_Chr(2,12, (seconds / 10) + 48);
- Lcd_Chr(2,13, (seconds % 10) + 48);
-
- //IntToStr(year, year1); ByteToStr(month, month1);ByteToStr(date, date1);
- //ByteToStr(hours, hours1); ByteToStr(minutes, minutes1);ByteToStr(seconds, seconds1);
- UART1_Write_Text("DATE:");
- UART1_Write(year/1000+48); UART1_Write((year%1000)/100+48);UART1_Write((year%100)/10+48);UART1_Write(year%10+48);//print year
- UART1_Write('-');
- UART1_Write(month/10+48);UART1_Write(month%10+48); //Print month
- UART1_Write('-');
- UART1_Write(date/10+48);UART1_Write(date%10+48); //Print date
- UART1_Write(' '); // CR
- UART1_Write(' '); // LF
-
- UART1_Write_Text("Time:");
- UART1_Write(hours/10+48);UART1_Write(hours%10+48); //Print hour
- UART1_Write(':');
- UART1_Write(minutes/10+48);UART1_Write(minutes%10+48); //Print minute
- UART1_Write(':');
- UART1_Write(seconds/10+48);UART1_Write(seconds%10+48); //Print second
- UART1_Write(13); // CR
- UART1_Write(10); // LF
- /*LCD_Out(1,1,"Date:"); // Prepare and output static text on LCD
- Lcd_Chr(1,8,':');
- Lcd_Chr(1,11,':');
- Lcd_Chr(1, 6, (date / 10) + 48); // Print tens digit of date variable
- Lcd_Chr(1, 7, (date % 10) + 48); // Print oness digit of date variable
- Lcd_Chr(1, 9, (month / 10) + 48);
- Lcd_Chr(1,10, (month % 10) + 48);
- Lcd_Chr(1,12, ((year / 1000) % 10) + 48); // Print year
- Lcd_Chr(1,13, ((year / 100) % 10) + 48);
- Lcd_Chr(1,14, ((year / 10) % 10) + 48);
- Lcd_Chr(1,15, (year % 10) + 48);
- */
- }
- void main() {
- Init_Main(); // Perform initialization
- UART1_Init(4800); // Initialize UART module at 4800 bps
- //Lcd_Init(); // Initialize Lcd
- //Lcd_Cmd(_LCD_CLEAR); // Clear display
- //Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
- Lcd_Out(1, 1, "Temp:"); // Write message text on Lcd
- //Lcd_Out(2, 1, "Time:");
- CustomChar(1, 14);
- Lcd_Chr(1, 15, 'C');
- //Delay_ms(5);Skip first read due to not accurate
- Ow_Reset(); // Onewire reset signal
- Ow_Write(0xCC); // Issue command SKIP_ROM
- Ow_Write(0x44); // Issue command CONVERT_T
- Delay_us(120);
- Ow_Reset();
- Ow_Write(0xCC); // Issue command SKIP_ROM
- Ow_Write(0xBE); // Issue command READ_SCRATCHPAD
-
-
- Delay_ms(1000);
- //Delay_ms(100); // Wait for UART module to stabilize
- UART1_Write_Text("Start");
- UART1_Write(13); // CR
- UART1_Write(10); // LF
-
- //--- main loop
- do {
- //--- perform temperature reading
- Ow_Reset(); // Onewire reset signal
- Ow_Write(0xCC); // Issue command SKIP_ROM
- Ow_Write(0x44); // Issue command CONVERT_T
- Delay_us(120);
- Ow_Reset();
- Ow_Write(0xCC); // Issue command SKIP_ROM
- Ow_Write(0xBE); // Issue command READ_SCRATCHPAD
-
- Read_Time(); // Read time from RTC
- Display_Time(); // Prepare and display on LCD
- Delay_ms(400);
- temp1 = Ow_Read();
- temp2 = Ow_Read();
- temp = (temp2 << 8) + temp1;
- //--- Format and display result on Lcd
- Display_Temperature(temp);
- LightVolt = ReadADC8591(0);
- UART1_Write_Text("The volt on LDR is ");
- ByteToStr(LightVolt, volt);UART1_Write_Text(volt);//UART1_Write_Text("/255)*5V");
- UART1_Write(13); // CR
- UART1_Write(10); // LF
- if (seconds==30)
- {AT24C02_Write1Byte(minutes+128,LightVolt); }
-
- if(seconds==0)
- {Display_24C02();}
- Delay_ms(450);
- UART1_Write(13); // CR
- UART1_Write(10); // LF
- } while (1);
- }
復制代碼
51hei.png (8.75 KB, 下載次數: 46)
下載附件
2020-5-1 13:47 上傳
所有資料51hei提供下載:
8051 18B20 I2C.zip
(38.46 KB, 下載次數: 39)
2020-5-1 05:39 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|