Watchdog Timer สำหรับ 89S52 ใน Keil

ถ้าพูดถึงไมโครคอนโทรลเลอร์ตระกูล MCS-51 ที่ผมชอบใช้ ก็เป็นเบอร์ 89S52 เนื่องจากมีราคาที่ถูกมาก และที่ถูกอกถูกใจคือผมไม่ต้องถอด IC มา burn เหมือนแต่ก่อนแล้ว ผมต่อสายจาก parallel port มา burn IC ได้เลย (ISP Programming) สะดวกกว่า ICD2 ของ Microchip เสียอีก

เอาละมาเข้าเรื่องกันดีกว่า มันมีอยู่งานนึงที่ผมใช้ 89S52 แต่มันเป็นงานที่ทำตลอด 24 ชั่วโมง ฉะนั้นมันแฮงค์ไม่ได้เลย ผมจำได้ว่า 89S52 มันมี Watchdog Timer ในตัวด้วย เลยไม่รอช้าเปิด datasheet มาดู เค้าบอกว่าอย่างนี้

การที่จะ Enable ให้ Watchdog ทำงานนั้นให้เขียนข้อมูล 0x1E และ 0xE1 ลงไปใน register WDTRST ต้องเขียนต่อกันเลยนะถึงจะใช้ได้ ส่วน Watchdog Timer ตัวนี้เป็น Counter 13 บิตแล้วจะนับขึ้นทุก machine cycle แล้วถ้าปล่อยให้นับได้ถึง 8191 (0x1FFF) เมื่อไหร่ละก็ จะเกิดการรีเซต ฉะนั้นเราต้องเขียนโปรแกรมไปคอยเคลียร์ไม่ให้ Watchdog Timer มันนับไปถึงค่า Overflow 8191

การเคลียร์ Watchdog Timer ก็ทำเหมือนกับ enable นะแหล่ะ ก็เขียนข้อมูล 0x1E และ 0xE1 ลงไปใน register WDTRST ถ้าอยากรู้ว่า 8191machine cycle นี่นานขนาดไหนมาลองคำนวนเล่นๆกันดีกว่า

ตัวอย่าง สมมุติว่าใช้ XTAL 11.0592 MHz แล้ว clock 12 ลูกจะได้ 1 machine cycle

T = (8191*12)/(11059200) = 8.887 mS ฉะนั้นเราต้องไปเคลียร์ Watchdog Timer ทุกๆ 8.8 mS เป็นอย่างน้อย หรือใครจะเคลียร์ทุกๆ 1 mS ก็ยิ่งดี ส่วนตัวเลข 8191 นี่เค้ากำหนดมาตายตัว เราไม่สามารถ scale ได้

ลองดู code ที่จะนำไปใช้กับ Compiler keil ดู

อันดับแรกเราก็ต้องประกาศ sfr (Speacial Function Register) ก่อนเพราะใน AT89X52.h ไม่ได้ประกาศ register WDTRST มาให้

sfr WDTRST = 0xa6;
sfr AUXR = 0x8e;

จากนั้นก็ Enable และ เคลียร์ด้วย Sub void kickdog()

void kickdog()??????????????????????????????? //every 8191 Machine Cycle
{ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //~8 ms
WDTRST = 0x1e;
WDTRST = 0xe1;
}

จากนั้นเราก็หาที่วาง void kickdog() ใน function ต่างๆ (แนะนำว่าควรวางใน loop while(1) )? เพียงเท่านี้ 89S52 ของเราก็ทำงานได้นานแสนนาน โดยที่ไม่แฮงค์ (ถึงแฮงค์ก็รีเซตตัวเองขึ้นใหม่ได้)

การทดลองที่ 7 เขียนโปรแกรม Interface กับ DigitalPot

MCP4011

MCP4011

อาจจะมีบางงานที่คุณต้องการจะควบคุณสัญญาณ Analog ด้วย Digital I/O เช่นควบคุม Gain แต่ไม่รู้ว่าจะใช้อะไรควบคุม ลองมาดูตัวนี้ครับครับ MCP4011 Low-Cost 64-Step Volatile Digital POT มีความละเอียด 6 บิต หรือ 64 สเตป ใช้ขาสัญญาณเพียง 2 ขาในการ Interface ขา CS และ U/D

