PIC Vietnam

Go Back   PIC Vietnam > Các Đề Tài > PIC và Robot trên nền Ubuntu

Tài trợ cho PIC Vietnam
Trang chủ Đăng Kí Hỏi/Ðáp Thành Viên Lịch Bài Trong Ngày Vi điều khiển

PIC và Robot trên nền Ubuntu Đây là một chủ trương mới mà chúng ta cần chú ý.

Trả lời
 
Ðiều Chỉnh Xếp Bài
Old 15-09-2015, 12:33 AM   #1
ttai
Đệ tử 1 túi
 
Tham gia ngày: Dec 2005
Bài gửi: 12
:
Lập trình PIC trên linux (XC16, ASM30, Pickit2)

Chào các bạn,
Lâu nay không đóng góp gì, hôm nay sẵn vợ con dắt nhau qua hàng xóm ở nên rãnh được tí, mình kể lại kinh nghiệm lập trình với PIC, dsPIC trên linux. Vì cũng ít thấy ở VN người ta chia sẻ về linux, nên mạo muội chia sẻ chút xíu, hy vọng được góp ý. Arigatou!

Mình hiện dùng Manjaro, dựa trên Arch. Nhưng bạn dùng Ubuntu, Linux Mint hay Linux distro khác cũng tương tự.

1. Để viết code, mình dùng chương trình Mousepad. Ở distro khác thì có thể dùng Gedit... Điểm mạnh của các editor mặc định này so với Notepad trên windows đó là nó hỗ trợ high-light rất nhiều định dạng code. Ví dụ bạn soạn thảo một file văn bản main.c hoặc main.py thì nó sẽ định dạng màu sắc cho văn bản đó dựa trên code C hoặc Python để dễ làm việc. (Có vẻ tương tự Notepad++ nhỉ).
Dù sao thì mình không muốn dùng MPLABX IDE hoặc MPLAB 8 vì lý do máy quá cùi, không chạy mượt để mà lập trình được, và hơn nữa mình cũng chả cần tới mấy tính năng quản lý project cao cấp trên IDE.


Mousepad trên Manjaro.

2. Để biên dịch, mình cài XC16 từ Microchip, bản dành cho Linux. Hiện tại thì XC16 có vẻ là lựa chọn tối ưu để biên dịch cho dsPIC trên linux. Mình có biết SDCC nhưng không rõ nó có hỗ trợ dsPIC chưa. Dù sao đi nữa nếu có trình biên dịch nào mã nguồn mở mình sẽ dùng. Hiện tại chưa tìm được nên đành hài lòng với XC16, bản miễn phí.

http://www.microchip.com/pagehandler...tools/mplabxc/

Sau khi cài xong, thường thì xc16 sẽ nằm ở /opt/microchip/xc16/. Nếu không có, bạn dùng lệnh này để tìm vị trí cài xc16

Code:
locate xc16-gcc
Ví dụ để biên dịch file main.c trong thư mục /home/username/project/main.c, mình dùng những lệnh sau trong terminal:

Code:
cd /home/username/project/
/opt/microchip/xc16/v1.25/bin/xc16-gcc main.c -mcpu=30F4011 -Wl,--script=p30F4011.gld
/opt/microchip/xc16/v1.25/bin/xc16-bin2hex a.out
mv a.hex main.hex
nếu bạn lưu file code C là tên khác hoặc bạn dùng dsPIC khác thì đổi tên ở dòng thứ 2.
Để tiện lợi thì tốt nhất bạn tạo một file text, với nội dung như sau, ví dụ lưu thành tên file là compile.sh

Nội dung file compile.sh
Code:
#!/usr/bin/bash
# This script compile file main.c into main.hex
# Use for XC16 and dsPIC30F4011.

