قسم الميكروكنترولر والروبوت ودوائر الاتصال بالحاسب الالي قسم المتحكمات الـ microcontroller و المعالجات microprocessor و التحكم الرقمي بالكمبيوتر CNC والانظمة الآلية والروبوت Robots

   

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 26-07-2017, 04:34 PM المشاركة 153   
افتراضي



البرنامج الثانى باستخدام 4 وحدة عرض أى أن مدى التزايد والتناقص هو 0-9999 :
الدائرة الكهربية :



البرنامج :

كود:
 
/*
UP Down Counter with Four 7-Segment Display Multiplexing
In this project four common anode 7-segment LED displays are connected to
PORTD of a PIC16F877A  * 4MHz .
Digit 1 (left digit) enable pin is connected to port pin RA0 ( Thousands)
and digit 2  enable pin is connected to port pin RA1 (Hundreds) .
and digit 3  enable pin is connected to port pin RA2 (Tens) .
and digit 4  enable pin is connected to port pin RA3 (Ones) .
The program counts up -down from buttons at RB0 , RB1 .
The display is updated in a timer interrupt service routine at every 5ms by :
Reload TMR0=100 & prescaler ration 1:32>> imer interrupt service routine at
 (255-100) *32us=5ms = scanning time
*/

#define Thous_Dig  PORTA.B0 //Thousands  unit
#define Hund_Dig  PORTA.B1//Hndreds unit
#define Tens_Dig PORTA.B2//Tens unit
#define Ones_Dig PORTA.B3//ones unit



//Global variable
unsigned char Count = 0;
unsigned char Flag = 0;
bit oldstate1;
bit oldstate2;

//-Function to Return mask for common anode 7-seg. display
unsigned short mask(unsigned short num) {
 switch (num) {
 case 0 : return 0xC0;
 case 1 : return 0xF9;
 case 2 : return 0xA4;
 case 3 : return 0xB0;
 case 4 : return 0x99;
 case 5 : return 0x92;
 case 6 : return 0x82;
 case 7 : return 0xF8;
 case 8 : return 0x80;
 case 9 : return 0x90;
 } //case end
}
// TMR0 timer interrupt service routine. The program jumps to the ISR at every 5ms.

void interrupt ()
{

//Local variable
unsigned char Thous_Seg,Hund_Seg,Tens_Seg, Ones_Seg;
TMR0 = 100; 				// Re-load TMR0>>255-100=155usx32(prescaler)=5ms
INTCON = 0x20; 				// >>>>Set T0IE and clear T0IF<<<<
if(Flag == 0) 				// Do digit 1
{
Ones_Dig = 1;
Tens_Dig = 1;
Hund_Dig = 1;
Thous_Seg = Count / 1000; 			// TENS_SEG >>tens
PORTD = mask(Thous_Seg); 			// Send to PORTD
Thous_Dig = 0; 				// Enable digit 1>>RA0
}
 else
if(Flag == 1) 				// Do digit 1
{
Ones_Dig = 1;
Tens_Dig = 1;
Thous_Dig = 1;

Hund_Seg = (Count / 100)%10; 			// TENS_SEG >>tens
PORTD = mask(hund_Seg); 			// Send to PORTD
Hund_Dig=0; 				// Enable digit 1>>RA0
}
else
if(Flag == 2) 				// Do digit 1
{
Ones_Dig = 1;
Hund_Dig = 1;
Thous_Dig = 1;
Tens_Seg = (Count / 10)%10; 			// TENS_SEG >>tens
PORTD = mask(Tens_Seg); 			// Send to PORTD
Tens_Dig=0; 				// Enable digit 1>>RA0
}

 else
if(Flag == 3) 				// Do digit 1
{
Tens_Dig = 1;
Hund_Dig = 1;
Thous_Dig = 1;

Ones_Seg = Count %10; 			// TENS_SEG >>tens
PORTD = mask(Ones_Seg); 			// Send to PORTD
Ones_Dig = 0; 				// Enable digit 1>>RA0
}

 Flag =Flag++;
if (Flag > 3)    Flag=0;

				// Toggle Flag as switch  , Counter


}
//
// Start of MAIN Program. configure PORTA and PORTD as outputs.
// In addition, configure TMR0 to interrupt at every 10ms
//
void main()
{
ADCON1=0X07;        		//set A PORT general I/O
TRISD= 0; 			// PORTD are outputs
PORTD=0XFF;
TRISA = 0; 			//  outputs
PORTA=0XFF;
TRISB=0XFF;
PORTB=0XFF;

// Configure TMR0 timer interrupt
OPTION_REG = 0xC4;	 	// Prescaler = 32
TMR0 = 100; 			// Load TMR0L with 100
INTCON = 0xA0; 			// Enable TMR0 interrupt

for(;;) // Endless loop
{

//UP Count
if (Button(&PORTB, 0, 1, 0)) {               		// Button 0 : Detect logical 0
      oldstate1 = 1;                              		// Update flag
    }
    if (oldstate1 && Button(&PORTB, 0, 1, 1)) {   	// Detect zero-to-one transition
        Count = Count +1;
        oldstate1 = 0;                                                 	// Update flag
    }
//DOWN Count
        if(Button(&PORTB,1,1,0)){		// Button 1 : Detect logical 0
        oldstate2 = 1;                              		// Update flag
}

          if (oldstate2 && Button(&PORTB, 1, 1, 1)) {   	// Detect zero-to-one transition
            Count = Count -1;
            oldstate2 = 0;                              		// Update flag
}

    if (Count > 9999)                 			// if it's more than 9999 go to 0;
   Count = 0;

}
}

اعلانات

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 28-07-2017, 03:29 PM المشاركة 154   
افتراضي


الموديول TIMER1 :
• الموديول Timer1 هو مؤقت / عداد 16-bit يتكون من سجلين 8-bit هما السجل TMR1H و السجل TMR1L ، وهى قابلة للقراءة منها والكتابة إليها .
• زوج سجلات المؤقت TMR1 تتزايد من 0000h إلى FFFFh وتلف إلى 0000h . مقاطعة المؤقت TMR1 ، إذا كانت ممكنة ، تتولد عند الطفحان overflow حيث يتم تحديد (1) بت علم المقاطعة TMR1IF (PIR1<0>) . هذه المقاطعة يمكن تمكينها / تعطيلها عن طريق تحديد (1) / مسح (0) بت تمكين المقاطعة
TMR1IE (PIE1<0>) .
المؤقت Timer1 يمكن أن يعمل فى نظامين :
• نظام المؤقت timer .
• نظام العداد counter .
يتم تحديد نظام الغمل عن طريق بت اختيار الساعة TMR1CS (T1CON<1>) .
فى نظام المؤقت ، يتزايد المؤقت Timer1 كل دورة تعليمة .
فى نظام العداد ، يتزايد عن كل حافة صاعدة لدخل الساعة الخارجية .
• يمكن تفعيل / تعطيل المؤقت Timer1 عن طريق تحديد (1) / مسح (0) بت التحكم
TMR1ON (T1CON<0>) .



[img] [/img]

عمل المؤقت Timer1 فى نظام المؤقت Timer :
يتم اختيار نظام المؤقت timer عن طريق مسح (0) البت TMR1CS (T1CON<1>) . فى هذا النظام ، يكون دخل الساعة إلى المؤقت هو Fosc/4 . بت النحكم فى التزامن T1SYNC (T1CON<2>) لا يكون لها تأثير لأن الساعة الداخلية تكون دائما متزامنة .
عمل المؤقت Timer1 كعداد Counter :
المؤقت Timer1 قد يعمل فى أى من النظام المتزامن أو الغير متزامن اعتمادا على تحديد البت TMR1CS .
عندما يتم تزايد المؤقت Timer1 من خلال مصدر خارجى ، يحدث التزايد عند الحافة الصاعدة . بعد تمكين المؤقت Timer1 فى نظام العداد يجب أن لدى الموديول أولا حافة هابطة قبل أن يبدأ الغداد فى التزايد .





صيغة حساب الزمن :

كود:
T  = machine cycle * prescaler * count (65536 - TMR1H: TMR1L);
Machine cycle = 4 / Fosc;
Fosc  is the crystal oscillator clock frequency
مثال : توليد زمن قدرة واحد ثانية باستخدام كريستال بتردد 20MHz .

كود:
Machine cycle = 4 / 20Mhz = 0.2us. T = 0.2 * 4 * 12500 = 10000us or 10ms.
سوف نستخدم المقاطعة للحصول على زمن واحد ثانية بعد 100 مرة مقاطعة .


كود:
Char count;
	
void  interrupt () { 
Count ++ ;       // for each TIMER1 interrupt increments the counting variable
TMR1L = 0x2C ;   // recharge the TMR1L;
TMR1H = 0xCF ;   // recharge the TMR1H;
PIR1.TMR1IF = 0 ;  // clear the overflow.
}
	
