PDA

View Full Version : Bỏ bồ già ASM, chuyển sang bồ nhí C mà rắc rối quá!


Jerry
11-01-2008, 04:01 PM
Hi all,

Trước nay cứ bám váy mụ bồ già ASM, đến nay mụ khó tính quá nên phải tính kế đi kiếm bồ trẻ C cho nó dễ dụ. Ai ngờ trẻ thì có trẻ mà cũng rất khoai. Tui thử viết chương trình với mục đích:

- Sử dụng 2 phím bấm:
OK nối RB6
Cancel nối RB7

Khi phím được bấm thì mức điện áp trên chân cổng nối với phím bấm là 0V.

- Khi cấp nguồn cho board mạch và chưa bấm phím, LCD hiển thị màn hình 1.

- Mỗi lần bấm OK, LCD lần lượt chuyển sang màn hình 2 rồi màn hình 3...

Đây là code nhưng nạp vào rồi bấm phím mà chả thấy xi nhê gì. Vác đồng hồ ra đo ở chân RB6 thì thấy mức điện áp có 1.6V khi phím không bấm (bình thường phải là mức 5V chứ nhỉ). Không hiểu tại sao có hiện tượng này.

Xin nhờ các cao thủ trên diễn đàn giúp sức.


#include <16F877A.h>
#include <def_877a.h>
#device *=16 adc=10
#FUSES NOWDT, XT, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=4000000)
#use fast_io (b)

#define OK PIN_B6
#define Cancel PIN_B7


#include <lcd_lib_4bit.c>

int8 count;
char phim;

char Button(void)
{
while(1)
{
if(!OK) return 'O';
if(!Cancel) return 'E';
}
}

//-----------------------------------------------------------------

void main(void)
{
set_tris_a(0xC0);
set_tris_b(0xC1);

LCD_init();
delay_ms(500);
LCD_putcmd(0x80);
Printf(LCD_putchar,"Hi ev'body"); //Hien thi man hinh 1
LCD_putcmd(0xC0);
Printf(LCD_putchar,"Khoi tao...");

phim=Button();
if(phim=='O')
{
LCD_putcmd(0x01); //xoa man hinh
LCD_putcmd(0x80);
Printf(LCD_putchar,"Enter Pressed"); //Hien thi man hinh 2
}
//end main-----------------------------------------------------------
}

nguyen.geo
11-01-2008, 04:47 PM
Chào bạn !
Thứ nhất thường thì khi chân nào dùng làm chân bàn phím với cách mắc như bạn thì thường dùng 1 con điện trở nối lên VCC để cho nó phân biệt Mức thấp và mức cao vì chân bàn phím bạn chọn là Input.
Còn đoạn chương trình bạn viết tại sao nó lại kô chạy thì :
Đoạn này bạn viết tôi chưa bao giờ dùng nên không biết đúng hay không ai biết thì bảo tôi luôn :
char Button(void)
{
while(1)
{
if(!OK) return 'O';
if(!Cancel) return 'E';
}
}
còn tôi thì thường viết :
char Button(void)
{ unsigned char i;
while(1) ((Up==1)&&(Down==1)&&(Enter==1)&&(Menu==1));
if(!Up) i = 1;
if(!Down) i = 2;
if(!Enter) i = 3;
if(!Menu) i = 4; // cancel
return i;
}
// còn đây là cách mà tôi thường tạo Menu
unsigned char Menu(unsigned char menu)
{ unsigned char i;
Lcd(" hiển thị cái gì đó dòng 1 ");
while(1)
{ ... ghi lệnh C0 ra Lcd để nó về đàu dòng thứ 2 trước.
if(menu==1) Lcd(" dòng thứ 2 gì đó ");
else if(menu==2) Lcd(" dòng thứ 2 gì đó khác ");
else ...........
Delay(); // khoảng 200ms
i = Button();
if(i==1) menu++; // nhớ là cần phải giới hạn xem có bao nhiêu Menu nếu không thì...
if(i==2) menu--;

if(i==4) goto Extit;
}
Exit : làm cái gì đó trước khi thoát ở đây như còi kêu chẳng hạn
return menu;
}