/opt/microchip/xc16/v1.25/bin/xc16-gcc main.c -mcpu=30F4011 -Wl,--script=p30F4011.gld
/opt/microchip/xc16/v1.25/bin/xc16-bin2hex a.out
mv a.hex main.hex
Nếu bạn dùng Shell khác, ví dụ Korn Shell thì sửa dòng đầu tiên. Thường phổ biến hiện nay là Bash.

Sau đó cho file compile.sh quyền thực thi:

Code:
sudo chmod +x compile.sh
Mỗi khi soạn thảo xong file C, bạn cần biên dịch code, chỉ cần click đôi vào file compile.sh, hoặc gõ terminal:

Code:
./compile.sh
...là file main.c được biên dịch thành main.hex.
Để quá trình biên dịch dễ dàng không báo lỗi, bạn nên copy các file mô tả của dsPIC vào cùng thư mục với file C. Ví dụ mình đang lập trình dsPIC30F4011, mình copy 2 file p30F4011.h và p30F4011.gld vào cùng thư mục file main.c, vậy là ok không lo trình biên dịch báo lỗi không tìm đc file.

Cũng như trên, muốn biết file p30F4011.h hoặc gld nằm ở đâu, dùng lệnh

Code:
locate p30F4011.h
Thường nó nằm ở /opt/microchip/xc16/v1.25/support/dsPIC30F/h/

3. Để nạp vào dsPIC, mình dùng mạch PICkit2 và chương trình pk2cmd. Microchip có cung cấp source code ở đây, mình lấy về và cài. Hoặc trên Manjaro thì trong Repo có cái pk2cmd-plus. Nếu bạn dùng mạch nạp khác hoặc ứng dụng khác, thì chắc có cách riêng của nó. Pk2cmd có bản dành cho windows, mình biết là PICkit2 có GUI cho windows, nhưng dùng command line có cái hay của nó, rất nhanh và tự động hóa được một số bước.
Để nạp file main.hex vào dspic, mình dùng lệnh sau:

Code:
pk2cmd -P DSPIC30F4011 -M -F main.hex
Nếu bạn thấy lệnh dài quá thì đừng sợ, mình sẽ dùng "bí danh" để gọi nó mỗi lần cần cho ngắn. Mở file .bashrc trong thư mục home:

Code:
mousepad ~/.bashrc #Nếu dùng editor khác thì đổi tên lệnh chỗ này, ví dụ gedit ...
Thêm dòng sau vào cuối file:
Code:
alias pk="pk2cmd -PDSPIC30F4011 -M -F"
Lưu lại là ok. Mỗi lần cần nạp file main.hex vào dsPIC chỉ cần gõ:

Code:
pk main.hex
là đủ.

4. Về bootloader, để làm việc tiện lợi thật không thể thiếu nó. Mình cũng vò đầu bứt tai với tinybootloader trên linux. Mới đầu còn chưa hiểu tí gì về bootloader nên rất khó khăn.
Để "biên dịch" (assemble - dịch thế nào nhỉ?) file bootloader, mình sẽ dùng XC16 luôn. Và chỗ này là chỗ command line làm tốt việc còn GUI ko được nè.
Không rõ có phải thế không, nhưng có vẻ từ XC16 đã không còn cái gọi là ASM30 nữa, mà XC16 sẽ assemble ASM cho dsPIC luôn. Vì vậy bạn hoàn toàn có thể assemble cho dsPIC trên MPLABX, nhưng mình đã thử, và có một điểm khó chịu. Bootloader chỉ chiếm khoảng 87 words cuối của Flash dsPIC, nhưng khi assemble xong, lại lòi đâu ra thêm một đống lệnh từ địa chỉ 0x100 trở đi. Việc này làm cho bootloader không chay được bình thường. Vò đầu bứt tai thì ra là bởi XC16 chạy trên MPLABX, khi assemble nó lại đem một số "macro" của C ra dùng. Ở đoạn 0x100 là đoạn khởi tạo environment, stack các kiểu... Trong khi chúng ta không cần tới. Vì vậy mình đã thử tìm hiểu dùng command line xem sao. Kết quả rất OK. Như sau:

