PDA

View Full Version : Lập trình với ngôn ngử Basic


TTL
19-06-2006, 01:21 PM
Sau khi đăng nhập vào diễn đàn em thấy hầu như mọi người sử dụng CCS và HT để lập trình cho PIC, ngôn ngữ trên hổ trợ rất nhiều tuy nhiên bên cạnh dó cũng có ngôn ngữ BASIC giúp ích chúng ta rất nhiều trong việc thiết kế các module nhỏ. Do đó em xin trình bày mốt số câu lệnh với BASIC giúp cho các bạn mới học để làm quen với PIC
Chương trình sử dụng đựoc Down tại:
http://www.oshonsoft.com/downloads.html

TTL
19-06-2006, 01:21 PM
Đầu tiên là cách khai báo biến, trong Basic hổ trợ 4 loại dữ liệu đó là:
Bit: có giá trị 0 hoặc 1
Byte: chiếm 1 byte có giá trị từ 0 – 255
Word: chiếm 2 byte có giá trị từ 0-65536
Long: chiếm 4 byte có gía trị từ 0-4294967295
Trong chương trình Basic mà em sử dụng thì không có hổ trợ số âm và thưc nhưng bằng thuật tóan ta có thể thay thế được.
Cú pháp : dim <tên biến> as <loại, kiểu biến>
Vd: dim a as byte
Dim b as bit
Dim c as word
Dim d as long
Và chúng ta cũng có thể sử dung khai báo kiểu mảng (vd: sử dụng trong giải mã led 7 đọan)
Vd: dim a(10) as byte ‘khai báo mãng a gồm 10 phần tử kiểu byte.
Ngoài ra chúng ta còn có thể truy suất tới từng bit của biến
Dim a as byte
a.5=7 ‘khai báo biến a là byte và set bit thứ sáu là 1
Hoặc gán trực tiếp với các port hoặc các thanh ghi
Trisb=0ffh ‘khai báo portb là input
Status.5=1 ‘nhảy vào bank 1
Portc.1=1 ‘set bit thứ hai port c lên 1 nếu port c là output

TTL
19-06-2006, 01:22 PM
Cách khai báo hằng và đạt lại tên cho các thanh ghi
Cú pháp: const <tên hằng>= <gia trị> hoặc define <tên hằng>= <gía trị>
Vd: khai báo a là hằng số và có giá trị là 5
Const a=5
Cú pháp: symbol <tên mới> = <bit hoặ thanh ghi>
Vd: SYMBOL LED1 = PORTB.0
LED1 = 1

TTL
19-06-2006, 01:23 PM
Các phép tóan gồm có (+; -; *; /; %) và các phép tóan logic (not; and; or; nand; nor; xor; nxor)
Ví dụ:
DIM A AS WORD
DIM B AS WORD
DIM X AS WORD
A = 123
B = A * 234
X = 2
X = (12345 - B * X) / (A + B)
Ví dụ:
DIM A AS BIT
DIM B AS BIT
DIM X AS BIT
X = NOT A
X = A AND B
X = A OR B
X = A XOR B
X = A NAND B
X = A NOR B
X = A NXOR B

TTL
19-06-2006, 01:23 PM
Câu lện goto: dung để nhảy tới 1 nhã nào đó đã được đặt tên trước
Vídụ:
DIM A AS WORD
A = 0
loop: A = A + 1
GOTO loop
Ví dụ: sử dung portb làm mạch dếm với chu kì 1s
Dim a as byte
Trisb=00
Main:
Portb=a
A=a+1
Goto main
End

TTL
19-06-2006, 01:24 PM
Cậu lệnh chờ dợi.
Cú pháp: delayms(<số mili giây cần trì hõan>) , delayus(<số micro giay cần trì hõan>)
Vd: nếu ta dung thãch anh 4Mhz thì cau lệnh delayms(1) sẽ cho ta trì hõan 1000 câu lệnh ( tương dương với 1000 câu lện nop)
Ví dụ:
DIM A AS WORD
A = 100
WAITMS A
WAITUS 50

