Thông báo

Collapse
No announcement yet.

Cổng nối tiếp UART, các ngắt ngoài của 8051

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • #16
    Việc tràn ngăn xếp ko phụ thuộc vào chương trình ngắt dài hay ngắn mà phụ thuộc vào việc khởi tạo con trỏ Stack Pointer. Với con 89C51 có 128 bytes RAM, từ 00-->7F, khởi tạo SP khoảng 5F thì có lập trình thoải mái mà không tràn. 5F --> 7F có 32 bytes dùng thả cửa.

    Cơ chế của nó là LIFO, bác nào lập trình mà tràn được thì công lực 8051 cao phải biết

    Comment


    • #17
      Nguyên văn bởi ngohaibac Xem bài viết
      Do vậy chương trình viết lại như sau:
      Code:
      #include <REGX51.H>
      
      void time0 () interrupt 1
      {
      	TR0 = 0;
      	P2_1 = 0;
      }
      void main()
      {
      	TMOD = 0X02;
      	TH0 = 0XDC;
      	P2_1 = 1;
      	IE = 0X82;
      	TF0 = 0;
      	TR0 = 1;
      	while(1){
      	};
      		
      }
      Chúc bạn thành công.
      Tôi không hiểu ngắt mà bạn áp dụng vào đây có công dụng gì? Mong được chỉ giáo!

      Comment


      • #18
        Bổ xung thêm phát, con trỏ stack = 0x07 khi bắt đầu chạy. Con trở SP luôn trỏ tới đỉnh của ngăn xếp. Nếu chúng ta không can thiếp gì thì khi SP tăng lên thì có thể ghi đè vào dữ liệu ở các băng thanh ghi, vùng RAM định địa chỉ bit, ..

        Đó là nguyên nhân khởi tạo SP ở địa chỉ cao trong RAM để tránh xảy ra xung đột với các dữ liệu trong các vùng trên.

        Chúc cá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


        • #19
          Nguyên văn bởi quatnan1000 Xem bài viết
          Tôi không hiểu ngắt mà bạn áp dụng vào đây có công dụng gì? Mong được chỉ giáo!
          Chương trình đó mình chỉ viết lại cho đúng theo bạn đó hỏi thôi mà bạn. Chứ còn chương trình này dùng ngắt thì ngắt chẳng có tác dụng gì nữa cả .Chương trình chỉ nhảy vào ngắt có 1 phát mà thôi.

          Cảm ơn bạn đã góp ý.
          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


          • #20
            Chào mọi người

            Có ai đã làm truyền tốc độ cao truyền nối tiếp (chỉ rs232) chưa ?
            Khoảng 115200 baud .
            Nhờ Mod và mọi người giúp đở .
            Thanhks .

            Comment


            • #21
              Bạn tớ làm rùi. Dùng 89S52 và lợi dụng timer2 của nó để đạt được tốc độ baud này. Nghe nó nói thế chứ tớ chưa làm
              Hà Nội của ta
              Thủ đô yêu dấu
              Một thời đạn bom, một thời hòa bình...:cafe:

              Comment


              • #22
                Cho mình hỏi làm sao để tăng số ngắt ngoài của 8051 lên?
                Theo mình tìm hiểu thì có mấy cách sau:

                1/ dùng timer ở chế độ 8-bit tự nạp lại TLx= FFH và THx=FFH ,các chân T1
                T0 dùng như các chân ngắt

                2/ dùng chung ngắt ngoài bằng cách nối các cổng của port 1 qua cổng AND rồi ngõ out nối với ngắt ngoài ( cách này có thể mở rộng tới 256 ngắt ko biet đúng ko nữa )

                3/ dùng port nối tiếp chế độ UART 9-bit có tốc độ baud cố định , ngõ RXD làm ngõ vào ngắt.....
                Trong 3 cách trên mình có tìm hiểu qua nhưng ở cách thứ 3 mình hoàn toàn chưa hiểu .Bác nào hiểu thì làm ơn giải thích giúp mình với

                Ngoài 3 cách mình nói trên có còn cách nào khác nữa ko?
                Last edited by alibobone; 13-12-2006, 15:18.

                Comment


                • #23
                  Hi alibobone,
                  Trong thiết kế hệ vi xử lý, sử dụng số lượng lớn các ngắt là điều nên tránh. Làm vậy bạn sẽ phải xử lý thêm rất nhiều vấn đề: mức ưu tiên giữa các ngắt, tài nguyên dùng chung ... Thông thường chỉ dùng ngắt cho một trong các trường hợp sau:
                  - sự kiện cần được đáp ứng nhanh.
                  - sự kiện cần được đáp ứng vào một thời điểm tương đối chính xác nào đó, hoặc theo lịch trình.
                  - ở tình trạng hoàn toàn thụ động với các sự kiện có tác động ngắn (ví dụ khi nhận dữ liệu từ bên ngoài qua cổng nối tiếp).

                  Đừng nghĩ nhiều tìm cách mở rộng ngắt ra vài chục hay vài trăm ngắt ngoài để "đủ dùng" cho hệ vi xử lý của bạn, thay vào đó hãy nghĩ theo hướng phân bổ các task xử lý như thế nào cho hợp lý để có thể xử lý kịp thời tất cả các tác động, các sự kiện với số lượng ngắt tối thiểu.

                  Thân mến,
                  blackmoon.

                  Comment


                  • #24
                    bác nào jup em với: Em gặp một bài về 89s52 giao tiếp qua cổng nối tiếp với cổng COM1 để đếm SP bằng cam biến hồng ngoai.. Em chưa gặp trường hợp nào phải giao tiếp với máy tính cả--> không bít phải hiển thị số sp đếm được như thế nào nữa?Bác nào giúp em với ????

                    Comment


                    • #25
                      Em cũng ko hiểu rõ lắm ! nhưng theo cách hiểu của em thì :

                      cảm biến sẽ qua 1 con LM324 rồi vào 1 chân ngắt ngoài INT của 89s52. vi điều khiển sẽ đếm số sản phẩm mỗi khi có ngắt ở chân này . số sản phẩm sẽ được đặt trong một biến nào đó . Sau đó mình lập trình để cho 89s52 gửi đi số này qua Port nối tiếp có sử dụng Max232. Cái khó là làm sao để chuyển con số này sang được mã ASCII vì máy tính sẽ từ mã này để hiển thị kí tự.
                      Để thấy được con số mà máy tính đã nhận qua cổng nối tiếp từ 89s52 thì ta có thể dùng phần mềm có sẵn của Windows là Hyper terminal . phần mềm này sẽ hiển thị những gì máy tính đã nhận được.

                      Hic ! em chỉ biết có vậy thôi à !!! mong các bác cho ý kiến ! vì em cũng rất thích phần này nhưng còn mù mờ lắm !!!
                      ------
                      Qrio' qrio` qrioooooo!!!!>:D<

                      Comment


                      • #26
                        Cái chính là ở chổ đó. Bác có thể giúp em vói được không?Qrio tô?!
                        :laycu: Trúc xinh trúc mọc đầu đình
                        Em xinh em bị hắc lào vưỡn xinh!

                        Comment


                        • #27
                          Uart-lcd-i2c

                          Sau một thời gian tìm hiểu VDK 8051 và tham khảo các bài viết trên mạng, nay e đã viết được một số modul cho các giao tiếp trên. E nghĩ rằng, với những người mới tìm hiểu về 8051, có thể đọc hiểu và dùng ngay các modul này một cách dễ dàng.
                          Last edited by Thiên Phong; 16-12-2006, 10:21.

                          Comment


                          • #28
                            1.uart

                            Ở đây tôi chỉ đưa lên các modul chính, còn cách thức giao tiếp của 8051 với máy tính qua UART như thế nào thì các bạn tự tìm hiều nhé. Các modul tôi viết bằng KeilC51.
                            Code:
                            //***************Thiết lập cho UART****************
                            void uart_init()//dung trong truyen thong noi tiep
                            {
                            	SCON=0x50;//che do 8 bit du lieu,1 bit sart,1 bit stop
                            	TMOD&=0x0F;//
                                TMOD|=0x20;//timer1 in mode2
                                TH1=0xFD;//set baut rate at 9600(11.0592Mhz)
                                TL1=0xFD;
                                ES=1;//cho phep ngat noi tiep
                            	EA=1;//cho fep tat ca cac ngat
                            	TR1=1;//chay timer1
                            }//tham khảo thêm trong tài liệu của Thầy Tống Văn On
                            //***************Gửi 1 ký tự *********************
                            void send_data(char uart_data)//gui du lieu qua cong COM
                            {
                            	TI=0;
                            	SBUF=uart_data;
                            	while(TI==0){}//cho trong khi dang gui du lieu
                            	TI=0;
                            }
                            //***************Gửi một chuỗi ký tự*****************
                            void send_string(char my_data[])
                            {
                            	unsigned char len_my_data,q;
                            	len_my_data=strlen(my_data);
                            	for(q=0;q<len_my_data;q++)
                            		{
                            			send_data(my_data[q]);
                            		}
                            
                            }
                            //*************Nhận 1 ký tự*********************
                            void receive_data() interrupt 4//nhan du lieu
                            {
                            	if(RI==1)
                            		{
                            			RI=0;
                            			uart_data_receive=SBUF;
                            		}
                            }
                            /*Co 2 su kiện để ngắt truyền thông nối tiếp xảy ra:1 là sau khi gửi xong 1 ký tự ; 2 là sau khi nhận được 1 ký tự. CHo nên trong hàm receive_data() ta phải kiểm tra cờ (RI==1) hay không, để chắc chắn đó là ngắt do nhận xong 1 ký tự.*/
                            trên đây là các modul chính để làm việc với UART. các bạn viết thêm modul nhận 1 chuỗi ký tự mới từ máy tính xuống nhé.
                            Nếu bạn nào chưa có chương trình chạy trên máy tính để giao tiếp với 8051 qua UART thì liên hệ với tôi nhé:thienphong39@gmail.com.
                            Last edited by VNarmy; 12-03-2007, 23:20. Lý do: đưa vào tag code

                            Comment


                            • #29
                              Lcd

                              Để giao tiếp với LCD, ta có thể giao tiếp = 4 bit hoặc 8 bit. Giao tiếp 4 bit thì đã có một bạn trong diễn đàn này đưa lên khá lâu rồi và biết bằng asm. Ở đây tôi giao tiếp = 8 bit và viết bằng C.
                              Có 2 cách thức làm việc với LCD, gửi dữ liệu lên LCD(chủ yếu) và đọc dữ liệu từ LCD.
                              Trước khi làm việc với LCD, bạn phải thiết lập cho LCD.
                              Sau đây là các modul chính:
                              Code:
                              //*************thoi gian cho LCD thuc hien xong lenh************
                              void wait_LCD(void)
                              {//P1 nối với D0-D7 của LCD
                              //bạn phải định nghĩa trước các chân RS,RW,E được nối với chân nào của VDK
                                 P0_7=1;
                                 RS=0;//gui lenh len LCD
                                 RW=1;//va yeu cau doc du lieu tren LCD xuong
                                 while(P0_7==1)//trong khi P1_7=1 tuc la LCD dang ban, cho cho den khi P1_7=0
                                    {E=0;E=1;}
                              }
                              //*********chuong trinh dung de gui 1 lenh dieu khien len LCD*****
                              void send_command(unsigned char my_command)
                              //my_command o day co the o dang HEX hoac thap fan deu dc
                              {
                                P1=my_command;
                                RS=0;//Xet RS=0 de gui lenh;Neu RS=1->gui du lieu can hien thi len LCD
                                RW=0;//Xet RW=0 de ghi hoac gui lenh len LCD;RW=1->doc tu LCD xuong
                                E=1;//cho E 1 xung cao->thap de chot du lieu tren LCD
                                E=0;
                               wait_LCD();
                                
                              }
                              //*************Thiết lập ban đầu cho LCD************
                              void init_LCD(void)//khoi tao cho LCD
                              {  	
                                 delay(500);
                                 send_command(0x38);//Dung LCD 2*16, ma tran 5x7
                                 send_command(0x01);//xoa man hinh
                                 send_command(0x02);//tro ve dau dong
                                 send_command(0x0C);//bat hien thi, tat con tro
                              }
                              //***********gui 1 ky tu len LCD**************
                              void send_char(char my_char)//my_char o day co the o dang HEX theo ma ASCII;vd:A(65);B(66)....
                              {
                                 P1=my_char;
                                 RS=1;//de gui data
                                 RW=0;//gui du lieu len
                                 E=1;
                                 E=0;
                                 wait_LCD();
                              }
                              //*********ct dung de ghi 1 chuoi ky tu cho truoc len LCD********
                              void send_string(char my_string[],unsigned int time)
                              {//trong do "my_string" la chuoi can hien thi; 
                              //"time" la khoang thoi gian hien ra 2 ky tu lien tiep nhau;tinh = mili giay
                                unsigned int i,len_string;
                                len_string=strlen(my_string);//'strlen' la ham tra ve do dai cua chuoi
                                for (i=0;i<len_string;i++)
                                    {
                              	    send_char(my_string[i]);
                              		delay(time);//khoang thoi hien ra 2 ky tu lien tiep trong chuoi
                              	  }
                              
                              }
                              //*****Đây là hàm Delay()***************
                              void delay(unsigned int ms)
                                { 
                                  unsigned int i,j;
                                  for (i=0; i<ms; i++)
                              	  { for (j=0; j<120; j++); 
                              	    
                              	  }
                                }
                              Last edited by VNarmy; 12-03-2007, 23:18.

                              Comment


                              • #30
                                Timer0,Timer1,Timer2,INTO,INT1

                                Code:
                                //****Thiêt lập ban đầu cho các ngắt*********
                                void timer0_init()//dung cho ngat timer 0
                                 {
                                   TMOD&=0xF0;//0xFO=1111.0000
                                   TMOD|=0x01;//timer0 in mode 1(16bit).để thay đổi các mode làm việc, bạn tính toán và thay đổi ở đây.
                                   ET0=1;
                                   EA=1;   //tham khao "ho vi dieu khien 8051"
                                   TH0=0x00;//DC;       //Phai chu y
                                   TL0=0x00;     //Phai chu y
                                   TR0=1;
                                  }
                                void timer1_init()//dung cho ngat timer 1
                                 {
                                   TMOD&=0x0F;//0xOF=0000.1111
                                   TMOD|=0x10;//timer1 in mode 1(16bit)
                                   ET1=1;
                                   EA=1;   //tham khao "ho vi dieu khien 8051"
                                   TH1=0x00;       //Phai chu y
                                   TL1=0x00;     //Phai chu y
                                   TR1=1;
                                  }
                                void timer2_init()//thiet lap cho timer2
                                {//chỉ dùng cho 89S.
                                T2MOD &=0xFC;//T20E=0, DCEN=1
                                T2MOD |=0X01;
                                EXF2=0;//RESET FLAG
                                TCLK=0;RCLK=0;//DISABLE BAUD RATE GENERATOR
                                EXEN2=0;//IGNORE EVENTS ON T2EX
                                TH2=0xf0;
                                TL2=0xf0;
                                RCAP2H=0xf0;
                                RCAP2L=0xf0;
                                C_T2=0;//timer MODE
                                CP_RL2=0;//RELOAD MODE
                                EA=1;//INTERRUPT ENABLE
                                ET2=1;//ENABLE TIMER2 INTERRUPT
                                TR2=1;//TIMER2 RUN
                                
                                }
                                void INT0_init()
                                {
                                	EA=1;//cho phep tat ca ngat
                                	EX0=1;//cho phep ngat ngoai0
                                	IT0=1;//ngat theo suon(IT0=0:ngat theo muc)
                                }
                                //----------------thiet lap cho phep ngat ngoai1---------
                                void INT1_init()
                                {
                                	EA=1;//cho phep tat ca ngat
                                	EX1=1;//cho phep ngat ngoai1
                                	IT1=1;//ngat theo suon
                                }
                                //*********các chương trình phục vụ ngắt*********
                                void chuongtrinh_timer0 (void) interrupt 1//chuong trinh phuc vu ngat timer0
                                {
                                //bạn sẽ viết các việc muốn 8051 làm khi có ngắt timer0 vào đây
                                
                                //phần này giu nguyen	
                                //TH0 và TL0 do bạn tính toán
                                	TH0=0xf0;
                                	TL0=0xf0;
                                	TF0=0;
                                	TR0=1;
                                }
                                void chuongtrinh_timer0 (void) interrupt 3//chuong trinh phuc vu ngat timer1
                                {	
                                //bạn sẽ viết các việc muốn 8051 làm khi có ngắt timer1 vào đây
                                
                                //phần này giu nguyen	
                                //TH1và TL1 do bạn tính toán
                                	TH1=0xf0;
                                	TL1=0xf0;
                                	TF1=0;
                                	TR1=1;
                                }
                                //---------chuong trinh phuc vu ngat ngoai 1------------
                                void chuongtrinh_INTO(void) interrupt 0
                                {	
                                		
                                }
                                //---------chuong trinh phuc vu ngat ngoai 1------------
                                void chuongtrinh_INT1(void) interrupt 2
                                {
                                //*****Lư ý: bạn phải thay đổi một chút trong thiết lập ban đầu cho các ngắt để lựa chọn các chế độ làm việc phù hợp với mục đích của bạn. Các chế độ làm việc của các ngắt bạn phải tham khảo thêm tại "họ vi dk 8051" của thầy Tống.	
                                }
                                Last edited by VNarmy; 24-07-2007, 18:37.

                                Comment

                                Về tác giả

                                Collapse

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

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

                                Collapse

                                Đang tải...
                                X