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 12-03-2006, 04:18 PM   #1
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
HTPIC - các chương trình cho PIC6F877A

Tôi đã viết các bài viết ở Điện tử Việt Nam tại luồng này:
http://dientuvietnam.net/forums/show...4688#post14688

Ngôn ngữ là: HTPIC

Có lẽ bài toán nháy led là bài toán đơn giản và tạo hứng thú cho các bạn học vi điều khiển. Tôi xin mạn phép up chương trình nháy led đơn giản và xin các bạn cho ý kiến là liệu có thể tối ưu chương trình này đến mức nào nữa?


Miêu tả phần cứng: nối các chân của PORTD với các 8led. Các chân còn lại của led nối với một con trở hạn dòng 330Ohm, sau đó nối với GND.


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



Hình 1: Nháy 8led rất đẹp .
Phần mềm: dùng HTPIC.

Hiện tuợng: các bạn chạy thử xem thế nào

Giải pháp: có 2 giải pháp là dùng ngắt hoặc dùng delay.

Chương trình đầu là dùng delay:

Sau đây là chương trình:

Code:
#include<pic.h>
__CONFIG(HS & PWRTEN & BOREN & LVPDIS & WDTDIS );
//================================================================
//==  ham Delay doi so la so miligiay can gay tre
void delayMS(unsigned int time){
	while(time--){
		TMR0 = 6;
		T0IF = 0; // xoa co ngat 
		while(!T0IF);
	};
}

// == Ham khoi tao cho chip PIC16F877A
void init(void){
	// Khoi tao I/O cho cac port
	ADCON1 = 0x07;  // PortA dung la I/O Port
	TRISA = 0xFF; // Port A as input
	TRISB = 0xFF;
	TRISC = 0xFF;
	TRISD = 0x00;// PortD as output
	
	// Khoi tao cho cac thanh ghi	
	OPTION  = 0x00; // dung prescaler cho timer0 voi ti le la 1:2
}

// Chuong trinh chinh
void main(void){
	unsigned char i;
	 init();
	while(1){
		for(i = 0;i<8;i++){
			 PORTD = (1<<i) + (1<<(7-i));
			delayMS(5000);
		};
	};	
}
Câu lênh PORTD = (1<<i) + (1<<(7-i)); là dùng toán tử dịch bít.

File gửi kèm có 2 file: PJ1.c và PJ2.c . PJ1.C là chương trình dùng delay, PJ2 là dùng ngắt.

Xin mọi người cho ý kiến.

thay đổi nội dung bởi: ngohaibac, 05-01-2007 lúc 03:22 PM.
ngohaibac vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 12-03-2006, 04:18 PM   #2
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
Đây là chương trình dùng ngắt timer0.

Code:
#include<pic.h>

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

//================================================================
// Hàm ng?t Timer0
void interrupt inter0(void){
	static unsigned char i;
	static unsigned int counter; // bien dem su kien ngat timer0
	if(T0IF){ // neu co ngat Timer0 xay ra
		++	counter;
		if(counter == 500){
			PORTD = (1<<i) + (1<<(7-i));
			++i;
			if(i==8) i=0;
			counter = 0;
		};
		TMR0 = 6;
		T0IF = 0 ; // xoa co ngat, cong viec khong the thieu sau ham ngat
		};
}

// == Ham khoi tao cho chip PIC16F877A
void init(void){
	// Khoi tao I/O cho cac port
	TRISD = 0x00;// PortD as output
	
	// Khoi tao cho cac thanh ghi	
	OPTION  = 0x00; // dung prescaler cho timer0 voi ti le la 1:2

	// Khoi tao cho ngat Timer0
	GIE = 1; // cho phep ngat toan cuc
	T0IE = 1; // cho phep ngat timer0
	T0IF = 0; // xoa co ngat
	TMR0 = 6; // khoi tao
}

// Chuong trinh chinh
void main(void){
	 init();
	while(1); // de con tro PC khong nhay lung tung,con lam gi thi lam :D
}
Thuật giải của chương trình dùng ngắt đó là: dùng một biến tĩnh kiểu static để đếm số lần xuất hiện ngắt timer0.

Trong chương trình này mình sau 500 ngắt timer0 thì mới quét led1 lần.

Ngoài ra cũng dùng thêm biến static i để biết được đang quét led nào. Do đó dùng ngắt sẽ tiện hơn nhiều. Và dùng đếm sự kiện ngắt thì ta có thể không cần dùng Prescaler với tỉ lệ quá cao, tránh được sai số nhiều.

