Thư viện giao tiếp RS232 cho PIC18 bằng HTPIC18

May 3, 2009

Đây là thư viện viết cho vi điều khiển PIC dòng PIC18 bằng HTPIC. Thư viện được tạo dựa vào Datasheet của PIC18.

Đã test với PIC18F4680, PIC18F4431

File Header: UART.h

// UART.h
//============================
#ifndef _UART_H
#define _UART_H
//=============================
#include "pic18.h"
#include "sysdef.h"
//=============================
// Declare sosme functions
void UART_Init(unsigned int BaudRate);	// Initialize for UART
void UART_PrChar(unsigned char a);
void UART_PrString(const char* str);
unsigned char UART_Read(void);		// Read data from UART Port
void UART_detectBaudRate(void);		// Auto detect baud rate
#endif

Giải thích các hàm:

  • UART_Init: Khởi tạo module giao tiếp UART, tham số là tốc độ truyền BaudRate. Ví dụ: UART_Init(9600)
  • UART_PrChar: Gửi một kí tự ra cổng RS232. Ví dụ: char x = 'a'; UART_PrChar(x);
  • UART_PrString(const char* str): gửi 1 xâu kí tự ra cổng RS232. Ví dụ: UART_PrString("Anh yeu em");
  • unsigned char UART_Read(void) : Đọc 1 byte từ cổng COM
  • UART_detectBaudRate(void): Tự động xác định tốc độ baudrate được truyền xuống PIC18, Master phải truyền kí tự 'U' để PIC18 tự xác định và thiết lập tốc độ (cái này có trong datasheet nhá :) )

File thực thi: UART.c

// UART.C
# include "UART.h"
# include "pic18.h"
# include "sysdef.h"
// Initialize UART
void UART_Init(unsigned int BaudRate){
	unsigned int n;
// Configure BaudRate
	BRGH = 0; 				// Low speed.
	BRG16 = 1;				// 16-Bit Baud Rate Generator - SPBRGH and SPBRG
	// Baudrate = Fosc/[16(n+1)]  => n = ((Fosc/Baudrate)>>4) - 1;  n = SPBRGH: SPBRG;
	n = ((Fosc/BaudRate)>>4) - 1;
	SPBRG = n;
	SPBRGH = n>>8;
// Enable the asyncchronous serial port.
	SYNC = 0 ;				// Asynchronous mode
	SPEN = 1;				// Serial port enable.
	TRIS_TX = 0;
	TRIS_RX = 1;
//Configure for Transmitter mode.	
 
	TXEN  = 1; 				// Transmit enable
//Configure for Receiver mode
	CREN = 1;				// Enable the reception
//Interrupt
	RCIF = 0;
	RCIE = 1;				// Reception Interrupt Enable
	GIE = 1;				// Global Interrupt Enable
	PEIE = 1;				// Perapheral Interrupt Enable
 
}
//===========================
 
void UART_PrChar(unsigned char a){
	while(!TRMT);
	TXREG = a;
}
//====================================
void UART_PrString(const char* str){
	while(*str)
		UART_PrChar(*str ++);}
//=================================================
unsigned char UART_Read(void){
	return (RCREG);
}
//===============================================
void UART_detectBaudRate(void){
	TXSTA 	= 0b00100100;
	RCSTA 	= 0b10010000;
#if defined(_18F4680)
	BAUDCON = 0b00001001;
#endif
#if defined(_18F4431)
	BAUDCTL = 0b00001001;
#endif
	while(ABDEN){
#if defined(_18F4680)
		if(ABDOVF == 1) ABDOVF = 0;
#endif
	};
}

Tất cả tham số của bộ UART được định nghĩa trong SysDef.h của mình:

// SysDef.h
//
// System Defination for specific IC
//
#ifndef SYSDEF_H
#define SYSDEF_H
// Crystal
#define	Fosc	20000000	
 
// UART Module
#define TX			RC6
#define RX 			RC7
#define TRIS_TX		TRISC6
#define TRIS_RX		TRISC7
 
#define	UART_Data	TMR1H	// UART Data temporary
 
#endif // EOF

Tải thư viện về: PIC18_UART_LIb (920)

Cách dùng thư viện

Copy các file thư viện này vào trong thư mục Project của bạn, ở file nào muốn dùng thư viện thì thêm header vào:

#include "UART.h"

Chúc các bạn thành công.