Jerry
11-01-2008, 06:46 PM
Chào bạn !
Thứ nhất thường thì khi chân nào dùng làm chân bàn phím với cách mắc như bạn thì thường dùng 1 con điện trở nối lên VCC để cho nó phân biệt Mức thấp và mức cao vì chân bàn phím bạn chọn là Input.


Cái mạch này tui viết bằng ASM, vẫn các chức năng đó, chạy ngon lành mà. Nói để chứng minh lỗi không phải do phần cứng.

namqn
11-01-2008, 07:09 PM
Đơn giản nhất là Jerry viết chương trình thử nghiệm 1 phím bật tắt 1 LED, để xem đoạn code bắt phím có làm việc đúng hay không. Khi bắt đầu với một trình biên dịch mới, tôi vẫn thường làm những thí nghiệm đơn giản nhất, để đảm bảo là mình hiểu rõ hành vi của trình biên dịch.

Thân,

hanhluckyly
11-01-2008, 09:34 PM
theo mình nghĩ chương trình bạn viết không chạy là do không có vòng lặp kiểm tra trạng thái chân hay nói cách khác là quét chân thêm cái while vào

linhnc308
12-01-2008, 09:10 AM
Check lại phần khởi tạo cho PORT. làm như sau:
output_b(0xC0);
set_tris_a(0xC0);
set_tris_b(0xC1);
port_b_pullups (TRUE);

Hàm quét phím nên thêm vòng lặp để kiểm tra xem phím nhả chưa. Đơn giản hơn thì tôi thêm hàm trễ delay_ms
char Button(void)
{
if(!OK) {
while(!OK);
return 'O';
}
if(!Cancel) {while(!Cancel);return 'E';}
}

Bạn cũng nên làm theo lời khuyên của anh Nam, rất bổ ích, hay test từ những cái đơn giản trước để biết vấn đề nằm ở đâu. Tôi vẫn thường làm như vậy.

Jerry
12-01-2008, 10:09 AM
Báo cáo với các bác là em hơi tự tin thái quá khi nghĩ mình làm ASM ngon rồi, thì chuyển sang C chỉ là thay đổi ngôn ngữ. Chính vì vậy nên mới làm theo kiểu thế này. Có lẽ nên làm theo lời khuyên của bác Nam.

Tuy nhiên đã thử theo lời khuyên của linhnc308, kết quả có tên là Nguyễn Y Vân (đọc ngược).

Bây giờ sẽ thử theo cách của Nguyen.geo. Sẽ báo cáo kết quả ngay sau khi thử xong.

Rất mong các cao thủ tiếp tục ra tay chỉ giúp.

Jerry
12-01-2008, 03:50 PM
Tớ làm được rồi nè

#define OK PIN_B6
#define Cancel PIN_B7

#define OK_PRESSED !input(OK)

#include <lcd_lib_4bit.c>

int8 count;
char phim;

//-----------------------------------------------------------------

void main(void)
{
output_b(0xC0);
set_tris_a(0xC0);
set_tris_b(0xC1);
port_b_pullups (TRUE);

LCD_init();
delay_ms(500);
LCD_putcmd(0x80);
Printf(LCD_putchar,"Hi ev'body"); //Hien thi man hinh 1
LCD_putcmd(0xC0);
Printf(LCD_putchar,"Khoi tao...");

while (!OK_PRESSED) {}
LCD_putcmd(0x01); //xoa man hinh
LCD_putcmd(0x80);
Printf(LCD_putchar,"Enter Pressed"); //Hien thi man hinh 2
}

Jerry
12-01-2008, 04:01 PM
Nhưng kiểu dò phím thế này vẫn còn trẻ con, vì không ai đưa vợ đi làm đầu rồi lại phải ngồi ở quán gội đầu để đợi vợ làm đầu xong mới chở về cả. Trong thời gian chờ vợ làm đầu, ta có thể đi cưa gái, nhậu nhẹt, cafe cà fáo với anh em chiến hữu. Vợ làm đầu xong nháy 1 cái là ta lại có mặt. Như thế mới là tối ưu chứ nhể.

