Thông báo

Collapse
No announcement yet.

tutorial cho HTPIC

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

  • #31
    Với PIC thì phải dùng mẹo 1 chút còn với 51 thì không cần. Vẫn có thể ngắt lồng nhau song nếu không cẩn thận nó thành đệ quy thì treo ngay.
    Nhà sản xuất chuyên nghiệp các sản phẩm OEM cho gia dụng và công nghiệp.

    Biến tần
    Máy giặt
    Lò vi sóng
    Bếp từ.
    Tủ lạnh.
    Điều hòa

    Comment


    • #32
      Nguyên văn bởi MinhHa
      Với PIC thì phải dùng mẹo 1 chút còn với 51 thì không cần. Vẫn có thể ngắt lồng nhau song nếu không cẩn thận nó thành đệ quy thì treo ngay.
      Hihi.. mẹo gì vậy anh?
      Phải chăng là làm một biến đếm số lần vào ngắt, nếu số lần vượt quá giới hạn cho phép của ngăn xếp thì không bật GIE nữa.
      Các bước chương trình phục vụ ngắt:
      -Xóa cờ ngắt.
      -Tăng biến đếm số lần ngắt lên 1 , nếu vẫn nhỏ hơn giới hạn ngăn xếp thì GIE=1;
      -Tiếp tục chương trình phục vụ ngắt.

      Hihi... đúng ko anh MH.

      Comment


      • #33
        không đúng. 3T lưu ý khi xảy ra ngắt thì MCU làm gì và khi kết thúc ngắt thì nó làm gì nhé.
        GIE = 1 giống như MCU kết thúc ngắt đó và cho ngắt khác được hoạt động. Nhưng thực sự khi kết thúc ngắt nó còn phải POP PC ra khỏi stack nữa.
        Có bao nhiêu lần vào ngắt thì phải có bấy nhiêu lần ra ngắt. Nếu lồng vào thì có n lần vào ngắt nhưng chỉ có 1 lần ra ngắt. Như vậy sẽ treo ngay.
        Nhà sản xuất chuyên nghiệp các sản phẩm OEM cho gia dụng và công nghiệp.

        Biến tần
        Máy giặt
        Lò vi sóng
        Bếp từ.
        Tủ lạnh.
        Điều hòa

        Comment


        • #34
          Rảnh rỗi ngồi viết chương trình hiển thị led7 thanh chơi chơi. Ở đây em chỉ dùng 1 led thôi cho đơn giản. Còn việc quét led đã viết ở các bài trước rùi .

          Đây là sơ đồ nguyên lý:

          Tiếp theo là chương trình bằng HTPIC:

          Code:
          #include<pic.h>
          __CONFIG(HS & PWRTEN & BOREN & LVPDIS & WDTDIS );
          
          // bộ font cho led7 
          const unsigned char Font[]={ 0b00000011, 0b10011111, 0b00100101, 0b00001101, 0b10011001,\
          							0b01001001, 0b01000001, 0b00011111, 0b00000001, 0b00001001};
          void init(void)
          	{
          		//-------------------------init for PORTs
          		OPTION = 0b00000000; // dùng Prescaler với k= 1:2
          		TRISD	= 0b00000000;
          		TRISE	= 0b11111111;
          		PORTD = Font[0] ; // ban đầu cho hiển thị số 0
          		//-------------------------init for interrupt vầ timer0
          		GIE	= 1; // cho phép ngắt toàn cục
          		T0IE    = 1;  // cho phép ngắt timer0
          		TMR0    = 6;  // đặt giá trị đầu cho TMR0
          	}
          
          void interrupt MyInt(void){
          	static int counter;  // biến đếm sự kiện ngắt timer
          	static unsigned char i;  // biến đếm số đang hiển thị trên led
          	if (T0IF  &  T0IE){  // nếu có ngắt
          		T0IF = 0 ;
          		TMR0 = 6;
          		++ counter;
          		if( counter == 1000){  // cứ 1s thì hiển thị hiển thị tiếp
          			counter = 0 ;  // reset lại bộ đếm
          			PORTD = Font[i++];
          			if( i ==10) i = 0;
          		};
          	};
          }
          
          void main(){
          	init();
          	while(1);
          }
          Chương trình trên cực kỳ đơn giản song chỉ có một câu lệnh cần chú ý là:
          Code:
          if (T0IF  &  T0IE){
          vì timer0 tự chạy nên cờ T0IF liên tục set lên khi đó nếu không phải là ngắt timer0 mà là một ngắt khác xảy ra. Khi đó trong hàm ngắt chương trình sẽ thử điều kiện T0IF = = 1 sẽ đúng. Nếu chúng ta chỉ dùng là
          Code:
           if (T0IF)
          thì tất nhiên là điều kiện thử đúng và sẽ thực hiện chương trình trong if .

          Nếu lúc đó ta đã disable ngắt timer0 mà giờ nó lại thực hiện chương trình trong timer0 thì chương trình chạy quá sai rùi. Đây là chú ý của anh BA . Nếu không nhận ra thì có khi sai nhiều đó . Khi chúng ta viết chương trình ngắt trong ngắt thì sẽ thấy điều này .

          Chúc các bạn thành công.
          Last edited by ngohaibac; 25-03-2006, 07:25. Lý do: sửa lại code chút
          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


          • #35
            Ac ac!

            Tutorial HTPIC sao ko thấy tài liệu lập trình HTPIC vậy các bác!
            AI có thì share cho anh em với!

            Comment


            • #36
              Chào nhn.

              Cái này lập trình như chương trình C bình thường và thao tác với các thanh ghi rất đơn giản mà.Đơn giản vì các header file đã định nghĩa sẵn địa chỉ của các thanh ghi rồi nên mình không cần phải định nghĩa lại nữa. Mình có quyển nào về HTPIC đâu .

              Toàn viết trực tiếp với các thanh ghi mà thôi. Nếu có ai thắc mắc về các chương trình thì mình xin giải thích.

              Các chương trình đều đã được test đảm bảo về tính đúng đắn của nó . Mình đã edit lại một số bài viết ở trước. Hi vọng là các bạn dùng ngon lành .

              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


              • #37
                Adc

                Bài tiếp theo tôi đã làm, đã test rồi nhưng hôm này con PIC nó bị "ốm" nên không test được.

                Đã vậy 3 ngày không được vào diễn đàn vì bọn hack DDOS thấy nhớ quá. Nên vào một cái là up ngay chương trình về ADC cho bà con xem . Bạn nào test luôn lại cái và báo lại kết quả cho mình luôn nha.

                Phần cứng: Biến trở 10k mắc vào AN0. Đo áp biến đổi ADC hiển thị lên 4 con led7

                Đây là schematic:




                Loại PIC: 16F877A

                Thuật giải là cứ sau mỗi thời gian trích mẫu thì lại bắt đầu chuyển đổi ADC luôn. Khi có ngắt AD thì lưu giá trị vào số number. Còn quét led thì liên tục quét.
                Ở đây mình tạo ra một timer0 1ms. Thời gian trích mẫu AD = 4ms x counter2.
                Mình edit lại đây

                Source code:
                Code:
                #include<pic.h>
                __CONFIG(HS & PWRTEN & BOREN & LVPDIS & WDTDIS );
                
                const unsigned char Font[]={ 0b00000011, 0b10011111, 0b00100101, 0b00001101, 0b10011001,\
                							0b01001001, 0b01000001, 0b00011111, 0b00000001, 0b00001001};
                
                //===== hàm khoi tao
                void interrupt MyInt(void){
                	static int counter1,counter2;
                	// counter1  dem so lan Timer0 tran
                	// counter2  dem so lan ca 4 led duoc quet
                	static unsigned int number;
                	static unsigned int a[4]={0,0,0,0};
                	static unsigned char j;			  // biến đếm kiểm tra xem led nào đang được quét
                		if(T0IF & T0IE){	
                			TMR0 = 6;
                			T0IF = 0 ;// xoa co ngat
                			if( ++counter1 == 10){
                				counter1 = 0;
                				PORTD = 0xFF;
                				PORTA  = 0xFF - (1<< (j+1)) ;
                				PORTD	= Font[a[j]];
                				if(j++ == 3 ) {
                					j=0;
                					RD0 = 0; 
                					++counter2;
                				};
                			};
                			if(counter2 == 30 ){ // cap nhat so vao sau 300 ms
                				counter2 = 0;
                				if (ADIF == 0) {
                					ADGO = 1 ;  // chuyen doi ADC tiep 
                					a[3] = (unsigned char)number/1000;
                					a[2] = (number/100)%10;
                					a[1] = (number/10)%10;
                					a[0] = number%10;
                					};
                			};
                		};
                	if ( ADIE & ADIF){
                		//number = (unsigned int)((((ADRESH <<8) + ADRESL)*500)>>10);
                		//number = (unsigned int)((ADRESH * 256 + ADRESL ) * 500)>>10;
                		number=(ADRESH<<8)|ADRESL;		
                		number=(unsigned int) (number* 4.8876);		//5000/1023
                		ADIF  = 0 ;
                	};
                	}
                
                //Hàm khoi tao
                void init(void)
                	{
                		//Khoi tao cho cac port
                		OPTION = 0b00000000;
                		TRISA	= 0b00000001;			 //  RA0 là input cho dau vao cua analog
                		TRISB	= 0b11111111;
                		TRISC	= 0b11111111;
                		TRISD	= 0b00000000;
                		PORTD = Font[0];
                		TRISE	= 0b11111111;
                
                		//Khoi tao cho ADC, co the viet don gian theo thanh ghi cung ok, viet nhu sau cho chinh sua don gian
                		
                		ADFM = 1;  						// chon can le ben phai voi ket qua 10 bit
                		PCFG3 = PCFG2 = PCFG1 = 1; PCFG0 = 0;  
                										// chon 1 dau RA0 la Analog con l?i la Digital, chon ap tham chieu la VDD - VSS
                		ADCS2 = ADCS1 = ADCS0 = 0 ; // chon tan so chuyen doi AD
                		CHS2 = CHS1 = CHS0 = 0 ; 		// chon chanle AN0 lam chuyen doi ADC
                		ADGO = 0 ;
                		ADON = 1; 						// Bat AD module
                
                		//  Khoi tao cho ngat
                		GIE		= 1; 					 // Global Interrupt Enable 
                		T0IE = 1;        					// Ngat timer0
                		TMR0 = 6;
                		PEIE = 1;  						// enable PI 
                		ADIE = 1 ;						// Ngat AD Module
                	}
                
                //------------------------------------MAIN
                void main(){
                	init();
                	ADGO = 1 ; 					// Bat dau chuyen doi ADC 
                	while(1);
                }
                
                //=============== Hết
                Chết thật viết bài mà vẫn còn quên. Các bạn chú ý: khi khởi tạo ADC chúng ta có thể viết ngắn hơn theo byte ADCON0, ADCON1. Nhưng ở đây tôi tách ra thành từng bit để cho chi tiết dễ chỉnh sửa hơn.

                Chúc mọi người thành công. Mai viết tiếp
                Last edited by ngohaibac; 21-04-2006, 09:10.
                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


                • #38
                  Bên www.picvietnam.com tôi có viết bài viết về biến kiểu volatile tại luồng
                  http://www.picvietnam.com/forum//sho...p?t=325&page=4
                  như sau. xin mọi người tham khảo và có ý kiến gì thì nói nha


                  Nguyên văn bởi pb1
                  Nhà mình có bác nào dảnh thì giải thích giúp em cái này cái:
                  static volatile bit flag=0;
                  static volatile unsigned int t1=0,t2=0;
                  Khai báo biến kiểu này là kiểu gì thế?
                  Theo tài liệu tại: \HT-PIC\manual\manual.pdf trang 153 . Bọn nó viết thế này: (tạm dịch)

                  Kiểu dữ liệu volatile được dùng để báo cho trình dịch biết rằng đối tượng được khai báo kiểu volatile có thể không cần lưu trữ lại giá trị giữa các lần truy cập liên tiếp. Điều đó làm cho chương trình có sự tối ưu hoá từ việc là những dư thừa rõ ràng đang được loại ra khi sử dụng một đối tượng có kiểu volatile bởi ví đối tượng đó có thể thay đổi tuỳ theo chương trình hoạt động như thế nào.

                  Tất cả các port I/O và tất cả các biến mà bị thay đổi giá trị trong trình phục vụ ngắt nên khai báo kiểu volatile.

                  Ví dụ:
                  Code:
                  volatile static near unsigned char PORTA @ 0xF80;
                  Đối tượng volatile được truy nhập theo một cách khác so với một đối tượng không có khai báo volatile. Khi gán giá trị của một đối tượng không có khai báo volatile = 1 thì đối tượng này sẽ bị xoá và địa chỉ của đối tượng sẽ tăng lên. Nhưng với biến có khai báo violatile thì cách hoạt động như sau: đầu tiên là gán giá trị của thanh ghi W = 1 và sau đó là lưu giá trị đó vào địa chỉ của ban đầu của đối tượng đó.

                  Kết luận: như vậy là khai báo volatile được dùng với biến phải sử dụng liên tục. Khi khai báo như thế thì tiết kiệm được địa chỉ của RAM.

                  Khi các bạn mở các file include ra sẽ thấy được rằng bọn nó khai báo địa chỉ cho các port đều theo kiểu này
                  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


                  • #39
                    Pwm

                    Theo datasheet PIC687XA tại trang 67,68 về PWM, chúng ta dễ dàng có thể viết được chương trình điều chế độ rộng xung (Pulse Width Modulation).

                    Chương trình dưới đây điều chế một xung với tần số 15KHz và có độ rộng xung tăng dần từ 0-> 100% theo bước tăng là 10% sau mỗi khoảng thời gian 1s.

                    Code:
                    PWM Period = [ PR2 +1 ] x 4 x Tosc x   (TMR2 Prescaler Value)
                    PWM Duty Cycle = [ CCPR1L : CCP1CON<5:4>) x Tosc x  (TMR2  Prescaler Value)
                     =>   CCPR1L : CCP1CON<5:4> = k% x (TMR2 + 1 ) x 4;
                    với k là độ rộng xung (%) k = 0 -> 100
                    Sau đây là chương trình có kèm theo mô tả phần cứng:

                    Code:
                    /*;========================================================
                    ; Ten chuong trinh	: Dieu che do rong xung
                    ; Nguoi thuc hien	: Ngo Hai Bac (NOHB)
                    ; Ngay thuc hien	: 12/04/06
                    ; Phien ban	: 1.0
                    ; Mo ta phan cung	: Dung PIC16F877A - thach anh 20MHz
                    ; 					Dieu che do rong xung ra chan RC2/CCP1, chan RC2 noi voi led roi noi voi tro 220 Ohm, roi noi voi dat.
                    ;					=> sau 1s thi tang do rong xung len 10%
                    ;----------------------------------------------------------------
                    ; Ngay hoan thanh	: 
                    ; Ngay kiem tra	: 
                    ; Nguoi kiem tra	: 
                    ;----------------------------------------------------------------
                    ; Chu thich	: Phan chuong trinh nho cho du an lon :D
                    			PWM dung timer2 
                    ;========================================================*/
                    #include<pic.h>
                    __CONFIG(HS & UNPROTECT & PWRTEN & BOREN & LVPDIS & WDTDIS );
                    
                    //============ cac marco
                    
                    
                    //=============  ham khoi tao 
                    void init(void){
                    //===== init for PWM
                    	// PWM Period = [ PR2 +1 ] x 4 x Tosc x   (TMR2 Prescaler Value)
                    	PR2 = 82;						// Tan so = 15 KHz, TMR2 Prescaler Value = 4
                    	// PWM Duty Cycle = [ CCPR1L : CCP1CON<5:4>) x Tosc x  (TMR2  Prescaler Value)
                    	// =>   CCPR1L : CCP1CON<5:4> = k% x (TMR2 + 1 ) x 4;
                    	CCPR1L = 0;
                    	TRISC2 = 0;						// RC2 la output
                    	RC2  = 1;
                    	T2CON = 0b00000101;			// Timer2 on, TMR2 Prescaler Value = 4
                    	CCP1CON = 0b00001100;		// CCP1 hoat dong trong che do PWM
                    //===== init cho SFR
                    	OPTION = 0x00;					// dung tro keo len PortB, TMR0 Prescaler = 2 va dung cho TMR0
                    	TMR0 = 0x06;					// khoi tao cho Timer0
                    	T0IF = 0;						// xoa co ngat timer0
                    	T0IE = 1;						// timer0 Interrupt Enable 
                    	GIE = 1;							// Global Interrupt Enable 
                    }	
                    
                    //============= ham ngat 
                    void interrupt MyInt(void){
                    	static volatile unsigned char k;		// % do rong xung =>  0<= k <= 100
                    	static volatile unsigned int counter1;
                    	int temp;
                    	// ==== Ngat timer0
                    	if (T0IE & T0IF ){
                    		T0IF = 0;
                    		TMR0 = 6;
                    		if(++counter1 == 1000){
                    			counter1 = 0;
                    			temp = 4* (PR2 + 1) * k/100;
                    			CCPR1L = temp>>2;
                    			CCP1Y  = temp - ((temp>>1)<<1);//temp%2;
                    			CCP1X = (temp>>1)%2;
                    			//CCPR1L = (TMR2 + 1)>>1 ;
                    			k += 10; 					// tang 10%
                    			if( k > 100) k=0;
                    		};	
                    	};
                    }
                    
                    //=============  ham chinh Main
                    void main(void){
                    	init();
                    	while(1);
                    }
                    Chương trình đã được test bằng mạch thật. Hiện tượng: led sáng dần dần sau đó sáng rõ. Rồi lại tắt, tiếp tục sáng dần dần,..
                    Ngẫu hứng đêm khuya viết tí. Sáng mai dạy viết tiếp.

                    Chúc anh em ngủ ngon .
                    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


                    • #40
                      Mình bi giờ mới vào được diễn đàn sau khi thiết lập Proxy cho trình duyệt. Nên post vài bài cho anh em tham khảo và cho ý kiến. Các bài này mình viết bên picvietnam.com rồi tại luồng sau:
                      http://www.picvietnam.com/forum//showthread.php?t=339

                      OK, mình xin thay đoạn chương trình đó bằng cách gọi hàm:
                      Code:
                      Convert(a,4,number);
                      Với hàm Convert được khai báo và định nghĩa ở trên hàm MyInt như sau:
                      Code:
                      // ========== Ham chuyen doi
                      void Convert(unsigned char *a,unsigned char index, unsigned int number){
                      	unsigned char i;
                      	for(i=0;i< index; i++){
                      		*(a+i)  = number%10;
                      		number = number/10;
                      	};	
                       }
                      Các bạn đổi lại kiểu dữ liệu của mảng a trong chương trình lại thành kiểu Unsigned char.

                      Đoạn code đã được test bằng phần cứng.Đảm bảo thay thế đúng.

                      Mình xin đưa lại code mới:

                      Code:
                      /*;========================================================
                      ; Ten chuong trinh	: Quet 4led 7 thanh
                      ; Nguoi thuc hien	: Ngo Hai Bac (NOHB)
                      ; Ngay thuc hien	: 12/04/06
                      ; Phien ban			: 2.0		
                      ; Mo ta phan cung	: Dung PIC16F877A - thach anh 20MHz
                      ; 					4 led 7 anot chung, cac catot noi voi PORTD, 4 chan anot noi voi cuc E trans A1015
                      ;					cuc B cua trans noi voi chan 7->5 cua PORTA
                      ;----------------------------------------------------------------
                      ; Ngay hoan thanh	: 
                      ; Ngay kiem tra	: 
                      ; Nguoi kiem tra	: 
                      ;----------------------------------------------------------------
                      ; Chu thich	: 		
                      ;========================================================*/
                      #include<pic.h>
                      __CONFIG(HS & PWRTEN & BOREN & LVPDIS & WDTDIS );
                      
                      const unsigned char Font[]={ 0b00000011, 0b10011111, 0b00100101, 0b00001101, 0b10011001,\
                      							0b01001001, 0b01000001, 0b00011111, 0b00000001, 0b00001001};
                      
                      // ========== Ham chuyen doi
                      void Convert(unsigned char *a,unsigned char index, unsigned int number){
                      	unsigned char i;
                      	for(i=0;i< index; i++){
                      		*(a+i)  = number%10;
                      		number = number/10;
                      	};	
                       }
                      
                      //===== hàm khởi tạo
                      void interrupt MyInt(void){
                      	static int counter1,counter2;
                      	// counter1 dem so lan Timer0 tran
                      	// counter2  dem so lan ca  4 led7 thanh  duoc quet
                      	static volatile unsigned int number;
                      	static volatile unsigned char a[4]={0,0,0,0};
                      	static volatile unsigned char j;  // bien dem kiem tra xem led nao duoc quet
                      		if(T0IF & T0IE){	
                      			TMR0 = 6;
                      			T0IF = 0 ;// xoa co ngat
                      			++counter1;
                      			if( counter1 == 3){
                      				counter1 = 0;
                      				PORTD = 0xFF;
                      				PORTA  = 0xFF - (1<<(5- j)) ;
                      				PORTD	= Font[a[j]];
                      				if(++j==4) {
                      					j=0;
                      					++counter2;
                      				};
                      			};
                      			if(counter2 == 200){
                      				 if(++number>9999) number= 0;
                      				counter2 = 0;
                      				Convert(a,4,number);
                      			};
                      		};
                      	}
                      
                      //------------------------------------init
                      void init(void)
                      	{
                      		//-------------------------init for PORTs
                      		OPTION = 0b00000000;
                      		ADCON1 = 0b00000111;
                      		TRISA	= 0b00000000;
                      		TRISB	= 0b11111111;
                      		TRISC	= 0b11111111;
                      		TRISD	= 0b00000000;
                      		PORTD = Font[0];
                      		TRISE	= 0b11111111;
                      		//-------------------------init for interrupt
                      		GIE		= 1;
                      		T0IE = 1;
                      		TMR0 = 6;
                      	}
                      
                      //------------------------------------MAIN
                      void main(){
                      	init();
                      	while(1);
                      }
                      
                      // ============== Hết code

                      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


                      • #41
                        USART - truyền dữ liệu nối tiếp với PC

                        Đây là chương trình khi PC gửi dữ liệu đến PIC thì PIC sẽ phản hồi lại kí tự mà nó đã nhận được. Là một phần trong bài tập lớn của tôi nên tôi sẽ post dần lên cho anh em tham khảo và cho ý kiến về độ tối ưu của chương trình.
                        Code:
                        /*========================================================
                        ; Ten chuong trinh	: giao tiep USART voi PC, nhan duoc thi hien thi lai
                        ; Nguoi thuc hien	: ngohaibac
                        ; Ngay thuc hien	: 
                        ; Phien ban	: 1.0
                        ; Mo ta phan cung	: Dung PIC16F877A - thach anh 20MHz
                        ;		chan RC7/TX noi voi chan R1OUT cua MAX232
                        ;		chan RC6/RX noi voi chan T1IN cua MAX232
                        ;----------------------------------------------------------------
                        ; Ngay hoan thanh	: 
                        ; Ngay kiem tra	: 
                        ; Nguoi kiem tra	: 
                        ;----------------------------------------------------------------
                        ; Chu thich	: Chuong trinh dung giao tiep USART
                        
                        ;========================================================*/
                        #include<pic.h>
                        
                        __CONFIG(HS & PWRTEN & BOREN & LVPDIS & WDTDIS );
                        
                        // ham init - khoi tao 
                        void initUART(void){
                        // Khoi tao cho USART
                        	TRISC = TRISC | 0b11000000;			// Bit 7,6 la RX va TX phai la Input
                        	SPEN = 1 ;		// Enable Serial Port communication.
                        	SYNC =	 0;		// che do khong dong bo Asynchronous
                        	// cho che do truyen
                        	TXEN = 1;		//enable truyen
                        	TX9 = 0 ;		// chon che do 8 truyen  bit du lieu
                        	BRGH = 1; 		// High - speed
                        	SPBRG = 129;	//Baud = 9600;	voi HS, Baud Rate = Fosc/(16(X+1))  
                        	TXIE = 0;		// khong dung ngat Truyen
                        	// Che do nhan du lieu
                        	RCIE  =  1;		// dung ngat nhan
                        	PEIE = 1;		// cho phep ngat ngoai vi
                        	GIE  = 1;			// cho phep ngat toan cuc
                        	RX9 = 0;			// nhan 8 bit
                        	CREN = 1;		// lien tuc nhan du lieu; = 0 k lien tuc nhan du lieu
                        	
                        }
                        
                        
                        // ham truyen du lieu 1 ký tự
                        void putch(unsigned char byte) 
                        {
                        	/* output one byte */
                        	while(!TXIF);	/* set when register is empty */
                        	//	continue;
                        	TXREG = byte;
                        }
                        
                        void init(void){
                        	initUART();
                        
                        }
                        // ham ngat
                        void interrupt MyInt(void){
                        	unsigned char temp;
                        	if(RCIF){						// Neu co ngat nhan du lieu noi tiep
                        		temp = RCREG;
                        		RCIF = 0;					// Xoa co ngat RCIF
                        		putch(temp);
                        	};
                        }
                        
                        // ham chinh 
                        void main(void){
                        	//unsigned char a[] =" anh yeu em nhieu lam, em biet k?";
                        	//unsigned char i = 0;
                        	init();
                        	//for(i= 0; i<33; i++) putch(a[i]);
                        	//for(i= 0; i<10; i++) putch(i+48);
                        	while(1);
                        }
                        Chương trình này chỉ đơn giản là một ví dụ về truyền nhận dữ liệu còn nếu các bạn muốn truyền, nhận một sâu thì các bạn phải dùng Timeout cho nó để chống mất dữ liệu như sự cố đường dây mà PIC nhà ta vẫn chờ mỏi cả cổ mà vẫn k nhận được hết dữ liệu mà nó cần thì chết .

                        Chương trình đã được test và chạy ngon lành.

                        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


                        • #42
                          Timer1 đếm xung hiển thị 4 Led7 đoạn

                          Có lẽ chương trình hiển thị số lên led7 đoạn đã được mịnh viết bên dientuvietnam.net nên sẽ không viết lại nữa nha. Nhưng máy mình không vào được site này. Nên đành post lên bên này vậy.

                          Sau đây là chương trình đếm xung từ chân RC1/T1OSI/CCP2 để hiển thị lên 4led 7 thanh. Một chương trình cũng rất đơn giản.Xin mời các bạn xem và cho ý kiến về chương trình này:
                          Code:
                          /*;========================================================
                          ; Ten chuong trinh	: Quet 4led 7 thanh
                          ; Nguoi thuc hien	: Ngo Hai Bac (NOHB)
                          ; Ngay thuc hien	: 
                          ; Phien ban	: 1.0
                          ; Mo ta phan cung	: Dung PIC16F877A - thach anh 20MHz
                          ; 					4 led 7 anot chung, cac catot noi voi PORTD, 4 chan anot noi voi cuc E trans A1015
                          ;					cuc B cua trans noi voi chan 7->5 cua PORTA
                          ;					Xung ngoai duoc cho vao chan RC1/T1OSI/CCP2
                          ;----------------------------------------------------------------
                          ; Ngay hoan thanh	: 
                          ; Ngay kiem tra	: 
                          ; Nguoi kiem tra	: 
                          ;----------------------------------------------------------------
                          ; Chu thich	: 		
                          ;========================================================*/
                          #include<pic.h>
                          __CONFIG(HS & PWRTEN & BOREN & LVPDIS & WDTDIS );
                          
                          const unsigned char Font[]={ 0b00000011, 0b10011111, 0b00100101, 0b00001101, 0b10011001,\
                          							0b01001001, 0b01000001, 0b00011111, 0b00000001, 0b00001001};
                          
                          
                          // Chuyen doi
                          void Convert(unsigned char *a,unsigned char index, unsigned int number){
                          	unsigned char i;
                          	for(i=0;i< index; i++){
                          		*(a+i)  = number%10;
                          		number = number/10;
                          	};	
                           }
                          
                          //=====  Ham khoi tao
                          void interrupt MyInt(void){
                          	static volatile unsigned int counter1,counter2;
                          	// counter1 dem so lan Timer0 tran
                          	// counter2  dem so lan ca  4 led7 thanh  duoc quet
                          	static volatile unsigned int number;
                          	static volatile unsigned char a[4]={0,0,0,0};
                          	static volatile unsigned char j;  // bien dem kiem tra xem led nao duoc quet
                          		if(T0IF & T0IE){	
                          			TMR0 = 6;
                          			T0IF = 0 ;// xoa co ngat
                          			++counter1;
                          			if( counter1 == 3){
                          				counter1 = 0;
                          				PORTD = 0xFF;
                          				PORTA  = 0xFF - (1<<(5- j)) ;
                          				PORTD	= Font[a[j]];
                          				if(++j==4) {
                          					j=0;
                          					++counter2;
                          				};
                          			};
                          			if(counter2 == 2000){
                          				number = (TMR1H << 8) | TMR1L;
                          				TMR1ON = 0 ; // ngung Timer1
                          				TMR1H = TMR1L = 0;
                          				TMR1ON = 1 ;  // bat lai Timer1
                          				 if(number>9999) number= 0;
                          				counter2 = 0;
                          				Convert(a, 4, number);
                          			};
                          		};
                          	}
                          
                          //------------------------------------init
                          void init(void)
                          	{
                          		//=================   init for PORTs
                          		OPTION = 0b00000000;
                          		ADCON1 = 0b00000111;
                          		TRISA	= 0b00000000;
                          		TRISB	= 0b11111111;
                          		TRISC	= 0b11111111;
                          		TRISD	= 0b00000000;
                          		PORTD = Font[0];
                          		TRISE	= 0b11111111;
                          		//================  Khoi tao cho Timer0
                          		GIE		= 1;
                          		T0IE = 1;
                          		TMR0 = 6;
                          		
                          		// ========= Khoi tao cho dem Timer1
                          		TMR1CS   = 1;						// Timer1 hoat dong o che do Counter Mode
                          		T1SYNC  = 1;						// TMR1 hoat dong o che do dem khong dong bo
                          		T1OSCEN = 1;						// Dem xung tu chan RC1/T1OSI/CCP2
                          		T1CKPS1 = T1CKPS0 = 0;			// Chon Prescaler = 1:1
                          		TMR1H = TMR1L = 0;
                          		TMR1IE = 0;						// Khong dung ngat Timer1
                          		TMR1ON = 1;						// Bat Timer1
                          		
                          	}
                          
                          //------------------------------------MAIN
                          void main(){
                          	init();
                          	while(1);
                          }
                          // =============  Kết thúc
                          Chúc mọi người 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


                          • #43
                            Điều chế PWM và đếm xung hiển thị 4Led

                            Đây là chương trình điều chế xung PWM trên chân RC2/CCP1 và đếm xung từ chân RC1/T1OSI/CCP2 hiển thị lên 4led7 thanh. Mình dùng Encoder 100 lỗ mượn của bạn .
                            Code:
                            #include<pic.h>
                            __CONFIG(HS & PWRTEN & BOREN & LVPDIS & WDTDIS );
                            
                            const unsigned char Font[]={ 0b00000011, 0b10011111, 0b00100101, 0b00001101, 0b10011001,\
                            							0b01001001, 0b01000001, 0b00011111, 0b00000001, 0b00001001};
                            
                            
                            // Chuyen doi
                            void Convert(unsigned char *a,unsigned char index, unsigned int number){
                            	unsigned char i;
                            	for(i=0;i< index; i++){
                            		*(a+i)  = number%10;
                            		number = number/10;
                            	};	
                             }
                            
                            //=====  Ham khoi tao
                            void interrupt MyInt(void){
                            	static volatile unsigned int counter1, counter2, counter3;//, counterTimer1;
                            	unsigned int temp;					
                            	// counter1 dem so lan Timer0 tran
                            	// counter2  dem so lan ca  4 led7 thanh  duoc quet
                            	static volatile unsigned int number;
                            	static volatile unsigned char a[4]={0,0,0,0};
                            	static volatile unsigned char j,k;  // bien dem kiem tra xem led nao duoc quet
                            		if(T0IF & T0IE){	
                            			TMR0 = 6;
                            			T0IF = 0 ;// xoa co ngat
                            			++counter1;
                            			if( counter1 == 5){
                            				counter1 = 0;
                            				PORTD = 0xFF;
                            				PORTA  = 0xFF - (1<<(5- j)) ;
                            				PORTD	= Font[a[j]];
                            				if( j==2) RD0= 0;
                            				if(++j==4)	j=0;
                            			};
                            			if(++counter2 == 200){
                            				number  = (TMR1H << 8) | TMR1L;
                            				// gia tri toc do trong 1s = number * 1000/(100 * counter2 )		(vong/s)
                            				number = number * 5 ;	 //= number *0.0 5 vong/s  => * 5vong/s de hien thi len 4led
                            				TMR1ON = 0 ; // ngung Timer1
                            				TMR1H = TMR1L = 0;
                            				TMR1ON = 1 ;  // bat lai Timer1
                            				 if(number>9999) number= 0;
                            				counter2 = 0;
                            				Convert(a, 4, number);
                            			};
                            			if(++counter3 == 1000){
                            				k  = 70;
                            				counter3 = 0;
                            				temp = 4* (PR2 + 1) * k/100;
                            				CCPR1L = temp>>2;
                            				CCP1Y  = temp - ((temp>>1)<<1);//temp%2;
                            				CCP1X = (temp>>1)%2;
                            				//k += 10; 					// tang 10%
                            				//if( k > 100) k=0;
                            			};	
                            		};
                            }
                            
                            //------------------------------------init
                            void init(void){
                            
                            //===== init for PWM
                            	// PWM Period = [ PR2 +1 ] x 4 x Tosc x   (TMR2 Prescaler Value)
                            	PR2 = 82;						// Tan so = 15 KHz, TMR2 Prescaler Value = 4
                            	// PWM Duty Cycle = [ CCPR1L : CCP1CON<5:4>) x Tosc x  (TMR2  Prescaler Value)
                            	// =>   CCPR1L : CCP1CON<5:4> = k% x (TMR2 + 1 ) x 4;
                            	CCPR1L = 0;
                            	TRISC2 = 0;						// RC2 la output
                            	RC2  = 1;
                            	T2CON = 0b00000101;			// Timer2 on, TMR2 Prescaler Value = 4
                            	CCP1CON = 0b00001100;		// CCP1 hoat dong trong che do PWM
                            
                            //=================   init for PORTs
                            	OPTION =  0b00000000;
                            	ADCON1 = 0b00000111;
                            	TRISA	= 0b00000000;
                            	TRISD	= 0b00000000;
                            	PORTD = Font[0];
                            
                            //================  Khoi tao cho Timer0
                            	GIE		= 1;
                            	T0IE = 1;
                            	TMR0 = 6;
                            	
                            // ========= Khoi tao cho dem Timer1
                            	TMR1CS   = 1;						// Timer1 hoat dong o che do Counter Mode
                            	T1SYNC  = 1;						// TMR1 hoat dong o che do dem khong dong bo
                            	T1OSCEN = 1;						// Dem xung tu chan RC1/T1OSI/CCP2
                            	T1CKPS1 = T1CKPS0 = 0;			// Chon Prescaler = 1:1
                            	TMR1H = TMR1L = 0;
                            	TMR1IE = 0 ;						// Khong dung ngat Timer1
                            	TMR1ON = 1;						// Bat Timer1
                            }
                            
                            //------------------------------------MAIN
                            void main(){
                            	init();
                            	while(1);
                            }
                            // == Kết thúc
                            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


                            • #44
                              Giao tiếp USART điều khiển động cơ , thiết bị ngoại vi

                              Chương trình sau nhận lệnh từ PC truyền xuống. Các bạn dựa vào cấu trúc chương trình có thể tự lập cho mình chương trình để làm. Đây là một phần nhỏ trong chương trình thiết kế bộ PID điều khiển động cơ một chiều 12V của tôi:

                              Code:
                              /*========================================================
                              ; Ten chuong trinh	: giao tiep USART voi PC, nhan duoc thi hien thi lai
                              ; Nguoi thuc hien	: ngohaibac
                              ; Ngay thuc hien	: 
                              ; Phien ban	: 1.0
                              ; Mo ta phan cung	: Dung PIC16F877A - thach anh 20MHz
                              ;		chan RC7/TX noi voi chan R1OUT cua MAX232
                              ;		chan RC6/RX noi voi chan T1IN cua MAX232
                              ;----------------------------------------------------------------
                              ; Ngay hoan thanh	: 
                              ; Ngay kiem tra	: 
                              ; Nguoi kiem tra	: 
                              ;----------------------------------------------------------------
                              ; Chu thich	: Chuong trinh dung giao tiep USART
                              
                              ;========================================================*/
                              #include<pic.h>
                              
                              __CONFIG(HS & PWRTEN & BOREN & LVPDIS & WDTDIS );
                              
                              // ham init - khoi tao 
                              void initUART(void){
                              // Khoi tao cho USART
                              	TRISC = TRISC | 0b11000000;			// Bit 7,6 la RX va TX phai la Input
                              	SPEN = 1 ;		// Enable Serial Port communication.
                              	SYNC =	 0;		// che do khong dong bo Asynchronous
                              	// cho che do truyen
                              	TXEN = 1;		//enable truyen
                              	TX9 = 0 ;		// chon che do 8 truyen  bit du lieu
                              	BRGH = 1; 		// High - speed
                              	SPBRG = 129;	//Baud = 9600;	voi HS, Baud Rate = Fosc/(16(X+1))  
                              	TXIE = 0;		// khong dung ngat Truyen
                              	// Che do nhan du lieu
                              	RCIE  =  1;		// dung ngat nhan
                              	PEIE = 1;		// cho phep ngat ngoai vi
                              	GIE  = 1;			// cho phep ngat toan cuc
                              	RX9 = 0;			// nhan 8 bit
                              	CREN = 1;		// lien tuc nhan du lieu; = 0 k lien tuc nhan du lieu
                              	
                              }
                              
                              // Chuyen doi
                              void Convert(unsigned char *a,unsigned char index, unsigned int number){
                              	unsigned char i;
                              	for(i=0;i< index; i++){
                              		*(a+i)  = number%10;
                              		number = number/10;
                              	};	
                               }
                              
                              // ham truyen du lieu
                              void putch(unsigned char byte) 
                              {
                              	/* output one byte */
                              	while(!TXIF);	/* set when register is empty */
                              	//	continue;
                              	TXREG = byte;
                              }
                              
                              // ==== Ham ghi len tren mot gia tri cua so co 4 chu so
                              void puts(unsigned int number){	// truyen 4 so cua number
                              	unsigned char i;
                              	unsigned char a[] = {0,0,0,0};
                              	Convert(a,4,number);
                              	for(i= 0;i<2;i++) putch(a[i]+48);
                              	putch(0x2C);
                              	for(i= 2;i<4;i++) putch(a[i]+48);
                              	putch(0x20);
                              }
                              
                              // ======= Ham ghi len tren mot vector gom 4 phan tu
                              void putsVector(unsigned char *a,unsigned char n){
                              	unsigned char i;
                              	for(i = 0;i<n;i++) putch(a[i]);
                              }
                              
                              
                              // Ham khoi tao chung
                              void init(void){
                              	initUART();
                              //================  Khoi tao cho Timer0
                              	GIE		= 1;
                              	T0IE = 1;
                              	TMR0 = 6;
                              	
                              }
                              // ham ngat
                              void interrupt MyInt(void){
                              	unsigned char temp, i,j;
                              	static volatile unsigned char counter4, allow;		// temp: bien dem nhan,allow: cho phep nhan du lieu
                              	static volatile unsigned char K[17];
                              	static volatile unsigned char Kp;
                              	static volatile unsigned char Ki;
                              	static volatile unsigned char Kd;
                              	static volatile unsigned char n;
                              	//Kp, Ki, Kd la tham so PID, n la toc do
                              	if(T0IF & T0IE){	
                              		TMR0 = 6;
                              		T0IF = 0 ;// xoa co ngat
                              	};
                              	if(RCIF){						// Neu co ngat nhan du lieu noi tiep
                              		temp = RCREG;
                              		RCIF = 0;					// Xoa co ngat RCIF
                              		switch(temp){
                              			case 'B': 		//  ===  Bat dau cho dong co chay 
                              				putch('B'); allow = 0;
                              				break;
                              			case 'K':			// ===	Tat dong co
                              				putch('K'); allow = 0;
                              				break;
                              			case 'A':			// === Nhap cac gia tri cho Kp,Ki,Kd
                              				putch('A');
                              				allow = 1;	// chuyen sang nhap cho cac tham so cua mang.
                              				break;
                              			};
                              		if (allow){
                              			K[counter4++] = temp;
                              			if(counter4 == 17) {
                              				allow = 0; 
                              				putsVector(K,17);
                              			};
                              		};	
                              	};
                              }
                              
                              // ham chinh 
                              void main(void){
                              	//unsigned char a[] =" anh yeu em nhieu lam, em biet k?";
                              	unsigned char i = 0;
                              	init();
                              	//for(i= 0; i<33; i++) putch(a[i]);
                              	//for(i= 0; i<10; i++) putch(i+48);
                              	while(1);
                              }
                              Chương trình này và 2 chương trình ở trên đều được test và chạy ngon lành.

                              Chúc mọi người 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


                              • #45
                                Tối ưu các chương trình,chương trình USART

                                Giờ mình xin đưa ra các chương trình mà mình tối ưu dần dần và cảm thấy nó dễ hiểu. Mình xin đưa ra cho các bạn xem và cho ý kiến. Mình sẽ tối ưu từng chương trình một.

                                Đầu tiên là chương trình dùng giao tiếp USART, trong chương trình này mình dùng thư viện stdio.h có hàm printf(). Tuy nhiên bạn phải định nghĩa hàm putch(..) thì mới sử dụng được hàm này.

                                Hàm printf( ) sẽ truyền xâu dữ liệu theo định dạng C ra cổng nối tiếp USART.

                                Code:
                                /*========================================================
                                ; Ten chuong trinh	: giao tiep USART voi PC, nhan duoc thi hien thi lai
                                ; Nguoi thuc hien	: ngohaibac
                                ; Ngay thuc hien	: 
                                ; Phien ban	: 1.0
                                ; Mo ta phan cung	: Dung PIC16F877A - thach anh 20MHz
                                ;		chan RC7/TX noi voi chan R1OUT cua MAX232
                                ;		chan RC6/RX noi voi chan T1IN cua MAX232
                                ;----------------------------------------------------------------
                                ; Ngay hoan thanh	: 
                                ; Ngay kiem tra	: 
                                ; Nguoi kiem tra	: 
                                ;----------------------------------------------------------------
                                ; Chu thich	: Chuong trinh dung giao tiep USART
                                
                                ;========================================================*/
                                #include<pic.h>
                                # include "stdio.h"
                                
                                __CONFIG(HS & PWRTEN & BOREN & LVPDIS & WDTDIS );
                                
                                // ham init - khoi tao 
                                void init(void){
                                // Khoi tao cho USART
                                	TRISC = TRISC | 0b11000000;			// Bit 7,6 la RX va TX phai la Input
                                	SPEN = 1 ;		// Enable Serial Port communication.
                                	SYNC =	 0;		// che do khong dong bo Asynchronous
                                	// cho che do truyen
                                	TXEN = 1;		//enable truyen
                                	TX9 = 0 ;		// chon che do 8 truyen  bit du lieu
                                	BRGH = 1; 		// High - speed
                                	SPBRG = 129;	//Baud = 9600;	voi HS, Baud Rate = Fosc/(16(X+1))  
                                	TXIE = 0;		// khong dung ngat Truyen
                                	// Che do nhan du lieu
                                	RCIE  =  1;		// dung ngat nhan
                                	PEIE = 1;		// cho phep ngat ngoai vi
                                	GIE  = 1;			// cho phep ngat toan cuc
                                	RX9 = 0;			// nhan 8 bit
                                	CREN = 1;		// lien tuc nhan du lieu; = 0 k lien tuc nhan du lieu
                                }
                                // ham truyen du lieu
                                void putch(unsigned char byte) 
                                {
                                	/* output one byte */
                                	while(!TXIF);	/* set when register is empty */
                                	//	continue;
                                	TXREG = byte;
                                }
                                // ham ngat
                                void interrupt MyInt(void){
                                	unsigned char temp;
                                	if(RCIF){						// Neu co ngat nhan du lieu noi tiep
                                		temp = RCREG;
                                		RCIF = 0;					// Xoa co ngat RCIF
                                		printf(" da nhan duoc du lieu: %c", temp);
                                	};
                                }
                                
                                // ham chinh 
                                void main(void){
                                	init();
                                	while(1);
                                }
                                Chương trình này rất có ích khi muốn test chương trình giao tiếp qua USART.

                                Chúc các bạn thành công. Ngủ cái đã. Mai còn phải ôn thi .
                                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

                                Về tác giả

                                Collapse

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

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

                                Collapse

                                Đang tải...
                                X