ساعة وبيان درجة الحرارة وتقنية برمجة DS1307-DS18B20-LCD-PIC16F876
منتديات الهندسة الكهربية والإلكترونية والميكاترونكس والكومبيوتر :: الميكروكونترولر PIC والبرجة بلغة السى والمترجم مسكروسى برو :: الميكروكونترولر PIC والبرمجة بلغة السى والمترجم ميكروسى برو
صفحة 1 من اصل 1
ساعة وبيان درجة الحرارة وتقنية برمجة DS1307-DS18B20-LCD-PIC16F876
ساعة وبيان درجة الحرارة وتقنية برمجة DS1307-DS18B20-LCD-PIC16F876
المرجع :
https://www.mediafire.com/file/tpmm16acabidqaa/ds1307-ds18b20-pic16f876-lcd.rar/file
شاشة العرض العادى :
شاشة عرض وضع الضبط :
المرجع :
https://www.mediafire.com/file/tpmm16acabidqaa/ds1307-ds18b20-pic16f876-lcd.rar/file
شاشة العرض العادى :
شاشة عرض وضع الضبط :
رد: ساعة وبيان درجة الحرارة وتقنية برمجة DS1307-DS18B20-LCD-PIC16F876
- الكود:
// LCD module connections
sbit LCD_RS at RB0_bit; // LCD_RS assigned to PORT RB0;
sbit LCD_EN at RB1_bit; // LCD_EN assigned to PORT RB1;
sbit LCD_D4 at RB4_bit; // LCD_D4 assigned to PORT RB4;
sbit LCD_D5 at RB5_bit; // LCD_D5 assigned to PORT RB5;
sbit LCD_D6 at RB6_bit; // LCD_D6 assigned to PORT RB6;
sbit LCD_D7 at RB7_bit; // LCD_D7 assigned to PORT RB7;
sbit LCD_RS_Direction at TRISB0_bit; // LCD_RS assigned to TRIS B0;
sbit LCD_EN_Direction at TRISB1_bit; // LCD_EN assigned to TRIS B1;
sbit LCD_D4_Direction at TRISB4_bit; // LCD_D4 assigned to TRIS B4;
sbit LCD_D5_Direction at TRISB5_bit; // LCD_D5 assigned to TRIS B5;
sbit LCD_D6_Direction at TRISB6_bit; // LCD_D6 assigned to TRIS B6;
sbit LCD_D7_Direction at TRISB7_bit; // LCD_D7 assigned to TRIS B7;
// End LCD module connections
char second,minute,hour,weekday,day,month,year;
//--------------------- Reads time and date information from RTC (DS1307)
void Read_Time()
{
I2C1_Start(); // Issue start signal
I2C1_Wr(0xD0); // Address DS1307, see DS1307 datasheet
I2C1_Wr(0); // Start from address 0
I2C1_Repeated_Start(); // Issue repeated start signal
I2C1_Wr(0xD1); // Address DS1307 for reading R/W=1
second =I2C1_Rd(1); // Read seconds byte
minute =I2C1_Rd(1); // Read minutes byte
hour =I2C1_Rd(1); // Read hours byte
weekday =I2C1_Rd(1); // Read week day byte
day =I2C1_Rd(1); // Read day byte
month =I2C1_Rd(1); // Read month byte
year =I2C1_Rd(0); // Read Year byte
I2C1_Stop(); // Issue stop signal
}
//-----------------write time routine------------------
void Write_Time(char minute, char hour ,char weekday,char day,char month,char year)
{
char tmp1, tmp2;
tmp1 = minute / 10; //Write tens of minute
tmp2 = minute % 10; //Write unit of minute
minute = tmp1 * 16 + tmp2; //Includes all value
tmp1 = hour / 10; //Write tens of hour
tmp2 = hour % 10; //Write unit of hour
hour = tmp1 * 16 + tmp2; //Includes all value
tmp1 = weekday / 10; //Write tens of weekday
tmp2 = weekday % 10; //Write unit of weekday
weekday = tmp1 *16 +tmp2; //Includes all value
tmp1 = day / 10; //Write tens of day
tmp2 = day % 10; //Write unit of day
day = tmp1 *16 +tmp2; //Includes all value
tmp1 = month / 10; //Write tens of month
tmp2 = month % 10; //Write unit of month
month = tmp1 *16 +tmp2; //Includes all value
tmp1 = year / 10; //Write tens of year
tmp2 = year % 10; //Write unit of year
year = tmp1 *16 +tmp2; //Includes all value
I2C1_Start(); // issue start signal
I2C1_Wr(0xD0); // address DS1307
I2C1_Wr(0); // start from word at address (REG0)
I2C1_Wr(0x80); // write $80 to REG0. (pause counter + 0 second)
I2C1_Wr(minute); // write minutes word to (REG1)
I2C1_Wr(hour); // write hours word (24-hours mode)(REG2)
I2C1_Wr(weekday); // write 6 - Saturday (REG3)
I2C1_Wr(day); // write 14 to date word (REG4)
I2C1_Wr(month); // write 5 (May) to month word (REG5)
I2C1_Wr(year); // write 01 to year word (REG6)
I2C1_Wr(0x80); // write SQW/Out value (REG7)
I2C1_Stop(); // issue stop signal
I2C1_Start(); // issue start signal
I2C1_Wr(0xD0); // address DS1307
I2C1_Wr(0); // start from word at address 0
I2C1_Wr(0); // write 0 to REG0 (enable counting + 0 second)
I2C1_Stop(); // issue stop signal
}
//-------------------- Formats date and time---------------------
void Transform_Time()
{
second = ((second & 0x70) >> 4)*10 + (second & 0x0F);
minute = ((minute & 0xF0) >> 4)*10 + (minute & 0x0F);
hour = ((hour & 0x30) >> 4)*10 + (hour & 0x0F);
weekday =(weekday & 0x07);
day = ((day & 0xF0) >> 4)*10 + (day & 0x0F);
month = ((month & 0x10) >> 4)*10 + (month & 0x0F);
year = ((year & 0xF0)>>4)*10+(year & 0x0F);
}
//------------------------Display time---------------------------
char *txt,*mny;
void Display_Time()
{
switch(weekday)
{
case 1: txt="Mon"; break; // Monday;
case 2: txt="Tue"; break; // Tuesday;
case 3: txt="Wed"; break; // Wednesday;
case 4: txt="Thu"; break; // Thursday;
case 5: txt="Fri"; break; // Friday;
case 6: txt="Sat"; break; // Saturday;
case 7: txt="Sun"; break; // Sunday;
}
LCD_Out(1, 1,txt);
LCD_chr(1, 4,',');
switch(month)
{
case 1: mny="Jan"; break;
case 2: mny="Feb"; break;
case 3: mny="Mar"; break;
case 4: mny="Apr"; break;
case 5: mny="May"; break;
case 6: mny="Jun"; break;
case 7: mny="Jul"; break;
case 8: mny="Aug"; break;
case 9: mny="Sep"; break;
case 10: mny="Oct"; break;
case 11: mny="Nov"; break;
case 12: mny="Dec"; break;
}
Lcd_Chr(1, 6, (day / 10) + 48); // Print tens digit of day variable
Lcd_Chr(1, 7, (day % 10) + 48); // Print oness digit of day variable
Lcd_Out(1, 9,mny);
Lcd_out(1,13,"20");
Lcd_Chr(1,15, (year / 10) + 48); // we can set year 00-99 [tens]
Lcd_Chr(1,16, (year % 10) + 48); // we can set year 00-99 [ones]
Lcd_Chr(2, 1, (hour / 10) + 48);
Lcd_Chr(2, 2, (hour % 10) + 48);
Lcd_Chr(2, 3,':');
Lcd_Chr(2, 4, (minute / 10) + 48);
Lcd_Chr(2, 5, (minute % 10) + 48);
Lcd_Chr(2, 6,':');
Lcd_Chr(2, 7, (second / 10) + 48);
Lcd_Chr(2, 8, (second % 10) + 48);
}
/*-------------------------------------------------------------*/
//-------------------Display Time in Set mode--------------------
char minute1,hour1,weekday1,day1,month1,year1;
char minute2,hour2,weekday2,day2,month2,year2;
void Display_Time_SetMode()
{
switch(weekday1)
{
case 1: txt="Mon"; break; // Monday;
case 2: txt="Tue"; break; // Tuesday;
case 3: txt="Wed"; break; // Wednesday;
case 4: txt="Thu"; break; // Thursday;
case 5: txt="Fri"; break; // Friday;
case 6: txt="Sat"; break; // Saturday;
case 7: txt="Sun"; break; // Sunday;
}
LCD_Out(1, 1,txt);
LCD_chr(1, 4,',');
Lcd_Chr(1, 6, (day1 / 10) + 48); // Print tens digit of day variable
Lcd_Chr(1, 7, (day1 % 10) + 48); // Print oness digit of day variable
Lcd_chr(1,10, (month1 / 10) + 48); // Print tens digit of month variable
Lcd_chr(1,11, (month1 % 10) + 48); // Print oness digit of month variable
Lcd_out(1,13,"20");
Lcd_Chr(1,15, (year1 / 10) + 48); // Print tens digit of year variable
Lcd_Chr(1,16, (year1 % 10) + 48); // Print oness digit of year variable
Lcd_Chr(2, 1, (hour1 / 10) + 48); // Print tens digit of hour variable
Lcd_Chr(2, 2, (hour1 % 10) + 48); // Print oness digit of hour variable
Lcd_Chr(2, 3,':');
Lcd_Chr(2, 4, (minute1 / 10) + 48); // Print tens digit of minute variable
Lcd_Chr(2, 5, (minute1 % 10) + 48); // Print oness digit of minute variable
Lcd_Chr(2, 6,':');
Lcd_Chr(2, 7, (0 / 10) + 48);
Lcd_Chr(2, 8, (0 % 10) + 48);
}
char SPos;
//----------------------Move cursor routine----------------------
char index;
void movecursor()
{
char i,moveto;
if(SPos==0)
lcd_cmd(_lcd_first_row); // set weekday;
if(SPos==1)
lcd_cmd(_lcd_first_row); // set day;
if(SPos==2)
lcd_cmd(_lcd_first_row); // set month;
if(SPos==3)
lcd_cmd(_lcd_first_row); // set year;
if(SPos==4)
lcd_cmd(_lcd_second_row); // set hours;
if(SPos==5)
lcd_cmd(_lcd_second_row); // set minutes;
moveto = 2;
switch(index)
{
case 0: moveto = 2;break;
case 1: moveto = 6;break;
case 2: moveto =10;break;
case 3: moveto =15;break;
case 4: moveto = 1;break;
case 5: moveto = 4;break;
}
for(i=1; i<= moveto; i++)
lcd_cmd(_lcd_move_cursor_right);
}
/////////////////////////////////////////////////////////////////////////
//------------Start Buttons routine--------------;
char setuptime=0;
void Press_Switch()
{
if(setuptime)// After Button SET pressed first time
{
if(Button(&portc,2,1,0)) // If buttons at port c2 is pressed , cursor or select item
{
delay_ms(200);
SPos++;
if(SPos>5)
SPos=0;
index++;
if(index > 5)
index=0;
movecursor();
}
//-----------------------------case mode to set all values---------------------
switch(SPos)
{
case 0: if(button(&portc,0,1,0)) // If buttons at port c0 is pressed , INC
{
Delay_ms(200);
weekday1++;
if(weekday1 > 7)
weekday1=1;
Display_Time_SetMode();
index=0;
movecursor();
}
if(button(&portc,1,1,0)) // If buttons at port c1 is pressed , DEC
{
Delay_ms(200);
weekday1--;
if(weekday1 < 1)
weekday1=7;
Display_Time_SetMode();
index=0;
movecursor();
}
break;
case 1: if(button(&portc,0,1,0)) // If buttons at port c0 is pressed
{
Delay_ms(200);
day1++;
if(day1 > 31)
day1 = 1;
Display_Time_SetMode();
index=1;
movecursor();
}
if(button(&portc,1,1,0)) // If buttons at port c1 is pressed
{
Delay_ms(200);
day1--;
if(day1 < 1)
day1 = 31;
Display_Time_SetMode();
index=1;
movecursor();
}
break;
case 2: if(button(&portc,0,1,0)) // If buttons at port c0 is pressed
{
Delay_ms(200);
month1++;
if(month1 > 12)
month1 = 1;
Display_Time_SetMode();
index=2;
movecursor();
}
if(button(&portc,1,1,0)) // If buttons at port c1 is pressed
{
Delay_ms(200);
month1--;
if(month1 < 1)
month1 = 12;
Display_Time_SetMode();
index=2;
movecursor();
}
break;
case 3: if(button(&portc,0,1,0)) // If buttons at port c0 is pressed
{
Delay_ms(200);
year1++;
if(year1 > 99)
year1 = 1;
Display_Time_SetMode();
index=3;
movecursor();
}
if(button(&portc,1,1,0)) // If buttons at port c1 is pressed
{
Delay_ms(200);
year1--;
if(year1 < 1)
year1 = 99;
Display_Time_SetMode();
index=3;
movecursor();
}
break;
case 4: if(button(&portc,0,1,0)) // If buttons at port c0 is pressed
{
Delay_ms(200);
hour1++;
if(hour1 > 23)
hour1 = 0;
Display_Time_SetMode();
index=4;
movecursor();
}
if(button(&portc,1,1,0)) // If buttons at port c1 is pressed
{
Delay_ms(200);
hour1--;
if(hour1 > 23)
hour1 = 0;
Display_Time_SetMode();
index=4;
movecursor();
}
break;
case 5: if(button(&portc,0,1,0)) // If buttons at port c0 is pressed
{
Delay_ms(200);
minute1++;
if(minute1 > 59)
minute1 = 0;
Display_Time_SetMode();
index=5;
movecursor();
}
if(button(&portc,1,1,0)) // If buttons at port c1 is pressed
{
Delay_ms(200);
minute1--;
if(minute1 > 59)
minute1 = 0;
Display_Time_SetMode();
index=5;
movecursor();
}
break;
} // end "if is in switch mode"
} // end "if is in setup"
///////////////////////////////////////////////////////////////////////////////////////////
if(button(&portc,5,1,0)) // If buttons at port c5 is pressed ,Enter SETUP mode
{
Delay_ms(200);
setuptime = !setuptime;
if(SetupTime)
{
lcd_cmd(_lcd_clear);
lcd_cmd(_lcd_blink_cursor_on);
weekday1=weekday;
hour1=hour;
minute1=minute;
day1=day;
month1=month;
year1=year;
Display_Time_SetMode();
SPos=0;
index=0;
movecursor();
}
else
{
Lcd_Cmd(_Lcd_clear);
lcd_cmd(_lcd_cursor_off);
weekday2=weekday1;
hour2=hour1;
minute2=minute1;
day2=day1;
month2=month1;
year2=year1;
Write_time(minute2,hour2,weekday2,day2,month2,year2);
}
}
}
//----------------------End Buttons Routine-------------------
//------------------Temperature sensor routines---------------
const unsigned short TEMP_RESOLUTION = 12; // 9 for DS1820 and 12 for DS18B20
char *text = "000,0";
unsigned temp;
void Display_Temperature(unsigned int temp2write)
{
const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
char temp_whole;
unsigned int temp_fraction;
unsigned short isNegative = 0x00;
// Check if temperature is negative
if (temp2write & 0x8000)
{
text[0] = '-';
temp2write = ~temp2write + 1;
isNegative = 1;
}
// Extract temp_whole
temp_whole = temp2write >> RES_SHIFT ;
// Convert temp_whole to characters
if (!isNegative){
if (temp_whole/100)
text[0] = temp_whole/100 + 48; // Extract hundreds digit
else
text[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
// Print temperature on LCD
Lcd_Out(2, 10,text);
lcd_chr(2, 15,223); // Ascii code for degrees symbol;
Lcd_chr(2, 16,'C'); // Show symbol "C" from Celsius
}
//----------------Read and display Temperature from DS18B20--------------
void Read18b20()
{
//--- Perform temperature reading
Ow_Reset(&PORTC, 7); // Onewire reset signal;
Ow_Write(&PORTC, 7, 0xCC); // 0xCC Issue command SKIP_ROM;
Ow_Write(&PORTC, 7, 0x44); // Issue command CONVERT_T;
Delay_us(700); // delay 0,7s (required for signal
// processing);
Ow_Reset(&PORTC, 7); // Onewire reset signal;
Ow_Write(&PORTC, 7, 0xCC); // Issue command SKIP_ROM;
Ow_Write(&PORTC, 7, 0xBE); // Issue command READ_SCRATCHPAD;
temp = Ow_Read(&PORTC, 7); // Next Read Temperature, read Byte
// 0 from Scratchpad;
temp = (Ow_Read(&PORTC, 7) << + temp; // Then read Byte 1 from Scratchpad
// and shift 8 bit left and add the Byte 0;
//--- Format and display result on Lcd
Display_Temperature(temp); // Call Display_Temperature;
}
//------------------Temperature sensor routines---------------
void Init_Main()
{
CMCON |=7; //TURN OFF ANALOGUE COMPARATOR AND MAKE PORTA TO DIGITAL I/O;
I2C1_Init(100000); // initialize I2C
Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // Clear LCD display
Lcd_Cmd(_LCD_CURSOR_OFF); // Turn cursor off
//Display_Time();
!setuptime=1;//setuptime=0;
index=0;
SPos=0;
}
//-----------------Here we have the Main Routine----------------
void main()
{
Init_Main();
while (1) // While loop
{
Read_Time(); // read time from RTC(DS1307)
Transform_Time(); // Transform time
Press_Switch(); // Check buttons;
if(!setuptime)
{
Display_Time();
Read18b20();
}
}
}
رد: ساعة وبيان درجة الحرارة وتقنية برمجة DS1307-DS18B20-LCD-PIC16F876
نبدأ من الدالة الرئيسية :
وفيها يتم
• استدعاء دالة التهيئة :
• إنشاء حلقة غير منتهية وبداخلها
1- استدعاء دالة قراءة بيانات الشريحة DS1307
2- استدعاء دالة تحويل البيانات من ثتائى مكود عشرى إلى عشرى :
3- استدعاء دالة الضغط على مفاتيح التحكم . فى الوضع الابتدائى جميع المفاتيح غير مضغوطة وخاصة مفتاح الضبط SET ويكون المتغير setuptime فى وضعه الابتدائى وهو الصفر ويتحقق شرط عبارة
فيتم تنفيذ جسمها حيث يتم :
• استدعاء دالة عرض الزمن
• ثم استدعاء دالة قرأة درجة الحرارة
وهكذا نكون قد حصلنا على شاشة العرض الأولى (العرض العادى للزمن والتاريخ ودرجة الحرارة) . وتتكرر الحلقة الغير منتهية ويظل العرض العادى طالما لم يتم الضغط على مفتاح الضبط SET .
• عند الضغط على مفتاح الضبط SET يتم عكس حالة المتغير setuptime (من حالة الصفر إلى حالة الواحد) فيؤدى ذلك إلى عدم تحقق شرط عبارة if ومن ثم عدم عرض شاشة العرض الأولى والسماح بعرض شاشة العرض الثانية (شاشة عرض الضبط) كما سنرى فى دالة مفاتيح التحكم Press_Switch . عند الضغط على مفتاح الضبط SET مرة أخرى يتم العودة لعرض العرض العادى .
- الكود:
//-----------------Here we have the Main Routine----------------
void main()
{
Init_Main();
while (1) // While loop
{
Read_Time(); // read time from RTC(DS1307)
Transform_Time(); // Transform time
Press_Switch(); // Check buttons;
if(!setuptime)
{
Display_Time();
Read18b20();
}
}
}
وفيها يتم
• استدعاء دالة التهيئة :
- الكود:
void Init_Main()
{
CMCON |=7; //TURN OFF ANALOGUE COMPARATOR AND MAKE PORTA TO DIGITAL I/O;
I2C1_Init(100000); // initialize I2C
Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // Clear LCD display
Lcd_Cmd(_LCD_CURSOR_OFF); // Turn cursor off
//Display_Time(sec, minu, hr, week_day, day, mn, year);
!setuptime=1; //setuptime=0;
index=0;
SPos=0;
}
• إنشاء حلقة غير منتهية وبداخلها
- الكود:
while (1) // While loop
{
Read_Time(); // read time from RTC(DS1307)
Transform_Time(); // Transform time
Press_Switch(); // Check buttons;
if(!setuptime)
{
Display_Time();
Read18b20();
}
}
}
1- استدعاء دالة قراءة بيانات الشريحة DS1307
- الكود:
char second,minute,hour,weekday,day,month,year;
//--------------------- Reads time and date information from RTC (DS1307)
void Read_Time()
{
I2C1_Start(); // Issue start signal
I2C1_Wr(0xD0); // Address DS1307, see DS1307 datasheet
I2C1_Wr(0); // Start from address 0
I2C1_Repeated_Start(); // Issue repeated start signal
I2C1_Wr(0xD1); // Address DS1307 for reading R/W=1
second =I2C1_Rd(1); // Read seconds byte
minute =I2C1_Rd(1); // Read minutes byte
hour =I2C1_Rd(1); // Read hours byte
weekday =I2C1_Rd(1); // Read week day byte
day =I2C1_Rd(1); // Read day byte
month =I2C1_Rd(1); // Read month byte
year =I2C1_Rd(0); // Read Year byte
I2C1_Stop(); // Issue stop signal
}
2- استدعاء دالة تحويل البيانات من ثتائى مكود عشرى إلى عشرى :
- الكود:
//-------------------- Formats date and time---------------------
void Transform_Time()
{
second = ((second & 0x70) >> 4)*10 + (second & 0x0F);
minute = ((minute & 0xF0) >> 4)*10 + (minute & 0x0F);
hour = ((hour & 0x30) >> 4)*10 + (hour & 0x0F);
weekday =(weekday & 0x07);
day = ((day & 0xF0) >> 4)*10 + (day & 0x0F);
month = ((month & 0x10) >> 4)*10 + (month & 0x0F);
year = ((year & 0xF0)>>4)*10+(year & 0x0F);
}
3- استدعاء دالة الضغط على مفاتيح التحكم . فى الوضع الابتدائى جميع المفاتيح غير مضغوطة وخاصة مفتاح الضبط SET ويكون المتغير setuptime فى وضعه الابتدائى وهو الصفر ويتحقق شرط عبارة
- الكود:
if(!setuptime)
فيتم تنفيذ جسمها حيث يتم :
• استدعاء دالة عرض الزمن
- الكود:
Display_Time();
//------------------------Display time---------------------------
char *txt,*mny;
void Display_Time()
{
switch(weekday)
{
case 1: txt="Mon"; break; // Monday;
case 2: txt="Tue"; break; // Tuesday;
case 3: txt="Wed"; break; // Wednesday;
case 4: txt="Thu"; break; // Thursday;
case 5: txt="Fri"; break; // Friday;
case 6: txt="Sat"; break; // Saturday;
case 7: txt="Sun"; break; // Sunday;
}
LCD_Out(1, 1,txt);
LCD_chr(1, 4,',');
switch(month)
{
case 1: mny="Jan"; break;
case 2: mny="Feb"; break;
case 3: mny="Mar"; break;
case 4: mny="Apr"; break;
case 5: mny="May"; break;
case 6: mny="Jun"; break;
case 7: mny="Jul"; break;
case 8: mny="Aug"; break;
case 9: mny="Sep"; break;
case 10: mny="Oct"; break;
case 11: mny="Nov"; break;
case 12: mny="Dec"; break;
}
Lcd_Chr(1, 6, (day / 10) + 48); // Print tens digit of day variable
Lcd_Chr(1, 7, (day % 10) + 48); // Print oness digit of day variable
Lcd_Out(1, 9,mny);
Lcd_out(1,13,"20");
Lcd_Chr(1,15, (year / 10) + 48); // we can set year 00-99 [tens]
Lcd_Chr(1,16, (year % 10) + 48); // we can set year 00-99 [ones]
Lcd_Chr(2, 1, (hour / 10) + 48);
Lcd_Chr(2, 2, (hour % 10) + 48);
Lcd_Chr(2, 3,':');
Lcd_Chr(2, 4, (minute / 10) + 48);
Lcd_Chr(2, 5, (minute % 10) + 48);
Lcd_Chr(2, 6,':');
Lcd_Chr(2, 7, (second / 10) + 48);
Lcd_Chr(2, 8, (second % 10) + 48);
}
• ثم استدعاء دالة قرأة درجة الحرارة
- الكود:
Read18b20();
وهكذا نكون قد حصلنا على شاشة العرض الأولى (العرض العادى للزمن والتاريخ ودرجة الحرارة) . وتتكرر الحلقة الغير منتهية ويظل العرض العادى طالما لم يتم الضغط على مفتاح الضبط SET .
• عند الضغط على مفتاح الضبط SET يتم عكس حالة المتغير setuptime (من حالة الصفر إلى حالة الواحد) فيؤدى ذلك إلى عدم تحقق شرط عبارة if ومن ثم عدم عرض شاشة العرض الأولى والسماح بعرض شاشة العرض الثانية (شاشة عرض الضبط) كما سنرى فى دالة مفاتيح التحكم Press_Switch . عند الضغط على مفتاح الضبط SET مرة أخرى يتم العودة لعرض العرض العادى .
رد: ساعة وبيان درجة الحرارة وتقنية برمجة DS1307-DS18B20-LCD-PIC16F876
مفاتيح التحكم :
مفتاح الدخول والخروج من نظام الضبط SETUP
فى الوضع الابتدائى يكون المتغير setuptime بصفر وذلك يمنع عمل المفاتيح إلا بعد الضغط على مفتاح الدخول فى وضع الضبط SETUP المتصل بالطرف C5 .
عند الضغط على المفتاح SETUP يتم عكس حالة المتغير setuptime من الصفر إلى الواحد ويتحقق شرط عبارة if(SetupTime) ويتم تنفيذ عبارات جسمها :
• مسح الشاشة .
• تشغيل وميض المؤشر .
• نسخ محتويات متغيرات البيانات الحالية إلى متغيرات جديدة .
• استدعاء دالة عرض التوقيت فى وضع الضبط Display_Time_SetMode()
فيها يتم استخدام عبارة switch..case لتحويل أيام الإسبوع من رقم إلى نص ثم تنسيق الشاشة لتكون شاشة عرض الضبط .
• بعد ذلك يتم تصفير متغيرات العدادات SPos (موضع المؤشرفى أى صف ضبط ) و index ( لحركة موضع المؤشر مكان الضبط على الصف المحدد) ويتحكم فى تزايدهما مفتاح المؤشر cursor المتصل بالطرف C2 حيث يسمح له بالعمل بعد ضغط مفتاح الضبط .
• استدعاء دالة تحريك المؤشر movecursor :
• بعد اختيار موضع المؤشر (صف SPos وعامود index ) نستخدم مفاتيح الزيادة والنقصان لتعديل البيانات
• بعد انتهاء الضبط يتم الضغط على مفتاح الضبط مرة أخرى للخروج من وضع العرض والعودة إلى الوضع العادى مع حفظ (كتابة) التغييرات :
مفتاح الدخول والخروج من نظام الضبط SETUP
- الكود:
if(button(&portc,5,1,0)) // If buttons at port c5 is pressed ,Enter SETUP mode
{
Delay_ms(200);
setuptime = !setuptime;
if(SetupTime)
{
lcd_cmd(_lcd_clear);
lcd_cmd(_lcd_blink_cursor_on);
weekday1=weekday;
hour1=hour;
minute1=minute;
day1=day;
month1=month;
year1=year;
Display_Time_SetMode();
SPos=0;
index=0;
movecursor();
}
else
{
Lcd_Cmd(_Lcd_clear);
lcd_cmd(_lcd_cursor_off);
weekday2=weekday1;
hour2=hour1;
minute2=minute1;
day2=day1;
month2=month1;
year2=year1;
Write_time(minute2,hour2,weekday2,day2,month2,year2);
}
}
فى الوضع الابتدائى يكون المتغير setuptime بصفر وذلك يمنع عمل المفاتيح إلا بعد الضغط على مفتاح الدخول فى وضع الضبط SETUP المتصل بالطرف C5 .
عند الضغط على المفتاح SETUP يتم عكس حالة المتغير setuptime من الصفر إلى الواحد ويتحقق شرط عبارة if(SetupTime) ويتم تنفيذ عبارات جسمها :
• مسح الشاشة .
• تشغيل وميض المؤشر .
• نسخ محتويات متغيرات البيانات الحالية إلى متغيرات جديدة .
• استدعاء دالة عرض التوقيت فى وضع الضبط Display_Time_SetMode()
- الكود:
//-------------------Display Time in Set mode--------------------
char minute1,hour1,weekday1,day1,month1,year1;
char minute2,hour2,weekday2,day2,month2,year2;
void Display_Time_SetMode()
{
switch(weekday1)
{
case 1: txt="Mon"; break; // Monday;
case 2: txt="Tue"; break; // Tuesday;
case 3: txt="Wed"; break; // Wednesday;
case 4: txt="Thu"; break; // Thursday;
case 5: txt="Fri"; break; // Friday;
case 6: txt="Sat"; break; // Saturday;
case 7: txt="Sun"; break; // Sunday;
}
LCD_Out(1, 1,txt);
LCD_chr(1, 4,',');
Lcd_Chr(1, 6, (day1 / 10) + 48); // Print tens digit of day variable
Lcd_Chr(1, 7, (day1 % 10) + 48); // Print oness digit of day variable
Lcd_chr(1,10, (month1 / 10) + 48); // Print tens digit of month variable
Lcd_chr(1,11, (month1 % 10) + 48); // Print oness digit of month variable
Lcd_out(1,13,"20");
Lcd_Chr(1,15, (year1 / 10) + 48); // Print tens digit of year variable
Lcd_Chr(1,16, (year1 % 10) + 48); // Print oness digit of year variable
Lcd_Chr(2, 1, (hour1 / 10) + 48); // Print tens digit of hour variable
Lcd_Chr(2, 2, (hour1 % 10) + 48); // Print oness digit of hour variable
Lcd_Chr(2, 3,':');
Lcd_Chr(2, 4, (minute1 / 10) + 48); // Print tens digit of minute variable
Lcd_Chr(2, 5, (minute1 % 10) + 48); // Print oness digit of minute variable
Lcd_Chr(2, 6,':');
Lcd_Chr(2, 7, (0 / 10) + 48);
Lcd_Chr(2, 8, (0 % 10) + 48);
}
فيها يتم استخدام عبارة switch..case لتحويل أيام الإسبوع من رقم إلى نص ثم تنسيق الشاشة لتكون شاشة عرض الضبط .
• بعد ذلك يتم تصفير متغيرات العدادات SPos (موضع المؤشرفى أى صف ضبط ) و index ( لحركة موضع المؤشر مكان الضبط على الصف المحدد) ويتحكم فى تزايدهما مفتاح المؤشر cursor المتصل بالطرف C2 حيث يسمح له بالعمل بعد ضغط مفتاح الضبط .
- الكود:
//------------Start Buttons routine--------------;
char setuptime=0;
void Press_Switch()
{
if(setuptime)// After Button SET pressed first time
{
if(Button(&portc,2,1,0)) // If buttons at port c2 is pressed , cursor or select item
{
delay_ms(200);
SPos++;
if(SPos>5)
SPos=0;
index++;
if(index > 5)
index=0;
movecursor();
}
• استدعاء دالة تحريك المؤشر movecursor :
- الكود:
//----------------------Move cursor routine----------------------
char index;
void movecursor()
{
char i,moveto;
if(SPos==0)
lcd_cmd(_lcd_first_row); // set weekday;
if(SPos==1)
lcd_cmd(_lcd_first_row); // set day;
if(SPos==2)
lcd_cmd(_lcd_first_row); // set month;
if(SPos==3)
lcd_cmd(_lcd_first_row); // set year;
if(SPos==4)
lcd_cmd(_lcd_second_row); // set hours;
if(SPos==5)
lcd_cmd(_lcd_second_row); // set minutes;
moveto = 2;
switch(index)
{
case 0: moveto = 2;break;
case 1: moveto = 6;break;
case 2: moveto =10;break;
case 3: moveto =15;break;
case 4: moveto = 1;break;
case 5: moveto = 4;break;
}
for(i=1; i<= moveto; i++)
lcd_cmd(_lcd_move_cursor_right);
}
• بعد اختيار موضع المؤشر (صف SPos وعامود index ) نستخدم مفاتيح الزيادة والنقصان لتعديل البيانات
- الكود:
switch(SPos)
{
case 0: if(button(&portc,0,1,0)) // If buttons at port c0 is pressed , INC
{
Delay_ms(200);
weekday1++;
if(weekday1 > 7)
weekday1=1;
Display_Time_SetMode();
index=0;
movecursor();
}
if(button(&portc,1,1,0)) // If buttons at port c1 is pressed , DEC
{
Delay_ms(200);
weekday1--;
if(weekday1 < 1)
weekday1=7;
Display_Time_SetMode();
index=0;
movecursor();
}
break;
case 1: if(button(&portc,0,1,0)) // If buttons at port c0 is pressed
{
Delay_ms(200);
day1++;
if(day1 > 31)
day1 = 1;
Display_Time_SetMode();
index=1;
movecursor();
}
if(button(&portc,1,1,0)) // If buttons at port c1 is pressed
{
Delay_ms(200);
day1--;
if(day1 < 1)
day1 = 31;
Display_Time_SetMode();
index=1;
movecursor();
}
break;
case 2: if(button(&portc,0,1,0)) // If buttons at port c0 is pressed
{
Delay_ms(200);
month1++;
if(month1 > 12)
month1 = 1;
Display_Time_SetMode();
index=2;
movecursor();
}
if(button(&portc,1,1,0)) // If buttons at port c1 is pressed
{
Delay_ms(200);
month1--;
if(month1 < 1)
month1 = 12;
Display_Time_SetMode();
index=2;
movecursor();
}
break;
case 3: if(button(&portc,0,1,0)) // If buttons at port c0 is pressed
{
Delay_ms(200);
year1++;
if(year1 > 99)
year1 = 1;
Display_Time_SetMode();
index=3;
movecursor();
}
if(button(&portc,1,1,0)) // If buttons at port c1 is pressed
{
Delay_ms(200);
year1--;
if(year1 < 1)
year1 = 99;
Display_Time_SetMode();
index=3;
movecursor();
}
break;
case 4: if(button(&portc,0,1,0)) // If buttons at port c0 is pressed
{
Delay_ms(200);
hour1++;
if(hour1 > 23)
hour1 = 0;
Display_Time_SetMode();
index=4;
movecursor();
}
if(button(&portc,1,1,0)) // If buttons at port c1 is pressed
{
Delay_ms(200);
hour1--;
if(hour1 > 23)
hour1 = 0;
Display_Time_SetMode();
index=4;
movecursor();
}
break;
case 5: if(button(&portc,0,1,0)) // If buttons at port c0 is pressed
{
Delay_ms(200);
minute1++;
if(minute1 > 59)
minute1 = 0;
Display_Time_SetMode();
index=5;
movecursor();
}
if(button(&portc,1,1,0)) // If buttons at port c1 is pressed
{
Delay_ms(200);
minute1--;
if(minute1 > 59)
minute1 = 0;
Display_Time_SetMode();
index=5;
movecursor();
}
break;
}
• بعد انتهاء الضبط يتم الضغط على مفتاح الضبط مرة أخرى للخروج من وضع العرض والعودة إلى الوضع العادى مع حفظ (كتابة) التغييرات :
- الكود:
else
{
Lcd_Cmd(_Lcd_clear);
lcd_cmd(_lcd_cursor_off);
weekday2=weekday1;
hour2=hour1;
minute2=minute1;
day2=day1;
month2=month1;
year2=year1;
Write_time(minute2,hour2,weekday2,day2,month2,year2);
}
}
}
مواضيع مماثلة
» مشروع متحكم رقمى فى درجة الحرارة السالبة والموجبة بالحساس DS18B20 والميكروكونترولر 16F628 والسفن سيجمنت مع المترجم CCS C :
» شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة
» درجة الحرارة وقياسها Temperature and its Measurement
» الناقل 2IC وساعة التوقيت الحقيقى DS1307 ومشاريع الساعات الرقمية :
» تدريب : استخدام المحول ADC لقياس درجة الحرارة بالحساس LM35 مع المترجم CCS C :
» شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة
» درجة الحرارة وقياسها Temperature and its Measurement
» الناقل 2IC وساعة التوقيت الحقيقى DS1307 ومشاريع الساعات الرقمية :
» تدريب : استخدام المحول ADC لقياس درجة الحرارة بالحساس LM35 مع المترجم CCS C :
منتديات الهندسة الكهربية والإلكترونية والميكاترونكس والكومبيوتر :: الميكروكونترولر PIC والبرجة بلغة السى والمترجم مسكروسى برو :: الميكروكونترولر PIC والبرمجة بلغة السى والمترجم ميكروسى برو
صفحة 1 من اصل 1
صلاحيات هذا المنتدى:
لاتستطيع الرد على المواضيع في هذا المنتدى