Cho nên phần tiếp theo của chương trình sẽ khó hơn 1 chút. Cùng 1 phím nhưng "bấm lâu" thì làm công việc A, "bấm nhanh" thì làm công việc B.

- Thời gian "bấm nhanh" sẽ nhỏ hơn 2 giây
- Thời gian "bấm lâu" sẽ lớn hơn hoặc bằng 2 giây.

Nào, tui bắt đầu viết đây!

Jerry
14-01-2008, 09:06 AM
Đầu tiên là thử quét phím bằng timer0 (chưa thử bấm nhanh hay bấm lấu)

#include <16F877A.h>
#include <def_877a.h>
#device *=16 adc=10
#FUSES NOWDT, XT, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=4000000)
#use fast_io (b)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bi ts=9)

#define OK PIN_B6
#define Cancel PIN_B7

#define OK_PRESSED !input(OK)

#include <lcd_lib_4bit.c>

int8 count;
char phim;
int8 isr_count;

#int_TIMER0
void interrupt_timer0()
{
if(OK_PRESSED)
{
isr_count++;
if(isr_count==81)
{
isr_count==0;
disable_interrupts(GLOBAL);
disable_interrupts(INT_TIMER0);
}
}
else
{
disable_interrupts(GLOBAL);
disable_interrupts(INT_TIMER0);
}
}

//-----------------------------------------------------------------

void main(void)
{
output_b(0xC0);
set_tris_a(0xC0);
set_tris_b(0xC1);
port_b_pullups (TRUE);

LCD_init();
delay_ms(500);
LCD_putcmd(0x80);
Printf(LCD_putchar,"Hi ev'body"); //Hien thi man hinh 1
LCD_putcmd(0xC0);
Printf(LCD_putchar,"Khoi tao...");

if(OK_PRESSED)
{ //enable timer0
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
}
if(isr_count==0)
{
LCD_putcmd(0x01); //xoa man hinh
LCD_putcmd(0x80);
Printf(LCD_putchar,"Enter Pressed"); //Hien thi man hinh 2
}
}



Nhưng mà chưa được. Nạp chương trình, cắm điện vào nó hiện luôn Enter Pressed, dù thực tế chưa bấm phát nào. Các cao thủ đâu hết cả rồi, trả lời tui đi chứ.

namqn
14-01-2008, 08:08 PM
- Biến isr_count chưa được khởi tạo trong main(), nên rất có thể nó mang giá trị 0 khi thực thi main(). Do đó lệnh xuất ra LCD chuỗi "Enter Pressed" có thể được thực thi.

- main() không có vòng lặp chính, dẫn đến chạy hết các lệnh trong main() thì sẽ chạy tiếp các lệnh trong flash, giả thiết chúng đều là 3FFFh, tức là lệnh addlw 0xff, thì PIC sẽ chạy đến ô nhớ cuối cùng của flash chương trình, sau đó PC sẽ trở về 0000h, và PIC lại chạy chương trình như vừa bị reset (không hoàn toàn giống như reset bằng MCLR).

- Timer0 chưa được khởi tạo, do đó hành vi là không xác định trước.

Thân,

Jerry
15-01-2008, 08:22 AM
- Em tưởng biến isr_count em khai báo ngay từ đầu thì nó là biến toàn cục, dùng trong hàm nào cũng được??

- Em sửa lại chương trình thế này nhưng vẫn chưa chạy được:


#include <16F877A.h>
#include <def_877a.h>
#device *=16 adc=10
#FUSES NOWDT, XT, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=4000000)
#use fast_io (b)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bi ts=9)

#define OK PIN_B6
#define Cancel PIN_B7

#define OK_PRESSED !input(OK)

#include <lcd_lib_4bit.c>

int8 count;
char phim;
int8 isr_count,press;

#int_TIMER0
void interrupt_timer0()
{
if(OK_PRESSED)
{
isr_count++;
if(isr_count==81)
{
isr_count=0;
press=1;
disable_interrupts(GLOBAL);
disable_interrupts(INT_TIMER0);
}
}
else
{
press=0;
disable_interrupts(GLOBAL);
disable_interrupts(INT_TIMER0);
}
}

