Ccs c for pic16F877a mục lục I. Tổng quan về ccs vì sao ta sử dung ccs ?



tải về 1.15 Mb.
trang5/15
Chuyển đổi dữ liệu23.08.2016
Kích1.15 Mb.
#26977
1   2   3   4   5   6   7   8   9   ...   15

5.8. Ngắt ngoài và đèn 7 đoạn

Một phương án khác:

#include <16F877A.h>
#fuses NOWDT, XT
#fuses NOLVP // important
#use delay(clock=4000000)

// 0 1 2 3 4 5 6 7 8 9


byte const DIGITS[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f };
int8 i = 0;
///////////////////////////////////////////////////////////
/* private */void off_on_led_transistor() {
output_low(PIN_D1);
delay_ms(1);
output_high(PIN_D1);
}
///////////////////////////////////////////////////////////
/* private */void display(int8 digit) {
output_c(DIGITS[digit] ^ 0xff);
off_on_led_transistor();
}
///////////////////////////////////////////////////////////
#INT_EXT
void ngat_RB0() {
i = (i < 9) ? i+1 : 1;
delay_ms(200); // switch debounce period
}
///////////////////////////////////////////////////////////
/**
* Count number of key presses and display it on a 7-segment LED.
* If the number is 9, the next count will be 1
*
* Wiring (TM Board)
* (1) PIC's B0 to R0
* Matrix Key C0 to GND
* (2) PIC's C0-C6 to 7-segment LED's A-G
* PIC's D1 to 7-segment LED's C2
*/
void main() {
enable_interrupts(GLOBAL);
enable_interrupts(INT_EXT);

while (true)


display(i);
}

5.9. Chương trình hiển thị phím số ra đèn 7 đoạn (không dùng interrupt)

Code:


///////////////////////////////////////////////////////////

/* private */void off_on_led_transistor() {

output_low(PIN_D1);

delay_ms(1);

output_high(PIN_D1);

}

///////////////////////////////////////////////////////////



void display(int8 digit) {

output_c(DIGITS[digit] ^ 0xff);

off_on_led_transistor();

}

///////////////////////////////////////////////////////////



int8 char_to_digit(char c) {

return c & 0b00001111; // first 4 bits only

}

///////////////////////////////////////////////////////////



int1 digit_key_pressed(char key) {

byte pattern;

pattern = 0b00110000;

return (key & pattern) == pattern;

}

///////////////////////////////////////////////////////////



/**

* Echo digit-key presses (0 to 9) of a 4x3 keypad to the 7-segment LED

*

* Configuration:



* Use PORTB for keypad by uncommenting the following line in PICC\Drivers\KBDD.c

* #define use_portb_kbd TRUE

*

* Wiring: (TM Board)



* (1) PIC's B1-B7 to Matrix Keypad's R3-R0&C2-C0 (notice the reverse order)

* (2) PIC's C0-C6 to 7-segment LED's A-G

* PIC's D1 to 7-segment LED's C2

*/

void main() {



int8 i, digit;

char key;


kbd_init();

while (true) {

key = kbd_getc();

if (digit_key_pressed(key)) {

digit = char_to_digit(key);

for (i = 0; i < 200; i++) // repeat the display for human eyes

display(digit);

}

}



}

5.10. Chương trình hiển thị phím số ra đèn 7 đoạn (DÙNG INTERRUPT)

Chương trình hiển thị phím số trên bàn phím 4x3 ra đèn 7 đoạn (DÙNG INTERRUPT).

#include <16F877A.h>
#fuses NOWDT, XT
#fuses NOLVP // important
#use delay(clock=4000000)

#include // in PICC\Drivers