Tạo một file có tên asm.sh với nội dung như sau:
Code:
#!/usr/bin/bash
#This script to execute commands to assemble dsPIC .s file into Intel Hex file for burning later.
#Assembler:
#input file=tinybld_ds30F4011.s  
#output file=tinybld_ds30F4011.o with format ELF, also create a list file named tinybld_ds30F4011.lst
/opt/microchip/xc16/v1.25/bin/xc16-as -o tinybld_ds30F4011.o -p30F4011 -omf=elf -alsm -a=tinybld_ds30F4011.lst tinybld_ds30F4011.s


#Linker:
#input file=tinybld_ds30F4011.o
#output file=tinybld_ds30F4011.out
/opt/microchip/xc16/v1.25/bin/xc16-ld -omf=elf --script=p30F4011.gld --no-data-init tinybld_ds30F4011.o -o tinybld_ds30F4011.out

#[Optional] Dump the Linked Object file to a file to examine:
/opt/microchip/xc16/v1.25/bin/xc16-objdump tinybld_ds30F4011.out -D -s > tinybld_ds30F4011.objdmp

#Convert Linked Object file into Intel HEX file for dspic:
/opt/microchip/xc16/v1.25/bin/xc16-bin2hex tinybld_ds30F4011.out
Nếu dùng cho chip khác, thì bạn phải đổi tên chip trong code này. Đồng thời nếu tên file asm khác, thì cũng phải đổi tương ứng. Kết quả cho ra file hex có tên cùng tên file asm (mà microchip đặt đuôi là .s)
Cũng cho file này quyền thực thi:

Code:
sudo chmod +x asm.h
Để chạy, cũng như compile.sh, có thể double click, hoặc thực thi trong terminal
Code:
./asm.h
chương trình trên máy tính thì dùng Tiny Multi Bootloader+ (hỗ trợ rất nhiều chip không chỉ của microchip mà còn AVR, TI MSP...), và mã nguồn mở. Tức một cái là nó lại chạy trên windows, và viết bằng Visual. Muốn chạy trên linux phải dùng Mono (một lớp ảo hỗ trợ chạy ứng dụng windows. Sở dĩ không dùng Wine được mà phải dùng Mono vì Wine chưa hỗ trợ cổng USB). Ở đây: http://sourceforge.net/projects/tinypicbootload/

Tới đây là đủ để mình viết code cho dsPIC trên linux rồi. Mấy bạn quan tâm thì cho ý kiến góp ý và cùng sử dụng linux nhé.
Thực sự linux cực dễ dùng, và cái ý nguyện đằng sau linux và open source software, free software là rất hay. Mình từ bỏ windows được gần 10 năm rồi cũng vì thích linux. Làm việc với AVR, STM trên linux rất tự nhiên vì AVR chẳng hạn,, dùng trình biên dịch nguồn mở. Atmel hỗ trợ linux rất tích cực. Chỉ dạo gần đây thì Microchip mới bắt đầu ngó qua Linux, và việc MPLABX ra đời cho Linux là dấu hiệu tích cực của họ. Chương trình pk2cmd là do một nhóm người dùng-developer viết ra cho microchip thì phải. Cái này mình không biết rõ nên không dám chém nhưng có tò mò xem họ bàn về nó trên google group. Cái ý mình muốn nói khi viết bài này thì rõ ràng là xin các bạn hãy dùng linux. Trừ khi bạn có tiền mua bản quyền windows và các phần mềm trên đó. Còn không thì không có lý do gì không sử dụng linux cả (chà, trừ khi bạn mua máy MAC thì khác, mình chưa bao giờ rớ tới MAC nên không dám bàn). Bởi vì ở Linux, mình cảm thấy sự tự do mà mình khôg tìm được ở windows bản crack (và cả sự thư thản tâm hồn nữa ...vì mình không ăn cắp nữa).
Trên linux, muốn hiển thị data từ cổng serial chẳng hạn, cũng chỉ một lệnh trên terminal, và nó hiển thị trên terminal luôn.
Muốn vẽ đồ thì biểu diễn data nhận được theo thời gian thực, thì cũng chỉ cần vài lênh python. Và tất cả đều miễn phí. Ngay cả con máy Gateway LT27 cùi mía của mình còn chạy được linux, làm được những việc mình muốn làm như trên thì yeah, I love Linux.

