วันอาทิตย์ที่ 29 มกราคม พ.ศ. 2566

STC8F1K08S2

    

Fig.1 STC8F1K08S2 MCU


    เหตุจากการที่ซื้อ MCU ของ STC มาหลายอัน พอมีเวลาว่าง เอามาลองเล่นเรื่อยๆ วันนี้ถึงคิว STC8F1K08S2 TSSOP20 มี 20 pin ราคา 0.38USD (ประมาณ 13 บาท)

Fig.2 STC8F1K08's features that lack of PCA

    มี 3 timer, 2 uart, SPI,I2C แต่ไม่มี ADC, PWM,PCA,CCP ฉะนั้นก็ต้องใช้ในงานที่ไม่ต้องการ analog input ส่วน PWM หรือ analog output ก็เขียนโปรแกรมให้มันทำงานได้ โดยใช้ timer ช่วยกำหนดเวลา จะว่าไป STC8H, STC8G ดูดีกว่า เพราะมี ADC

    8F1K08 series นี้ มี Flash 8kB, SRAM 1.2kB นอกนี้ยังมี EEPROM ขนาด 3kB ที่เขียนได้เป็นแสนๆ ครั้ง

    เมื่อไม่มี PCA ก็ไม่มี software timer ให้ใช้ แต่ก็มี timer0,1,2 ให้ใช้ ต้องเอามาทำตัวจับเวลาสักอัน และได้เลือก timer0 มาทำหน้าที่นี้ ส่วน timer1,2 เอาไว้ใช้กับ uart1,2
    นึกถึง millis() ของ arduino ที่ไว้ใช้ทำ non-blocking process แต่ท้ายที่สุด millis() ก็จะเกิด overflow ทำให้เกิดการทำงานที่ผิดพลาดได้

    เมื่อใช้ timer 16bit auto reload จะไม่เกิดปัญหาแบบเดียวกันกับ millis() 

1. Timer0
การใช้งาน Timer0 มีรีจิสเตอร์ที่เกี่ยวข้องตามนี้
    TMOD,TCON, TL0, TH0, ET0, EA, AUXR

void Timer0_Isr() interrupt 1
{
    //TF0 = 0;        //hardware set and reset automatically.
    P10   = !P10;    //test output

}//end timer0 isr

void main()
{
    TMOD = 0x00;    //timer0 mode0 16bit auto reload
    TL0     = 65536 - 10*18432000/(12*1000);    //10ms at 18.432MHz
    TH0    = (65536 - 10*18432000/(12*1000))>>8;
    TR0    = 1;        //start timer0
    ET0    = 1;        //enable timer0 interrupt
    EA     =  1;        //enable global interrupt
    while(1);
}//end main

Fig 3. captured P10 with 10ms width

    2. เอา timer0 มาช่วยทำ non-blocking
ก็นับจำนวนครั้งของ timer overflow ใน timer0_interrupt

void Timer0_Isr() interrupt 1
{
    //TF0 = 0;        //hardware set and reset automatically.
    count++;        //count every timer0 overflown
    if(count%10 == 0)
        t100ms = 1;
   
if(count%100 == 0)
        t1sec    = 1;
    if(count == 200)
        count = 0;    //reset counter
}//end timer0 isr

    ใน while loop ปกติ ก็ดูว่ามันมีค่าเท่ากับ 1 หรือยัง
while(1)
{
    if(t100ms == 1)    //do this every 100ms
    {
        P10 = !P10;    //test timing
        t100ms = 0;    //clear timer , declared as bit
variable
    }
   
if(t1sec == 1)    //do this every 1sec
    {
        P11 = !P11;    //test timing
        t1sec = 0;    //clear timer , declared as bit variable
    }

}//end while

Fig 4. Captured P10 and P11 while using timer0 for non-blocking

Fig.5 STC8F1K08S2 working with HMI.

    พอมีตัวเวลา timer0 ก็เอามาช่วยในการทำ PWM หรือว่าเป็น analog output (นึกถึง analog.write() ของ Arduino) ก็เขียนโค้ดให้มันทำได้

    ความถี่ของ PWM ที่จะทำ ก็เอาสัก 1000Hz ส่วนของ Arduino ไลบรารี่เขาทำมาให้ประมาณ 490Hz

แต่ที่ 1000Hz นั้นจะมีคาบเวลา 1ms และ %duty PWM ก็ทำการปรับให้ยอดคลื่น x ให้กว้าง-แคบ ตามต้องการ

Fig.6 PWM 's wave form.
    ส่วนการปรับ x ก็ใช้ Timer 0 ช่วยในงานนี้ วิธีคือกำหนดใน interrupt service routine (ISR) ให้ทำการปรับค่าของ TL0, TH0

    เรารู้ว่า ที่ความถี่ 18.432MHz ใน 12T มันต้องทำงาน 1536 รอบจึงจะใช้เวลา 1ms เมื่อเป็นอย่างนี้แล้วก็ต้องกำหนดให้ TL0, TH0 มีค่า 65536 - 1536 = 64000
    64000 เป็นค่าตั้งต้นของ TL,TH และเมื่อ Timer
ทำงานอีกแค่ 1536 รอบ ค่า TL,TH ก็จะล้น เมื่อล้นก็เกิด interrupt (ที่ล้นก็เพราะตัวแปรเป็นชนิด 16bit เก็บค่าได้ 65536 ค่า เมื่อเกินกว่านี้ มันไม่ใช่ 65537 แต่มันจะไปเริ่มที่ 0 ใหม่ วนๆ ไป)
    กลับมาที่ค่า x มันก็แค่ใส่ค่า ที่เป็นสัดส่วน 1/100 ของ 1536 เช่น ต้องการ 75% ก็ใส่ค่า 65536 - (75/100)x1536 = 64384   
ประมาณนี้
void timer0_isr() interrupt 7
{
    TR0 = 0;
    if(P35 == 0){
        TL0    =    65536-(75/100)*1536;    //64384;
        TH0    =    (
65536-(75/100)*1536)>>8;
    }else {
        TL0    =    65536 - (25/100)*1536;
        TH0    =    (
65536 - (25/100)*1536)>>8;
    }
    P35 = !P35;    //toggle pin P3.5
    TR0 = 1;        //start timer0 again
   
    count++;                    //general purpose timer,counter
    if(count == 2000)        //x2 = 1ms
    {
        
t1sec = 1;
        count = 0;
    }
}

Fig. 7 Timer0 making PWM

Fig.8 95% duty PWM and pulse from Timer0.

 ก็ไม่สะดวกเท่าไหร่ เลือกได้ ก็เลือกเอารุ่นที่มี PWM ก็จะดี ไม่ต้องวุ่นวายขนาดนี้

ไม่มีความคิดเห็น:

แสดงความคิดเห็น

MAPs

วันก่อนได้ลองเขียนแบบ แบบตัวนั้นมันต้องแนบแผนที่สังเขปของโครงการ ลองๆ แล้วก็ใช้ snazzymaps แล้วก็เอามาทำต่อใน inkscape มันก็ออกมาดูได้ระดับห...