ขอความช่วยเหลือเกี่ยวกับ I2C Bit-bang หน่อยครับ

  • 15 Replies
  • 4335 Views
โปรแกรมใช้งานได้แล้วครับ ขอบคุณทุกคนที่ให้ความช่วยเหลือครับ ปรับเปลี่ยนส่วนของการรับค่า ACK ก็สามารถใช้งานได้เลยครับ

นี่ Code ส่วน ACK ที่แก้ไขครับ
Code: [Select]
void I2C_ACK(void)
{
DDR_I2C &= (0<<DDSDA)|(1<<DDSCL); //SET SDA to INPUT
cbi(PORT_OUT_I2C, SCL);
delay_us(6);
sbi(PORT_OUT_I2C, SCL);
delay_us(6);
while((PORT_IN_I2C&(1<<PINSDA))==0x40) //Wait ACK from Slave
{
}
cbi(PORT_OUT_I2C, SCL);
delay_us(6);
DDR_I2C |= (1<<DDSDA)|(1<<DDSCL); //SET OUTPUT
}

*

Offline pa_ul

  • ***
  • 247
    • View Profile
ถ้าคิดว่าอุปกรณ์ปลายทางจะทำงานปรกติ และ ACK มาอย่างแน่นอน ก็คงใช้งานได้ แต่ถ้าเกิดมีปัญหาอะไรซักอย่าง แล้วอุปกรณ์ไม่ส่ง ACK มา มันก็จะค้าง แล้วจะทำยังไง

การเขียนโปรแกรมเพื่อติดต่อสื่อสารไม่ว่าจะรูปแบบใดก็ตาม เรื่องที่สำคัญที่สุดก็คือการจัดการปัญหาที่เกิดขึ้นในระหว่างการรับส่ง ไม่ว่าจะรับไม่ได้,ส่งไม่ออก,ข้อมูลผิดพลาดรับ 0 เป็น 1 รับ 1 เป็น 0 ฯลฯ

*

Offline JENG

  • *****
  • 808
  • รู้ทุกเรื่องเว้นเรื่องจริง
    • View Profile
ไม่แนะนำให้เขียนแบบมี dead loop เช่นกันครับ อาจเก็บเป็น flag แทน แล้วใช้เป็นเงี่อนไขใน main ก็ได้
สามารถติดตาม electoday ได้ที่

Facebook
www.facebook.com/groups/coopmicro

Google+
https://plus.google.com/communities/103482067769375459277

☺☺☺ความรู้ และความฉลาด ไม่ใช่สิ่งเดียวกัน จะมีประโยชน์อะไร ถ้าฉลาดแต่อยู่ในกะลา☺☺☺

*

Offline firmware.c

  • *****
  • 181
  • Firmware Design
    • View Profile
ต้องเขียนแบบ timeout ครับ หาก ack มาก่อนก็ cancel timeout ไป แต่หากไม่มาจน timeout system ต้องกลับมาทำงานต่อแล้วจัดการต่อไป
IAR Embedded Workbench for ARM
AVR-Studio + AVR-GCC
CodeBlocks + MinGw
CodeBlocks + Gtk+

คือถ้าหาก ไม่ส่ง ack มาภายในเวลาที่กำหนดก็ให้โปรแกรม กระโดดข้ามไปทำงานในส่วนปกติก่อน แล้วค่อยกลับมาติดต่ออีกทีในภายหลัง
อย่างนี้ผมเข้าใจถูกไหมครับ

ขอสอบถามหน่อยครับว่า avr studio 5 มีคำสั่งอะไรใช้กระโดดข้ามการทำงานไหมครับ ใช้ยังไง และต้องประกาศ include อะไรครับ ขอบคุณครับ

*

Offline JENG

  • *****
  • 808
  • รู้ทุกเรื่องเว้นเรื่องจริง
    • View Profile
เข้าใจถูกแล้วครับ ผมยกตัวอย่างเช่น งานของคุณคืออ่านค่า ds1307 แล้วมาแสดงผลเป็นอย่างนี้ สลับกันไปเรื่อยๆชิมิ
ทีนี้ถ้าเกิด ACK เน่า หรือมีปัญหากับการติดต่อว่างั้นเหอะ ถ้ามี dead loop อย่างที่ท่านเขียน โปรแกรมก็จะค้างเติ่งอยู่อย่างนั้น
ไม่ไปไหน การแสดงผลก็จะหยุดชะงักเช่นกัน มีทางเดียวก็คือ reset ระบบ

แต่ถ้าเขียนให้ระบบมี timeout ก็จะสามารถไปทำงานถัดไปได้และยังสามารถใช้เป็นเงื่อนไขแจ้งความผิดพลาดได้ด้วย
เช่นถ้าเกิด timeout ก็อาจแสดงผลว่า ds1307 fail แล้วให้ระบบทำการเิริ่มติดต่อ ds1307 ใหม่ แบบนี้เป็นต้น...  ;D

#edit
ขอสอบถามหน่อยครับว่า avr studio 5 มีคำสั่งอะไรใช้กระโดดข้ามการทำงานไหมครับ ใช้ยังไง และต้องประกาศ include อะไรครับ ขอบคุณครับ

ขึ้นอยู่กับ coding ครับไม่มีแบบสำเร็จรูป ถ้ามีก็คงเป็น watch dog แต่นั้นมันปลายเหตุ
สามารถติดตาม electoday ได้ที่

Facebook
www.facebook.com/groups/coopmicro

Google+
https://plus.google.com/communities/103482067769375459277

☺☺☺ความรู้ และความฉลาด ไม่ใช่สิ่งเดียวกัน จะมีประโยชน์อะไร ถ้าฉลาดแต่อยู่ในกะลา☺☺☺

ขอบคุณสำหรับคำแนะนำมากครับ :)

*

Offline firmware.c

  • *****
  • 181
  • Firmware Design
    • View Profile
Code: [Select]
time = TIMEOUT;
error = 1;
do {
  if (ACK) {
     error = 0;
     break;
  }
} while (--time);
IAR Embedded Workbench for ARM
AVR-Studio + AVR-GCC
CodeBlocks + MinGw
CodeBlocks + Gtk+