// 0 1 2 3 4 5 6 7 8 9
byte const DIGITS[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f };
///////////////////////////////////////////////////////////
/* private */void off_on_led_transistor() {
output_low(PIN_D1);
delay_ms(1);
output_high(PIN_D1);
}
///////////////////////////////////////////////////////////
void display(int8 digit) {
output_c(DIGITS[digit] ^ 0xff);
off_on_led_transistor();
}
///////////////////////////////////////////////////////////
int8 char_to_digit(char c) {
return c & 0b00001111; // first 4 bits only
}
///////////////////////////////////////////////////////////
int1 digit_key_pressed(char key) {
byte pattern;
pattern = 0b00110000;
return (key & pattern) == pattern;
}
///////////////////////////////////////////////////////////
#INT_RB
void RB_handler() {
int8 i, digit;
char key;

key = kbd_getc();


if (digit_key_pressed(key)) {
digit = char_to_digit(key);
for (i = 0; i < 200; i++) // repeat the display for human eyes
display(digit);
}
}
///////////////////////////////////////////////////////////
/**
* Echo digit-key presses (0 to 9) of a 4x3 keypad to the 7-segment LED
*
* Configuration:
* Use PORTB for keypad by uncommenting the following line in PICC\Drivers\KBDD.c
* #define use_portb_kbd TRUE
*
* Wiring: (TM Board)
* (1) PIC's B1-B7 to Matrix Keypad's R3-R0&C2-C0 (notice the reverse order)
* (2) PIC's C0-C6 to 7-segment LED's A-G
* PIC's D1 to 7-segment LED's C2
*/
void main() {
enable_interrupts(GLOBAL);
enable_interrupts(INT_RB);
kbd_init();
while (true) {
// do nothing
}
}

Đoạn mã hiển thị led 7 thanh này, dấu ^ có ý nghĩa là vì hả các bác
void display(int8 digit) {
output_c(DIGITS[digit] ^ 0xff);
off_on_led_transistor();
}
Thân.


Dấu "^" là ký hiệu phép toán XOR (exclusive OR) trong C.

Phép toán && là phép and logic.Chắc là không phải giải thích về phép toán này.



5.11. Thay đổi tốc độ đèn led dung ngắt

Code:


//**************************************************************************

// Author : nhh

// Date : 03/04/06

// Hardware: PIC16F877A

//**************************************************************************

#include <16F877A.h>

#fuses NOWDT,PUT,XT,NOPROTECT

#use delay(clock=1000000)

#use fast_io(b)

#byte portb=0x06

#byte intcon=0x000B

#bit RB4=portb.4

#bit RB5=portb.5

#bit RBIF=intcon.0 //dinh nghia co ngat RB

#bit RBIE=intcon.3 //dinh nghia bit cho phep ngat RB
// Chuong trinh ngat

#int_RB


void ngat_RB()

{

if((RBIF)&&(RBIE))



{

//Kiem tra sw1

{

if(RB4==0)



{

portb=0b00000001;

delay_ms(200);

portb=0b00001111;

delay_ms(200);

}

}



//Kiem tra sw2

{

if(RB5==0)



{

portb=0b00001000; //led1,2 sang

}

}

RBIF=0; //Xoa co ngat RB



}

}

// Chuong trinh chinh



main()

{

set_tris_b(0b11110000);



portb=0b11110000;

enable_interrupts(global);

enable_interrupts(int_RB);

ext_int_edge(H_to_L);

while(true)

{

}



}



Em ko dùng ngắt nhiều nên hỏi có vẽ ngu ngơ, xin thông cảm.....
hai đoạn khai báo biến dưới đây để làm gì em không hiểu????
#byte portb=0x06
#byte intcon=0x000B
Vì trong chương trình chính đã định ngõ vào ra của port B rồi, với lại cũng đã cho ngắt toàn cục rồi mà.Tại sao phải nhất thiêt là 0x06 và 0x000B mà ko là giá trị khác////Em thử gán giá trị khác thì ct chạy sai...Giúp với

