2 Attachment(s)
Đúng là mọi người không chịu vào hết các trang mà mình quan tâm, địa chỉ các thanh ghi cũng như các thứ khác các bạn lấy ở đây.
|
Mình xem qua các chương trình cậu viết ở trên đều không sai nhưng chưa tối ưu, các cậu cứ xem phần chương trình bên asm thì rõ, vấn đề này cũng đã được thảo luận rất nhiều rồi mà. Các file mình đưa ra xẽ giúp chúng ta hỗ trợ thêm cách lập trình bằng C, và đến một lúc nào đó nếu các bạn đã thông tư tưởng của mình thì, lúc đấy viết trên HTpic hay CCs đều không khác nhau.
|
Gửi nhh:
Bài : Giải mã bàn phím Mạch quét 16 phím, hiện kết quả lên led 7 đoạn. Trong chuong trinh thieu dinh nghia #byte intcon=0x000B và port xuất ra led 7 đoạn là PORTC không phải portd như hình vẽ. |
To vnt3140
Đúng là trong đó hình vẽ và chương trình có nhầm portc và portd, do khi chạy proteus và mạch thật thiết lập port ok nhưng khi vẽ ORCAD bị nhầm. Các bạn chỉ thay đổi chút xíu thôi mà! Còn chưa định nghĩa byte intcon, sao bạn chỉ phát hiện ra nó, còn các bít RBx nữa thì sao.....Nhưng tất cả đã được định nghĩa trong file defs_16F877A.h.Mình nhớ đã gởi file này lên rồi nhưng bây giờ tìm lại không thấy đâu cả.Pó tay luôn ! Dạo này sao lú lẫn quá!Mình sẽ gởi lên sau! :D |
Trích:
Bác nên khai báo biến i là biến toàn cục thì mới có khả năng đếm số lần ngắt. Chúc khỏe. hpecom. |
Trích:
Chúc sức khỏe. hpecom. |
minh dang lam ve de tai dieu khien ma tran led
da co ai nghien cuu ve van de nay chua neu co tai lieu thi gui cho minh voi cam on nhe |
1 Attachment(s)
Trích:
Để cho việc viết chương trình được thuận lợi hơn, những lần sau nên include cái file DEFS_16F877A.h vào để không phải khai báo dài dòng nữa ! |
Chương trình gửi ký tự ra 2x16 LCD dùng CCS C
Chương trình gửi ký tự ra 2x16 LCD dùng CCS C
#include "16F877A.h" // PIC16F877A header file #use delay(clock=4000000) // for 4Mhz crystal #fuses XT, NOWDT, NOPROTECT, NOLVP // for debug mode #define WRITE_DATA 0 #define WRITE_COMMAND 1 #define NCHAR_PER_LINE 16 // max char numbers per line #define MS10 10 // 10 milliseconds #define US400 400 // 400 microseconds #define LCD_RS PIN_A1 #define LCD_RW PIN_A2 #define LCD_E PIN_A3 /////////////////////////////////////////////////////////// // /* private */ void lcd_write(byte dat, int1 option) { delay_us(US400); if (option == WRITE_DATA) output_high(LCD_RS); else // option == WRITE_COMMAND output_low(LCD_RS); output_low(LCD_RW); output_b(dat); output_high(LCD_E); delay_us(US400); output_low(LCD_E); } /////////////////////////////////////////////////////////// // void lcd_init(void) { output_low(LCD_E); // Let LCD E line low lcd_write(0x38, WRITE_COMMAND); // Set LCD 16x2, 5x7, 8bits data delay_ms(15); lcd_write(0x01, WRITE_COMMAND); // Clear LCD display delay_ms(MS10); lcd_write(0x0f, WRITE_COMMAND); // Open display & current delay_ms(MS10); lcd_write(0x06, WRITE_COMMAND); // Window fixed (Character Entry Mode?) delay_ms(MS10); } /////////////////////////////////////////////////////////// // void lcd_display_char(int8 line, int8 pos, char ch) { line = (line == 0) ? 0 : 1; pos = (pos > NCHAR_PER_LINE) ? NCHAR_PER_LINE : pos; lcd_write(0x80 + 0x40 * line + pos, WRITE_COMMAND); lcd_write(ch, WRITE_DATA); } /////////////////////////////////////////////////////////// void lcd_display_str(int8 line, char str[], int8 nchars) { int8 i; for (i = 0; i < nchars; i++) lcd_display_char(line, i, str[i]); } /////////////////////////////////////////////////////////// /** * Display characters to a 2x16 LCD * * (1) LCD1 to GND * (2) LCD2 to VDD 5 volts * (3) LCD4 (RS) - LCD5 (RW) - LCD6 (E) to A1, A2, A3 * (4) LCD7-LCD14 to B0-B7 (bus data) * * Ref: http://pic16.com/bbs/dispbbs.asp?boa...ID=5879&page=1 */ void main(void) { int8 i; char LINE1[] = { "SGN Tech" }; char LINE2[] = { "Xin chao" }; lcd_init(); // use of lcd_display_char() for (i = 0; i < 8; i++) lcd_display_char(0, i, LINE1[i]); // use of lcd_display_str lcd_display_str(1, LINE2, 8); } |
Re: Chương trình gửi ký tự ra 2x16 LCD dùng CCS C
CCS C có một ví dụ hay hơn: Chỉ cần dùng 4 bits D4-D7 của LCD:
Examples\EX_LCDKB.C Trích:
|
Ví dụ nhỏ về ngắt ngoài
Bình thường thì LED6 sáng, LED7 tối. Khi nhấn phím, LED6 tối, LED7 sáng
trong vòng 0,5 giây, rồi trở về trạng thái ban đầu (LED6 sáng, LED7 tối) #include <16F877A.h> #fuses NOWDT, XT #use delay(clock=4000000) void high_b6_low_b7() { output_high(PIN_B6); output_low(PIN_B7); } void low_b6_high_b7() { output_low(PIN_B6); output_high(PIN_B7); } /////////////////////////////////////////////////////////// #INT_EXT void RB0_handler() { low_b6_high_b7(); delay_ms(500); high_b6_low_b7(); } /////////////////////////////////////////////////////////// /** * Keep B6 on and B7 off. Pressing the button causes interrupt: * B6 off and B7 on, delay half second, then B6 on and B7 off * * Wiring (TM Board) * (1) PIC's B0 to Matrix Key R0 * Matrix Key C0 to GND * (2) PIC's B6-B7 to LED6-LED7 * * Ref: Interrupt Mechanism * http://www.mikroelektronika.co.yu/en...sicbook/06.htm */ void main() { enable_interrupts(GLOBAL); // enable all interrupts enable_interrupts(INT_EXT); // enable external interrupt from pin RB0/INT high_b6_low_b7(); while (true) { // do nothing } } |
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); } Trích:
|
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. } } Nguyen The Vinh. |
Chương trình hiển thị phím số ra đèn 7 đoạn (không dùng interrupt)
Code:
Chương trình hiển thị phím số trên ma trận phím 4x3 ra đèn 7 đoạn (không dùng interrupt) |
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 <kbd.c> // 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 } } |
Múi giờ GMT. Hiện tại là 09:32 PM. |
Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam