có thể dùng ngắt ngoài cũng được ,ko nhất thiết phải vòng lặp kiểm tra
Thông báo
Collapse
No announcement yet.
HƯỚNG DẪN LẬP TRÌNH KEIL C CHO 8051-[Chỉ dành post bài hướng dẫn]
Collapse
X
-
Nguyên văn bởi mhai_nguyen Xem bài viếtEm dang muon viet chuong trinh 89S52 giao voi EEPROM 24C04 theo chuan i2c nhung khó quá bác nào lam vê cái này roi post nên cho xem tham khảo với.
Mình muốn kiêm tra nó bằng cách hiển thị nên LCD, mong các bác hướng dẫn
Thank!
Comment
-
Chào các bác,
Cho em hỏi 1 tí. Khi vào tạo mới project, sau 1 số bước next, đến bước chọn Chip "Select device for Target" em nhìn mãi không thấy Tên con chip yêu quý của mình.
Em đã tải bản Keil 3 mà cũng không nhìn thấy. Vậy bác nào biết, hướng dãn em cách đặt thông số cho 1 loại chip mới mà library của KEIL không hỗ chợ. Nếu hướng dẫn cho em tất cả các thông số trong "Option for target" : Device, Target, Ouput, Listing, C51, A51,..., Debug, Utilities, thì tốt quá. Những thông số này chắc người nào làm quen thì mới hiểu được.
Thank- Chúc các bác 1 tuần làm việc hiệu quả.:monkey: :monkey: :monkey:
Comment
-
Chào cả nhà!
Xin các cao thủ làm ơn cho em hỏi tí ! Bài toán của em đưa ra là: Em có 05 phím ấn. Nếu em ấn một phím bất kì trong 5 phím trên thì đèn sáng và chuông kêu trong mười giây.Sau đó đèn tắt và chuông tắt trở về trạng thái ban đầu(chuông không kêu và đèn không sáng) để chờ đợt ấn phím mới!
Rất mong nhận được sự chỉ giáo của các bác!
Thanks!
Comment
-
Chào cả nhà!
Xin các cao thủ làm ơn cho em hỏi tí ! Bài toán của em đưa ra là: Em có 05 phím ấn. Nếu em ấn một phím bất kì trong 5 phím trên thì đèn sáng và chuông kêu trong mười giây.Sau đó đèn tắt và chuông tắt trở về trạng thái ban đầu(chuông không kêu và đèn không sáng) để chờ đợt ấn phím mới!
Rất mong nhận được sự chỉ giáo của các bác!
Thanks!
Bạn có thể chọn cho chế độ ngắt ngoài hoạt động ở kích cạnh xuống.
Khi có 1 kích cạnh xuống thì xử lý ngắt.Code đơn giản như sau.
Code:#include "regx52.h" void init() { //khoi dong cho phep ngat toan cuc EA=1; EX0=1;//cho phep ngat ngoai IT0=1;//Kích cạnh xuống } void main() { P1_0=1; while(1); } void mo_chuong() interrupt IE0_VECTOR using 0 { //bạn cho thêm các code để kích mở chuông và đèn tuơng ứng.(có thể là delay để có khoảng thời gian bạn muốn. }
Sông dài, Thuyền lớn, Biển rộng bao la.
Tháo neo ngôn ngữ, lèo lái con thuyền kiến thức nhân loại.
Comment
-
Trước tiên mình xin cám ơn bạn quoc_thaibk đã hướng dẫn rất chi tiết cho mình!
Nhưng mình lại quên mất một yêu cầu nữa của bài toán là: Khi các phím được ấn cùng một lúc thì phím nào bấm trước sẽ được ưu tiên nghĩa là khi đó đèn sáng và chuông kêu còn các phím khác muốn bấm cũng không có tác dụng gì cả( chuông không kêu và đèn không sáng). Đồng thời chuông kêu và đèn sáng trong vòng 10s thì tắt rồi tiếp tục chờ ấn phím tiếp theo.
Rất mong các bạn chỉ giáo cho mình với (vì mình mới làm quen với VĐK bằng ngôn ngữ C nên mình còn rất lúng túng).Last edited by baccuc1; 23-11-2006, 08:29.
Comment
-
Nguyên văn bởi mhai_nguyen Xem bài viếtEm dang muon viet chuong trinh 89S52 giao voi EEPROM 24C04 theo chuan i2c nhung khó quá bác nào lam vê cái này roi post nên cho xem tham khảo với.
Mình muốn kiêm tra nó bằng cách hiển thị nên LCD, mong các bác hướng dẫn
Thank!
Tui cho bác một số hàm cơ bản, bác đọc thêm datasheet của 24c04 để viết tiếp nhé. Chúc thành công.
Code:EXTRN DATA (val) PUBLIC SDA, SCL PUBLIC i2c_start, i2c_stop, i2c_write, i2c_read, set_SDA, set_SCL, delay3ms SDA BIT P1^0 SCL BIT P1^1 CSEG I2C SEGMENT CODE RSEG I2C set_SDA: SETB SDA JNB SDA, set_SDA RET set_SCL: SETB SCL JNB SCL, set_SCL RET i2c_start: CALL set_SCL CALL set_SDA CALL set_SCL CLR SDA NOP CLR SCL NOP RET i2c_stop: CLR SDA CALL set_SCL NOP CALL set_SDA NOP RET i2c_write: ; Write EEPROM PUSH ACC PUSH PSW MOV R1, #8 MOV A, val repeat: RLC A JC setsda CLR SDA JMP continue setsda: CALL set_SDA continue: CALL set_SCL NOP CLR SCL DJNZ R1, repeat SETB SDA CALL set_SCL loop: JB SDA, loop CLR SCL POP PSW POP ACC RET i2c_read: ; Read EEPROM PUSH ACC PUSH PSW MOV R1, #8 SETB SDA repeat1: CALL set_SCL NOP MOV C, SDA RLC A CLR SCL DJNZ R1, repeat1 MOV val, A POP PSW POP ACC RET delay3ms: TT0: MOV R2,#6 MOV R3,#92 TT1: DJNZ R3,TT1 DJNZ R2,TT1 RET END
Last edited by VNarmy; 07-07-2007, 17:31.Đường đến những ngày vinh quang không còn xa
Con đường chúng ta... chúng ta đã chọn.
Comment
-
Nguyên văn bởi baccuc1 Xem bài viếtTrước tiên mình xin cám ơn bạn quoc_thaibk đã hướng dẫn rất chi tiết cho mình!
Nhưng mình lại quên mất một yêu cầu nữa của bài toán là: Khi các phím được ấn cùng một lúc thì phím nào bấm trước sẽ được ưu tiên nghĩa là khi đó đèn sáng và chuông kêu còn các phím khác muốn bấm cũng không có tác dụng gì cả( chuông không kêu và đèn không sáng). Đồng thời chuông kêu và đèn sáng trong vòng 10s thì tắt rồi tiếp tục chờ ấn phím tiếp theo.
Rất mong các bạn chỉ giáo cho mình với (vì mình mới làm quen với VĐK bằng ngôn ngữ C nên mình còn rất lúng túng).
Còn nếu bạn thiết kế kiểu VĐK thì để ít tốn chip thì bạn chỉ việc nối vào các port của MCU.
Vì công việc của bạn chỉ đơn giản là đơn công nên không cần thiết kế theo hướng ngắt.
Chỉ cần lặp kiểm tra ở tốc độ cao (vài trăm hz) thì bạn có thể khá tốt (Có 2 nguời nhấn cùng 1 lúc bao giờ đâu ) sau khi bắt đuợc nút nhấn thì công việc còn lại là thực thi.Để đơn giản thì tuơng ứng là các pin MCU nối ra điều khiển đồng thời led và chuông( lưu ý là dùng transistor đệm không thì cháy port đấy nhé) nếu có 5 nút thì có thể có 5 pin out cho 5 đèn nhưng chuông kích thì chỉ cần 1 để tiết kiệm ấy mà .
Sông dài, Thuyền lớn, Biển rộng bao la.
Tháo neo ngôn ngữ, lèo lái con thuyền kiến thức nhân loại.
Comment
-
Nguyên văn bởi mhai_nguyen Xem bài viếtEm dang muon viet chuong trinh 89S52 giao voi EEPROM 24C04 theo chuan i2c nhung khó quá bác nào lam vê cái này roi post nên cho xem tham khảo với.
Mình muốn kiêm tra nó bằng cách hiển thị nên LCD, mong các bác hướng dẫn
Thank!
Code:void delay_i2c() { while(0); while(0); } void start_i2c() { SDA=1; SCL=1; delay_i2c(); SDA=0; delay_i2c(); SCL=0; delay_i2c(); } void stop_i2c() { SDA=0; SCL=0; delay_i2c(); SCL=1; delay_i2c(); SDA=1; delay_i2c(); } unsigned char rx_i2c(unsigned char ACK) { unsigned char d=0,x; SDA=1;// tha noi cong // qua trinh doc du lieu tu ngoai vao for (x=0;x<8;x++) { d<<=1; SCL=1; while(SCL==0); // khi da co canh len thi doc du lieu tu ngoai vao delay_i2c(); if (SDA) d|=1; SCL=0; } // // tao xung ACK luu y la co xet xem la co can tao xung ACK khong if (ACK) SDA=0; else SDA=1; SCL=1; delay_i2c(); SCL=0; SDA=1;//release the SDA line return d; } bit tx_i2c(unsigned char trans) { unsigned char x; bit ACK; SCL=0; for (x=0;x<8;x++) { if(trans&0x80) SDA=1; else SDA=0; trans<<=1; SCL=1; delay_i2c(); SCL=0; delay_i2c(); } //release all line and wait for ACK sign //release SDA=1; SCL=1; // delay_i2c(); while(SCL==0); ACK=SDA; SCL=0;//pull down all line return ACK; }
Khi ghi 1 dữ liệu với thiết bị slave thì:
-Master gửi tín hiệu start i2c (bạn có thể dùng hàm start_i2c())
-Master gửi device address với bit R/W =0 của slave -->slave tuơng ứng phải báo xung ACK (kéo chân SDA xuống 0)
-Master gửi địa chỉ của ô nhớ cần ghi.
-Master gửi data cần ghi tuơng ứng.- Truờng hợp chỉ muốn ghi vào 1 ô thì chỉ cần gửi 1 data.
- Trường hợp muốn ghi liên tục vào các ô nhớ sau đó thì gửi các data liên tiếp tự động slave tăng địa chỉ lên.Ở đây lưu ý 1 điều là chế độ ghi liên tục này sẽ chỉ ghi trong 1 page thôi với các 24XX khác nhau thì có page khác nhau 16byte hay 8 byte tùy vào datasheet khi mà bạn tăng liên tục thì vuợt qua nó sẽ quay vòng lại các ô nhớ trong page.
-Sau khi đã ghi xong các ô nhớ cần thiết thì thực hiện quá trình stop --> có thể dùng stop_i2c()
Với quá trình đọc ô nhớ thì khác 1 tý ở chỗ là có quá trình gọi lại quá_trình_rỗng(dummy sequence) ở 3 buớc đầu.
-Master gửi xung start
-Master gửi địa chỉ slave bit Read/Write=0.
-Master gửi địa chỉ ô nhớ
-Master gửi lại xung start 1 lần nữa.
-Master gửi địa chỉ của slave với bit Read/Write=1
-Master nhận dữ liệu từ slave và báo ACK nếu muốn nhận tiếp data tại ô nhớ kế tiếp.Lưu ý là nếu đọc liên tục thì sẽ đọc hết các ô nhớ trong vùng 8 bit (còn ở bit 9 thì cố định do quá trình truyền địa chỉ đã cố định.Cái này là trường hợp 24C04 còn với các chip lớn hơn thì có nhiều bit hơn bạn coi thêm datasheet)
-Nếu không nhận nữa thì Báo xung NACK và sau đó là xung stop.(Cái này gọi là NAK).
Code:unsigned char d; init(); P1=P2=0xff; start_i2c(); if (tx_i2c(0xA0)) goto error; if (tx_i2c(0x01)) goto error; if (tx_i2c(99)) goto error; //write 0x99 to ROM at address 0x01 stop_i2c(); delay(10);//time write cycle start_i2c(); if (tx_i2c(0xA0)) goto error;//write if (tx_i2c(0x01)) goto error;//dummy sequence start_i2c(); if(tx_i2c(0xA1)) goto error;//read d=rx_i2c(0);//doc 1 byte voi xung N_ACK stop_i2c();
Sông dài, Thuyền lớn, Biển rộng bao la.
Tháo neo ngôn ngữ, lèo lái con thuyền kiến thức nhân loại.
Comment
-
Chào các bạn!
Bài tập về phím ấn, mình lập trình như sau:
#include <AT89x52.H>
void delay(unsigned char giay)
{
while(giay--)
{
//day la chuong trinh tao tre 1s
unsigned char temp;
temp=1000;
while(temp--)
{
//day la doan chuong trinh tao tre 1 ms
TMOD=0x01; //su dung timer0,che do 16 bit
TH0=0xFC;
TL0=0x18 ;
TR0=1; // Day la bit khoi dong bo dinh thoi 0
while(!TF0);
TR0=0;
TF0=0;
}
}
}
main()
{
if (P0!=0xFF) P1_0=0;
{
if (P0_0 ==0) P1_1=0;
elseif (P0_1==0) P1_2=0;
elseif (P0_2==0) P1_3=0;
elseif (P0_3==0) P1_4=0;
elseif (P0_4==0) P1_5=0;
Endif
}
delay(10);
P1=0xFF; P0=0xFF
goto main() ;
}
Mình viết xong chạy thử thì nó báo lỗi sau:
Build target 'Target 1'
compiling Phim an khong che.c...
PHIM AN KHONG CHE.C(43): warning C206: 'elseif': missing function-prototype
PHIM AN KHONG CHE.C(43): error C267: 'elseif': requires ANSI-style prototype
PHIM AN KHONG CHE.C(43): error C141: syntax error near 'P1_2'
PHIM AN KHONG CHE.C(44): error C141: syntax error near 'P1_3'
PHIM AN KHONG CHE.C(45): error C141: syntax error near 'P1_4'
PHIM AN KHONG CHE.C(46): error C141: syntax error near 'P1_5'
PHIM AN KHONG CHE.C(48): error C202: 'Endif': undefined identifier
PHIM AN KHONG CHE.C(48): error C141: syntax error near '}'
PHIM AN KHONG CHE.C(52): error C141: syntax error near 'goto'
PHIM AN KHONG CHE.C(52): error C141: syntax error near '(', expected ';'
Target not created
Mong các bạn làm ơn chỉ bảo giúp với!
Thanks!
Comment
-
Mình sửa qua về cú pháp cho bạn nhé.
Code:#include <AT89x52.H> // thay bằng #include "regx52.h" void delay(unsigned char giay) { while(giay--) { //day la chuong trinh tao tre 1s unsigned char temp; temp=1000; while(temp--) { //day la doan chuong trinh tao tre 1 ms TMOD=0x01; //su dung timer0,che do 16 bit TH0=0xFC; TL0=0x18 ; TR0=1; // Day la bit khoi dong bo dinh thoi 0 while(!TF0); TR0=0; TF0=0; } } } main() { if (P0!=0xFF) P1_0=0; { if (P0_0 ==0) P1_1=0; elseif (P0_1==0) P1_2=0; // thay elseif = else if elseif (P0_2==0) P1_3=0; // tương tự elseif (P0_3==0) P1_4=0; elseif (P0_4==0) P1_5=0; //Endif // làm gì có endif :D. } delay(10); P1=0xFF; P0=0xFF //goto main() ; // trời đất làm gì có goto main(), muốn nhảy tại chỗ chỉ cần while(1); }
Như vậy bạn định dùng một vòng lặp để quét phím sao? Như thế thật là phí tài nguyên chíp. Bạn nên dùng ngắt để tạo ra một vòng quét xác định đừng dùng delay. Khi đó thời gian rảnh rỗi có thể làm được khối việc đó.
Nếu theo ý của bạn là dùng lặp trong main thì bạn nên cho toàn bộ code đó vào trong vòng lặp như sau:
Code:while(1){ }
Chúc bạn thành công.Technical sale at WT Microelectronics S'pore
Hỗ trợ dự án sử dụng các hãng Texas Instrument, STMicro, Freescale, Fairchild, International Rectifier, Ublox, Lumiled, Maxim
Liên hệ: 0915.560.511 hoặc ngo.haibac@wtmec.com
Comment
-
Mình nghĩ thêm cho bạn một thuật giải kiểm tra phím ấn nữa nhé:
Code:unsigned char temp = 0; while(1){ if(P0 != 0xFF){ temp = P0; temp &= 0x1F; // and để lấy 5 bít thấp của P0 temp= temp<<1; // dịch 1 bít sang trái P1 = (P1 & 0xC0) | temp; delay(10); P0 = P1 = 0xFF; // reset lại }; };
Chúc bạn thành công.Technical sale at WT Microelectronics S'pore
Hỗ trợ dự án sử dụng các hãng Texas Instrument, STMicro, Freescale, Fairchild, International Rectifier, Ublox, Lumiled, Maxim
Liên hệ: 0915.560.511 hoặc ngo.haibac@wtmec.com
Comment
Bài viết mới nhất
Collapse
-
Trả lời cho Mạch nguồn đôi dùng 7812 và 7912bởi tmcodonThank bác nhá. Tìm mãi mới thấy. Giờ vọc đã xem sao...
-
Channel: Hỗ trợ học tập
hôm nay, 10:39 -
-
bởi tungdqEm cần tìm sơ đồ mạch một số Main máy tính đời cao như Asrock B560M-HDV, các cao nhân chỉ giúp với. Thank!
-
Channel: Các mạch điện ứng dụng
Hôm qua, 08:27 -
-
Trả lời cho Kiểm tra biến ápbởi lamvu0677nhân tiện cho mình hỏi thêm về cái phần test hipot (cao áp),là để kiểm tra độ bền cách điện giưa các cuộn dây,mà thấy thông số test thường ở mức 4kvac,vậy nếu mấy con fail đó xài bình thường vẫn dduocj phải không ạ,vì điện mình làm gì lên tới mức đó
-
Channel: Điện tử dành cho người mới bắt đầu
10-11-2024, 08:52 -
-
Trả lời cho Kiểm tra biến ápbởi lamvu0677máy đo số vòng thì cty có ,mà nó to quá,tưởng có máy nào gọn gọn bỏ túi được thì tiện hơn,vì đi lại nhiều...
-
Channel: Điện tử dành cho người mới bắt đầu
10-11-2024, 08:47 -
-
bởi tmcodonMình thấy diễn đàn có chuyên mục quảng cáo rồi mà. Bạn đóng góp để mở luồng riêng
-
Channel: Hướng dẫn sử dụng diễn đàn
09-11-2024, 13:36 -
-
bởi Nicole08Xin chào mọi người, tôi đã sử dụng Flashforge Inventor 2 được gần 5 năm và rất hài lòng với nó, nhưng tuần trước đã xảy ra sự cố. Có vẻ như động cơ bước đưa sợi in vào đầu nóng đã bị hỏng. Mọi thứ khác có vẻ ổn trên máy...
-
Channel: Điện tử dành cho người mới bắt đầu
09-11-2024, 12:55 -
Comment