//-----------------------------------------------------------------

void main(void)
{
press=0;
output_b(0xC0);
set_tris_a(0xC0);
set_tris_b(0xC1);
port_b_pullups (TRUE);

LCD_init();
delay_ms(500);
LCD_putcmd(0x80);
Printf(LCD_putchar,"Hi ev'body"); //Hien thi man hinh 1
LCD_putcmd(0xC0);
Printf(LCD_putchar,"Khoi tao...");

if(OK_PRESSED)
{ //enable timer0
set_timer0(6);
setup_timer_0(RTCC_INTERNAL);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
}
while(press!=1) {}
LCD_putcmd(0x01); //xoa man hinh
LCD_putcmd(0x80);
Printf(LCD_putchar,"Enter Pressed"); //Hien thi man hinh 2

}


Bây giờ nó chỉ hiển thị màn hình đầu tiên
Hi ev'body
Khoi tao...
Bấm phím ko thấy xi nhê gì.

Jerry
15-01-2008, 09:17 AM
Chạy được rồi này, vấn đề đúng là nằm ở gạch đầu dòng thứ 2 và thứ 3 của bác Nam


#include <16F877A.h>
#include <def_877a.h>
#device *=16 adc=10
#FUSES NOWDT, XT, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=4000000)
#use fast_io (b)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bi ts=9)

#define OK PIN_B6
#define Cancel PIN_B7

#define OK_PRESSED !input(OK)

#include <lcd_lib_4bit.c>

int8 count;
char phim;
int8 isr_count,press;

#int_TIMER0
void interrupt_timer0()
{
if(OK_PRESSED)
{
isr_count++;
if(isr_count==81)
{
isr_count=0;
press=1;
disable_interrupts(GLOBAL);
disable_interrupts(INT_TIMER0);
}
}
else
{
press=0;
disable_interrupts(GLOBAL);
disable_interrupts(INT_TIMER0);
}
}

//-----------------------------------------------------------------

void main(void)
{
press=0;
output_b(0xC0);
set_tris_a(0xC0);
set_tris_b(0xC1);
port_b_pullups (TRUE);

LCD_init();
delay_ms(500);
LCD_putcmd(0x80);
Printf(LCD_putchar,"Hi ev'body"); //Hien thi man hinh 1
LCD_putcmd(0xC0);
Printf(LCD_putchar,"Khoi tao...");

while (!OK_PRESSED) { }
//enable timer0
set_timer0(6);
setup_timer_0(RTCC_INTERNAL);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);

while(press!=1) {}
LCD_putcmd(0x01); //xoa man hinh
LCD_putcmd(0x80);
Printf(LCD_putchar,"Enter Pressed"); //Hien thi man hinh 2

}

Jerry
24-01-2008, 10:13 AM
Phần tiếp theo là tui học giao tiếp USART. Các công việc tui dự định làm là:
- Truyền 1 chuỗi ký tự từ máy tính xuống
- Mạch target nhận các ký tự và hiển thị lên LCD

Trước tiên tui thử truyền liên tục các ký tự '*' lên máy tính, dùng phần mềm HDD Serial Port Monitor để view các ký tự truyền lên:

#include <16F877A.h>
#include <def_877a.h>
#device *=16 adc=10
#FUSES NOWDT, XT, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=4000000)
#use fast_io (b)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bi ts=9)

#define OK PIN_B6
#define Cancel PIN_B7

#define OK_PRESSED !input(OK)

#include <lcd_lib_4bit.c>

int8 count, press;
char phim;
int16 isr_count;

//-----------------------------------------------------------------

void main(void)
{
press=0;
output_b(0xC0);
set_tris_a(0xC0);
set_tris_b(0xC1);
port_b_pullups (TRUE);



while(!txif) putc('*');
}


Nhưng kết quả là không hề thấy ký tự * được truyền lên. Tại sao vậy? Mong nhận được sự giúp đỡ của mọi người.

