এটিএমগা 328 এ 64-এর ক্লক প্রেস্কেলারে চলাকালীন, আমার টাইমারগুলির মধ্যে একটি মৃত্যুদন্ড কার্যকর করার সময় একটি নির্দিষ্ট সময়ে অজানা কারণে গতি বাড়ায়।
TLC5940 দ্বারা প্রয়োজনীয় ক্লকিং তৈরি করতে আমি ATmega328 এ দুটি টাইমার ব্যবহার করছি (কেন এটি নীচে দেখুন; এটি প্রশ্নের অনিবার্য )। TIMER0
দ্রুত পিডব্লিউএম ব্যবহার করে একটি ঘড়ি সংকেত উত্পন্ন করে OC0B
এবং নীচে সেট আপ করা হয়:
TCCR0A = 0
|(0<<COM0A1) // Bits 7:6 – COM0A1:0: Compare Match Output A Mode
|(0<<COM0A0) //
|(1<<COM0B1) // Bits 5:4 – COM0B1:0: Compare Match Output B Mode
|(0<<COM0B0)
|(1<<WGM01) // Bits 1:0 – WGM01:0: Waveform Generation Mode
|(1<<WGM00)
;
TCCR0B = 0
|(0<<FOC0A) // Force Output Compare A
|(0<<FOC0B) // Force Output Compare B
|(1<<WGM02) // Bit 3 – WGM02: Waveform Generation Mode
|(0<<CS02) // Bits 2:0 – CS02:0: Clock Select
|(1<<CS01)
|(0<<CS00) // 010 = clock/8
;
OCR0A = 8;
OCR0B = 4;
TIMSK0 = 0;
TIMER2
প্রতি 256 TIMER0
চক্রে একটি ফাঁকা নাড়ি তৈরি করতে ডেটা লাইনটি পাকস্থল করে এবং নীচে সেট আপ করা হয়:
ASSR = 0;
TCCR2A = 0
|(0<<COM2A1) // Bits 7:6 – COM0A1:0: Compare Match Output A Mode
|(0<<COM2A0) //
|(0<<COM2B1) // Bits 5:4 – COM0B1:0: Compare Match Output B Mode
|(0<<COM2B0)
|(0<<WGM21) // Bits 1:0 – WGM01:0: Waveform Generation Mode
|(0<<WGM20)
;
TCCR2B = 0
|(0<<FOC2A) // Force Output Compare A
|(0<<FOC2B) // Force Output Compare B
|(0<<WGM22) // Bit 3 – WGM02: Waveform Generation Mode
|(1<<CS22) // Bits 2:0 – CS02:0: Clock Select
|(0<<CS21)
|(0<<CS20) // 100 = 64
;
OCR2A = 255;
OCR2B = 255;
TIMSK2 = 0
|(1<<TOIE2); // Timer/Counter0 Overflow Interrupt Enable
TIMER2
ওভারফ্লোতে একটি আইএসআর কল করে (প্রতি 256 চক্র)। আইএসআর ম্যানুয়ালি একটি ফাঁকা ডাল তৈরি করে এবং প্রয়োজনে একটি লেচিং নাড়ি তৈরি করে:
volatile uint8_t fLatch;
ISR(TIMER2_OVF_vect) {
if (fLatch) {
fLatch = 0;
TLC5940_XLAT_PORT |= (1<<TLC5940_XLAT_BIT); // XLAT -> high
for (int i=0;i<10;i++)
nop();
TLC5940_XLAT_PORT &= ~(1<<TLC5940_XLAT_BIT); // XLAT -> high
}
// Blank
TLC5940_BLANK_PORT |= (1<<TLC5940_BLANK_BIT);
for (int i=0;i<10;i++)
nop();
TLC5940_BLANK_PORT &= ~(1<<TLC5940_BLANK_BIT);
}
nop()
উপরের কোড বিলম্ব শুধু যুক্তিবিজ্ঞান বিশ্লেষক ট্রেস উপর নাড়ি আরো আপাত করা হয়। main()
ফাংশনটির লুপটি দেখতে কেমন তা এখানে দেখুন: কিছু সিরিয়াল ডেটা প্রেরণ করুন, আইএসআরটি ল্যাচিংয়ের যত্ন নেওয়ার জন্য অপেক্ষা করুন এবং তারপরে আবার এটি করুন:
for (;;) {
if (!fLatch) {
sendSerial();
fLatch = 1;
_delay_ms(1);
}
nop();
}
sendSerial()
কিছু এসপিআই প্রেরণ করে ( ব্রেভিটির জন্য পেস্টবিনে কোড ) আমার সমস্যাটি হ'ল sendSerial()
কমপ্লিট হওয়ার পরে , fLatch
ক্লকিং টাইমার গতিবেগকে কম (প্রক্রিয়াজাতকরণ) এ সেট করার অপেক্ষায় । এখানে যুক্তি বিশ্লেষক ট্রেস দেওয়া হয়েছে (আমি সেই অঞ্চলগুলিকে কাটা করেছি যেখানে একই সংকেত গ্রাফিককে আরও ছোট করে তোলে):
বাম দিকে, 0 এবং 1 চ্যানেলগুলি এসপিআই ডেটা প্রেরণের টেল এন্ড দেখায়। এছাড়াও বাম দিকে, চ্যানেল 4 এ, আপনি একটি ফাঁকা নাড়ি দেখতে পাবেন। চ্যানেল 2 তে প্রত্যাশার সাথে সাথে ক্লকিং ডাল চাগগুলি। চিত্রের ফাঁক যেখানে রয়েছে তার চারপাশে, রুটিনের অভ্যন্তরে fLatch
সেট করা 1
আছে main()
। এবং শীঘ্রই এর পরে TIMER0
প্রায় 4 এর গুণক গতি বাড়ায় Event আবার পাঠানো। আমি delay_ms(1);
লাইনটি বের করার চেষ্টা করেছি main()
, তবে একই ফলাফল পাওয়া যায়। কি হচ্ছে? আমার মনে রাখা উচিত যে এটিমেগা একটি 20 মেগাহার্জ স্ফটিক বন্ধ হয়ে গেছে এবং তারপরে নিম্নলিখিত কোডটি ব্যবহার করে x৪x হ্রাস করে:
CLKPR = 1<<CLKPCE;
CLKPR = (0<<CLKPS3)|(1<<CLKPS2)|(1<<CLKPS1)|(0<<CLKPS0);
এটি এর জন্য: আমি টিএলসি 5940 এলইডি ড্রাইভারটি নিয়ন্ত্রণ করার জন্য পরীক্ষা নিরীক্ষা করছি : এই চিপগুলির জন্য ক্লকিং চক্রের শেষে একটি বাহ্যিক ঘড়ি এবং পুনরায় সেট করা দরকার।
sendSerial()
আমার কোড যা এসপিআই এর মাধ্যমে ডেটা প্রেরণ করে: এটি TCCR
(টাইমার নিয়ন্ত্রণ) নিবন্ধগুলিতে স্পর্শ করে না ।