void  main () {
INTCON.GIE = 1 ; // enable global interruption;
INTCON.PEIE = 1 ; // enable interruption of peripherals;
PIE1.TMR1IE = 1 ; // enable interrupt of TIMER1;
// TMR1 receives the value 53036 (65536 - 12500), which in Hexadecimal is 0xCF2C
TMR1L = 0x2C ; // least significant byte
TMR1H = 0xCF ; // most significant byte
T1CON = 0b00100001 ; // Timer mode, prescaler 1: 4, internal clock;
while ( 1 ) {
if (count == 100 ) {     // when count = 100, that is, when time reaches
PORTB.RB0 = ~ PORTB.RB0 ; // 1s (100 * 10ms) reverses the state of portb, pin RB0.
}                     
	
}
}

اعلانات اضافية ( قم بتسجيل الدخول لاخفائها )

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 28-07-2017, 10:58 PM المشاركة 155   
افتراضي


موديول المؤقت Timer2 :
موديول المؤقت Timer2 هو مؤقت 8-bit بقاسم تردد سابق prescaler وقاسم تردد لاحق postscaler . هذا الموديول يمكن أن يستخدم مع موديول تعديل عرض النبضة PWM . السجل TMR2 هو سجل قابل للقراءة والكتابة ويتم مسحه عند أى إعادة Reset للجهاز .
ساعة الدخل (Fosc/4) لها خيار لقاسم تردد سابق بنسبة 1:1, 1:4,1:16 ، يتم اختيارها بواسطة بتات التحكم
T2CKPS1:T2CKPS0 (T2CON<1:0>) .
الموديول Timer2 له سجل فترة 8-bit يسمى PR2 .
يتم تزايد المؤقت Timer2 من 00h حتى يطابق السجل PR2 عندئذ يتم يعود reset إلى الصفر 00h عند دورة التزايد التالية . السجل PR2 هو سجل قابل للقراءة والكتابة . عند الإعادة Reset يتم تهيئة السجل PR2 بالقيمة FFh .
الخرج المطابق للسجل TMR2 يذهب خلال مقياس التردد اللاحق 4-bit postscaler ( يعطى مقياس 1:1 إلى 1:16 ) ، لتوليد المقاطعة بالمؤقت TMR2 ، بتحديد علم البت TMR2IF (PIR1<1>) .
يمكن غلق المؤقت Timer2 عن طريق مسح بت التحكم TMR2ON (T2CON<2>) ، لتقليل استهلاك القدرة .



الشكل التالى يبين سجل التحكم فى المؤقت Timer2 :





صيغة حساب زمن المقاطعة بالمؤقت Timer2 :

كود:
T = machine cycle * prescaler * postscaler * PR2
Machine cycle = 4 / Fosc
مثال :

كود:
Using a clock of 12Mhz, prescaler 1:16 and postscaler 1:16.
T = (4/12) * 16 * 16 * 255 = 21760us = 21.7ms
البرنامج :

كود:
void  interrupt () {
PORTB .F1 = ~ PORTB .F1 ; // reverses the state of pin RB1
PIR1 .TMR2IF = 0 ; // clears the interrupt flag
}
	
void  main () {
INTCON .GIE = 1 ; // enable global interruption
INTCON .PEIE = 1 ; // enable interruption of peripherals
PIE1 .TMR2IE = 1 ; // enable interrupt of TIMER2
T2CON = 0b01111111 ; // Postcaler 1:16, TIMER2 on and prescaler 1:16;
TRISB .F1 = 0 ; // define pin RB1 as output
PORTB .F1 = 0 ; / Sets pin RB1 as initial state at low level
PR2 = 255 ; // sets the value for PR2
}


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 28-07-2017, 11:25 PM المشاركة 156   
افتراضي


تدريب على المقاطعة باستخدام المؤقتات
الغرض
• استخدام المؤقتات TMR0, TMR1 , TMR2 .
• استخدام المقاطعات .
ربما لاحظت وجود عيب عند تنفيذ التأخير عند استخدام الحلقات.
في مثل تلك الحالة يكون الميكروكونترولر 'أسير' ولا يفعل شيئا. ببساطة ينتظر لحين مرور بعض الوقت.
هذا الوقت الضائع ترفا غير مقبول لذلك يجب تطبيق بعض الطرق الأخرى .