TTL
19-06-2006, 01:25 PM
Các câu lệnh về vòng lặp FOR , WHILE và câu lện điều kiện IF
Vòng lặp FOR:
Cú pháp:
For <giá trị dầu> to <giá trị cuối> step <bước nhảy>
Thực hiện lệnh
Next <tên biến dể tiếp tục>
Ví dụ:
DIM A AS BYTE
DIM B AS BYTE
DIM X AS BYTE
B = 255
X = 2
TRISB = 0
FOR A = B TO 0 STEP -X
PORTB = A
NEXT A

Vòng lặp While:
Cú pháp:
While (<điều kiện>)
Thực hiệ lệnh
Wend ‘kết thúc
Ví dụ:
DIM A AS BYTE
TRISB = 0
A = 255
WHILE A > 0
PORTB = A
A = A - 1
WAITMS 100
WEND
PORTB = A

Câu lện điều kiện IF
Cú pháp:
If <điều kiện> then
Thực hiện lệnh
Else ‘ ngược lại
Thực hiện lệnh
End if
Ví dụ:
DIM A AS BYTE
TRISB = 0
A = 255
WHILE A > 0
PORTB = A
A = A - 1
WAITMS 100
WEND
PORTB = A

TTL
19-06-2006, 01:26 PM
Câu lệnh LOOKUP giống như là kỹ thuật bảng tra. Ví dụ đi63n hình là dung giải mã led bảy thanh.
Ví dụ:
DIM DIGIT AS BYTE
DIM MASK AS BYTE
loop:
TRISB = %00000000
FOR DIGIT = 0 TO 9
MASK = LOOKUP(0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F), DIGIT
PORTB = MASK
WAITMS 1000
NEXT DIGIT
GOTO loop
Ngoài ra nó còn cho phép ta trả về mã ASCII của kí tự;
Ví dụ:
MASK = LOOKUP("ABCDEFGHIJK"), INDEX

TTL
19-06-2006, 01:27 PM
Sử dụng chương trình con với cau lệnh GOSUB
Cú pháp: gosub <tên chương trình con>
Ví dụ:
SYMBOL ad_action = ADCON0.GO_DONE
SYMBOL display = PORTB
TRISB = %00000000
TRISA = %111111
ADCON0 = 0xC0
ADCON1 = 0
HIGH ADCON0.ADON
main:
GOSUB getadresult
display = ADRESH
GOTO main
END
getadresult:
HIGH ad_action
WHILE ad_action
WEND
RETURN

Ví dụ trên là biến đổi giá trị Analog đưa vào RA.0 và thể hiện ra PORTB.0 sử dung chương trình con và các vòng lặp.

TTL
19-06-2006, 01:29 PM
Sử dung EEPROM nội:
Cú pháp:
READ <địa chỉ> ,<giá trị> ‘đọc từ EEPROM
WRITE <địa chỉ> ,<giá trị> ‘ghi vào EEPROM
Ví dụ
DIM A AS BYTE
DIM B AS BYTE
A = 10
READ A, B
WRITE 11, B

TTL
19-06-2006, 01:29 PM
Sử dụng ngắt: sau khi viết chương trình chính xong thì cuối cùng ta viết chương trinh phục vụ ngắt.
Cú pháp:
Main:
…….
…….
Goto main
End

On interrupts
<chương trình phục vụ ngắt viế ở đây>
Resume

TTL
19-06-2006, 01:30 PM
Ví dụ ngắt ngoài RB0:
DIM A AS BYTE
A = 255
TRISA = 0
PORTA = A
INTCON.INTE = 1
ENABLE
END
ON INTERRUPT
A = A - 1
PORTA = A
INTCON.INTF = 0
RESUME

Đọan chương trình trên sử dụng ngắt ngoài ở chân RB.0. Nếu có ngắt thì gảim a đi 1 và đưa giá trị của a ra PORTA. Lưu ý là khi kết thúc chương trình phục vụ ngắt thì phải xoa cờ ngắt

TTL
19-06-2006, 01:32 PM
Ví dụ ngắt do bộ định thời:
DIM T AS WORD
T = 0
TRISA = 0xFF
ADCON1 = 0
TRISB = 0
OPTION_REG.T0CS = 0
INTCON.T0IE = 1
ENABLE
loop:
ADCIN 0, PORTB
GOTO loop
END
ON INTERRUPT
SAVE SYSTEM
T = T + 1
INTCON.T0IF = 0
RESUME

