PIC Vietnam

Go Back   PIC Vietnam > Microchip PIC > Các ngôn ngữ lập trình khác (CCS C, HT PIC,...)

Tài trợ cho PIC Vietnam
Trang chủ Đăng Kí Hỏi/Ðáp Thành Viên Lịch Bài Trong Ngày Vi điều khiển

Trả lời
 
Ðiều Chỉnh Xếp Bài
Old 14-08-2006, 06:09 PM   #1
typhn
Đệ tử 1 túi
 
Tham gia ngày: Apr 2006
Bài gửi: 19
:
Hình như Picvietnam ko mặn mà với Htpic lắm.
Em sang bên dientuvietnam hỏi vậy
typhn vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 18-08-2006, 02:27 PM   #2
lep
Đệ tử 1 túi
 
Tham gia ngày: Aug 2006
Bài gửi: 12
:
sao minh chạy thu chuong trình đơn giản cho một led tắt mot giây sáng 1 giay tải về nạp pic 877a chạy thử mà không dược nhân dịp cho minh hỏi co chuong trình nào viết ASM rồi chuyển sang C còn C chuyển qua ASM minh biết rồi tại vì mình mới học pic minh không dùng ASM mà đi thẳng vào viết C cho pic trên diển dàn thì bày ASM nhiều
lep vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 18-08-2006, 07:38 PM   #3
namqn
Trưởng lão PIC bang
 
Tham gia ngày: Feb 2006
Nơi Cư Ngụ: Tp. HCM, Việt Nam
Bài gửi: 3,025
:
Send a message via Yahoo to namqn
Trích:
Nguyên văn bởi lep
sao minh chạy thu chuong trình đơn giản cho một led tắt mot giây sáng 1 giay tải về nạp pic 877a chạy thử mà không dược nhân dịp cho minh hỏi co chuong trình nào viết ASM rồi chuyển sang C còn C chuyển qua ASM minh biết rồi tại vì mình mới học pic minh không dùng ASM mà đi thẳng vào viết C cho pic trên diển dàn thì bày ASM nhiều
Cho đến thời điểm này tôi vẫn chưa thấy có phần mềm nào có khả năng chuyển asm thành C.

Thân,
__________________
Biển học mênh mông, sức người có hạn.

Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau:
http://www.picvietnam.com/forum/showthread.php?t=1263
namqn vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 03-08-2011, 09:32 PM   #4
dovanhung
Nhập môn đệ tử
 
Tham gia ngày: May 2008
Bài gửi: 1
:
Crack HT PICC

huyentien8688@gmail.com
Cac buoc Crack HT PICC for pic 10/12/16

1. Cài đặt MPLAB IDE trong đó có kích chọn Hi-tech C compiler for PIC (hoặc chọn luôn complete).
2. Sau khi cài đặt HT-Pic sẽ vào một thư mục riêng trong Program files. Chạy file Activate or TRIAL PRO mode (Trong trường hợp của tôi là: "C:\Program Files\HI-TECH Software\PICC\9.81\resources\setup.exe"). Nó sẽ hỏi các bác dùng trial hay active luôn. Chọn "active PRO/Standard mode". Tick vào Off-line activation by email. Rồi điền một cái serial number bất kỳ sáu số. VD. 654321. Sau đó click finish
3. Chại cái chương trình "phát mã khóa" .exe rồi chỏ đến file HCPICP-654321-activation-request.txt trong thư mục cài đặt HT-pic. Cái thuốc này sẽ phát một file khóa giống như bác đã mua từ email (he he).
4. Chạy HT-PIC activation một lần nữa, nó sẽ chúc mừng các bác đã dùng bản PRO.
dovanhung vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 04-05-2012, 12:31 PM   #5
tuan_utc
Nhập môn đệ tử
 
Tham gia ngày: Feb 2012
Bài gửi: 2
:
Các bạn ơi ! cho mình hỏi bạn nào có tài liệu hướng dẫn học HT Pic cụ thể không? cho em xin với. Đang làm đề tài tốt nghiệp liên quan đến ngôn ngữ lập trình này.
tuan_utc vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 14-10-2006, 09:50 AM   #6
moutainBK
Nhập môn đệ tử
 