هل تتذكر موضوع المؤقتات ؟
هل تتذكر موضوع المقاطعات ؟
هذا التدريب يصنع رابط بينهما بطريقة عملية .

الدائرة الكهربية :




فكرة البرنامج :

• مطلوب توفير تأخير طويل بما يكفى لملاحظة التغيرات على المنفذ . يستخدم لذلك الموقت TMR0 مع تخصيص "معامل القسمة " prescaler لهذا الغرض.
• يتم إنشاء مقاطعة عند كل حدوث طفحان overflow بسجل المؤقت TMR0 فيتم تنفيذ روتين المقاطعة وفى كل مرة يقوم روتين المقاطعة تلقائيا بتزايد المتغير "cnt" بواحد .
• عندما تصل القيمة الموجودة بهذا المتغير إلى 400 يتم تزايد المنفذ port B بواحد وتظهر النتيجة على شكل إضاءة ليدات .
يتم تنفيذ الإجراء بأكمله من 'وراء الكواليس، مما يمكن الميكروكونترولر بعمل شىء آخر .

النتيجة :
إضاءة الليدات الثمانية المتصلة بالمنفذ PORT B بشكل يمثل الأرقام من 1 إلى 255 بالنظام الثنائى أى من 00000001 إلى 11111111 .



حساب زمن المقاطعة :

كود:
(4/8MHz) * prescaler * (255-96)
0.5 * 32 * 159 = 2544us = 2.544ms
2.544 * 400 times = 1 sec

البرنامج :

كود:
unsigned cnt;                 	// Define variable cnt

void interrupt() {
    cnt++;                    	// Interrupt causes cnt to be incremented by 1
    TMR0 = 96;               	// Timer TMR0 is returned its initial value
    INTCON = 0x20;           	// Bit T0IE is set, bit T0IF is cleared
}

void main() {

    OPTION_REG = 0x84;         // Prescaler is assigned to timer TMR0
    TRISB = 0;               	// All port B pins are configured as outputs
    PORTB = 0x0;              	// Reset port B

    TMR0 = 96;                	// Timer T0 counts from 96 to 255
    INTCON = 0xA0;            	// Enable interrupt TMR0

    cnt = 0;                  	// Variable cnt is assigned a 0
    
    do {                      	// Endless loop

        if (cnt == 400) {    	// Increment port B after 400 interrupts
            PORTB = PORTB++;  	// Increment number on port B by 1
            cnt = 0;          	// Reset variable cnt
        }

    } while(1);
}
المقاطعة باستخدام المؤقت TMR1 :
فى هذه الحالة يتم تمكين المقاطعة بعد حدوث طفحان فى المؤقت TMR1 والمكون من السجلين
(TMR1H, TMR1L). مزيج من تغيرات الخانات فى المنفذ PORT B يختلف عن البرنامج السابق حيث يتم إضاءة الأربعة خانات الأولى ثم بعد فترة التأخير تنطفأ ويتم إضاءة الأربع خانات الأخيرة وبعد فترة التأخير تتكرر العملية .



حسابات زمن المقاطعة :

كود:
TMR1H = 0x80; // Set initial value for timer TMR1
TMR1L = 0x00;  // TMR1 = 32768
(4/8MHz) * prescaler * (65535 – 32768 ) 
0.5 * 1 * 32767 = 16383.5 us = 16.384 ms
16.384 ms * 76 times = 1.2 sec
البرنامج :

كود:
unsigned short cnt; // Define variable cnt
void interrupt() {
cnt++ ; // Interrupt causes cnt to be incremented by 1
PIR1.TMR1IF = 0; // Reset bit TMR1IF
TMR1H = 0x80; // TMR1H and TMR1L timer registers are returned
TMR1L = 0x00; // their initial values
}
void main() {
PORTB = 0xF0; // Initial value of port B bits
TRISB = 0; // Port B pins are configured as outputs
T1CON = 1; // Set timer TMR1 , prescaler 1:1 
PIR1.TMR1IF = 0; // Reset bit TMR1IF
TMR1H = 0x80; // Set initial value for timer TMR1
TMR1L = 0x00;
PIE1.TMR1IE = 1; // Enable interrupt on overflow
cnt = 0; // Reset variable cnt
INTCON = 0xC0; // Enable interrupt (bits GIE and PEIE)
do { // Endless loop
if (cnt == 76) { // Change port B state after 76 interrupts
PORTB = ~PORTB; // Number in port B is inverted
cnt = 0; // Reset variable cnt
}
} while (1);
}