TL: Đây là khai báo địa chỉ của thanh ghi portB và thanh ghi intcon. Thường thì mỗi thanh ghi có một địa chỉ, giống như số nhà ấy, bạn khai báo nhầm địa chỉ của nó, nghĩa là bạn vào nhầm nhà rồi còn gì.
Với 16F877A
PORTB : địa chỉ 06h
INTCON : địa chỉ 0Bh
Vì trong file 16F877A.h của CCS C không có khai báo tường tận như trong các file .inc của Microchip, muốn sử dụng cho tiện thì khai báo thêm vào. Bạn mở file .h của con pic đang làm việc ra xem người ta đã khai báo những gì rồi.

+Sau khi vào trang Web của CCSC để tìm hiểu về vấn đề này mình lĩnh hội được một vài điều như sau:
- Thứ nhất, một thiết kế sẽ là không tối ưu nếu trong CTC ngắt lại gọi đến một hàm khác đã được sử dụng trong Main hay hàm khác, đặc biệt là khi bản thân hàm này lại gọi đến hàm khác nữa...(những hàm chứa trong các header thường gọi lẫn nhau như vậy).
- Thứ hai nếu sử dụng hàm như nêu trên thì chương trình chạy sẽ không theo đúng ý đồ lập trình (chẳng hạn như trong chương trình mà mình vừa Pót). Điều này xảy ra là do bộ nhớ Stack bị tràn (stack của PIC chỉ có 8 mức) khi gọi hàm chồng chéo (cả hàm Main và CTC ngắt đều gọi...).
- Thứ ba bên CCSC khuyên nếu buộc phải gọi hàm như vậy (chẳng hạn như hàm delay_ms như trên) thì hãy khai báo ở cà hàm Main và hàm ngắt ???.
TL Điều này thì mình không rõ vì đã thử nhưng không có hiệu quả.

Vấn đề của bạn như có thể giải thích một cách dễ hiểu như sau:


Nếu cả 2 hàm đều được gọi trong cả hàm ngắt và hàm main thì sẽ phát sinh ra lỗi. Tại sao lại thế. Các bạn thử suy nghĩ mà xem. khi hàm main đang chạy đến hàm mà nó và hàm ngắt cùng gọi. Nếu không có ngắt xẩy ra cùng thời điểm đó thì không có vấn đề gì cả. nhưng nếu có ngắt thì nó phải lưu các thông số hiện tại và nhảy vào ngắt, và khi nó nhảy ra khỏi ngắt thì các dữ liệu đã lưu sẽ bị chồng lên trong khi thực hiện hàm đó trong ngắt. vậy chương trình sẽ không đúng nữa.
Trong Keil C của 89 thì nó chỉ là warning nhưng trong css c thì nó là error. và theo quan điểm của tôi nó phải là một error.

Nếu bạn muốn dùng 2 cái delay_ms() trong cả ngắt và main thì mình nghĩ không có cách nào đâu. nếu bạn cứ muốn dùng nó thì hãy tạo ra 2 hàm delay_ms1() và delay_ms2() và trong ngắt gọi một hàm và trong main gọi hàm còn lại.


Còn có một cách nữa mình nghĩ nó sẽ pro hơn đấy là. Mình xin viết lại một đoạn chương trình của bạn trong: bạn khai báo một biến toàn cục như thế này nhé.
//=======
int1 bit_timer0_status;

#INT_TIMER1