Volatile Digital Potentiometer in SOT-23 packages

64 Taps: 63 Resistors with Taps to VSS and VDD Simple Up/Down (U/D) Protocol Power-up to midscale

  • Resistance Values: 2.1Ohm, 5kOhm, 10kOhm, 50kOhm
  • Low Tempco: – Absolute (Rheostat): <150 ppm (typ.) – Ratiometric (Potentiometer): <10 ppm (typ.)
  • Low Wiper Resistance: 70? (typ.)
  • Low-Power Operation: 1mA Max Static Current
  • Wide Operating Voltage: 1.8V to 5.5V Extended Temperature Range: -40C to +125C
ตำแหน่งขา

ตำแหน่งขา

การเขียนโปรแกรมให้ POT มีค่าลดลง

void increase_pot (unsigned char nstep)
{
unsigned char a,cnt;
UD_POT = 0;
CS_POT = 0;
for (cnt = 0;cnt < nstep;cnt++){ a = 8;
while(a)
a–;
UD_POT = 1;
a = 8;
while(a)
a–;
UD_POT = 0;
}
CS_POT = 1;
}

ให้ขา U/D เป็น “0″ ก่อนแล้วจึงดึง CS ลง “0″ จากนั้นก็ส่ง pulse ไปที่ขา U/D ส่ง pulse ไป 1 ลูกค่า POT จะลดลงไป 1 Step

การเขียนโปรแกรมให้ POT มีค่าเพิ่มขึ้น

void decrease_pot (unsigned char nstep)
{
unsigned char a,cnt;
UD_POT = 1;
CS_POT = 0;
for (cnt = 0;cnt < nstep;cnt++){ a = 8;
while(a)
a–;
UD_POT = 0;
a = 8;
while(a)
a–;
UD_POT = 1;
}
CS_POT = 1;
}

ให้ขา U/D เป็น “1″ ก่อนแล้วจึงดึง CS ลง “0″ จากนั้นก็ส่ง pulse ไปที่ขา U/D ส่ง pulse ไป 1 ลูกค่า POT จะเพิ่มขึ้นไป 1 Step

การทดลอง

การทดลอง MCP4011 DigitalPot
การทดลอง MCP4011 DigitalPot

ทฤษฎีก็ว่ากันไปแล้วมาถึงการทดลอง ผมได้ลองใช้ MCP4011 เป็นตัวปรับ Gain ของ AMP LM386 โดยให้ไมโครคอนโทรลเลอร์ 89S52 รับค่าจากสวิตช์ ถ้ากดสวิตช์เพิ่มเสียง MCP4011 ก็จะเพิ่มค่า R ทำให้เสียงดังขึ้น และจะมีตัวเลขแสดง Step ของ MCP4011 ใชว์ที่จอ LCD16x2 ด้วย ในทางตรงกันข้าม ถ้ากดสวิตช์ลดเสียงก็จะลดค่า R ทำให้เสียงค่อยลง ค่าสูงสุดที่กดได้จะเป็น 64/64 และค่าต่ำสุดเท่ากับ 0/64 สำหรับตัว MCP4011 ถ้าสนใจสามารถซื้อได้ที่ บ. Electronics Source

89S52 Port Define

  • P1.1 <—> CS (MCP4011)
  • P1.2 <—> U/D (MCP4011)
  • P1.3 <—> SW UP
  • P1.4<—> SW UP

Download Code MCS51 การทดลองที่ 7 เขียนโปรแกรม Interface กับ DigitalPotentiometer ควบคุมความดังของเสียงเพลงด้วยการกดปุ่ม

สร้างเสียงดนตรีด้วย Microcontroller MCS-51

โปรเจคนี้ผมทำขึ้นตอนที่เรียนอยู่ลาดกระบังครับ โดย อ. ให้คิดโปรเจคง่ายๆ ใช้ไมโครคอนโทรลเลอร์เขีียนโปรแกรม เลยมาเป็นโปรเจคนี้ ผมคิดว่าทุกท่านคงรู้จัก Mini organ คือมันก็คล้ายๆกับ Electone หรือ Keyboard นั่นแหล่ะเพียงแต่มันมีตัวโน๊ตไม่เยอะ ตอนที่เรียนนั้นเถียงกับ อ.แทบตาย โดยทาง อ.บอกว่าผมไม่สามารถ Generate ความถี่ออกมาที่ลำโพงได้เพราะ MCU ต้องไป Scan Key ด้วย ผมก็เถียงว่ามันทำได้