Tham gia ngày: Dec 2005
Bài gửi: 6
:
Các bác giúp em với!!!
EM đã cài MPLAB 7.42 và HT PIC 9.50,các bác bảo HT PIC tự nhúng vào MPLAB khi cài nó phải ko?
Bây giờ em soạn file .C trong MPLAB,em muốn biên dịch nó sang file .HẼ cũng trong môi trường MPLAB(sử dụng HT PIC để biên dịch ) thì phải làm cách nào?
Mong các bác trả lời sớm nha
EM cảm ơn nhiều!!!!!!!!
moutainBK vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 05-01-2007, 03:17 PM   #7
ngohaibac
Đệ tử 9 túi
 
ngohaibac's Avatar
 
Tham gia ngày: Oct 2005
Nơi Cư Ngụ: BKHN
Bài gửi: 231
:
Send a message via Yahoo to ngohaibac
Bạn muốn biên dịch file .c của bạn thì bạn phải gắn nó vào trong một Project nhé.

Đầu tiên bạn tạo một Project rùi Add file đó vào rùi biên dịch, thế là xong. Mình cài bản HT PIC 9.50 nhưng không biên dịch được và báo lỗi ở file PICC.exe nên đành quay lại dùng bản 8.05PL2.

Bạn chỉ cần cài bản 8.05 dùng ngon lành.
http://www.picvietnam.com/forum//showthread.php?t=31

Chúc bạn thành công.
ngohaibac vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 05-01-2007, 03:54 PM   #8
ngohaibac
Đệ tử 9 túi
 
ngohaibac's Avatar
 
Tham gia ngày: Oct 2005
Nơi Cư Ngụ: BKHN
Bài gửi: 231
:
Send a message via Yahoo to ngohaibac
Quét led7 thanh.

Sau đây mình copy một số bài bên dientuvietnam.net sang đây và trả lời từng câu hỏi mà các bạn hỏi nhé.

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.

thay đổi nội dung bởi: ngohaibac, 05-01-2007 lúc 04:00 PM.
ngohaibac vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 05-01-2007, 03:56 PM   #9
ngohaibac
Đệ tử 9 túi
 
ngohaibac's Avatar
 
Tham gia ngày: Oct 2005
Nơi Cư Ngụ: BKHN
Bài gửi: 231
:
Send a message via Yahoo to ngohaibac
Chuyển đổi 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:




Hình 3: Chuyển đổi ADC, hiển thị LED7 segment.
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
ngohaibac vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 05-01-2007, 03:58 PM   #10
ngohaibac
Đệ tử 9 túi
 
ngohaibac's Avatar
 
Tham gia ngày: Oct 2005
Nơi Cư Ngụ: BKHN
Bài gửi: 231
:
Send a message via Yahoo to ngohaibac
Điều chế PWM.

http://dientuvietnam.net/forums/show...?t=1406&page=4
Bài viết số 39.

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 .
ngohaibac vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 05-01-2007, 04:04 PM   #11
ngohaibac
Đệ tử 9 túi
 
ngohaibac's Avatar
 
Tham gia ngày: Oct 2005
Nơi Cư Ngụ: BKHN
Bài gửi: 231
:
Send a message via Yahoo to ngohaibac
Tối ưu các chương trình,chương trình giao tiếp USART

http://dientuvietnam.net/forums/show...?t=1406&page=5
Bài số 45.

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 .
ngohaibac vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 05-01-2007, 04:09 PM   #12
ngohaibac
Đệ tử 9 túi
 
ngohaibac's Avatar
 
Tham gia ngày: Oct 2005
Nơi Cư Ngụ: BKHN
Bài gửi: 231
:
Send a message via Yahoo to ngohaibac
Lấy đặc tính h(t) của động cơ.

http://dientuvietnam.net/forums/show...?t=1406&page=5
bài 46.

Chào các bạn. Tôi đã làm xong bài tập lớn môn lý thuyết điều khiển tự động là thiết kế bộ điều khiển PID trên nền PIC.Bây giờ tôi xin đưa các đoạn code của bài tập lớn của tôi.

Đầu tiên là công việc là lấy đặc tính đáp ứng h(t) của động cơ để từ đó tính toán các tham số Kp, Ki, Kd. Đây là bước tính toán thô các giá trị của bộ PID sau đó mình mới tinh chỉnh lại sau ở một chương trình khác.