void lapngat()
{
bit_timer0_status =1;
}
//===========
// và đưa công việc của bạn muốn thực hiện khi có ngắt vào đây.
//===========
void isr_timer0(void)
{
count++;
if (count==200)
while(true)
{
output_high(PIN_C1);
delay_ms(1000);
if(!input(PIN_B3)) break;
output_low(PIN_C1);
delay_ms(1000);
}
//===========
//và trong hàm main bạn phải làm thế này
//===========
void main(void)
{
if(bit_timer0_status)
{
//có thể cấm ngắt timer0.
//gọi hàm thực hiện công việc.
isr_timer0();
bit_timer0_status=0;
//bật ngắt trở lại
}
}

Giải pháp của bạn rất hay, và thực ra sau khi mình tìm hiểu điều này trên chuyên trang của CCSC mình cũng có ý tưởng na ná như vậy.


Nhưng nó vẫn có những hạn chế nhất định. Mình sẽ phân tích cho bạn như sau:
Giả sử chương trình viết theo cách của bạn, khi nó kiểm tra đến lệnh 'if(bit_timer0_status)' mà chưa xảy ra ngắt thì nó sẽ không thực hiện hàm 'isr_timer0()', qua đó rồi ngắt mới xảy ra thì chương trình lại không test 'if(bit_timer0_status)' và không thực hiện hàm 'isr_timer0()', tức là không có ngắt. Còn nếu trong chương trình mà luôn kiểm tra 'if(bit_timer0_status)' thì đang từ việc sử dụng phương pháp ngắt lại thành ra phương pháp thăm dò ???
Bạn chưa đọc kỹ chương trình của mình thì phải. Sẽ không có trường hợp ngắt xẩy ra mà không thực hiện công việc mà bạn mong muốn. Có chăng thì nó chậm hơn so với khi để công việc trong ngắt một chút. thời gian này không đáng kể chỉ khoảng vài 2ms. cái này không ảnh hưởng gì phải không?
Tại sao mình lại bảo không có chuyện như bạn nói: Trong chương trình phục vụ ngắt mình đã sử dụng một bit 'bit_Timer0_Status', bit này có mục đích khi có ngắt thì bật nó lên để báo cho hàm main biết đã có ngắt xẩy ra. và kể cả khi hàm main đang làm những gì, ở đâu thì khi gặp lệnh if(bit_Timer0_Status) thì nó thực hiện công việc mong muốn. và khi thực hiện công việc này xong phải xóa bit này để dùng cho lần sau.

Như mình đã nói nếu viết theo cách của bạn thì gần như chắc chắn sẽ không thực hiện được hàm ngắt theo mong muốn. Đã đành khi timer1 báo cho(bit_Timer0_Status) =1 (timer đã ngắt), nhưng có thể nói chắc chắn rằng khi chương trình đang kiểm tra 'if(bit_timer0_status)' thì timer chưa ngắt vì nó kiểm tra ngay bắt đầu hàm main. Sau khi đã kiểm tra như vậy rồi thì chương trình có quay lại để tiếp tục kiểm tra đâu mà gọi hàm 'ngắt phụ' như bạn viêt.


Nếu bạn không tin thì hãy lập thử một chương trình đơn giản sử dụng ngắt theo cách bạn viết và mô phỏng thử trên Proteus. (việc này đơn giản và không tốn nhiều thời gian,chắc không cần nói thêm!)
Tiện đây mình nói với bạn về các phương pháp trao đổi dữ liệu nói chung. Có 3 phương pháp chủ yếu là pp thăm dò (polling), pp ngắt (interrupt) và pp trao đổi trực tiếp (pp thú ba mình không nhớ rõ lắm). Làm như cách của bạn chính là chuyển từ pp ngắt sang pp thăm dò.
Hóa ra bạn bảo mình là không cho cái if của mình vào trong cái while(true) của bạn. Thật ra cái đấy mình chỉ viết thí dụ thôi. Còn nếu bạn muốn sử dụng thì bạn phải tự làm thêm. Vì mình nghĩ trong một firmware cho vi điều khiển không có cái nào không có lệnh while(true){} cả. Còn nếu đọc đến đây mà bạn vẫn khăng khăng nó không thực hiện được ngắt thì... mình cũng bó tay rồi. Nếu cần mình sẽ cho bạn xem một chương trình của mình, mình đã viết và thành phẩm. Phải nói nó chạy phe phé.
Và cái thứ 2 mình muốn nói thêm. Mình chỉ đưa ra những phương án như trên cho bạn, để bạn tham khảo thôi chứ không phải hay ho gì. nên bạn không cần thiết phải so sánh nó với 3 cái mà bạn nói. Nói thật mình chả hiểu đếch gì về mấy cái đấy cả... hê hê.

+Xin hỏi tại sao chương trình dùng ngắt timer0 em làm giống nhu hướng dẫn mà nó không chịu chạy?

#include<18F4450.h>


#fuses NOWDT,PUT,HS,NOPROTECT
#use delay(clock=20000000)
#use fast_io(b)
#byte portb=0x6
#define led pin_B0
int8 a;
void ngat()
{
delay_ms(1000);
a=a<<1; // dich trai a 1bit
if(a==256)
a=1;
}
main()
{
a=1;
set_tris_b(0);
while(true)
{
ngat();
output_b(a);
}
}
Cách này thì PIC18F4550 cũng dịch leds vô tư. Nhưng mà muốn dùng TIMER0 như của bác nhh . Khi mình làm không hiểu tại sao lại không thể chạy. Nhờ bác chỉ giáo giùm nhé!
#include <18F4550.h>
#fuses NOWDT,PUT,XT,NOPROTECT
#use delay(clock=20000000) . Mình đã sửa lại code của nhh như vậy để phù hợp với PIC18F4550, nhưng không hiểu sao vẫn không chạy đơợc. Bạn có thể hướng dẫn kỹ hơn về Interrup và Timer không, cảm on bạn nhiều.

TL: Úi code của bạn sai rồi nếu muốn sử dụng được ngắt thì trong hàm main bạn phải thực hiện cho phép ngắt timer_0 và ngắt toàn cục (global) hoạt động, định xung nhịp cho timer, và hàm ngắt() phải được đặt ngay bên dưới chỉ thị #int_timer0 để trình dịch có thể hiểu được đây là hàm phục vụ ngắt, hàm ngắt() này bạn không thể gọi đến giống như một hàm thông thường đuợc mà nó chỉ được máy gọi đến khi có xuất hiện cờ tràn timer_0, mà khi đã sử dụng ngắt timer (tức ngắt định thời) thì bạn không nên dùng delay trong nó (rất dở),vì ngắt timer được tạo ra để thay thế hoàn hảo cho delay, code của bạn mình sửa như sau :
#include<18F4450.h>
#fuses NOWDT,PUT,HS,NOPROTECT
#use delay(clock=4000000)
int16 count=0;
int8 a=1;

#int_timer0


void ngat(){
++count;
if(count==2000) {count=0;a=a<<1;} // dich trai a 1bit
if(a==256) {a=1;count=0; }}

void main(){


enable_interrupts(global);
enable_interrupts(int_timer0);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2); //xung timer = xung máy/2
while(true) {
output_b(a);
}}
Như vậy ở hàm trên ta sẽ thấy sau mỗi lần tràn ngắt timer_0 (sau hai xung máy) biến đếm count sẽ tăng lên 1 đơn vị và cứ thế cho đến khi đạt giá trị 2000 (đây là giá trị mà bạn cần phải tính để chọn đúng thời gian cần làm làm trễ) khi đó biến a sẽ đuợc dịch bit sang trái,....rồi tiếp tục... chắc khúc này bạn hiểu rồi há.

