Em cần viết hàm delay chính xác. Đọc bên luồng 8051 có đoạn code:
//-----------------------------------------
void delay() {
for(i=0;i<20;i++) { //50000 x 20 = 1s
TH0=0x3c; //-50000 us
TL0=0xb0;
TR0=1;
while(!TF0); //cho timer0 tràn
TF0=TR0=0;
}
}
//---------------------------------------------
em hiểu ý tưởng như sau: nếu làm trên avr
cho vào vòng lặp for n lần:
{
giá trị định trước của thanh TCNT0=0x..;
cho timer chạy
kiểm tra cờ ngắt TOV0 trên thanh TIFR: nếu ==0 tiếp tục, ==1 <được bật> thoát
xóa TOV0=0.
}
cụ thể em làm thế này:
//--------------------------------------------------
void delay_100us(int x) // x là giá trị nhân với 100us
{
int i;
for(i=0;i<x;i++)
{
TCCR0=0x02; // prescale= clk/8
TCNT0=0x9B; // innitial =155
TIMSK=(1<<TOIE0); //enables timer interrupts0
while(TIFR=0x00) continue;
TIMSK=0x00; TIFR=0x00; // kiểm tra cờ ngắt timer0 TOV0 trong thanh TIFR
}
}
ngoài ra còn có trình phục vụ ngắt tràn đẻ set lại TCNT0 sau mỗi lần tràn:
ISR(TIMER1_OVF_vect)
{
TCNT0=0x9B;
TIFR=0x00;
}
em đã set bit cho phép ngắt toàn cục trong hàm main() // sei();
để TIMSK ở hàm main hay trong void delay_100us() thì kết quả vẫn vậy.
//--------------------------------------------------
Nhưng kết quả vẫn hàm delay vẫn ko hoạt đôgj
Em đoán lý do sau nhưng chưa biết khắc phục:
- dao động chọn cho đoạn trong hàm void delay_100us cần chọn là dao động nội, (em dùng d dộng thạch anh/8). Nhưng ko biết set thế nào, đọc trong datasheet là set fuse, nhưng ko biết set fuse CKSEL trong avrstudio liệu có ổn ko; set xong chíp có thể chạy ở mode thạch anh ngoài 8Mhz lại như ban đầu ko.
Em đã đọc 2 luồng về fuse cho avr, nhưng từ trước tới giờ cứ cắm thạch anh vào xong là nạp code để học mấy bài tập nhỏ nhỏ luôn, chưa bao giờ em động đến fuse (đọc datasheet thì cũng hiểu sơ sơ và CKSEL). Khi dùng avrstudio thi e chọn dao động thạch anh từ :menu Project \ Config Options \ điền frequency là 8Mhz (ở phía dưới ô devide At16) \ OK. Vậy thôi!
-Nhầm lẫn vị trí giữa TIMSK và TIFR.
Mong mọi người giúp đỡ, 2 ngày loay hoay mà chưa xong;
Còn đây là đoạn code bạn em viết trên CCS cho PIC thành công:
//----------------------------------------------------------------
void delay_100us(int x)
{
INT i;
TMROIF=0; // bit enables _timer_interrupt
for (i=0;i<x;i++)
{
set_timer0(6 ); // set innitial value
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2); // set internal clock as a source and prescale==2
while (TMROIF==0) ; //while (TMROIF==0) ; continue;
TMROIF=0;
}
}
//----------------------------------------------------------------
//-----------------------------------------
void delay() {
for(i=0;i<20;i++) { //50000 x 20 = 1s
TH0=0x3c; //-50000 us
TL0=0xb0;
TR0=1;
while(!TF0); //cho timer0 tràn
TF0=TR0=0;
}
}
//---------------------------------------------
em hiểu ý tưởng như sau: nếu làm trên avr
cho vào vòng lặp for n lần:
{
giá trị định trước của thanh TCNT0=0x..;
cho timer chạy
kiểm tra cờ ngắt TOV0 trên thanh TIFR: nếu ==0 tiếp tục, ==1 <được bật> thoát
xóa TOV0=0.
}
cụ thể em làm thế này:
//--------------------------------------------------
void delay_100us(int x) // x là giá trị nhân với 100us
{
int i;
for(i=0;i<x;i++)
{
TCCR0=0x02; // prescale= clk/8
TCNT0=0x9B; // innitial =155
TIMSK=(1<<TOIE0); //enables timer interrupts0
while(TIFR=0x00) continue;
TIMSK=0x00; TIFR=0x00; // kiểm tra cờ ngắt timer0 TOV0 trong thanh TIFR
}
}
ngoài ra còn có trình phục vụ ngắt tràn đẻ set lại TCNT0 sau mỗi lần tràn:
ISR(TIMER1_OVF_vect)
{
TCNT0=0x9B;
TIFR=0x00;
}
em đã set bit cho phép ngắt toàn cục trong hàm main() // sei();
để TIMSK ở hàm main hay trong void delay_100us() thì kết quả vẫn vậy.
//--------------------------------------------------
Nhưng kết quả vẫn hàm delay vẫn ko hoạt đôgj
Em đoán lý do sau nhưng chưa biết khắc phục:
- dao động chọn cho đoạn trong hàm void delay_100us cần chọn là dao động nội, (em dùng d dộng thạch anh/8). Nhưng ko biết set thế nào, đọc trong datasheet là set fuse, nhưng ko biết set fuse CKSEL trong avrstudio liệu có ổn ko; set xong chíp có thể chạy ở mode thạch anh ngoài 8Mhz lại như ban đầu ko.
Em đã đọc 2 luồng về fuse cho avr, nhưng từ trước tới giờ cứ cắm thạch anh vào xong là nạp code để học mấy bài tập nhỏ nhỏ luôn, chưa bao giờ em động đến fuse (đọc datasheet thì cũng hiểu sơ sơ và CKSEL). Khi dùng avrstudio thi e chọn dao động thạch anh từ :menu Project \ Config Options \ điền frequency là 8Mhz (ở phía dưới ô devide At16) \ OK. Vậy thôi!
-Nhầm lẫn vị trí giữa TIMSK và TIFR.
Mong mọi người giúp đỡ, 2 ngày loay hoay mà chưa xong;
Còn đây là đoạn code bạn em viết trên CCS cho PIC thành công:
//----------------------------------------------------------------
void delay_100us(int x)
{
INT i;
TMROIF=0; // bit enables _timer_interrupt
for (i=0;i<x;i++)
{
set_timer0(6 ); // set innitial value
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2); // set internal clock as a source and prescale==2
while (TMROIF==0) ; //while (TMROIF==0) ; continue;
TMROIF=0;
}
}
//----------------------------------------------------------------
Comment