picthanh
24-01-2008, 02:35 PM
bác Jerry oi! trước đây tui cũng từng làm như bác vậy,nhưng cung ko được .khi tui gửi lên máy tinh thi chương trình Serial Port Monitor của CCS hiện lên một loạt ký tự kiểu hexa ,và nó cứ gởi liên tục.ko bit tình trạng của bác có giống ko.tui nghe nói trên máy tính phải có phần mền để nhận cái chuỗi or ký tự mà mình gửi lên.tới giờ này tui vẫn pó tay ko bít lam sao để nhận nó hết.

falleaf
24-01-2008, 03:00 PM
Lâu rồi không dùng, nhưng hình như dùng printf chứ không phải putc nhỉ?

Chúc vui

Jerry
24-01-2008, 03:34 PM
Để chương trình dễ theo dõi hơn tui đã làm như sau: Dùng phần mềm Com Master do minhcuong cung cấp ở link này: http://www.picvietnam.com/forum/showthread.php?t=274&page=4. Phần mềm này sẽ gửi các ký tự gõ vào từ bàn phím xuống cho vi điều khiển, vi điều khiển nhận ký tự trong ngắt nhận và truyền trở lại cho máy tính.

#include <16F877A.h>
#include <def_877a.h>
#device *=16 adc=10
#FUSES NOWDT, XT, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=4000000)
#use fast_io (b)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bi ts=9)

#include <lcd_lib_4bit.c>


#INT_RDA
Receive_isr()
{
char c;
disable_interrupts(GLOBAL);
c = getc(); // nhận ký tự
putc(c); // truyền trả lại cho máy tính
enable_interrupts(GLOBAL);
}

//-----------------------------------------------------------------

void main(void)
{
output_b(0xC0);
set_tris_a(0xC0);
set_tris_b(0xC1);
port_b_pullups (TRUE);
set_tris_c(0xD0);

LCD_init();
delay_ms(500);
LCD_putcmd(0x80);

enable_interrupts(INT_RDA);
enable_interrupts (global);
while (1) {}

}



nhưng vẫn không thấy ký tự nào hiển thị trên màn hình receive của chương trình Com Master. Ai đã làm công việc tương tự thì làm ơn hướng dẫn giúp nhé.

Jerry
24-01-2008, 03:38 PM
@falleaf:
- putc(): This function sends a character over the RS232 XMIT pin
- printf(): Outputs a string of characters to either the standard RS-232 pins (first two forms) or to a specified function.

(copy right from CCS C Help)

Jerry
24-01-2008, 03:55 PM
@picthanh: Nó gửi liên tục thì chắc do firmware viết cho vi điều khiển của bạn nó gửi liên tục lên thôi. Cái Serial Port Monitor dùng để giám sát các thông tin truyền nhận ở cổng COM của máy tính, nghĩa là ta gửi gì ra cổng COM, hoặc nhận gì về từ cổng COM, nó đều hiển thị lên màn hình máy tính hết. Không hiểu cái "phần mềm để nhận cái chuỗi or ký tự mà mình gửi lên" là bạn muốn đề cập đến phần mềm gì. Nếu ta chỉ cần quan sát việc truyền nhận thôi thì chỉ cần Serial Port Monitor là đủ. Còn khi cần xử lý dữ liệu nhận về thì mới cần phần mềm để xử lý.

LeDuc
24-01-2008, 06:15 PM
bác Jerry oi! trước đây tui cũng từng làm như bác vậy,nhưng cung ko được .khi tui gửi lên máy tinh thi chương trình Serial Port Monitor của CCS hiện lên một loạt ký tự kiểu hexa ,và nó cứ gởi liên tục.ko bit tình trạng của bác có giống ko.tui nghe nói trên máy tính phải có phần mền để nhận cái chuỗi or ký tự mà mình gửi lên.tới giờ này tui vẫn pó tay ko bít lam sao để nhận nó hết.

Bạn thử delay một khoản thời gian xem sao .

hanhluckyly
24-01-2008, 06:56 PM
Bạn đã thử debug chương trình chưa lỗi ở dòng nào

namqn
24-01-2008, 08:52 PM
...

...
void main(void)
{
...
while(!txif) putc('*');
}