thay đổi nội dung bởi: ttai, 15-09-2015 lúc 12:43 AM.
ttai vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 15-09-2015, 02:36 AM   #2
ttai
Đệ tử 1 túi
 
Tham gia ngày: Dec 2005
Bài gửi: 12
:
5. Để giao tiếp với cổng com, có thể dùng cutecom, hoặc chính bản thân terminal. Nếu dùng cutecom thì cũng tương tự với các chương trình khác. Ví dụ với terminal thôi:

Code:
#Thiết lập com /dev/ttyUSB0 với baudrate cần thiết, 
stty -F /dev/ttyUSB0 speed 115200 raw #raw tức là hiển thị tất cả, không dấu thứ gì

#Dùng lệnh cat để đưa chuỗi nhận được ra stdout (tức là màn hình terminal)
cat /dev/ttyUSB0

#Nếu muốn có thể cho chuỗi này vào một file định sẵn
cat /dev/ttyUSB0 > filename.txt
Với dữ liệu nhận được, để vẽ đồ thị theo thời gian thực thì cũng đơn giản với linux. Hãy dùng python. Trước đây mình dùng matplotlib nhưng cảm thấy matplotlib châm, không đáp ứng được yêu cầu thời gian thực, nên mình dùng thư viện pyqtgraph, download ở đây pyqtgraph.org

Code python:
Code:
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import serial
import numpy as np
ser=serial.Serial('/dev/ttyUSB1',115200)

win=pg.GraphicsWindow()
win.setWindowTitle('DC motor speed display using PyQtGraph')

p1=win.addPlot()
p2=win.addPlot()
data1=[]
curve1=p1.plot(data1,pen=(255,255,0),name='Speed (RPM)')
curve2=p2.plot(data1,pen=(0,255,255))
ptr1=0
def update():
	global data1, curve1, ptr1
	speed=float(ser.readline())
	data1.append(speed)
	ptr1+=1
	curve1.setData(data1)
	curve2.setData(data1)
	curve2.setPos(ptr1,0)
	if ptr1>50:
		del data1[0]

timer=pg.QtCore.QTimer()
timer.timeout.connect(update)
timer.start(50)

## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()
Trong code python này mình dùng 2 plot để thử vẽ 2 đồ thị cùng một lúc, tuy nhiên luồng data thì chỉ có 1, chưa có thời gian làm nữa. Các bạn thử xem. Do chỉ có một luồng data cần vẽ biểu đồ nên khi gửi lên python không cần xử lý chuỗi nữa. Nếu có cần xử lý chuỗi trên python cũng không có gì phức tạp.

Đây là đồ thị thời gian thực, đáp ứng rất nhanh theo thực tế ở mạch điều khiển. Code python trên nếu chiu khó tinh chỉnh sẽ cho ra đồ thị đẹp và chuyên nghiệp hơn. Nếu muốn đẹp hơn nữa thì matplotlib, nhưng matplotlib khá chậm, không đáp ứng được yêu cầu thời gian thực.

ttai vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Trả lời


Quyền Sử Dụng Ở Diễn Ðàn
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is Mở
Smilies đang Mở
[IMG] đang Mở
HTML đang Tắt

Chuyển đến


Múi giờ GMT. Hiện tại là 05:34 PM.


Được sáng lập bởi Đoàn Hiệp
Powered by vBulletin®
Page copy protected against web site content infringement by Copyscape
Copyright © PIC Vietnam