Không biết mọi người có ý kiến thế nào?
ngohaibac vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 12-03-2006, 04:21 PM   #3
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
Giải mã LED7 thanh

Tiếp theo tôi xin đưa cho mọi người xem một chương trình của tui không biết liệu nó đã tối ưu chưa? Đã hiệu quả chưa?

Mô tả phần cứng: có 4 led 7 thanh. Các chân của PORTD 7->1 nối với các chân a->g của led7. Các chân RA5 đến RA3 nối vào cực bazơ của con uA1015 lần lượt nối với các cực Anot của 4 led.


Đây là sch: vì to quá nên cắt thành 2 nhìn cho rõ:




Hình 2: Quét led 7 thanh.
Yêu cầu của chương trình là: hiển thị ra 4 led các giá trị tăng dần từ 0000 đến 9999 sau đó lại quay lại.

Chương trình này lấy phần giải mã của anh 4MD. chương trình của anh ấy dùng cả delay. Nhưng tôi nghĩ là khi dùng ngắt rùi thì dùng delay làm gì cho phí. Do đó việc dùng ngắt làm cho ta đỡ tốn thời gian làm những việc linh tinh.

Các bạn cho ý kiến về giải thuật này.

Code:
#include<pic.h>
const unsigned char Font[]={ 0b00000011, 0b10011111, 0b00100101, 0b00001101, 0b10011001,\
							0b01001001, 0b01000001, 0b00011111, 0b00000001, 0b00001001};

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

//------------------------------------Interrupt
void interrupt MyInt(void){
	static int counter1,counter2;
	// counter1 dem so lan timer0 tran
	// counter2 dem so lan led duoc quet
	static unsigned int number;
	static unsigned int a[4]={0,0,0,0};
	static unsigned char j;
		if(T0IF){	
			++counter1;
			if( counter1 == 500){
				counter1 = 0;
				PORTD = 0xFF;
				PORTA	= 0xFF - (1<<(5-j));// bat mot led
				PORTD	= Font[a[j]];
				if(++j==4) {
					j=0;
					++counter2;
				};
			};
			if(counter2 == 500){
				 ++number;
				if(number>9999) number= 0;
				counter2 = 0;
				a[3] = number/1000;
				a[2] = (number/100)%10;
				a[1] = (number/10)%10;
				a[0] = number%10;
			};
		TMR0 = 6;
		T0IF = 0 ;// xoa co ngat
		};
	}

//------------------------------------init
void init(void)
	{
		//-------------------------init for PORTs
		OPTION = 0b00000000;
		ADCON1 = 0b00000111;
		TRISA	= 0b00000000;
		TRISB	= 0b11111111;
		TRISC	= 0b11111111;
		TRISD	= 0b00000000;
		TRISE	= 0b11111111;
		//-------------------------init for interrupt
		GIE		= 1;
		T0IE = 1;
		TMR0 = 6;
	}

//------------------------------------MAIN
void main(){
	init();
	while(1);  // Trong này làm gì thì làm
}
Anh 4MD cho ý kiến với em luôn.

Chương trình của mình có cái hay là khi bạn vừa dùng ngắt Timer0 để quét led bạn vừa có thể tận dụng nó để làm việc khác nữa như đếm số lần quét hoặc là delay để làm cái gì đó.

Cái này giống kiểu tiết kiệm chân vi điều khiển vậy . Dưới đây có file gửi kèm là 3 file .c của 3 bài trên.

Chúc các bạn thành công.
File Kèm Theo
File Type: zip PJ1.zip (1.4 KB, 1071 lần tải)

thay đổi nội dung bởi: ngohaibac, 05-01-2007 lúc 03:24 PM.
ngohaibac vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 25-03-2006, 12:35 PM   #4
chuabietgi
Đệ tử 1 túi
 
chuabietgi's Avatar
 
Tham gia ngày: Nov 2005
Bài gửi: 17
:
Cho tớ hỏi tí!
Bác dùng phần mềm gì để vẽ mạch vậy?Có free ở đâu không ?Cảm ơn!
chuabietgi vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 26-04-2006, 04:18 AM   #5
linhnc308
Đệ tử 5 túi
 
Tham gia ngày: Oct 2005
Bài gửi: 117
:
Trích:
a[3] = number/1000;
a[2] = (number/100)%10;
a[1] = (number/10)%10;
a[0] = number%10;
Hàm tách số chục trăm đơn vị này Bắc nên viêt thành một hàm riêng : tach_so(int x)
Bởi hàm này hay phải gọi đến trong CT quét LED 7 hay nhièu CT khác.
__________________
CallerID, Ethernet-RS232, PICWEB, Cảnh báo BTS
Giải pháp toàn diện giám sát - điều khiển từ xa qua GSM/Internet
0988006696