Nhưng kết quả là không hề thấy ký tự * được truyền lên. Tại sao vậy? Mong nhận được sự giúp đỡ của mọi người.
TXIF được bật lên '1' khi bộ đệm phát là rỗng (empty). Jerry viết như trên có nghĩa là khi bộ đệm không rỗng thì ta đẩy thêm một ký tự vào bộ đệm!!

Nên viết như sau:
while (1) {
while (!TXIF); //Wait until the transmit buffer is empty;
putc(c); //Send one character
delay_ms(500); //Wait for a while so human eye can see it
}

Thân,

picthanh
24-01-2008, 11:05 PM
hehe ! các bác xem nè em đã gởi được ký tự lên máy tính và nhận ký tự từ trên máy tính gởi xuống vi diều khiển và hiện lên LCD
em xài con 16f877a

#include "D:\PIC PROGRAM\RS232\goi ky tu.h"
#include <LCD.C>
#include <KBD.C>
#include <stdio.h>
#include <stdlib.h>

char k,c;

#int_RDA
RDA_isr()
{

c=getch();
lcd_gotoxy(1,2);
cd_putc(c);
}



void main()
{

port_b_pullups(TRUE);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
lcd_init();
kbd_init();
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);

while(1)
{
k=kbd_getc();
if (k!=0)
{
if(k!='*')
{
lcd_gotoxy(1,1);
lcd_putc(k);
printf("key = %c",k);
}
else lcd_putc('\f');
}
}

}

em xài chương trình ComMaster để nhận dữ liệu.
bác Jerry ơi ! em thư dùng Serial Port Monitor of CCS nhưng nó ko hiện dc ký tự mà em gởi lên, chỉ nhận một dãy số kiểu hexa thôi.trong khi đó ComMaster thì chạy ngon lành.ai giải thích giùm em tại sao vậy.

namqn: Bạn hãy học cách đặt code vào giữa hai tag [code] và [ /code] để định dạng.

picthanh
24-01-2008, 11:15 PM
các bác cho hỏi ComMaster có gửi một chuỗi ký qua cổng com dc ko nhỉ.em đã sữa chương trình lại một chút để VDK nhận một chuỗi ký tự từ cổng Com sau đó xuất ra LCD nhưng kết quả chăng thấy ký tự nào xuất hiện trên LCD cả.

char string[10];
#int_RDA
RDA_isr()
{
char i;

gets(string);
lcd_gotoxy(1,2);
for (i=0;i<strlen(string);i++)
lcd_putc(string[i]);

}

namqn: Nhắc lại lần nữa, bạn hãy học cách đặt code giữa hai tag [code] và [ /code] để định dạng

Jerry
25-01-2008, 07:57 AM
@picthanh:
- Com Master có cho phép gửi 1 chuỗi ký tự qua cổng COM
- Bạn có thể kiểm tra bằng cách nối tắt chân 2 và chân 3 của cổng COM lại, rồi gõ 1 chuỗi dữ liệu vào cửa sổ transmit của Com Master, sau đó nhấn nút Send.

linhnc308
25-01-2008, 09:51 AM
Các bạn vào trang web sau để download code PIC cho CCS. Đây là các chương trình tôi đã viết trước đây.
http://linhnc308.googlepages.com/
http://linhnc308.googlepages.com/myprojects

Chúc thành công.

picthanh
25-01-2008, 11:19 AM
các bác ơi,giúp em với .viết chương trình như đã up ở trên sao con pic 16f877a of em ko được nhận 1 chuỗi từ PC giống như trong phần help of CCS hướng dẫn .loay hoay từ hồi tối tới giờ mà nó vẫn ko chạy dc vậy.

Jerry
25-01-2008, 11:47 AM
Trong cái link mà linhnc308 đưa không thấy có phần USART. Bạn xem lại giúp nhé.

Jerry
26-01-2008, 03:20 PM
Hi, đã làm xong phần truyền nhận RS232, nhưng mới chỉ truyền nhận được từng ký tự, chưa truyền nhận chuỗi được. Sau đây là chương trình nhận chuỗi gồm 10 ký tự, bắt đầu bằng ký tự '0', kết thúc bằng ký tự '9'. Mục tiêu là như vậy nhưng chạy thử thì chưa được. Các bạn giúp tớ 1 tay nhé:


