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
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • 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
    SHARE KHO PHIM LỚN

    Comment


    • Em 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


      • Nguyên văn bởi mhai_nguyen Xem bài viết
        Em 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!
        Search đi nào, trên này có nhiều lắm rồi!

        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!
              Nếu vậy thì có lẽ bạn chĩ cần sơ đồ đơn giản của 5 cái nút như sau.

              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ết
                  Em 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!
                  Hi,
                  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ết
                    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).
                    Việv này thì nếu bạn đã biết sử dụng các IC số thì đã có bài viết về mạch nhấn chuông rồi đấy,bạn tìm lại chắc sẽ có.
                    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ết
                      Em 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!
                      Đây là code mình viết bằng C đã làm việc rất tốt với AT24C04
                      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;
                      }
                      còn đây là code mẫu tuơng tác với AT24C04.Các chế độ ghi khác bạn đọc là ok lưu ý là 24C04 dùng 9bit để truy xuất ngẫu nhiên nên bit cao nhất trong 9 bit đuợc truyền trong quá trình truyền 7 bit địa chỉ của EEPROM (bit thứ 7) còn 8 bit còn lại truyền lúc sau.
                      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.
                      1. Truờng hợp chỉ muốn ghi vào 1 ô thì chỉ cần gửi 1 data.
                      2. 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


                        • Trong đó:
                          // P1_0 đưa ra chuông
                          // P1_1 đưa ra đèn 1
                          // P1_2 đưa ra đèn 2
                          // P1_3 đưa ra đèn 3
                          // P1_4 đưa ra đèn 4
                          // P1_5 đưa ra đèn 5

                          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){
                             
                            }
                            Để mình xem kĩ lại xem vì thấy chương trình viết lung tung, chắc bạn chưa học C thì phải, ngôn ngữ viết giống viết với Matlab quá.

                            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 
                               };
                              };
                              Bạn nghĩ kĩ xem mình viết gì nhé . Bạn nên suy nghĩ theo ASM thì chương trình sẽ rất là tối ưu đó.

                              Chúc bạn thành công.
                              Last edited by ngohaibac; 24-11-2006, 14:23. Lý do: edit lại cho đúng :D
                              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


                              • Hải Bắc ơi! cậu cho mình hỏi câu lệnh:
                                P1 = (P1 & 0xC0) & temp; có nghĩa là gì không?! 0xC0 bạn tính ra bằng cách nào vậy?!
                                Thanks!

                                Comment

                                Về tác giả

                                Collapse

                                kien_tran Tìm hiểu thêm về kien_tran

                                Bài viết mới nhất

                                Collapse

                                Đang tải...
                                X