Đay là đạon chương trình ngắt do bộ dịnh thời Timer0, sau khi phục vụ ngắt nhớ xóa cờ ngắt

TTL
19-06-2006, 01:32 PM
Giao tiếp qua cổng nối tiếp chuẩn RS232. Ở đay chia ra làm 2 lọai là giao tiếp bằng phần mềm và phần cứng. Phần cứng là sử dụng chân RxD và TxD làm nhận và chuyển, còn phần mềm là sử dụng bất cứ chân nào làm RxD và TxD cũng được.
Phần cứng gồm có các câu lệnh: HSEROPEN, HSERIN, HSEROUT, HSERGET
Ví dụ:
DIM I AS BYTE
HSEROPEN 38400
WAITMS 1000
FOR I = 20 TO 0 STEP -1
HSEROUT "Number: ", #I, CrLf
WAITMS 500
NEXT I
DIM I AS BYTE
HSEROPEN 19200
loop:
HSERIN I
HSEROUT "Number: ", #I, CrLf
GOTO loop

DIM I AS BYTE
HSEROPEN 19200
loop:
HSERGET I
IF I > 0 THEN
HSEROUT "Number: ", #I, CrLf
WAITMS 50
ENDIF
GOTO loop
Phần mềm gồm các câu lệnh: SEROUT, SERIN.
Ví dụ:
DEFINE SEROUT_DELAYUS = 5000
SEROUT PORTC.6, 1200, "Hello world!", CrLf

DIM I AS BYTE
loop:
SERIN PORTC.7, 9600, I
SEROUT PORTC.6, 9600, "Number: ", #I, CrLf
GOTO loop

TTL
19-06-2006, 01:43 PM
Ví dụ chương trinh lấy mã Scancode của bàn phím sau đó gởi vào PC qua cổng nối tiếp.
Sơ dồ mạch:

TTL
19-06-2006, 01:44 PM
Code:
TRISB = 01h
TRISA = 01h
INTCON.GIE = 1
INTCON.INTE = 1
OPTION_REG.INTEDG = 0
'khai bao bien
Dim a As Word
Dim store As Byte
Dim i As Byte
Dim j As Bit
a = 0
i = 0
main:
Lcdout #store
If i >= 11 Then
a = ShiftRight(a, 1)
store = a.LB
Serout PORTA.1, 9600, #store
i = 0
a = 0
Lcdcmdout LcdClear
Endif
Goto main
End
On Interrupt
a.0 = a.0 Or PORTA.0
a = ShiftLeft(a, 1)
i = i + 1
INTCON.INTF = 0
Resume

Giải thích dọan chương trình này sử dung ngắt RB0 dể lấy mã Scancode cua bàn phím sau đó gởi qua port nối tiếp ở chân PortA.1.

TTL
19-06-2006, 01:45 PM
Cách sử dung LCD: Basic hổ trợ rất nhiều đối với điều khiển lcd với các câu lệnh dơn giản
DEFINE LCD_BITS = 8 ‘khai báo lcd sử dụng 8 bit data
DEFINE LCD_DREG = PORTB ‘dũ liệu vào ở PortB
DEFINE LCD_DBIT = 0
DEFINE LCD_RSREG = PORTD ‘khai báo chân RS của lcd
DEFINE LCD_RSBIT = 1
DEFINE LCD_EREG = PORTD ‘khai báo chân Enable của LCD
DEFINE LCD_EBIT = 3
DEFINE LCD_RWREG = PORTD ‘khai báo chân Read write
DEFINE LCD_RWBIT = 2
Lcdinit
Lcdout (<biến hoặc 1 chuỗi>)
Lcdcmd (<lệnh>)

Ví dụ xuât chữ HELLO ra lcd sử dụng 4 bit dữ liệu, rs ở portb.0. enable ở portb.1, read/write ở portb.2. chớp tắt với chu kỳ 1s.
DEFINE LCD_BITS = 4 ‘khai báo lcd sử dụng 8 bit data
DEFINE LCD_DREG = PORTB ‘dũ liệu vào ở PortB
DEFINE LCD_DBIT = 1 ‘4 bit cao cua port b
DEFINE LCD_RSREG = PORTb ‘khai báo chân RS của lcd
DEFINE LCD_RSBIT = 0
DEFINE LCD_EREG = PORTb ‘khai báo chân Enable của LCD
DEFINE LCD_EBIT = 1
DEFINE LCD_RWREG = PORTb ‘khai báo chân Read write
DEFINE LCD_RWBIT = 2
Lcdinit
Main:
Lcdout(“hello”)
Waitms(1000)
Lcdcmdout(lcdclear)
Goto main