Các bài viết liên quan:

  1. PIC16F887 Điều khiển thời gian đóng cắt một led từ PC qua UART Chào các bạn. Nay ngồi code cho con PIC16F887 để điều khiển đèn halogen, thực ra chính là điều khiển một chân rồi qua TIP122 và relay để điều khiển đèn thôi (vì dòng tải lên tới 10A). Mình thấy cách viết hay nên chia sẻ với các bạn. Dùng để lưu trữ luôn. Để [...]...
  2. Phan tich thuat toan: thuc hien lenh dieu khien tu PC qua RS232 Chào các bạn. Không biết ai đã đọc bài viết của mình PIC16F887 – Điều khiển thời gian đóng cắt một led từ PC qua UART chưa. Trong này, mình có thực hiện đặt thời gian đóng cắt từ PC bằng lệnh với cú pháp. Txyzt#: trong đó  xyzt là thời gian tính theo hệ [...]...
  3. Hướng dẫn lập trình giao tiếp RS232 trên PC bằng Visual C++ 6.0 Chào các bạn. Để cho website của mình thêm phong phú, nên mình cập nhật thêm một số tài liệu mà mình đã viết ở các diễn đàn điện tử. Có thể bản quyền vẫn thuộc về diễn đàn, nhưng mình nghĩ đây chỉ là sự chia sẻ cho những người chưa biết, chưa hiểu [...]...
  4. Lập trình giao tiếp RS232 qua Matlab Chào các bạn. Mình xin tổng hợp lại một số bài viết của mình về lập trình giao tiếp RS232 trên PC bằng phần mềm Matlab. I. Đối tượng Serial Object Việc giao tiếp này cũng rất dễ dàng thực hiện, không có gì là quá cao siêu cả. Mình đã giao tiếp thành công [...]...
  5. Quản lý và build Project với trình dịch HTPIC bằng Visual C++.Net 2005 Chào các bạn. Bài này mình viết lâu rồi nhưng thấy rất hay nên post lại cho các bạn. Các bạn dùng qua Visual C++ 6.0 và Visual C++.Net đều thấy tác dụng quản lý Project và gợi ý code rất là hay. Khi dùng ta sẽ không sợ quên hàm này, hàm kia.Quản lý [...]...
  6. Mã nguồn bài toán tìm số nguyên tố bằng C Bài này mình viết khi học môn Kỹ thuật Lập trình của thầy Hoàng Minh Sơn, để tìm N số nguyên tố đầu tiên với thuật toán tối ưu. Các bạn xem nhé, lấy làm tham khảo, ai có ý kiến ý cò gì thì cứ cho nhé :d. Nay mở lại các email đã [...]...

{ 6 comments… read them below or add one }

nguễn văn bách May 10, 2009 at 10:19 am

anh bắc cho em hỏi bài này cái.em mới vào nghề.em đang đọc về ngắt của con dspic,thử lập trình ngắt cho nháy đèn led từ 0-9 cho nó.chương trình của em gặp vấn đề thì phải,vì khi em thay đổi giá trị của PR1 thì thời gian nháy vẫn thế.nó vẫn nháy loạn lên.vậy mong các anh sửa giúp em với,và tư vấn cho em chút it về ngắt,khi nao` su dung ngat trong va khi nao su dung ngat ngoai.sau đây là đoạn chương trình của em:
#define __dsPIC33FJ12MC202__
#include
int led[10]={0x3F,0×06,0x5B,0x4F,0×66,0x6D,0x7D,0×07,0x7F,0×6 7};
int i;
void _ISR _T1Interrupt(void)
{
_T1IF = 0;
}
main()
{
TMR1=0;
PR1=0x2625A; //cho phep ngat sau 1 giay
T1CON=0×8030; //chon ti le dem trc la 256
_T1IF=0; //xoa co ngat TMR1
_T1IE=1; //cho phep ngat
TRISB=0xff00;
while(1)
{
for (i=0;i<10;i++)
{
PORTB=led[i];
}
}

Reply

ngohaibac May 11, 2009 at 8:38 am

Em thay PR1 thì có ảnh hướng gì ở đây đâu hả em. Em phải viết lệnh thay đổi PORTB ở trong hàm xử lý ngắt chứ em. Em viết trong while(1) thì PORTB luôn luôn sáng rồi :) .

Chúc em thành công.

Reply

Minh Toan November 19, 2009 at 2:15 pm

Anh Bắc cho em hỏi cái này,
Em có cái cảm biến truyền dữ liệu về theo dạng bất đồng bộ. Frame truyền: 1 Start, 8 Data, No Parity, 1 Stop. Tốc độ truyền 19200 baud. Dữ liệu truyền từ cảm biến về theo chuẩn Acsii.
Em muốn dùng con Atmega128 để đọc dữ liệu từ cảm biến về atmega này thì thực hiện như thế nào? Ví dụ cho cảm biến kết nối vào chân RxD0 va TxD0 của Atmega128.
Cám ơn anh.

Reply

ngohaibac November 19, 2009 at 10:41 pm

Chào em.

Cái này là em phải học khi em làm AVR chứ, sao lại hỏi anh thực hiện như thế nào nhỉ ? Nó chỉ là giao tiếp RS232 bình thường thôi mà.

Chúc em thành công.

Reply

makoto January 26, 2010 at 1:12 pm

Mình đang muốn dùng 18F4550 lấy mẫu ADC rồi copy kết quả vào 512 byte, gửi đến slave 18F4431. Slave nhận hết 512 byte thì lọc dữ liệu ra để xử lý, xử lý xong nhận tiếp….Nhưng không biết làm sao để gửi và nhận chính xác được ? Phải khai báo gửi nhận chuỗi thế nào cho 18F4550 và 18F4331 ??

Reply

Trần Hữu Trung July 9, 2010 at 9:23 am

Chào anh!
từ hôm bắt đầu học PIC tới h; tìm cái ji cũng thấy bài của anh,anh pro quá hehehe.
anh giúp em cái này với: trong khai báo_CONFIG(n,x) của HTPIC, n và x là gì vậy, có cách nào khai báo khác ko?

Reply

Leave a Comment

Previous post:

Next post: