stm32 mp3

Started by tha, June 17, 2014, 12:33:26 PM

Previous topic - Next topic

tha

ได้แล้วครับ คือต้องเซต sampling rate = 8 kHz (SCI_AICTRL0 = 0x000C) (ดูจาก application note) คือเซตในไฟล์ vs1003.c

/* Set sample rate divider=12 */
  //while( VS1003_ReadReg(SPI_AICTRL0) != 0x0012 )
  //{
//  VS1003_WriteReg(SPI_AICTRL0,0x0012);
   while( VS1003_ReadReg(SPI_AICTRL0) != 0x000C )
   {
  VS1003_WriteReg(SPI_AICTRL0,0x000C);

แก้จาก 0x0012 เป็น 0x000C

http://www.mediafire.com/download/ai8gh7d0t8om5d4/MP3_4_SW_Record(2).rar

เจอปัญหาเกี่ยวกับการใช้ systick ครับ ถ้าเราตั้ง NVIC_IRQChannelPreemptionPriority ของ EXTI = 0; DelaymS (systick) ในโปรแกรม interupt EXTI จะไม่ทำงานครับ คล้ายกับว่า priority มันเท่ากัน อันที่จริง systick_handler priority = -1 ซึ่งสูงกว่า 0 ไม่ใช่เหรอครับ แต่พอผมตั้ง NVIC_IRQChannelPreemptionPriority ของ EXTI0 = 1; DelaymS ในโปรแกรม interupt EXTI0 ถึงจะทำงานได้ งง! เอะผมเข้าใจอะไรผิดหรือป่าว? ท่านผู้รู้ช่วยตอบที  :-\

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
  NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;   
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);



void EXTI0_IRQHandler(void)
{
if ( EXTI_GetITStatus(EXTI_Line0) != RESET ) {
DelaymS(200);
//DelayuS(200000);

c++;
if(c==1)
{
  recording = 1;
}
else if(c==2)
{
  recording = 2;
  //c=0;
}
  EXTI_ClearITPendingBit(EXTI_Line0);
}
}

AppleIIe

Quoteเจอปัญหาเกี่ยวกับการใช้ systick ครับ ถ้าเราตั้ง NVIC_IRQChannelPreemptionPriority ของ EXTI = 0; DelaymS (systick) ในโปรแกรม interupt EXTI จะไม่ทำงานครับ คล้ายกับว่า priority มันเท่ากัน อันที่จริง systick_handler priority = -1 ซึ่งสูงกว่า 0 ไม่ใช่เหรอครับ แต่พอผมตั้ง NVIC_IRQChannelPreemptionPriority ของ EXTI0 = 1; DelaymS ในโปรแกรม interupt EXTI0 ถึงจะทำงานได้ งง! เอะผมเข้าใจอะไรผิดหรือป่าว? ท่านผู้รู้ช่วยตอบที  :-\

ไม่ใช้ผู้รู้นะครับ แต่มาช่วยค้นให้ ลองอ่านที่นี่ครับ http://micromouseusa.com/?p=279 น่าจะเป็นเพราะ ท่านเข้าใจว่า systick timer priority ผิดไป คงจะมีค่า priority เป็น 0 ครับ หรือเป็น Highest priority อยู่แล้ว ( priority มีค่าได้ 0-15 ค่ายิ่งมาก priority จะต่ำลงไป) แต่เมื่อท่านไปตั้งของ EXTI ให้มีค่าเป็น 0 ด้วย เลยเป็นการทำให้ systick ไม่สามารถ interrupt ได้อีก (สูงเท่าเทียมกัน) เมื่อท่านตั้งให้ priority ของ EXTI เป็น 1 ซึ่งต่ำกว่า คราวนี้ systick timer จึงสามารถ interrupt ได้แล้วเพราะมี priority ที่เหนือกว่า

แต่มีข้อสังเกตจาก code ของ ท่านว่าในส่วนของ interrupt ไม่น่าจะควรทำการ delay ให้มากนักนะครับ (เข้าใจว่าท่านคงจะทำเพื่อเป็น Switch Debouncing ) mcu หรือ cpu จะทำงานเป็นไปอย่างไม่มีประสิทธิภาพ และเกิดผลเสียมากกว่า อาจเกิด stack overflow ได้ง่ายด้วย ลองอ่าน http://forum.arduino.cc/index.php/topic,41819.0.html

อันนี้ของแถมครับ http://users.ece.utexas.edu/~valvano/Volume1/E-Book/C12_Interrupts.htm เผื่อใช้เป็นแนวทาง โดยเฉพาะที่หัวข้อ 12.2 ครับ
"Stay Hungry, Stay Foolish"
จงกระหาย และ ทำตัวโง่ให้ตลอดเวลา
"Innovation distinguishes between a leader and a follower."
นวัตกรรมแยกผู้นำกับผู้ตามออกจากกัน

คนฉลาด...ต้องโง่เป็น คนโง่ไม่เป็น...จะไม่มีทางฉลาด

AppleIIe

Quote from: tha on June 27, 2014, 09:53:56 AM
Quoteหากมีเวลาลองเชื่อมใช้กับ CooCox CoOS (http://www.coocox.org/CoOSGuide/CoOSUpdates.htm) ด้วยซิครับ จะได้สมบูรณ์มากขึ้น

น่าสนใจครับ ผมถูกโฉลกกับ Coocox ซะด้วย ถ้ามีเวลาว่างก็จะลองศึกษาดูเหมือนกัน แต่ก็ไม่มีพื้นฐานเกี่ยวกับ OS เลย เคยศึกษา chibios, freertos, rtx rtos พอไม่ค่อยได้ใช้กับใช้ไม่ค่อยเป็นก็ลืมหมด  :'(

จริงๆ RTOS ก็เป็นเรื่องที่ไม่ยากนักแล้ว เพียงขอให้ไปทำความเข้าใจใน concept ของ RTOS กันก่อน และทุกวันนี้มีตำราเยอะมากแล้ว มันเป็นตัวช่วยให้ใช้งาน mcu หรือ cpu ได้อย่างมีประสิทธิภาพมาก (แน่นอนต้องศึกษาและใช้ให้เป็นด้วย จึงจะดึงความสามารถออกมาได้อย่างเต็มที่) และยิ่ง mcu สมัยนี้ทำงานได้เร็วมาก หากได้ใช้ RTOS ร่วมด้วย งานที่มีความสลับซับซ้อนก็จะทำได้ง่ายและคุ้มค่ามากขึ้น ยิ่งเป็น mcu ที่ท่านใช้ (32 bit) ข้อจำกัดค่อนข้างน้อยกว่าเจ้าอื่นๆ

จากคู่มือของ http://www.coocox.org/downloadfile/CoOS/PDF/CooCox_CoOS_User_Guide.pdf
จะทำงานเข้ากับ coocox ได้โดยตรง คงใช้อย่างไม่ต้องปวดหัวนัก หากมีเวลาว่างและโอกาศที่ดีก็น่าจะลองศึกษาเพื่อเล่นหรือใช้งานดูนะครับ
"Stay Hungry, Stay Foolish"
จงกระหาย และ ทำตัวโง่ให้ตลอดเวลา
"Innovation distinguishes between a leader and a follower."
นวัตกรรมแยกผู้นำกับผู้ตามออกจากกัน

คนฉลาด...ต้องโง่เป็น คนโง่ไม่เป็น...จะไม่มีทางฉลาด


tha

Quoteไม่ใช้ผู้รู้นะครับ แต่มาช่วยค้นให้ ลองอ่านที่นี่ครับ http://micromouseusa.com/?p=279 น่าจะเป็นเพราะ ท่านเข้าใจว่า systick timer priority ผิดไป คงจะมีค่า priority เป็น 0 ครับ หรือเป็น Highest priority อยู่แล้ว ( priority มีค่าได้ 0-15 ค่ายิ่งมาก priority จะต่ำลงไป) แต่เมื่อท่านไปตั้งของ EXTI ให้มีค่าเป็น 0 ด้วย เลยเป็นการทำให้ systick ไม่สามารถ interrupt ได้อีก (สูงเท่าเทียมกัน) เมื่อท่านตั้งให้ priority ของ EXTI เป็น 1 ซึ่งต่ำกว่า คราวนี้ systick timer จึงสามารถ interrupt ได้แล้วเพราะมี priority ที่เหนือกว่า
ขอบคุณครับที่แนะนำ ผมว่า systick มีค่า default(ค่าที่ตั้งเริ่มแรก) ของ priority = 0 อย่างที่คุณว่า เพราะเวลาผมตั้ง priority ของ EXTI0 = 0 แล้ว systick ใน EXTI0 interupt จึงไม่ทำงาน คุณให้ข้อมูลที่ดีมาก ( http://micromouseusa.com/?p=279 ) คราวนี้ก็รู้เรื่อง interupt ได้แน่นขึ้น รวมทั้งการตั้ง priory ของ systick ด้วย (NVIC_SetPriority(SysTick_IRQn, 0);//set systick interrupt priority) ต่อไปคงไม่มีปัญหาอะไร
ส่วนที่ใส่ delay ใน exti interupt นั้น ก็เพื่อแก้ปัญหา Switch Debouncing ครับ เพราะผมใช้สวิทช์ในการ start กับ stop ตัวเดียวกัน ผมลองดีบักดูแล้วก็ไม่มีปัญหาอะไรครับ (รวมทั้ง delay ที่เป็น loop ธรรมดาด้วย) แต่ก็อย่างว่า function interupt ไม่ควรเรียกใช้ function ย่อยอื่นมาก
ส่วน CoOS ก้จะศึกษาเหมือนกัน เพราะกำลังว่างอยู่พอดี ขอบคุณที่แนะนำ  :D

AppleIIe

Quoteส่วนที่ใส่ delay ใน exti interupt นั้น ก็เพื่อแก้ปัญหา Switch Debouncing ครับ เพราะผมใช้สวิทช์ในการ start กับ stop ตัวเดียวกัน ผมลองดีบักดูแล้วก็ไม่มีปัญหาอะไรครับ (รวมทั้ง delay ที่เป็น loop ธรรมดาด้วย) แต่ก็อย่างว่า function interupt ไม่ควรเรียกใช้ function ย่อยอื่นมาก

วิธีนี้อาจจะไม่มีผลกระทบกับงานแบบนี้ แต่ถ้างานที่มีการตอบสนองมากกว่านี้ อาจเป็นปัญหานะครับ
ถ้าว่างพอลองคิดหาวิธีทำงานแบบไม่ใช้ Delay ดูซิครับ ซึ่งอาจจะขัดความรู้สึกบ้างเพราะท่านอาจจะเคยให้ทำงานแบบนี้มาบ่อยๆ (แต่เห็นว่าท่านใช้ Interrupt ในการตอบสนองแล้ว น่าจะลองให้ mcu ทำการตอบสนองได้อย่างราบรื่น โดยไม่ต้อง Delay ดูบ้าง) ลองศึกษาจากนี้ดูครับ http://bleaklow.com/2011/02/01/dont_delay.html
(เพียงแต่วิธีที่ไม่ใช้ Delay อาจยากที่จะทำความเข้าใจ ในการเป็นตัวอย่างแบบเริ่มต้น)
"Stay Hungry, Stay Foolish"
จงกระหาย และ ทำตัวโง่ให้ตลอดเวลา
"Innovation distinguishes between a leader and a follower."
นวัตกรรมแยกผู้นำกับผู้ตามออกจากกัน

คนฉลาด...ต้องโง่เป็น คนโง่ไม่เป็น...จะไม่มีทางฉลาด

tha


static void delay_ms(uint32_t ms)
{
    uint32_t len;
    for (;ms > 0; ms --)
        for (len = 0; len < 100; len++ );
}


ในไฟล์ vs1003.c ทำไมถึงจะต้องมี static หน้าฟังชั่น ใช้ในกรณีไหน หมายถึงอะไรครับ

man1400

static void delay_ms(uint32_t ms)
{
    uint32_t len;
    for (;ms > 0; ms --)
        for (len = 0; len < 100; len++ );
}


ในไฟล์ vs1003.c ทำไมถึงจะต้องมี static หน้าฟังชั่น ใช้ในกรณีไหน หมายถึงอะไรครับ

ตามความคิดของผม ถ้าผิดก็ขออภัย ฟังชั่นที่มี static นี้เป็น global ใช้ในกรณีที่ไม่ได้เขียนไว้ใน main ตัวปรีคอมไพเลอร์จะจัดการให้

mr.mai

ในภาษา C keyword static เมื่อใช้กับ function
จะทำให้ function มี scope อยู่ในไฟล์โมดูลที่มันอยู่เท่านั้น
คือโมดูลที่มันอยู่เท่านั้นจึงจะเห็นและเรียกใช้งานมันได้
ดังนั้นจึงไม่สามารถ extern function ที่เป็น static ไปให้กับไฟล์โมดูลอื่นเห็นได้
นั้นหมายความว่าในแต่ละไฟล์โมดูล อาจจะมี static function ที่มีชื่อซ้ำกันได้
หรืออาจจะไปซ้ำกับชื่อ function ธรรมดาที่ไม่ใช่ static ของโมดูลอื่นก็ได้
โดยที่ compiler จะไม่สับสนเวลาเรียกใช้ เพราะมันจะพิจารณาจาก scope ที่เล็กกว่าก่อนเสมอ

เสริมนิด : อันที่จริง linkage ของ function นั้นเป็น extern โดยปริยายอยู่แล้ว
ดังนั้นตอน extern function ไปยังไฟล์โมดูลอื่นจะใช้ keyword extern หรือไม่ก็ได้