TTL
19-06-2006, 01:47 PM
Ví dụ mạch dồng hồ bằng LCD.
Mạch.

TTL
19-06-2006, 01:47 PM
Code:
WaitMs 1000
'Khoi tao LCD
Define LCD_LINES = 2
Define LCD_CHARS = 16
Define LCD_BITS = 4
Define LCD_DREG = PORTB
Define LCD_DBIT = 0
Define LCD_RSREG = PORTA
Define LCD_RSBIT = 1
Define LCD_EREG = PORTA
Define LCD_EBIT = 3
Define LCD_RWREG = PORTA
Define LCD_RWBIT = 2
Lcdinit
'Khai bao bien
Dim x As Byte
Dim y As Byte
Dim g1 As Byte
Dim g2 As Byte
Dim g3 As Byte
Dim g4 As Byte
Dim a1 As Byte
Dim a2 As Byte
Dim b1 As Byte
Dim b2 As Byte
Dim c1 As Byte
Dim c2 As Byte
a1 = 0
a2 = 0
b1 = 0
b2 = 0
c1 = 0
c2 = 0
x = 00
y = 00
main:
Lcdcmdout LcdClear
g1 = x / 10
g2 = x % 10
g3 = y / 10
g4 = y % 10
If x >= 24 Then
x = 0
Endif
If y >= 60 Then
y = 0
Endif
If a1 = g1 And a2 = g2 And b1 = g3 And b2 = g4 Then
PORTA.0 = 1
Else
PORTA.0 = 0
Endif
c2 = c2 + 1
If c2 > 9 Then
c2 = 0
c1 = c1 + 1
Endif
If c1 > 5 Then
c1 = 0
b2 = b2 + 1
Endif
If b2 > 9 Then
b2 = 0
b1 = b1 + 1
Endif
If b1 > 5 Then
b1 = 0
a2 = a2 + 1
Endif
If a2 > 9 Then
a2 = 0
a1 = a1 + 1
Endif
If a1 >= 2 And a2 >= 4 Then
a2 = 0
a1 = 0
Endif
Lcdout #a1, #a2, ":", #b1, #b2, ":", #c1, #c2, " ", #x, ":", #y
Lcdcmdout LcdLine2Home
Lcdout "Digital clock "
WaitMs 998
Goto main
End
On Interrupt
WaitUs 100
If PORTB.6 = 1 Then
a2 = a2 + 1
Endif
If PORTB.4 = 1 Then
b2 = b2 + 1
Endif
If PORTB.7 = 1 Then
x = x + 1
Endif
If PORTB.5 = 1 Then
y = y + 1
Endif
INTCON.RBIF = 0
Resume

TTL
19-06-2006, 01:50 PM
Mạch đã thực hiện

TTL
19-06-2006, 01:55 PM
Mình chỉ biết chút ít thôi nếu anh nào biết thì bổ sung thêm vào , em cảm ơn

"Học PIC trong 1 ngày là quá nhiều nhưng để biết chi tiết về nó thì là quá ít"
"Học vô bờ quay đầu là bến"

TTL
19-06-2006, 01:56 PM
Bác F ơi sao em add file lên nó ko cho vậy

falleaf
19-06-2006, 05:57 PM
Em đã tải hình lên cũng chính là tải được file lên rồi đó thôi?

Lưu ý, có một số giới hạn về kích thước hình ảnh, sắp tới anh sẽ mở rộng kích thứơc hình lên một chút, lưu ý, bề rộng hình chỉ được tối đa 620 pixel, để tránh việc tràn khung hình, anh sẽ nâng lên 700px. Còn các file định dạng khác thì em phải đảm bảo kích thước file khoảng 700KB, nếu lớn hơn thì không được. File nào quá lớn, em chuyển dạng sang .zip để tải lên.

Cái nào quá lớn, thì email cho anh, anh gửi lên host.

Chúc vui