#include <16F877A.h>
#include <def_877a.h>
#device *=16 adc=10
#FUSES NOWDT, XT, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=4000000)
#use fast_io (b)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bi ts=8)

#define OK PIN_B6
#define Cancel PIN_B7

#define OK_PRESSED !input(OK)

#include <lcd_lib_4bit.c>

char mang[11];
int8 dem=0;
int1 flag;
char c;

//-----------------------------------------------------------------

void main(void)
{
int8 i;
press=0;
output_b(0xC0);
set_tris_a(0xC0);
set_tris_b(0xC1);
port_b_pullups (TRUE);
set_tris_c(0x90);

LCD_putcmd(0x01);
LCD_putcmd(0x80);

while(1)
{
if(kbhit()) {c=getc();
if(c=='0') flag=1;
if((c=='9')&&(flag==1)){flag=0; break;}
if(flag==1) {dem++; mang[dem]=c;}}
}
mang[10]='\0'; // kết thúc xâu ký tự
printf(LCD_putchar,"%s",mang); // Hiển thị lên LCD
printf("%s",mang); // truyền lên máy tính
}


Nạp chương trình và thử truyền chuỗi ký tự 0 2 3 1 6 5 4 8 7 9 xuống mà không thấy LCD hiện gì, không thấy PIC truyền gì lên máy tính luôn.

Jerry
29-01-2008, 10:35 AM
Báo cáo, tớ đã làm xong phần truyền nhận chuỗi gồm 10 ký tự. Chuỗi này có ký tự bắt đầu là 0, ký tự kết thúc là 9. Có thể dễ dàng modify chương trình để có số ký tự truyền nhận hoặc thay đổi ký tự bắt đầu - kết thúc. Sau đây là chương trình post lên cho những người mới học như tớ tham khảo:


#include <16F877A.h>
#include <def_877a.h>
#device *=16 adc=10
#FUSES NOWDT, XT, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=4000000)
#use fast_io (b)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bi ts=8)

#include <lcd_lib_4bit.c>

char mang[11];
int8 dem=0;
int1 flag, flag1;
char c;

#INT_RDA
Receive_isr()
{
c=getc();
if(c=='0') flag=1;
if((c=='9')&&(flag==1)){mang[dem]=c; dem++; flag=0; flag1=1;}
if(flag==1) {mang[dem]=c; dem++;}
}

//-----------------------------------------------------------------

void main(void)
{
output_b(0xC0);
set_tris_a(0xC0);
set_tris_b(0xC1);
port_b_pullups (TRUE);
set_tris_c(0x90);

LCD_init();
delay_ms(500);
LCD_putcmd(0x80);
Printf(LCD_putchar,"Hi ev'body"); //Hien thi man hinh 1
LCD_putcmd(0xC0);
Printf(LCD_putchar,__DATE__);

enable_interrupts(INT_RDA);
enable_interrupts (global);

while(1)
{
if(flag1==1)
{
LCD_putcmd(0x01); //xoa man hinh
LCD_putcmd(0x80);
mang[10]='\0';
printf(LCD_putchar,"%s",mang);
printf("%s",mang);
}
}
}

Jerry
29-01-2008, 10:37 AM
Phần tiếp theo tớ sẽ học là giao tiếp I2C giữa PIC6F877A và IC thời gian thực PCF8583. Ai có hứng thú thì nhào dzô trao đổi nhé.

falleaf
01-02-2008, 12:21 PM
Phần tiếp theo tớ sẽ học là giao tiếp I2C giữa PIC6F877A và IC thời gian thực PCF8583. Ai có hứng thú thì nhào dzô trao đổi nhé.

Phần này có tutorial rồi, nên xem tutorial trong bài viết về giao tiếp I2C.

Chúc vui

thang8831
21-09-2008, 08:25 AM
CCS của em không có file "lcd_lib_4bit.c" và "lcd_lib_4bit.h" khi chạy nó toàn báo không có file này bác nào cho em xin được không? thực ra chuyển sang file lcd.c thì ok nhưng em muốn có file này dùng cho tiện. Cám ơn các bác nhiều nhé!