+Chào các bạn mình mới học pic nên chưa biết nhiều mong được sự giúp đỡ, tui có vài câu hỏi mong được chỉ giáo tui sử dụng ngắt timer nhưng thấy lệnh set_timer0(); ko có tác dụng nghĩa là đặt số mấy cũng ko thấy thay đổi thậm chí ko có lệnh đó vẫn chạy như thường bạn nào làm ngắt timer rùi chỉ mình với

Code:


#include <18F4331.h>

#fuses HS,NOWDT,NOPROTECT,NOLVP

#use delay(clock=4000000)
int i=0;

void main()

{

setup_timer_0(rtcc_div_32);



set_timer0(10); ????nếu đặt 1 thì bao lâu mới ngắt

enable_interrupts(int_rtcc);

enable_interrupts(global);

while(true)

{

}

}


#int_rtcc

void ngat_timer()

{

i++;


output_D(i);

}

Cấu hỏi thứ 2 là khi giao tiếp máy tính mình truyền từ PC đến pic: dùng lệnh getc(); thì chỉ thu được 1 kí tự ví dụ truyền số 12 thì thu được 2 số 1 và 2 có bạn nào biết lệnh nào để lấy 1 chuỗi ko?



TL: Về timer 0 và hàm set_timer0(), bạn đọc thêm tài liệu hướng dẫn của CCS C (trang 206, ver. 4, 01/2007) và datasheet của chip.
Về getc(), nếu bạn dùng nó thì tất nhiên chỉ lấy được 1 ký tự là nó đã trở về. Bạn đọc thêm về hàm gets() trong tài liệu hướng dẫn của CCS C (đã nêu trên, trang 148) để đọc 1 chuỗi ký tự.