المقاطعة باستخدام المؤقت TMR2
• فى هذه الحالة تحدث المقاطعة بعد حدوث طفحان للمؤقت TMR2 .
• يتم إنشاء دالة جديدة تسمى Replace والتى لا تنتمى للغة السى وتستخدم فى عكس حالة أطراف المنفذ .
النتيجة إضاءة الليدات الفردية والانتظار لفترة ثم العكس أى إضاءة الليدات الزوجية والانتظار لفترة ثم تكرار العملية .



حسابات زمن المقاطعة :

كود:
(4/Fosc) * prescaler * postscaler * PR2
(4/8MHz) * 16 * 16 * 255 = 32640 us = 32.640 ms 
32.640 * 30 times = 1 sec
البرنامج :

كود:
unsigned short cnt; // Define variable cnt
void Replace() {
PORTB = ~PORTB; // Define new function ‘Replace’
} // Function inverts port state
void interrupt() {
if (PIR1.TMR2IF) { // If bit TMR2IF = 1,
cnt++ ; // Increment variable cnt by 1
PIR1.TMR2IF = 0;// Reset bit and
TMR2 = 0; // reset register TMR2
}
}
// main
void main() {
cnt = 0; // Reset variable cnt
PORTB = 0b10101010; // Logic state on port B pins
TRISB = 0; // All port B pins are configured as outputs
T2CON = 0xFF; // Set timer2, prescaler=16, postscaler=16,TMR2ON 
TMR2 = 0; // Initial value of timer register TMR2
PIE1.TMR2IE = 1; // Enable interrupt
INTCON = 0xC0; // Set bits GIE and PEIE
while (1) { // Endless loop
if (cnt > 30) { // Change PORTB after more than 30 interrupts
Replace(); // Function Replace inverts the port B state
cnt = 0; // Reset variable cnt
}
}
}


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 30-07-2017, 04:07 PM المشاركة 157   
افتراضي


التعديل فى عرض النبضات PWM



مقدمة :
الكثير من دوائر التحكم فى القدرة الكهربائية تستخدم تقنية "التعديل فى عرض النبضات" PWM كأساس لعملها .
لفهم كيف تقوم هذه التقنية بالتحكم فى القدرة الكهربائية ، تخيل جزء من دائرة على شكل مفتاح "سريع الفعل" والحمل المراد التحكم فيه (مصباح على سبيل المثال) كما فى الشكل التالى :



عندما يكون المفتاح مفتوح open لا يمر تيار فى المصباح وتكون القدرة المغذاة بصفر . فى لحظة غلق close المفتاح يستقبل الحمل الجهد الكامل للمصدر ويتم الإمداد بأقصى قدرة .
كيف نمد الحمل بقدرة متوسطة ؟ ولتكن 50% على سبيل المثال . أحد الأفكار هى جعل المفتاح يفتح ويغلق بسرعة للحصول على زمن فتح 50% وزمن غلق 50% . هذا يعنى أن ، فى المتوسط ، نصف الزمن يوجد به تيار (قدرة) ونصف الزمن لا يوجد به تيار (قدرة) .
يمكن القول أن القدرة المتوسطة كما لو كنا طبقنا جهد متوسط بقيمة 50% من جهد الدخل .



لاحظ أن غلق المفتاح يمكن أن يحدد عرض (زمن تواجد ) النبضة طالما أنه ظل فى هذه الحالة ، وأن الفترة الزمنية بين النبضات تستمر طالما أنه مفتوح . ويعرف مجموع الإثنين معا "بالزمن الدورى " للدورة والذى يتحكم فى التردد . العلاقة بين زمن تواجد النبضة والزمن الكلى (الزمن الدورى) تعرف"بدورة الخدمة أو العمل " duty cycle .
بتغيير عرض النبضة يمكننا التحكم فى القدرة المتوسطة المغذاة للحمل . وبالتالى عندما يتغير عرض النبضة من الصفر إلى أقصى قدرة تتغير أيضا دورة الخدمة كما هو مبين بالشكل التالى :



هذا المبدأ يستخدم للتحكم الدقيق باستخدام PWM عن طريق تعديل (تغيير) عرض النبضة للتحكم فى دورة الخدمة للإشارة المطبقة على الحمل وبالتالى القدرة المغذاة إليه .