http://linhnc308.blogspot.com
linhnc308@gmail.com
linhnc308 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 26-04-2006, 08:31 AM   #6
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
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.

thay đổi nội dung bởi: ngohaibac, 27-04-2006 lúc 08:32 AM.
ngohaibac vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 26-04-2006, 11:31 AM   #7
linhnc308
Đệ tử 5 túi
 
Tham gia ngày: Oct 2005
Bài gửi: 117
:
hay. Mình rất khoái lập trình C. Hồi trước làm AT toàn xài ASM, từ khi biết keil, toàn xài cái này thôi, chỉ khi nào có yêu cầu của khách mình mới viết bằng ASM. Viết bằng C cho nó nhanh. Nhưng minh vẫn thấy viết bằng ASM là nghệ thuật hơn cả. Tuy no hơi dài nhưng phải nói là hay, khi ta giải quyết đc những thuật toán đk...phải nói là hay...
Thực tế thì nên dùng C
__________________
CallerID, Ethernet-RS232, PICWEB, Cảnh báo BTS
Giải pháp toàn diện giám sát - điều khiển từ xa qua GSM/Internet
0988006696

http://linhnc308.blogspot.com
linhnc308@gmail.com
linhnc308 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 28-04-2006, 08:19 AM   #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
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.

thay đổi nội dung bởi: ngohaibac, 28-04-2006 lúc 08:23 AM.
ngohaibac vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 02-05-2006, 01:42 AM   #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
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.
ngohaibac vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 02-05-2006, 01:47 AM   #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 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.
ngohaibac vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 02-05-2006, 01:52 AM   #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
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.
ngohaibac vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 21-07-2006, 01:03 PM   #12
totite
Nhập môn đệ tử
 
Tham gia ngày: Feb 2006
Bài gửi: 5
:
Mình có viết một chương trình cho PIC6F88 bằng HT-PIC 805PL2, không hiểu sao trình biên dịch lại bắt đầu chương trình tại địa chỉ 07C0h chứ không phải từ 0000h? Mong các bác chỉ giúp em nhé.