+Thắc mắc ngắt timer

Em viết chương trình ngắt timer nhấp nháy led, nhưng nạp vào pic phải đợi 1 lúc sau nó mới bắt đầu nháy led, bác nào khắc phục jùm em với.
Đây là code:

#include <16F877A.h>

#include

#device 16F877*=16 ADC=10

#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT

#use delay(clock=4000000)

#use fast_io(b)

#use fast_io(c)

#use fast_io(d)
#int_timer0

void interrupt_timer0(){

int1 a;

int16 count;



set_timer0(56);

++count;


if(count == 500)

{

count=0;



a=~a;

RB0=a;


}

}

void main()



{

set_tris_b(0);

setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);

enable_interrupts(int_timer0);

enable_interrupts(global);

set_timer0(56);

while(true)

{

}



}

TL: Trước khi vào vòng while(true) trong main(), bạn nên đặt trước giá trị của count, nếu không thì count có thể mang giá trị bất kỳ, và điều kiện (count == 500) của bạn có thể phải sau khi count được tăng vài chục ngàn giá trị mới thỏa mãn (nếu tình cờ sau khi PIC reset biến count mang giá trị ngẫu nhiên là 501 chẳng hạn).
Tôi thường khởi tạo biến count ngay trước khi vào vòng while(true) trong main(), và dùng điều kiện (count >= 500) thay cho (count == 500) trong phần xử lý ngắt.

6. Chương trình ví dụ sau mô tả cách dùng PWM do CCS cung cấp.
PWM là gì? sử dụng nó vào mục đích gì?
1) PWM là gì? PWM là một bộ điều chế độ rộng xung. Có hai thông số (tạm gọi đơn giản như vậy, và có lẽ cũng chỉ quan tâm đến hai thông số này với PWM) quan trọng của PWM là chu kỳ xung T và thời gian t1 của mức logic 0,
trong ví dụ này thì t1 tương ứng với value. Để "điều chế độ rộng xung" thì chúng ta sẽ giữ nguyên T và thay đổi t1, theo yêu cầu của bài toán cụ thể.
Value trong ví dụ sau lấy được từ đầu vào anlaog, chu kỳ (hay tần số) của xung được chọn lựa từ PC thông qua cổng truyền thông nối tiếp RS232.
2) PWM dùng vào mục đích gì? Có nhiều ứng dụng cho nó, ví dụ truyền thông, điều khiển các van bán dẫn trong các biến tần, làm bộ nguồn chuyển mạch,...ôi nhiều lắm!
Bắt đầu viết nhé:

#if defined(__PCM__)


#include <16F877.h>

#fuses HS,NOWDT,NOPROTECT,NOLVP


#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, BRGH1OK)

#elif defined(__PCH__)


#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, BRGH1OK)
#endif