مما سبق نستنج أن إشارة PWM تتحدد عن طريق :
• تردد الإشارة .
• دورة خدمة الإشارة .
العمل بتعديل عرض النبضات PWM والميكروكونترولر PIC :
الميكركونترولر PIC16F877A ، على سبيل المثال ، فى بناءه الداخلى 2 موديول CCP "إلتقاط – مقارنة - تعديل بعرض النبضة) هما CCP1 و CCP2 .
يمكننا التعامل بسهولة مع الدوال الخاصة بتوليد أشارة ذات تعديل عرض النبضة PWM بالميكروسى .
الدوال التى تتناول الموديول CCP1 هى :

كود:
• Pwm1_Init
• Pwm1_ Set _Duty
• Pwm1_Start
• Pwm1_Stop
1- دالة تهيئة تردد إشارة تعديل عرض النبضة PWM :
فى الميكروسى تستخدم الدالة Pwm_Init() فى تحديد تردد إشارة PWM :

الصيغة :

كود:
 Pwm1_Init (freq);
حيث :
freq : هو التردد المطلوب لإشارة PWM .
مثال:

كود:
Pwm1_Init (4000) // بدء توليد إشارة بتعديل عرض النبضة بتردد 4 كيلوهرتز
2- دالة "دورة الخدمة" Duty Cycle
من خلال هذه الدالة يمكن التحكم فى دورة الخدمة لأشارة PWM . قيمة دورة الخدمة تتغير من الصفر إلى 255 ، الصفر يساوى 0% والقيمة 127 تساوى 50% والقيمة 255 تساوى 100% .

الصيغة :

كود:
PWM1_Set_Duty (duty_ratio);
حيث :
duty_ratio : قيمة من نوع الحرف char (0 to 255) تحدد النسبة المئوية لدورة خدمة PWM .

مثال :

كود:
PWM1_Set_ Duty (192); // تحديد دورة الخدمة بالقيمة 75 بالمئة



ونظرا لأن الميكروكونترولر يتعامل مع الأرقام ، ينبغى تحويل النسبة المئوية لدورة الخدمة إلى رقم .
يتم حساب قيمة دورة الخدمة من العلاقة :

كود:
 (Percent * 255) / 100
• لحساب القيمة المناظرة لدورة خدمة 10 % :

كود:
 (10 * 255) / 100 = 25.5
ولأن القيمة يجب أن تكون من نوع الحرف char فيجب أن تكون عدد صحيح بين الصفر و 255 , بالتالى نأخد القيمة 25 أى :

كود:
 PWM1_Set_Duty(25);
• Duty of 50%

كود:
 (50 * 255) / 100 = 127.50
كود:
PWM1_Set_Duty(127);
• Duty of 90%

كود:
 (90 * 255) / 100 = 229.50
كود:
PWM1_Set_Duty(229);
3- دالة البدء Start ودالة الانتهاء Stop :
من خلال دالة البدء PWM1_Start(); نقوم ببدء توليد إشارة PWM بالميكروكونترولر PIC ومن خلال دالة النهاية PWM1_Stop(); يتم إنهاء توليد إشارة PWM .

الصيغة :

كود:
 Pwm1_Start (); // initial signal generation module CCP1 PWM PIC
Pwm1_Stop (); / / stops the PWM signal generation module CCP1 PIC
مثال بسيط :


كود:
void main () {
  
     Pwm1_init (5000);
     Pwm1_ Set_Duty (127);
     Pwm1_Start ();

     while (1);
}

فى هذا البرنامج يتم تهيئة الموديول CCP1 بالميكروكونترولر PIC ليعمل بنظام PWM بتردد 5Khz ودورة خدمة 50% كما هو مبين فى الشكل التالى :



مثال آخر :
استخدام الموديول CCP2 بالميكروكونترولر PIC16F877A :

كود:
void main() {
  
    Pwm2_init(5000);
    Pwm2_Set_Duty(127);
    Pwm2_Start();

    while(1);.
}


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 30-07-2017, 05:27 PM المشاركة 158   
افتراضي


تدريب : تعديل عرض النبضات PWM باستخدام موديول المقارنة CCP بالميكروكونترولر PIC16F628A
الدائرة الكهربية :
يتم توصيل 2 مفتاح ضاغط إلى الأطراف RB0 , RB1 كمداخل . ويتم تشغيل ليد بواسطة الخرج المعدل PWM من الطرف RB3/CCP1 خلال مقاومة لتحديد التيار330R.يتم تزايد أو تناقص دورة الخدمة لإشارة الخرج PWM باستخدام المفاتيح الموجودة كمداخل وهذا يؤدى إلى التغيير فى شدة إضاءة الليد .