หลักการทำงาน

89C52 จะ Scan Key ไปทีละ row และ Column เมื่อเจอ Key ไหนกดก็จะสร้างสัญญาณ Logic”0″ และ Logic”1″ จากขา P3.5 เป็นสัญญาณ Square wave โดยค่า Time delay ในแต่ละปุ่มจะไม่เท่ากัน ทำให้ความถี่ของแต่ปุ่มมีเสียงเทียบได้กับตัวโน๊ตดนตรี โด เร มี ฟา ซอล ลา ที โด เมื่อสร้าง Square wave มาครบ 1 ลูกแล้ว 89C52 จะเช็คอีกว่ามีการปล่อย Key ยังถ้ายังไม่ปล่อยก็ generate เสียงต่อไป ถ้ามีการกด Key ใหม่ก็จะ Generate โทนเสียงใหม่วน loop ไปเรื่อยๆ

?

?;*********************************
;Microcontroller mini organ
;Pragrammer:Pratchaya Tongthong????
;*********************************
;P3.5 —-> SPEAKER????
MSEC??EQU??7FH
S_CODE??EQU??7DH
KEY???EQU??7CH??
S_CODE??EQU??7DH
NOTE1??EQU??7BH
NOTE2??EQU??7AH
KEYBUF??EQU??79H
PNTERHI??EQU??78H
PNTERLO??EQU??77H
DURATION?EQU??76H
;***********************************************
;Start? Scan key
;***********************************************INIT:??ACALL?SCAN?
???CJNE?A,#00,SONG
???SJMP??INIT
???
SCAN:??MOV??S_CODE,#00H???????
???MOV??P1,#0FFH???????
???SETB?P3.0
???SETB?P3.1
???SETB?P3.2??
???
???CLR ?P3.0????? ;Scan first column
???MOV??A,P1
???CJNE?A,#0FFH,CONVERT
???SETB?P3.0
???MOV??A,S_CODE?????
???ADD??A,#08
???MOV??S_CODE,A??
??????????????????????????????????????????????????
???CLR??P3.1????? ;Scan second column
???MOV??A,P1
???CJNE??? A,#0FFH,CONVERT
???SETB?P3.1????
???MOV??A,S_CODE?????
???ADD??A,#08
???MOV??S_CODE,A??
???
???CLR??P3.2????? ;Scan third column
???MOV??A,P1????
???SETB?P3.2?
???CJNE?A,#0FFH,CONVERT
???MOV??S_CODE,#00H
???SJMP??END
CONVERT:?INC??S_CODE???
???JNB??ACC.0,END
???RR??A
???SJMP?CONVERT
END:??MOV??KEY,S_CODE????
???MOV??A,KEY
???CJNE?A,#00,END1
???RET?
END1:??MOV??DPTR,#NOTE_1??
???MOV??A,KEY
???MOVC?A,@A+DPTR
???MOV??NOTE1,A? ????
???MOV??DPTR,#NOTE_2??
???MOV??A,KEY
???MOVC?A,@A+DPTR
???MOV??NOTE2,A
???RET
???
;***********************************************
;Generate Tone
;***********************************************
SONG:??CLR??P3.5
???ACALL?PERIOD
???SETB?P3.5
???ACALL?PERIOD
???MOV??P1,#0FFH
???MOV??A,P1
???CJNE?A,#0FFH,SONG
???SJMP?INIT
PERIOD:??MOV??R0,NOTE1
L1:???MOV??R1,#48
???DJNZ?R1,$
???NOP
???DJNZ?R0,L1
???MOV??R0,NOTE2
???DJNZ?R0,$
???RET
;***********************************************
;Note1 and Note2
;***********************************************??
NOTE_1:??DB??0,23,20,18,17,16,15,14,13,13,12,11,10,10,9,9,8,8,7,7,6
NOTE_2:??DB??0,20,42,27,24,23,28,33,42,08,17,32,48,18,38,11,34,9,36,14,43?

ทดสอบ

ผมลองเล่นเพลง Happy Birthday ครับ เสียงที่ออกมาก็ OK เลยไม่ผิดเพี้ยน

Download Assembly Code