void main() {


char selection=1;
int8 value;

printf("\r\nFrequency:\r\n");


printf(" 1) 7.8 khz\r\n");
printf(" 2) 19.5 khz\r\n");
printf(" 3) 0.48 khz\r\n");
do {
selection=getc();
}while((selection<'1')||(selection>'3'));

setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM

// The cycle time will be (1/clock)*4*t2div*(period+1)
// In this program clock=4000000 and period=127 (below)
// For the three possible selections the cycle time is:
// (1/4000000)*4*1*128 = 12.8 us or 7.8 khz
// (1/4000000)*4*4*128 = 51.2 us or 19.5 khz
// (1/4000000)*4*16*128= 204.8 us or 0.48 khz
switch(selection) {
case '1' : setup_timer_2(T2_DIV_BY_1, 127, 1);
break;
case '2' : setup_timer_2(T2_DIV_BY_4, 127, 1);
break;
case '3' : setup_timer_2(T2_DIV_BY_16, 127, 1);
break;
}

setup_port_a(ALL_ANALOG);


setup_adc(adc_clock_internal);
set_adc_channel( 0 );
printf("%c\r\n",selection);

while( TRUE ) {


value=read_adc();
//value++;
printf("%2X\r",value);
set_pwm1_duty(value); //value may be an 8 or 16 bit constant or variable
// This sets the time the pulse is
// high each cycle. We use the A/D
// input to make a easy demo.
// the high time will be:
// if value is LONG INT:
// value*(1/clock)*t2div
// if value is INT:
// value*4*(1/clock)*t2div
// for example a value of 30 and t2div
// of 1 the high time is 30us
// WARNING: A value too high or low will
// prevent the output from
// changing.
}
}

+


Yêu cầu của e là điều chỉnh độ rộng xung để thay đổi vận tốc của động cơ (trong để tài của e là động cơ của bơm cánh dẫn)
Cảm ơn các trưởng lão namqn! Rất mong nhận được sự giúp đỡ của bạn!


Với động cơ thì tần số điều chế thường quanh quẩn 20 kHz. Bây giờ bạn cho biết bạn dùng loại bộ điều khiển nào để điều chỉnh vận tốc của động cơ, bạn có đo vận tốc chứ? Từ ngõ ra của bộ điều chế độ rộng xung bạn làm thế nào để điều chỉnh vận tốc của động cơ? Động cơ đó có công suất khoảng bao nhiêu?









7. Tìm hiểu về LCD

LCD được tìm hiểu ở đây là HD44780 của hãng Hitachi, gồm 2 dòng, mỗi dòng 16 kí tự.




HD44780 có 14 chân, chức năng của các chân:


1.Các chân VCC, VSSVEE: Chân VCC_Cấp dương nguồn 5V, chân VCC_Nối đất, chân VEE được dùng để điều khiển độ tương phản của màn hình LCD.
2.Chân chọn thanh ghi RS (Register Select):
Có hai thanh ghi rất quan trọng bên trong LCD, chân RS được dùng để chọn các thanh ghi này như sau: Nếu RS = 0 thì thanh ghi mà lệnh được chọn để cho phép người dùng gửi một lệnh chẳng hạn như xoá màn hình, đưa con trỏ về đầu dòng,… Nếu RS = 1 thì thanh ghi dữ liệu được chọn cho phép người dùng gửi dữ liệu cần hiển thị trên LCD.
3.Chân đọc/ghi R/W:
Đầu vào đọc/ghi cho phép người dùng ghi thông tin lên LCD khi R/W = 0 hoặc đọc thông tin từ nó khi R/W = 1.

tải về 1.15 Mb.

Chia sẻ với bạn bè của bạn:
1   2   3   4   5   6   7   8   9   ...   15




Cơ sở dữ liệu được bảo vệ bởi bản quyền ©hocday.com 2024
được sử dụng cho việc quản lý

    Quê hương