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

  • Nguyên văn bởi natra2k2 Xem bài viết
    Một câu nữa:
    Có cách nào, hoặc macro nào để giúp nhập giá trị bằng nhị phân không?
    ví dụ bên ASM ta hay làm
    Code:
    mov P0, #10001000B  // gán cho P0 giá trị #11H
    bên Keil C không thấy nhập giá trị bằng kiểu nhị phân, chỉ có thể nhập bằng giá trị thập phân hoặc hexa thôi
    ví dụ
    Code:
    P0 = 0x11;
    Vừa tìm được trên forum của Keil 2 cái macro
    #define LongToBin(n) \
    (\
    ((n >> 21) & 0x80) | \
    ((n >> 18) & 0x40) | \
    ((n >> 15) & 0x20) | \
    ((n >> 12) & 0x10) | \
    ((n >> 9) & 0x08) | \
    ((n >> 6) & 0x04) | \
    ((n >> 3) & 0x02) | \
    ((n ) & 0x01) \
    )

    #define Bin(n) LongToBin(0x##n##l)

    sử dụng
    unsigned char i;
    i = Bin(10001000);
    Nhân đây cho mình hỏi luôn
    dòng LongToBin(0x##n##l), 2 dấu ## nghĩa là gì nhỉ? :d
    Last edited by natra2k2; 19-10-2006, 17:43.

    Comment


    • chuyển hex to 7 đoạn

      chào các BÁC trong diễn đàn :
      tôi có 1 số hex 16bit (25ef) cần chyển sang mã led 7 đoạn . Mong các BÁC giúp mình chương trình này
      |

      Comment


      • Cách đơn giản và khỏi mất thời gian tính toán số nhớ là:
        giả sử số của bạn là so_can_chuyen ở dạng int (16bit),các số sau khi chuyển chứa trong hex[5] và có tối đa 5 số BCD
        hex[0]=so_can_chuyen%10;
        so_can_chuyen\=10;
        hex[1]=so_can_chuyen%10;
        so_can_chuyen\=10;
        hex[2]=so_can_chuyen%10;
        so_can_chuyen\=10;
        hex[3]=so_can_chuyen%10;
        so_can_chuyen\=10;
        hex[4]=so_can_chuyen%10;
        so_can_chuyen\=10;
        //ở đây mình không lặp để cho trực quan 1 tý.

        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 quoc_thaibk Xem bài viết
          Cách đơn giản và khỏi mất thời gian tính toán số nhớ là:
          giả sử số của bạn là so_can_chuyen ở dạng int (16bit),các số sau khi chuyển chứa trong hex[5] và có tối đa 5 số BCD
          hex[0]=so_can_chuyen%10;
          so_can_chuyen\=10;
          hex[1]=so_can_chuyen%10;
          so_can_chuyen\=10;
          hex[2]=so_can_chuyen%10;
          so_can_chuyen\=10;
          hex[3]=so_can_chuyen%10;
          so_can_chuyen\=10;
          hex[4]=so_can_chuyen%10;
          so_can_chuyen\=10;
          //ở đây mình không lặp để cho trực quan 1 tý.
          Bác qt nhầm một chút các dấu \= phải là /=, dấu \ nó hiểu xuống dòng bác ạ!

          Comment


          • Nguyên văn bởi MicroDuyphi Xem bài viết
            * Quy trình thì như NgohaiBac nói rất đúng, sử dụng ngắt nào thì Enable ngắt đó trước khi vào sử dụng! "thaithutrang" có lẻ nhớ nhầm cờ ngắt, chỉ khi vào trình phục ngắt, sau khi thực thi thì cờ ngắt được tự động xóa rồi thoát!
            Còn việc vào 1 hàm ngắt, ngắt đó sẽ bị "cấm- Disenable" là do người lạp trình đã xóa bằng phần mềm, chẳng hạn ta cho bit "EA=0"(cấm ngắt toàn cục), hoặc IE0=0, khi đó trước khi thoát cần hồi phục lại nó!

            * Trong phần khai báo ngắt, NgohaiBac chưa nói về cái "USING"
            Trích từ đoạn code trên:
            /-------------------------------------/
            void inter0(void) interrupt 0 using 1
            {
            .
            .
            .
            }
            /-------------------------------------/
            Đoạn khai báo trên khai báo Hàm ngắt ngoài 0, sử dụng Bank 1 là do ta chọn "UISNG 1"
            Nếu bạn chọn "UISNG 0" có nghĩa là bạn chọn bank0, và đoanl code trên được viết lại như sau:
            /-------------------------------------/
            void inter0(void) interrupt 0 using 0
            {
            .
            .
            .
            }
            /-------------------------------------/

            ;====================
            Như vậy có 2 điểm cần lưu ý:
            ;====================
            1- Ta có thể chọn 4bank thanh ghi khi vào ngắt thông qua việc chọn UISNG0, hay 1 hay 2 hay 3
            2- Mặc định chương khi khởi động Bank thanh ghi được chọn sẽ là Bank 0
            Chao cac bac, noi den ngat e co cau hoi the nay, e dowl dc moi ct dung ngat truyen thong ho khai bao ham ngat nhu sau, mong cac bac nhan se cho::

            void serialhandler (void) interrupt SIO_VECTOR using 3
            {
            if (TI==1) {ti_busy=0;TI=0;}
            if (RI==1) {rx_char=SBUF; RI=0;}
            }
            minh ko hieu interrupt SIO_VECTOR la gi ca????????

            Comment


            • SIO_VECTOR là 1 macro mà file regx52.h định nghĩa sẵn,bạn có thể thay nó bằng con số cụ thể cũng đuợc (ví dụ ở đây là 4)
              Đây là các vị trí của các vector interrupt trong MCU (vị trí này là tuơng đối còn tuyệt đối là tính theo công thức abs_add=8*interrupt_number+3)
              Trong đó có rất nhiều ngắt đuợc định nghĩa là macro.
              Code:
              #define IE0_VECTOR	0  /* 0x03 ngắt ngoài  0 */
              #define TF0_VECTOR	1  /* 0x0B Timer 0 */
              #define IE1_VECTOR	2  /* 0x13  ngắt ngoài 1 */
              #define TF1_VECTOR	3  /* 0x1B Timer 1 */
              #define SIO_VECTOR	4  /* 0x23 ngắt nối tiếp */
              #define TF2_VECTOR	5  /* 0x2B Timer 2 */
              #define EX2_VECTOR	5  /* 0x2B Ngắt ngoài  2 */
              Trường hợp MCU bạn dùng cao cấp lên thì có nhiều ngắt định nghĩa riêng thì lúc đó các MACRO là không đủ nên bạn có thể tra datasheet để coi địa chỉ vector của ngắt đó rồi tính ra số ngắt (interrupt number) theo công thức trên.
              Last edited by quoc_thaibk; 23-10-2006, 21:10.

              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


              • Lần đầu post bài ko biet anh ngohaibac co giup cho ko.

                Sao khai báo unsigned char time... vậy mà nhập time=1000 ko thấy anh keil báo lỗi gì cả mà vẫn con chạy đúng moi chet chứ.
                Em dùng keilC V3.

                Comment


                • Nguyên văn bởi newstar Xem bài viết
                  Lần đầu post bài ko biet anh ngohaibac co giup cho ko.

                  Sao khai báo unsigned char time... vậy mà nhập time=1000 ko thấy anh keil báo lỗi gì cả mà vẫn con chạy đúng moi chet chứ.
                  Em dùng keilC V3.
                  Nó không báo gì cả nhưng thực chất nó chỉ lấy byte thấp thôi bạn ạ! Bạn chạy debug bằng Ctrl+F5 và xem giá trị của i khi nhập 1000, tương ứng 0x3E8, chỉ là 0xE8 thôi!

                  Comment


                  • Nguyên văn bởi natra2k2 Xem bài viết
                    Nó không báo gì cả nhưng thực chất nó chỉ lấy byte thấp thôi bạn ạ! Bạn chạy debug bằng Ctrl+F5 và xem giá trị của i khi nhập 1000, tương ứng 0x3E8, chỉ là 0xE8 thôi!
                    Cảm ơn natra2k2 nhieu!
                    Anh ngohaibac va cac cao thủ trên topic này thật nhiệt tình và rất hiệu quả. Em chỉ mới down topic này về đọc trong 1 đêm đã làm được rồi. Cảm ơn các anh nhiều lắm.

                    Mong các anh đừng nên delete topic này vội mà hãy chuyễn hướng sang kĩ thuật lập trình KeilC thay vì hướng dẫn sử dụng( 17 site đã quá đủ hướng dẫn rồi).

                    Hoi truoc em viết chuong trình đo tốc độ đọng cơ bằng ÁM tốn hết 147byte. Điều này hơi buồn: chuyển sang dùng keilC van thuật toán cũ lại mất hết 499byte

                    Đây là những đoạn code KeilC voi dung luong Rom co khac nhau chut it:
                    ***************************
                    *****449byte***************CHUONGTRINH 1
                    ***************************
                    Code:
                    #include <REGX51.H>
                    #define high(x) (((65536-x) & 0xFF00) >> 8)
                    #define low(x) ((unsigned char)(65536-x))
                    unsigned char dec[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
                    
                    void delay(unsigned int time)
                    	{
                    	while(time--)
                    		{
                    		 //TMOD=0x01;		// dùng timer chê ðô 1 (16 bit nap lai)
                    		 TH0=high(1000);
                    		 TL0=low(1000);
                    		 TR0=1;			//khoi ðông bô ðinh thoi
                    		 while(!TF0);	// waiting for TF0=1
                    		 TF0=0;
                    		 TR0=0;		
                    		}	
                    	}
                    
                    	void hienthi(unsigned char vitri,donvi)
                    {
                    			P0=vitri;
                    			P2=dec[donvi];
                    			
                    }
                    
                    void main()
                    {
                    hienthi(0xFF,0x00);
                    while(1)
                    {
                       unsigned int thuong;
                       unsigned char du;
                    	TMOD=0x51;		//timer 1 hoat dong mode 1-dem su kien,timer 0 hoat dong dinh thoi 16 bit
                    	TR1=1;			//khoi dong bo dinh thoi 1
                    	delay(500);		// nua giay
                    	thuong=TL1;	 		// chuyen TL1 vao "thuong" de tinh toan
                    	TL1=0x00;
                    	thuong=thuong*15;
                    	du=thuong%10;
                    	thuong=thuong/10;
                    	hienthi(0x01,du);	//hien thi hang don vi
                    	du=thuong%10;
                    	thuong=thuong/10;
                    	hienthi(0x02,du);	 //hien thi hang chuc
                    	du=thuong%10;
                    	thuong=thuong/10;
                    	hienthi(0x04,du);	//hien thi hang tram
                    	du=thuong;
                    	hienthi(0x08,du);
                    }
                    }




                    ***************************
                    *****453byte***************CHUONG TRINH 2
                    **************************
                    Code:
                    #include <REGX51.H>
                    #define high(x) (((65536-x) & 0xFF00) >> 8)
                    #define low(x) ((unsigned char)(65536-x))
                    unsigned char dec[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
                    
                    void delay(unsigned int time)
                    	{
                    	while(time--)
                    		{
                    		 //TMOD=0x01;		// dùng timer chê ðô 1 (16 bit nap lai)
                    		 TH0=high(1000);
                    		 TL0=low(1000);
                    		 TR0=1;			//khoi ðông bô ðinh thoi
                    		 while(!TF0);	// waiting for TF0=1
                    		 TF0=0;
                    		 TR0=0;		
                    		}	
                    	}
                    
                    //	void hienthi(unsigned char vitri,donvi)
                    //{
                    //			P0=vitri;
                    //			P2=dec[donvi];
                    			
                    //}
                    
                    void main()
                    {
                    P0=0x0F;
                    P2=dec[0x00];
                    while(1)
                    {
                       unsigned int thuong;
                       unsigned char du;
                    	TMOD=0x51;		//timer 1 hoat dong mode 1-dem su kien,timer 0 hoat dong dinh thoi 16 bit
                    	TR1=1;			//khoi dong bo dinh thoi 1
                    	delay(500);		// nua giay
                    	thuong=TL1;	 		// chuyen TL1 vao "thuong" de tinh toan
                    	TL1=0x00;
                    	thuong=thuong*15;
                    	du=thuong%10;
                    	thuong=thuong/10;
                    	P0=0x01;
                    	P2=dec[du];	//hien thi hang don vi
                    	du=thuong%10;
                    	thuong=thuong/10;
                    	P0=0x02;
                    	P2=dec[du];	 //hien thi hang chuc
                    	du=thuong%10;
                    	thuong=thuong/10;
                    	P0=0x04;
                    	P2=dec[du];	//hien thi hang tram
                    	du=thuong;
                    	P0=0x08;
                    	P2=dec[du];
                    }
                    }
                    *****************************
                    *****455byte***************CHUONG TRINH 3
                    ****************************
                    Code:
                    #include <REGX51.H>
                    #define high(x) (((65536-x) & 0xFF00) >> 8)
                    #define low(x) ((unsigned char)(65536-x))
                    unsigned char dec[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
                    
                    void delay(unsigned char time)
                    	{
                    	unsigned char temp;
                    	while(time--)
                    		{
                    		
                    		while(temp--)
                    		{
                    		
                    		 //TMOD=0x01;		// dùng timer chê ðô 1 (16 bit nap lai)
                    		 TH0=high(1000);
                    		 TL0=low(1000);
                    		 TR0=1;			//khoi ðông bô ðinh thoi
                    		 while(!TF0);	// waiting for TF0=1
                    		 TF0=0;
                    		 TR0=0;
                    		 }
                    		 temp=100;
                    		 		
                    		}	
                    	}
                    
                    	void hienthi(unsigned char vitri,donvi)
                    {
                    			P0=vitri;
                    			P2=dec[donvi];
                    			
                    }
                    
                    void main()
                    {
                    hienthi(0xFF,0x00);
                    while(1)
                    {
                       unsigned int thuong;
                       unsigned char du;
                    	TMOD=0x51;		//timer 1 hoat dong mode 1-dem su kien,timer 0 hoat dong dinh thoi 16 bit
                    	TR1=1;			//khoi dong bo dinh thoi 1
                    	delay(5);		// nua giay
                    	thuong=TL1;	 		// chuyen TL1 vao "thuong" de tinh toan
                    	TL1=0x00;
                    	thuong=thuong*15;
                    	du=thuong%10;
                    	thuong=thuong/10;
                    	hienthi(0x01,du);	//hien thi hang don vi
                    	du=thuong%10;
                    	thuong=thuong/10;
                    	hienthi(0x02,du);	 //hien thi hang chuc
                    	du=thuong%10;
                    	thuong=thuong/10;
                    	hienthi(0x04,du);	//hien thi hang tram
                    	du=thuong;
                    	hienthi(0x08,du);
                    }
                    }







                    SỰ KHÁC NHAU GIỮA 3 CHUONG TRÌNH LÀM THAY ĐỔ DUNG LUONG:

                    -cHUONG TRINH 1 DUNG HAM hienthi(unsigned char vitri,donvi)
                    -CHUONGTRINH 2 KHAC CHUONG TRINH 1 LÀ KO DÙNG HAM NÀY NŨA, MÀ KHI CẦN THÌ HIỂN THỊ TRỰC TIẾP( điều này làm tăng dung lương len 4byte);
                    -CHƯƠNG TRÌNH 3 CHỈ KHAC CHUONG TRÌNH 2 Ở HÀM DELAY. O ĐÂY MÌNH DÙNG 2 BIẾN 1BYTE LÀ TIME VÀ TEMP THAY CHO BIẾN 2 BYTE UNSIGNEN INT TIME O CHUONG TRINH 2.( điều này làm tang dung luong len 1 byte)
                    Last edited by VNarmy; 07-07-2007, 17:28.

                    Comment


                    • Tom lại,KeilC qua tuyet voi cho nhung lap trinh mang nang cấu trúc( điều này nếu ai đã tung su dung qua se biet). Tuy nhien, neu no lam tang dung luong len qua lon so voi ASM nhu vay( cai nay co thể do cách viết chuong trinh của mình con non kém---mong duoc chỉ giao) thi thật sự cũng rat bat loi cho nhung chuiong trinh lon.

                      Chúng ta hay cùng nhau trao đổi về kĩ thuật lập trình KeilC làm sao tối ưu về chu kỳ lệnh và dung luong.

                      Ví dụ, mình chua hieu, 1 lệnh nào đó của keilC mất bao nhiêu chu kì máy. Viec sủ dung các kiểu dinh dang làm sao cho tối uu, và làm sao là biết nó tối ưu.


                      Mong các cao giúp đỡ!!!!

                      Chuc moi nguoi luon thanh cong.
                      Last edited by newstar; 02-11-2006, 10:10.

                      Comment


                      • Nguyên văn bởi newstar Xem bài viết
                        Tom lại,KeilC qua tuyet voi cho nhung lap trinh mang nang cấu trúc( điều này nếu ai đã tung su dung qua se biet). Tuy nhien, neu no lam tang dung luong len qua lon so voi ASM nhu vay( cai nay co thể do cách viết chuong trinh của mình con non kém---mong duoc chỉ giao) thi thật sự cũng rat bat loi cho nhung chuiong trinh lon.

                        Chúng ta hay cùng nhau trao đổi về kĩ thuật lập trình KeilC làm sao tối ưu về chu kỳ lệnh và dung luong.

                        Ví dụ, mình chua hieu, 1 lệnh nào đó của keilC mất bao nhiêu chu kì máy. Viec sủ dung các kiểu dinh dang làm sao cho tối uu, và làm sao là biết nó tối ưu.


                        Mong các cao giúp đỡ!!!!

                        Chuc moi nguoi luon thanh cong.
                        Phần cuối, phần phụ lục của quyển C51 Primer có nói về các lệnh như for, while, lệnh gán, ... tương ứng với bao nhiêu chu kì máy đó bạn ạ. Nghiên cứu kỹ nhé.

                        Còn để tối ưu được chương trình so với ASM thì bạn hãy dùng các toán tử, các hàm gần với ASM như thay vì bạn dùng phép trừ thì dùng phép or chẳng hạn, nên dùng toán tử dịch bit,.. như thế chương trình sẽ rất là tối ưu. Tóm lại tránh các phép toán rườm rà, phức tạp.

                        Nên sử dụng kĩ thuật tra bảng giống ASM cho các mảng với từ khóa code để lưu trữ dữ liệu đó trong RAM thì khi tra sẽ nhanh hơn, không phải tính toán quá nhiều.

                        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


                        • 2 all! Mình có một câu hỏi về lập trình VĐk bằng KeilC mong mọi người chỉ giáo giúp! Mình xin cảm ơn trước nhé!
                          Mình muốn lập trình để điều khiển đèn sáng nghĩa là khi mình ấn nút ấn lần 1 thì đèn sáng và ấn tiếp cái nữa thì đèn tắt. Câu lệnh minh viết như sau khi mình dịch thì không báo lỗi j cả. Nhưng khi lắp thật thi không chạy chẳng hiểu sao cả

                          #include <AT89x52.H>
                          int n;
                          char m;
                          int dem;
                          dem=1;
                          void delay()
                          {
                          unsigned long i;
                          for(i=0;i<=10;++i) {}
                          }


                          void main()
                          {
                          while(1)
                          {
                          if(P1_0==0);
                          delay();
                          {
                          dem++;
                          }
                          if (dem%2!=0) P2_1=1;

                          else
                          P2_1=0;

                          }
                          }

                          Chân P1_0 mình đã đấu qua một phím ấn xuống mass

                          Comment


                          • bạn viết thế làm sao mà chạy được cơ chứ.

                            Bạn chỉ if(P1_0 ==0); rùi bỏ đấy đi delay rùi lại tăng giá tri biến dem. Như vậy biến dem lien tục tăng khi nó chẵn thì P2_1 = 0; còn khi lẻ thì P2_1 = 0;

                            Như vậy ấn phím nối vào chân P1_0 chẳng ảnh hưởng đến ai cả :d.

                            Góp ý với bạn, nên viết một hàm getkey để xem khi nào phím đựoc ấn, khi nào phím nhả, khi nào phím được giữ và tạo một vòng quét theo chu kì do bạn lựa chọn (dùng ngắt) để kiểm tra phím (vấn đề này mọi người đã thảo luận rùi) chứ không ai lại quét liên tục trong main dùng delay cả vì tốn tài nguyên quá để làm việc khác thì hơn.

                            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


                            • Hải Bắc ơi! Cậu làm ơn chỉ rõ giúp mình được kô?! Vì vi điều khiển mình mới làm quen nên trình còn non lắm!
                              Thanks!

                              Comment


                              • void main()
                                {
                                while(1)
                                {
                                if(P1_0==0)
                                {
                                delay();
                                dem++;
                                }
                                if (dem%2!=0) P2_1=1;else P2_1=0;
                                }
                                }
                                SHARE KHO PHIM LỚN

                                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