PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   Các ngôn ngữ lập trình khác (CCS C, HT PIC,...) (http://www.picvietnam.com/forum/forumdisplay.php?f=12)
-   -   Học CCS thông qua Tutorial PICVIETNAM (http://www.picvietnam.com/forum/showthread.php?t=689)

FFGmember 18-10-2006 05:20 PM

Học CCS thông qua Tutorial PICVIETNAM
 
Đã lâu lâu không đóng góp cho PIC Việt Nam gì rồi. Đợt này tự nhiên công việc liên quan đến PIC, yêu cầu đến việc sử dụng SPI, nhào zô luôn cho việc học CCS. Mong mỏi đóng góp chút gì đó cho tất cả mọi ngưòi.


1. Mục tiêu của việc học CCS:
• Sử dụng được CCS programmer
• Ứng dụng được chương trình hiển thị LCD
• Ứng dụng được chương trình kết nối SPI với EEPROM và MMC card. hiển thị các thông số lên LCD .


2. Nguồn tài liệu và công cụ làm việc:
• Theo tutorial của Linhnc308: http://www.picvietnam.com/forum//att...6&d=1157644591
• Chương trình CCS: down load ban CCS3.249.rar. http://www.tailieuvietnam.net/downlo...CCSC_3.249.rar
• Chương trình Proteus. 6.7

FFGmember 18-10-2006 05:47 PM

Ví dụ 1: thực thi bài nhấp nháy led
 
1 Attachment(s)
Bước 1: tạo một project mới test1 trong thư mục project1 ( CCS -> Project -> New -> PIC Wizard )
Bước 2: Copy paste đoạn code của Linhnc308 vào trong mục file test1.c

Trích:

#include <16f877a.h>
#include <def_877a.h>
#device *=16 ADC=8
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
void main()
{
// Thiet lap che do cho PORTB
TRISB = 0x00; // Tat ca PORTB deu la cong xuat du lieu
PORTB = 0xFF; // Tat het cac LED
While(1)
{
PORTB = 0; // Cho các LED sáng
delay_ms(250); // T.o th.i gian tr. 250ms
PORTB = 0xFF;
delay_ms(250);
}
}
Bước 3: Compile Unit ( F9 ) => chương trình báo lỗi, không có def_877A trong thư mục PICC/Device/ . Đọc lại bài hướng dẫn thấy có nói def_F877A là file khai báo thanh ghi của người sử dụng. Search một hồi trong diễ đàn cũng tìm được file def_876 -> chỉnh sửa rename rồi copy vào PICC/Device . Compile lại => chuơng trình chạy OK.
Bước 4: Quay trở lại đường link thư mục ban đầu …./Project1 check xem có file gì mới ko, file hex đã được tạo trong này rồi
Bước 5: Bật chương trình Proteus lên lắp mạch như linhnc308 => chỉnh thông số tần só thạch anh là 4Mhz rồi nạp file hex vào => chạy. Chương trình chạy OK

Túm lại : kết thúc VD1 này tôi đã thu được:
• Năm bắt được thành thạo các bước thực thi của CCS : tạo project mới, tạo file mới, các compile chương trình
• Nắm được cấu trúc khung cảu chương trình CCS, cách khai báo ban đầu
• Gợi nhớ lại Proteus 6.7 vì đã lâu lắm rồi ko sờ đến nó, chuẩn bị cho các Project tiếp theo.

Vi du 2, 3 ve` LCD, SPI den toi' giai quyet tiep.

FFGmember 19-10-2006 12:40 AM

Project2: Hiển thị lên LCD dùng lcd_lib_4bit.c
 
1 Attachment(s)
LCD cùng với led đơn và led 7 thanh là một trong những phương thức để hiển thị các kết quả các thông số. Thông thường tôi luôn chọn LCD vì lập trình đơn giản và đông thời có thể thể hiện được các giá trị mà mình mong muốn.

Có rất rất nhiều source code cho việc viết LCD 4 bit. Và một trong số đó là file lcd_lib_4bit.c đã đươc linhnc308 giới thiệu trong tập tutorial của mình

Lại thực thi các bước như ở trên, với đoạn code dưới đây.

PHP Code:

#include <16f877a.h>
#include <def_877a.h>
#device *=16 ADC=8
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
#include <lcd_lib_4bit.c> // Thu vien ham cho LCD

void main()
{
trisa 0xFF;
trisb 0x01;
trisd 0x00;
LCD_init();
Printf(LCD_putchar," PICVIETNAM tut");
LCD_putcmd(0xC3);
Printf(LCD_putchar," LCD 4bit ");



Khi lập trình đến LCD 4bit sử dụng lcd_lib_4bit.c cần lưu ý đến 2 điều
  • Chân nối đã được fix sẵn trong hàm lcd_lib_4bit.c, khi thay đổi chân cho phù hợp với việc thiết kế mạch là coi như đã thay đổi cả với các chương trình mình dùng truóc đó.
  • Trong chương trình sử dụng đến lệnh LCD_putcmd( 0xC3) chính là chỉ vị trí con trỏ cho việc hiển thị đoạn text. 0xC3 là vi tri thu 4 của dòng thứ 2

FFGmember 19-10-2006 04:30 AM

Project 1: Kết nối PIC 16F877A với EEPROM 25AA640.
 
Sorry mọi người là tối hôm nay em tìm mỏi cả mắt mà không thấy bất cử một thằng EEPROM nào có chuẩn giao tiếp SPI, cho nên ở Project này em chỉ xin được làm chay thôi, ai có điều kiện mạch thật hoặc có trình giả lập tốt thì xin test + đưa ra ý kiến cho em phát.

SPI là một chuẩn dữ liệu giao tiếp đơn giản nhất có tốc độ lớn nhất, tuy nhiên có độ an toàn không cao khi mà dây clock bị ảnh hưởng => dẫn đến ảnh hưởng đến toàn hệ thống.
Với PIC16F877A thì có 3 chân cho chế độ SPI đó là: RC3( clock ), RC4 ( SDI ), RC5 ( SD0) , còn chân select chíp thì lấy bất cứ một chân I/O thông thường.

Cơ chế SPI là quá trình dịch bít qua lại giữa Slave và Master qua 2 đường đây SDI, SDO. Ứng với mỗi IC khác nhau lại cho một chuẩn truyền tiếp riêng để điều khiển quá trình truyền. Với EEPROM 25AA640 cơ chế đó là:

Đọc byte:
Truyền lệnh 0000011 tiếp đến là truyền địa chỉ 16 byte, và đọc dữ liệu . Khi chân CS lên 1 => cũng là lúc báo hiệu kết thúc đường truyền.


http://i33.photobucket.com/albums/d5...7A/hinh1-1.jpg



Write byte
Viết lệnh command: 00000010, sau đó truyền địa chỉ 16 bit, rồi bắt đầu truyền dữ liệu. Quá trình truyền kết thức khi CS = 1


http://i33.photobucket.com/albums/d5...7A/hinh2-1.jpg


PHP Code:

void main()
{
// init ban dau
   
OUTPUT_LOW(PIN_C2);       
   
setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_4);
   
OUTPUT_HIGH(PIN_C2); 
   
delay(5);   
   
// truyen du lieu co gia tri 0x55 xuong eeprom tai dia chi 0x0004    
   
OUTPUT_LOW(PIN_C2);      
   
spi_write(0x02);        // command = 0x02 -> ghi du lieu
   
spi_write(0x00);
   
spi_write(0x04);
   
wpi_write(0x55);
   
OUTPUT_HIGH(PIN_C2); 
   
delay(5);
   
// Doc du leu
   
OUTPUT_LOW(PIN_C2);      
   
spi_write(0x03);       // command -= 0x03 -> doc du lieu
   
spi_write(0x00);
   
spi_write(0x04);
   
wpi_read(buff);
   
OUTPUT_HIGH(PORTD); 
   
delay(5);   
   
   while(
1);



Code trên hoàn toàn chỉ là ý tưởng như thế, ai có điều kiện hoặc đã làm rồi xin cho đôi lời.
Lâu lâu ko đựoc làm đến pic , nay còn được làm trên CCS nữa thấy thật thoải mái.

See Ua!

IMI 30-10-2006 11:47 AM

Quá hay. Và quá chi tiết.

anhquangngai 02-11-2006 08:12 PM

vậy muốn viết cho led đơn sáng dần và xoay phải xoay trái thì làm thế nào?
mình mới làm quen với CCS nên ko biết nhờ bạn giúp cho!

nhh 05-11-2006 09:53 AM

Trích:

Nguyên văn bởi anhquangngai (Post 5771)
vậy muốn viết cho led đơn sáng dần và xoay phải xoay trái thì làm thế nào?
mình mới làm quen với CCS nên ko biết nhờ bạn giúp cho!

http://www.picvietnam.com/forum//showthread.php?t=357
Tài liệu mô phỏng bạn hỏi ở đây:
http://www.picvietnam.com/forum//sho...p?t=406&page=2 Dưới cùng, bài của anh F có link.

anhquangngai 07-11-2006 04:13 PM

Trích:

Nguyên văn bởi nhh (Post 5813)
http://www.picvietnam.com/forum//showthread.php?t=357
Tài liệu mô phỏng bạn hỏi ở đây:
http://www.picvietnam.com/forum//sho...p?t=406&page=2 Dưới cùng, bài của anh F có link.

trong này ko có led sang dan !

nhh 08-11-2006 08:36 AM

Trích:

Nguyên văn bởi anhquangngai (Post 5846)
trong này ko có led sang dan !

Muốn làm led sáng dần, tức là bạn phải làm cho điện áp cấp vào chân led tăng dần.

Hãy sử dụng chức năng PWM điều chế độ rộng xung, nhưng trước hết bạn phải học cách sử dụng các Timer, Timer 2 phục vụ PWM.

thaithienanh 08-11-2006 09:40 PM

anh REMMEMBER ơi viết tiếp bài nữa đi

necati 14-11-2006 05:18 AM

http://rapidshare.com/files/2849523/...d_regfiles.rar

tranhuyky 14-11-2006 04:14 PM

Bước 5 mình bí rồi
 
gởi bạn FFGmember
Mình đã làm thử vd1 theo hướng dẫn của bạn rồi, nhưng tới bước 5 thì bí. Mình không biết cách nạp file hex vào trong proteus. Bạn hướng dẫn kỷ hơn cho mình được không. Cám ơn bạn trước nha.

anhquangngai 03-12-2006 07:01 PM

cho em hỏi về vòng lặp while
 
các bác có thể cho mình biết cách sử dụng vòng lặp while dc ko?
chương trình mình viết như sau nhưng vòng lặp while ko thực hiện đc
Code:

int8 a,b;
main()
{
while(a==8){
a++;
portb=00;
delay_ms(100);
portb=0xFF;
delay_ms(100);
}

em sử dụng như thế mà sao vòng lặp while ko chạy?

namqn 03-12-2006 07:15 PM

Bên ngoài vòng while nên khởi tạo giá trị cho biến a. Điều kiện lặp là a==8 do đó nếu giá trị a ban đầu không phải là 8 thì vòng lặp không chạy. Nếu vòng lặp có chạy thì chỉ chạy 1 lần, vì bên trong vòng lặp a bị thay đổi.

Thân,

anhquangngai 03-12-2006 09:10 PM

vậy nếu như chương trình gán biến a=8 thì vòng lặp sẽ ko lặp 8 lần
vậy thì chương trình này phải viết lại như thế nào??
PHP Code:

int8 a;
a=8;
main()
{
while(
a==8){
a++;
portb=00;
delay_ms(100);
portb=0xFF;
delay_ms(100);


và như vậy nếu như lệnh a++; ko dc thực hiện thì ko lặp dc 8 lần
nhưng vòng lệnh for thì thực hiện lặp 8 lần dc
PHP Code:

for(a=0;a<8;a++){..........} 



Múi giờ GMT. Hiện tại là 03:17 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