Vi điều khiển ứng dụng: PIC6F877A

Ngôn ngữ lập trình: HTPIC

Trong bài này tôi mục đích làm như sau: khi ấn "P" trên giao diện trên PC hay nói cách khác truyền kí tự P xuống chip thì nó nhận lệnh và cho động cơ hoạt động. Tôi điều chế một xung 15KHZ, ở đây cho độ rộng 100% luôn. Và từ đó liên tục đọc 500 giá trị và truyền lên PC.

Thời gian trích mẫu của hệ thống là 10ms. Tôi truyền số xung đo được lên PC, từ số liệu này sẽ tính toán ra tốc độ thực và vẽ được hàm h(t) của đối tượng. Tôi dùng chương trình Terminal (do lười nên không viết chương trình trên PC riêng) và lấy dữ liệu và cho vào Matlab để nội suy ra hàm quá độ h(t) . Tôi định viết một chương trình bằng Matlab nhận giao tiếp RS232 tính toán và đưa ra đồ thị luôn. Nhưng phải chờ tí đã, dạo này ôn thi nên hơi lười làm.

Chương trình Terminal và giao tiếp RS232 các bạn có thể xem tại
http://www.picvietnam.com/forum/show...p?t=274&page=2

Code chương trình trên Matlab: dùng nội suy Cubic
Code:
hold off;
x_rough= 0:0.01:5;
%x_fine= 0:0.05:0.8 ;% chon buoc noi suy tu xmin:0.1:xmax( voi xmin la gia tri nho nhat cua x_rough, xmax tuong tu;
x_fine = 0:0.001: 5;
data = [ ]; // Các giá trị số xung đo được 500 giá trị
data = data * 1000 /(10 * 100 *12);     
% tính toán ra tốc độ thực và chia cho 12V để suy ra đáp ứng khi U = 1V vì coi động cơ DC là tuyến tính
% 100 là số lỗ /1 vòng của Encoder
inter_cubic= interp1(x_rough,data,x_fine,'cubic');
% noi suy theo phuong phap cubic
plot(x_fine,inter_cubic,'k','LineWidth',2);
grid on;
Code cho PIC6F877A

Code:
#include<pic.h>
# include "stdio.h"

__CONFIG(HS & PWRTEN & BOREN & LVPDIS & WDTDIS );

const unsigned char Font[]={ 0b00000011, 0b10011111, 0b00100101, 0b00001101, 0b10011001,\
							0b01001001, 0b01000001, 0b00011111, 0b00000001, 0b00001001};

# define Ts 	10						// Thoi gian trich mau Ts (ms)
# define Encoder_resolution 100		// So lo cua Encoder/1 vong
# define Total_Point			500		// So diem can trich mau

// ham truyen du lieu
void putch(unsigned char byte) 
{
	/* output one byte */
	while(!TXIF);	/* set when register is empty */
	//	continue;
	TXREG = byte;
}

//=====  Ham khoi tao
void interrupt MyInt(void){
	static volatile unsigned int  i, Pulse_Encoder;
	// i la so diem trich mau
	// Pulse_Encoder = so xung do duoc tu Encoder
	static volatile unsigned char  allow,counter_Sampling;
	// allow la bien cho phep bat dau trich mau
	// counter_Sampling: bien dem de trich mau
	unsigned char RC_USART;			// gia tri doc duoc tu thanh ghi nhan du lieu USART
	if(T0IF & T0IE){	
		TMR0 = 6;
		T0IF = 0 ;// xoa co ngat
		if((++counter_Sampling  == Ts) && allow){				// Ts = 10 ms
			Pulse_Encoder  = (TMR1H << 8) | TMR1L;
			// Toc do dong co = Pulse_Encoder * 1000 / (Encoder_resolution * Ts)  (vong/s)
			printf("%6d",Pulse_Encoder);				// Truyen gia tri xung do tren Ts
			counter_Sampling  = 0;
			if (i++ == Total_Point){
				i  = 0;			// Neu trich duoc 500 diem thi dung dong co lai	
				CCPR1L = 0;
				allow = 0;
			};
		};	
	};
	if(RCIF){						// Neu co ngat nhan du lieu noi tiep
		RC_USART =  RCREG;
		RCIF = 0;					// Xoa co ngat RCIF
		switch(RC_USART){
			case 'P': 		//  ===  Bat dau cho dong co chay cho do rong xung = 100%
			TMR1ON = 0 ; // ngung Timer1
			TMR1H = TMR1L = 0;
			TMR1ON = 1 ;  // bat lai Timer1
			CCPR1L =  PR2 + 1;
			CCP1Y  =	CCP1X 	= 0;
			allow = 1;
			break;
		};		
	};
}

//------------------------------------init
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

//===== 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 = 0xFF;

//================  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ương trình đã test và cho đặc tính h(t) thí dụ với động cơ 12V của tôi như sau:

Hình bị mất, mình tìm lại upload sau.


Chúc các bạn thành công.
ngohaibac vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 14-03-2007, 01:29 AM   #13
ngohaibac
Đệ tử 9 túi
 
ngohaibac's Avatar
 
Tham gia ngày: Oct 2005
Nơi Cư Ngụ: BKHN
Bài gửi: 231
:
Send a message via Yahoo to ngohaibac
Chào các bạn.

Để có thể viết được chương trình bằng HTPIC cho hợp lý và tuân theo đúng trình dịch HTPIC, các bạn nên download manual của nó
PICC Manual

Tài liệu này rất hay (của www.htsoft.com).

Chúc các bạn thành công.
ngohaibac vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 06-04-2007, 02:36 PM   #14
ngohaibac
Đệ tử 9 túi
 
ngohaibac's Avatar
 
Tham gia ngày: Oct 2005
Nơi Cư Ngụ: BKHN
Bài gửi: 231
:
Send a message via Yahoo to ngohaibac
Chào các bạn.

Mình thấy quyển manual complier của bọn HTsoft cũng khá hay và đầy đủ chú ý. Do đó, thấy cái gì hay hay mình viết rùi các bạn góp ý kiến nhá. Có lẽ mình cũng nên lập thư viện cho HTPIC chứ nhỉ?? Thấy anh em dùng CCS hoạt động kinh quá .

Đầu tiên là cách khai báo một biến đặt tại một địa chỉ nhất định trong RAM.

Ví dụ, muốn Portvar là biến đặt tại địa chỉ 0x06 thì trong ASM ta dùng lệnh sau:
Code:
_Portvar EQU 06h
Khi đó mỗi khi thao tác với biến Portvar tức là thao tác với ô nhớ 06h.

Trong HTPIC các bạn khai báo như sau:
Code:
volatile unsigned char Portvar @ 0x06;
Chú ý từ khóa @.

Chúc các bạn thành công.
ngohaibac vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 06-04-2007, 02:36 PM   #15
ngohaibac
Đệ tử 9 túi
 
ngohaibac's Avatar
 
Tham gia ngày: Oct 2005
Nơi Cư Ngụ: BKHN
Bài gửi: 231
:
Send a message via Yahoo to ngohaibac
Thư viện LCD 16x2 8bit mode.

Mình xin upload thư viện viết cho LCD, ở đây mình dùng 8 bit mode cho LCD 2 line x 16 colum.

Code:
// LCD.h
#ifndef	 LCD_H
#define	LCD_H

# include <pic.h>

//============== Using LCD - 2 line, 16 colum
#define	LCD_MODE_2x16		(TRUE)					// HDM16216H-2, HDM16216H-4, HDM16216H-5, HDM16216H-B, HDM16216H-D, HDM16216L-2, HDM16216L-5, HDM16216L-7, HDM16216L-D, HDM16216L-B, HDM16216H-I

#define	LCD_CURSOR_BLINK					(FALSE)					// Blink/Noblink cursor mode
#define	LCD_CURSOR_ON					(TRUE)						// Cursor visible
#define	LCD_CURSOR_INCREMENT			(TRUE)						// Set left-to-right cursor movement
#define	LCD_CURSOR_SHIFT					(FALSE)					// Shift display on entry

#define	LCD_DISPLAY_ON					(TRUE)					// Turn display on/off

#define	LCD_ALLOW_USER_CHARS			(TRUE)					// Controls whether display uses ASCII for control chars or uses user-defined chars in lcd_putc()
#define	LCD_ENABLE_GETC					(TRUE)					// Save code space by setting to FALSE
#define	LCD_ENABLE_GOTOXY				(TRUE)					//   any functions which you will not
#define	LCD_ENABLE_PRINTF				(TRUE)					//   need in your application.
#define	LCD_ENABLE_UNSCROLL			(TRUE)
#define	LCD_ENABLE_SCROLL				(TRUE)
#define	LCD_ENABLE_CLEAR					(TRUE)

#define LCD_MAXROWS						((unsigned char)(2))
#define	LCD_MAXCOLS						((unsigned char)(16))
# define LCD_MULTI_LINE					(TRUE)

#define LCD_8_BIT_MODE						(TRUE)

//======================= Define LCD_PORT
#define	LCD_DATA_PORT		PORTD					// Port on which LCD data lines are connected
#define	LCD_TRIS_PORT		TRISD					// Need to specify the corresponding TRIS

# define LCD_RS			RA1
# define LCD_RW			RA2
# define LCD_E				RA3

# define LCD_TRIS_E		TRISA1
# define LCD_TRIS_RW		TRISA3
# define	LCD_TRIS_RS		TRISA2

// =======================  Define command code
#define	LCD_COMMAND_CLEAR				((unsigned char)(0x01))	//1.53 ms	// Clear screen, home cursor, unshift display
#define	LCD_COMMAND_HOME				((unsigned char)(0x02))	//1.53 ms	// Home cursor, unshift display
#define	LCD_COMMAND_BACKSPACE		((unsigned char)(0x10))				// Move cursor left one (destructive based on LCD_DESTRUCTIVE_BS)
#define	LCD_COMMAND_FWDSPACE		((unsigned char)(0x14))				// Move cursor right one
#define	LCD_COMMAND_PANLEFT			((unsigned char)(0x18))				// Move screen left one
#define	LCD_COMMAND_PANRIGHT			((unsigned char)(0x1C))			// Move screen right one


// ==================== Declare some functions
void delay_us (unsigned char us);
void delay_ms(unsigned char  ms);
unsigned char LCD_getByte (void);
void LCD_PrByte (unsigned char  c);
void LCD_Command(unsigned char c);
void LCD_PrChar (unsigned char  c);
void LCD_gotoXY(unsigned char row, unsigned char col);
unsigned char  LCD_getChar (void);						// Read character at cursor
void LCD_Init(void);
void LCD_PrString (const char* message); 

#endif
Các bạn sẽ thấy là khi muốn dùng LCD thì đầu tiên các bạn khai báo thông số cho LCD như các chân RS, RW, E, LCD_PORT ở Define LCD_PORT. Mặc định mình khai báo là: LCD_PORT là PortD, RS là RA1, RW là RA2, E là RA3.

Các bước thực hiện:

- Khởi tạo LCD dùng lệnh: LCD_Init();
- Thao tác ghi đọc bình thường, chú ý nhất là các hàm: LCD_gotoXY, LCD_PrString, LCD_PrChar, LCD_Command.

Tiếp theo là file LCD.c là file thực hiện:

Code:
//LCD.c
# include "lcd.h"

// ==== Some constants for LCD 16x2
const unsigned char  const LCD_ROW_ADDRESS[] =					// Row/Column information for LCD_gotoxy()
	{
	0x00,		// Line 1
	0x40		// Line 2
	};

const unsigned char  const LCD_INIT_STRING [] =					// LCD Init String on powerup
	{
	0b00000001,							//	Clear display
	0b00000010,							//	Home cursor
};

//==========================================================================================
void delay_us (unsigned char us){
	while(us--){
		asm("nop");
		asm("nop");
	};
}

//==========================================================================================
void delay_ms(unsigned char  ms){
	unsigned char	i, j;
	while(ms--){
		for (i = 0; i < 20; i++)
			for (j = 0; j < 100; j++)
				asm("nop");
		};
}
// ============================================================================================
unsigned char LCD_getByte (void){
	unsigned char retval; 									// Return value
	LCD_TRIS_PORT = 0xFF;								// Set port to all input
	LCD_RW = 1;											// Tell LCD we want to read
	delay_us(2);
	LCD_E = 1;												// Do the read
	delay_us(2);
	retval = LCD_DATA_PORT;
	LCD_E = 0;
	LCD_TRIS_PORT = 0x00;								// Set port back to outputs
	return (retval);
}
//====================================================================================================
void LCD_PrByte (unsigned char  c){						// Write byte to port in current RS mode
	unsigned char RS_Status;
	RS_Status = LCD_RS;									// Get old pin state
	LCD_RS = 0;											// Force into command mode to read state
	while (LCD_getByte () & 0x80);							// Wait for read state
	if (RS_Status)
		LCD_RS = 1;										// Restore RS to old state
	delay_us (1);
	LCD_RW = 0;											// Set to write mode
	delay_us (1);
	LCD_DATA_PORT = c;									// Send the character out
	LCD_E = 1;
	delay_us(1);
	LCD_E = 0;	
}
//================================================================================================
/*Ham yeu cau goi lenh dieu khien LCD*/
void LCD_Command(unsigned char c){						// Send command to LCD port
	LCD_RS = 0;
	LCD_PrByte(c);	
}
//================================================================================================
/*Ham yeu cau goi du lieu hien thi len LCD*/
void LCD_PrChar (unsigned char  c){						// Write character to LCD
	LCD_RS = 1 ;
	LCD_PrByte(c);
}
//=================================================================================================
void LCD_gotoXY(unsigned char row, unsigned char col){
	if (row > LCD_MAXROWS)						// Range limit
		row = LCD_MAXROWS;
	if (col > LCD_MAXCOLS)
		col = LCD_MAXCOLS;
	
	row = LCD_ROW_ADDRESS[row-1];					// Get address of first byte on desired row
	row += col - 1;
	LCD_Command (0x80 | row);							// Write new cursor address
}
//  ===================================================================================== 
unsigned char  LCD_getChar (void)							// Read character at cursor
	{
	unsigned char 	retval;										// Return value
	LCD_RS = 1;
	retval = LCD_getByte ();
	LCD_RS = 0;
	return (retval);
	}

//=======================================================================================
void LCD_Init(void){
	unsigned char i;	

	 LCD_TRIS_PORT 	=	0x00;
	 LCD_TRIS_E 	= 	0;
	 LCD_TRIS_RW 	=	0;
	 LCD_TRIS_RS 	=	0;

	LCD_E = 0 ;
	LCD_RS = 0;
	LCD_RW = 0; 
	 
	 //delay_ms(100); 							  //   Tao tre 100ms cho LCD khoi dong
	
	LCD_PrByte (0b00111000); 		//Function set  ; DL = 1(8 bits) , N = 1 (2 lines), F = 0 (5x8 dots)
	LCD_PrByte (0b00001100);		// Display on/off control 
	LCD_PrByte (0b00000110);		// Entry mode set

	LCD_PrByte(LCD_COMMAND_CLEAR);
	LCD_PrByte(LCD_COMMAND_HOME);
}

// ===================================================================================================  

void LCD_PrString (const char* message){					// Write message to LCD (C string type)

	while (*message)						//	Look for end of string
		LCD_PrChar (*message++);					//	Show and bump
}
Các bạn thêm 2 file này vào trong Project của mình và nhớ include file LCD.h vào chỗ đầu file chứa hàm Main nhé.

Các bạn có thể mô phỏng bằng Proteus chạy rất ok. Lúc nào gửi tiếp mấy cái đã test.

Chúc các bạn thành công.
ngohaibac vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Trả lời


Quyền Sử Dụng Ở Diễn Ðàn
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is Mở
Smilies đang Mở
[IMG] đang Mở
HTML đang Tắt

Chuyển đến

Similar Threads
Ðề tài Người gửi Chuyên mục Trả lời Bài mới
Cách giao tiếp DS1877 và PIC6F877A nbqvdp Cơ bản về vi điều khiển và PIC 7 05-08-2010 06:46 PM
Hỏi về chương trình HTPIC của ngohaibac riquelme Các ngôn ngữ lập trình khác (CCS C, HT PIC,...) 26 20-01-2007 09:42 PM
Giúp đỡ về HTPIC riquelme Cơ bản về vi điều khiển và PIC 0 11-01-2007 11:56 PM
Giao tiếp Pic6f877A qua cổng máy in???? spirit Cơ bản về vi điều khiển và PIC 8 11-09-2006 01:04 PM


Múi giờ GMT. Hiện tại là 02:45 AM.


Được sáng lập bởi Đoàn Hiệp
Powered by vBulletin®
Page copy protected against web site content infringement by Copyscape
Copyright © PIC Vietnam