1: #include <pic.h>
2: __CONFIG(INTIO & PWRTEN & BORDIS & WDTDIS & MCLRDIS & LVPDIS );
3:
4:
5:
6: #define R1 0x20;
7: #define R2 0x21;
8: void delayms(int n);
9: void init (void);
10:
11: void delayms(int n)
12: {
13: while(n--)
7C0 2FC6 GOTO 0x7c6
7C6 1283 BCF 0x3, 0x5
7C7 1303 BCF 0x3, 0x6
7C8 0820 MOVF 0x20, W
7C9 1903 BTFSC 0x3, 0x2
7CA 03A1 DECF 0x21, F
7CB 03A0 DECF 0x20, F
__________________
Y!M: trongkhaivt2000@gmail.com


Tìm tiên giữa suối mơ
Rêu xanh đá trắng bụi lu mờ
Âm thầm dạo bước cõi thiên thai
Tiên cảnh mênh mông trở lại rồi
Bên suối buồn man mác
Trăng thanh nước biết ánh trăng ngời
Tiên nữ hỡi nàng sao không thấy.
totite vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 18-03-2010, 09:34 AM   #13
congtam1189
Nhập môn đệ tử
 
Tham gia ngày: Mar 2010
Bài gửi: 2
:
sao ko cho dơn ve
congtam1189 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 14-08-2006, 12:44 AM   #14
typhn
Đệ tử 1 túi
 
Tham gia ngày: Apr 2006
Bài gửi: 19
:
Chào các bác.Em mới học về Pic.Mong các bác chỉ giáo
Em dùng Htpic.
Em viết 1 chương trình đơn giản sử dụng timer0.
Nhưng chả hiểu tại sao thời gian delay ko chính xác(em mô phỏng bằng proteus).
Em delay 1 giây mà mô phỏng chạy những 15 giây(sai số lớn quá)
Mà ko hiểu tại sao lệnh while(1) lại ko lặp lại.Khi đèn chạy được 1 chu kỳ thì nó tắt luôn chứ ko lặp lại.
các bác xem giúp em với
Code:
//========================================================
//Bai toan phanh xe.Phanh duoc noi vao RB0
//khi phanh thi RB0 o muc thap
//binh thuong RB0 o muc cao
//co 8 led o RD8 den RD0 se sang theo quy luat(khi phanh)
//10000000,01000000...00000001,11111111,00000000
//sau do lap lai neu chua nha phanh
//thoi gian delay la 1 giay
//thach anh 20 Mhz

//========================================================
#include<pic.h>
#define out  PORTD
__CONFIG(HS & PWRTEN & BOREN & LVPDIS &WDTDIS );
void DL(unsigned int giay);
//--------------------------------------------------------------------------------------------------
const unsigned char a[]={0b10000000,0b01000000,0b00100000,0b00010000,0b00001000,0b00000100,0b00000010,0b00000001,0b11111111,0b00000000};
//========================================================
void main() 
{
    unsigned char i;	
            TRISB	= 0b11111111;    //Dinh nghia cong B la INPUT		
	RBPU      =0;              //co dien tro trong keo len nguon          
            TRISD           = 0b00000000;		
i=0;
while(1)
  {   
     if(RB0==0)                    //nhan phanh
         {
                out=a[i];
                i=i+1;
                DL(25000);          //delay 1giay
                if(i==11) i=0;
         }
    else
         {
             out=0;
             i=0;
         }
  }
}             
    	
//------------------------------------------------------------------------
void DL(unsigned int giay)    
{
 while(giay--)  
     {  
        //delay 40 microgiay
        PSA=1;      //bo chia dung cho wdt
        T0CS=0;     //dung dem thoi gian
        TMR0=56;  
        while(!TMR0IF);	
        TMR0IF=0;    
     }
}
//=============================THE END===========================
typhn vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 06-01-2007, 09:44 AM   #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
Trích:
Nguyên văn bởi typhn View Post
Chào các bác.Em mới học về Pic.Mong các bác chỉ giáo
Em dùng Htpic.
Em viết 1 chương trình đơn giản sử dụng timer0.
Nhưng chả hiểu tại sao thời gian delay ko chính xác(em mô phỏng bằng proteus).
Em delay 1 giây mà mô phỏng chạy những 15 giây(sai số lớn quá)
Mà ko hiểu tại sao lệnh while(1) lại ko lặp lại.Khi đèn chạy được 1 chu kỳ thì nó tắt luôn chứ ko lặp lại.
các bác xem giúp em với
Code:
//========================================================
//Bai toan phanh xe.Phanh duoc noi vao RB0
//khi phanh thi RB0 o muc thap
//binh thuong RB0 o muc cao
//co 8 led o RD8 den RD0 se sang theo quy luat(khi phanh)
//10000000,01000000...00000001,11111111,00000000
//sau do lap lai neu chua nha phanh
//thoi gian delay la 1 giay
//thach anh 20 Mhz

//========================================================
#include<pic.h>
#define out  PORTD
__CONFIG(HS & PWRTEN & BOREN & LVPDIS &WDTDIS );
void DL(unsigned int giay);
//--------------------------------------------------------------------------------------------------
const unsigned char a[]={0b10000000,0b01000000,0b00100000,0b00010000,0b00001000,0b00000100,0b00000010,0b00000001,0b11111111,0b00000000};
//========================================================
void main() 
{
    unsigned char i;	
            TRISB	= 0b11111111;    //Dinh nghia cong B la INPUT		
	RBPU      =0;              //co dien tro trong keo len nguon          
            TRISD           = 0b00000000;		
i=0;
while(1)
  {   
     if(RB0==0)                    //nhan phanh
         {
                out=a[i];
                i=i+1;
                DL(25000);          //delay 1giay
                if(i==11) i=0;
         }
    else
         {
             out=0;
             i=0;
         }
  }
}             
    	
//------------------------------------------------------------------------
void DL(unsigned int giay)    
{
 while(giay--)  
     {  
        //delay 40 microgiay
        PSA=1;      //bo chia dung cho wdt
        T0CS=0;     //dung dem thoi gian
        TMR0=56;  
        while(!TMR0IF);	
        TMR0IF=0;    
     }
}
//=============================THE END===========================
Bạn xem lại code xem. Trong HTPIC định nghĩa thanh ghi TMR0IF là T0IF chứ nhỉ? Nó không định nghĩa TMR0IF đâu. Bạn xem lại đi rùi sửa nếu sai thì xin ý kiến tiếp .

Tiếp, mô phỏng bằng Poteus, quét led hiển thị không chính xác bạn ạ. Nên thử bằng Board thật nhé, xem có vấn đề gì không.

Trong hàm delay của bạn, là kiểu
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à 05:01 PM.


Đượ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