البرنامج :
البرنامج يعطى عشر مستويات مختلفة للتحكم فى شدة إضاءة الليد بتغيير دورة الخدمة من 0 إلى 250 بخطوة 25 فى كل مستوى . يتم تغيير دورة الخدمة عن طريق الضغط على المفاتيح الضاغطة UP , DOWN .

كود:
/*
Description: CCP module generating PWM
 MCU: PIC16F628A
 Oscillator: XT, 4.0 MHz
*/
 sbit UP at RB0_bit;
 sbit DOWN at RB1_bit;
 unsigned short new_DC, current_DC;

 void debounce(){
  Delay_ms(300);
 }

 void main() {
 CMCON = 0x07; // Disable comparators
 PORTB = 0x00; 
 TRISB = 0b00000011; // RB0, RB1 input, RB3 (PWM1) output
 PWM1_Init(5000);    // PWM module initialization (5KHz)
 new_DC = 0;         // Initial value of variable Duty Cycle
 current_DC = 0;
 PWM1_Start();       // Start PWM1 module with Zero DC
 PWM1_Set_Duty(current_DC);
 do {
  if (!UP){      // If the button connected to RB0 is pressed
   debounce();
   if (new_DC < 250)      // Don't go above 250
   new_DC = new_DC + 25 ; // increment Duty Cycle by 25
  }
  if (!DOWN) {   // If the button connected to RB1 is pressed
   debounce();
   if (new_DC !=0)        // Don't go below 0
   new_DC= new_DC - 25 ; // Decrement Duty Cycle by 25
  }
  if (current_DC != new_DC) {
   current_DC = new_DC ;
   PWM1_Set_Duty(current_DC); // Change the current DC to new value
  }
 } while(1);
}  // END main()
النتائج :
عند توصيل القدرة للدائرة تبدأ الإضاءة بمستوى الصفر (الدورة كلها OFF مستمر ) أى دورة الخدمة بصفر . بالضغط على المفتاح الضاغط UP تتزايد دورة الخدمة (يتزايد الجزء الموجب من الدورة ON) وتتزايد شدة إضاءة الليد حتى تصل دورة الخدمة إلى الواحد الصحيح (الدورة كلها ON مستمر) .


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 30-07-2017, 05:34 PM المشاركة 159   
افتراضي


تدريب : التحكم فى سرعة محرك بنظام PWM بالتعديل فى دورة الخدمة عن طريق مقاومة متغيرة متصلة بمدخل تناظرى
سوف نقوم بإنشاء برنامج بلغة السى الغرض منه تحميل دالة دورة الخدمة Pwm_set_duty() بقيمة ناتجة عن قراءة جهد تناظرى على المدخل AN0 أى أن دورة الخدمة تتغير من 0% إلى 100% ( من 0 إلى 255 ) تبعا لتغير جهد الدخل التناظرى والمناظر للقيمة من0 إلى 1023 وبالتالى يقوم الخرج PWM بالتحكم فى سرعة محرك المروحة .

الدائرة الكهربية :



البرنامج :

كود:
/*
************************************************ 
البرنامج : دخل تناظرى و تعديل فى عرض النبضة
الغرض : التحكم فى محرك مروحة عن طريق تعديل عرض النبضات من خلال دخل تناظرى
*/

void main () {

unsigned int a = 0; // تعريف متغير نوع عدد صحيح لحفظ نتيجة التحويل من تناظرى لرقمى  

ADCON1 = 0b00001001; // تهيئة طرف الدخل التناظرى  
TRISA = 255; // تهيئة أطراف المنفذ كمداخل 

Pwm_Init (5000); // تهيئة موديول تعديل عرض النبضة بتردد 5 كيلوهرتز 
Pwm_Start (); //بدء عمل موديول تعديل عرض النبضة  

do // حلقة غير منتهية 
 {
 a=Adc_Read(0); // قراءة القناة التناظرية صفر وحفظ قيمة نتيجة التحويل فى سجل مؤقت   
 a = (a / 4); // تحويل القيمة السابقة إلى نسبة مئوية لدورة الخدمة  
 Pwm_Set_Duty (a); //إرسال دورة الخدمة إلى موديول التحكم فى عرض النبضات لتظهر على طرف الخرج الخاص به  Delay_10us; // الانتظار لمدة 10 ميكروثانية 
}
   while (1); // التكرار بصفة مستمرة 

}
الشكل الموجى الناتج كما فى الشكل التالى :







الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 30-07-2017, 08:47 PM المشاركة 160   
افتراضي


التحويل من رقمى لتناظرى DAC وتوليد موجة جيبية باستخدام الميكروكونترولر PIC :
يمكن أن يتم هذا التحويل بطريقتين، الأولى استخدام موديول PWM بالميكروكونترولر ، والثانية استخدام عناصر خارجية للحصول على فرق الجهد .
التحويل باستخدام PWM :
التحويل من رقمى لتناظرى بموديول PWM يتم عن طريق أخذ الإشارة ذات التعديل بعرض النبضات وإجراء عملية إستخلاص demodulation عن طريق مرشح تمرير منخفض low-pass filter. هذا المرشح يجب أن يكون له تردد قطع cutoff frequency أقل بكثير من تردد أخذ العينة بما يقارب 10 مرات ، حيث أن الهدف منه إزالة (التخلص من) تردد أخذ العينة . حساب تردد القطع للمرشح يخضع للعلاقة التالية :



الشكل التالى يوضح دائرة مرشح تمرير منخفض من الدرجة الأولى first order:



الشكل التالى يوضح دائرة مرشح تمرير منخفض من الدرجة الثانية second order :



معادلة حساب هذا المرشح :



التردد المخصص لحامل PWM يجب أن يكون أكبر بكثير من تردد أخذ العينة للإشارة المعدلة . لاستعراض عملية التحويل يتم التصميم بأخذ 20 عينة تناظر دورة واحدة لإشارة جيبية sine signal . الشكل التالى يبين العينات والشكل الموجى :






لفهم طريقة التنفيذ راقب وحلل وحاكى البرنامج التالى :

كود:
 
// Declaring Constants for sine wave.
 const unsigned short Sine_Wave [20] =
 {
 	127, 146, 163, 177, 185, 189, 185,
 	177, 163, 146, 127, 107, 90, 76,
 	68, 65, 68, 76, 90, 107
 };

 void main (void)
 {
 	// Declaration of variables.
	 unsigned short n = 0;
 	// Set the PWM module to Fpwm = 15.625K Hz
 	PWM1_Init (15625);
 	// Start of PWM signal.
 	PWM1_Start ();
 	while (1) 	// infinite loop.
 	{
 		// Loop for the 20 samples of a sine wave cycle.
 		for (n = 0; n <20; n ++)
 		{
			 // Changing the duty cycle of the PWM.
 			PWM1_Set_Duty (Sine_Wave [n]);
 			// Delay 50u sec.
 			delay_us (50);
 		}
 	}
 }
لتنفيذ المحاكاة تحتاح للأجهزة التالية :
16F877A, RES, CAP, OP1P و الأوسليسكوب OSCILLOSCOPE . وهذ الأخير هو أوسليسكوب تخيلى لعرض الأشارات التناظرية والرقمية بأربع قنوات فى نفس الوقت .
دائرة تنفيذ مرشح التمرير المنخفض للتخلص من التردد الحامل Fpwm وهو فى هذه الحالة 15.6KHz ، تردد القطع للمرشح تقريبا 1.5KHz .
مستقبلا ، فى تطبيقات المرشحات يوصى ، بتحديد قيمة للمكثف C بين 100pF و 100nF ويتم حساب المقاومة R من المعادلات المذكورة أعلاه .
بهذه العناصر يتم تكوين الدائرة التالية :



عند إحراز تقدم فى المحاكاة فإن ذلك يرجع ، بكل التقدير، للأوسلوسكوب التخيلى الذى يظهر الإشارة التناظرية الناتجة بالمتحكم الرقمى PIC من خلال وحدة PWM و مرشح التمرير المنخفض ، المظهر المرئى للأوسليسكوب كما فى الشكل التالى :








الساعة معتمدة بتوقيت جرينتش +3 الساعة الآن: 05:36 AM
موقع القرية الالكترونية غير مسؤول عن أي اتفاق تجاري أو تعاوني بين الأعضاء
فعلى كل شخص تحمل مسئولية نفسه إتجاه مايقوم به من بيع وشراء وإتفاق وأعطاء معلومات موقعه
التعليقات المنشورة لا تعبر عن رأي موقع القرية الالكترونية ولايتحمل الموقع أي مسؤولية قانونية حيال ذلك (ويتحمل كاتبها مسؤولية النشر)