ไม่ถนัดที่จะใช้ 8051 เพราะถนัดใช้แต่กับ Arduino IDE ไปหาหนังสือมาอ่าน ก็พอถูไถไปได้ ได้แต่ก็ไม่ดี ในอดีตก็เคยได้ลองกับพวก PIC16xx แต่ก็ไม่ได้อะไรเป็นชิ้นเป็นอัน ยิ่งนานวันยิ่งลืม
ตั้งแต่มีร้านออนไลน์จากจีน โลกโมดูลส่วนตัวก็เปลี่ยนไปเยอะ มีของเล่นต่างๆ มากมายก่ายกองให้เลือก ยังนึกถึงวันที่ซื้อหนังสือ+ชิพของไทย ราคาเกือบพัน เพราะเหตุนี้ มันจึงไกลเกินเอื้อมในการซื้อหามาเล่นได้เหมือนยุคนี้
แม้ว่ามันมีมานาน มันจะเป็นของโบราณ แต่มันก็ปรับปรุงอยู่เรื่อย อย่างเช่น ปรับมาเป็น single clock machine (1T) ตอนนี้ก็ยังถูกใช้งานอยู่ และยังไม่หายไปจากโลกนี้ มันต้องมีอะไรบางอย่างที่ดี อย่างน้อยราคาก็ถูก ในกล่องที่บ้านก็ยังมีอยู่ พวก 8051 มีทััง ATMEL, STC, WCH, NUVOTON งงตัวเองเลย ซื้อมาทำไม ไหนๆ ก็มีของแล้ว ก็คงต้องให้เวลาและลองใช้งานดู มีเป้าหมายก็แค่แก้เบื่อ
Fig.1 STC15W408AS demo board cost 1.98USD (aliexpress) |
Fig.2 STC15W401WS series. |
มี RC ในตัว ก็ประหยัดดี ซื้อมาประกอบเองก็ได้ จะว่าไป STM8S น่าใช้กว่า ถูกกว่าด้วย (0.7USD)
Fig.3 STC15W408AS TSSOP20 pin map |
คู่มือของ STC มีตัวอย่างให้ดู ลองทำตาม
1) ลองทำ PWM ใช้ module2 (CCP2) ออกที่ขา P3.7
void main()
{
CCON = 0x00;
CMOD = 0x00; // 0:Sysclk /12 0x0E:Sysclk/8
CL = 0;
CH = 0;
CCAPM2 = 0x42;
PCA_PWM2 = 0x00;
CCAP2L = 0x00; //%Duty [ 0xFFFF - (CCAP2H<<8+CCAP2L) ] /0xFFFF
CCAP2H = 0x80;
CR = 1;
while(1);
}
Fig.4 PWM 50% duty at 1.8kHz |
Fig.5 DIV_CLK register |
ลองปรับความถี่ให้มันน้อยลง ต้องกำหนดใน register CLK_DIV
CLK_DIV = 0x07 // Sysclk /128
จะได้ความถี่น้อยลงมาเหลือ 14Hz ความถี่ระดับนี้ สังเกตุเห็นได้ด้วยตาเปล่า
Fig.6 PWM with CLK_DIV= 0x07. |
2) Software Timer 16bit
ลองใช้งาน software timer และใช้ interrupt
void main()
{
//CLK_DIV = 0x04;
CMOD = 0x0D; //Sysclk/6 and ECF = 1
CCON = 0x00;
CL = 0x00;
CH = 0x00;
CCAPM2 = 0x48; //1001000B timer 16bit
CCAPM2 |= 0x01; //enable interrupt
CCAP2L = 0x00;
CCAP2H = 0x40;
CCON |= 0x40; //start timer CR = 1;
EA = 1;
while(1);
}
void PCA_isr() interrupt 7
{
CF = 0;
CCF2 = 0;
P10 = !P10; //sbit P10 = P1^0; Test OUTPUT
}
การคำนวณ
Sysclk 18432000Hz
Freq. = 18432000Hz / 6 / 0xFFFF = 46.88 Hz
T = 1 / f = 1 / 46.88 = 21.33ms
compare time ( CCAP2H<<8 + CCAP2L ) = 0x4000
Duty (0xFFFF - 0x4000) / 0xFFFF = (65535 - 16384) / 65535 = 0.75
Timer 21.33ms x 0.25 = 5.33ms
Fig.7 Software timer while setting system clock 18.432MHz |
เอาไปทำ millis()
3) ADC
STC15408AS มี ADC 8Channel 10bit อยู่ที่ P1.0 -P1.7 ตามคู่มือจะมี register ที่เกี่ยวข้องหลายตัว
Fig.8 ADC register |
จะเอา P1.x ไหนเป็น ADCx ก็ตั้งค่าใน P1ASF register โดยให้ bit นั้นเป็น 1
ถ้าให้ P1ASF = 0x01; ให้ P1.0 เป็น ADC0
P1ASF = 0x02; //0b00000010 ให้ P1.1 เป็น ADC1
ADC_CTR register เป็นตัวควบคุม ADC ต้องกำหนด sampling rate และเลือก ADCx ไหนที่จะทำ conversion ซึ่งมันจะทำทีละขา ทำเสร็จมันก็เก็บค่าไว้ใน ADC_RES, ADC_RESL จากนั้นจะเอาค่าไปทำไรก็ตามสะดวก
CLK_DIV นอกจากจะเอาไว้ทำตัวหารความถี่แล้วยังเอาไว้กำหนดการจัดเรียงข้อมูลค่า ADC_RES
กำหนดบิท ADRJ = 1 จะชิดขวา ส่วน ADRJ = 1 ชิดซ้าย
IE Interrupt Enable กำหนด EA, EADC เมื่อทำ conversion เสร็จจะให้ interrupt หรือไม่ ก็ควรเปิดการใช้งาน เพราะระหว่างการ conversion จะได้ทำอย่างอื่น เมื่อเกิด interrupt ขึ้นมา ก็ reset flag ซะเลย
void main(){
P1ASF = 0x02; //Select ADC1 P1.1 pin
CLK_DIV = 0x20;
ADC_RES = 0; //reset value
ADC_RESL = 0; //reset value
ADC_CONTR = 0xC0; //1100000B, Active ADC 180 clock cycle
ADC_CONTR |=0x01; //Conversion at ADC1 (P1.1)
ADC_CONTR |=0x08; //Start convertion, ADC_START = 1
EA = 1;
EADC = 1;
while(1);
}//end main
void ADC_isr() interrupt 5 using 1
{
ADC_CONTR &= !ADC_FLAG;
SendByte(ADC_RES); //ส่งค่าออกไปทาง serial *ต้องสร้างฟังก์ชั่น SendByte()
SendByte(ADC_RESL);
ADC_RES = 0; //reset value
ADC_RESL = 0; //reset value
ADC_CONTR = 0xC1; //1100001B, Active ADC 180 clock cycle at P1.1
ADC_CONTR |=0x08; //Start conversion, ADC_START = 1
}//end ADC ISR
Fig.9 ADC conversion value. |
ผลการทำงาน มันทำงานเร็วมาก ควรใช้ timer หรือว่า delay เข้ามากำหนดระยะห่าง
ไม่มีความคิดเห็น:
แสดงความคิดเห็น