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

Đâ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ề: [download id="15"]

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.

{ 8 comments… add one }
  • nguễn văn bách May 10, 2009, 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,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6 7};
    int i;
    void _ISR _T1Interrupt(void)
    {
    _T1IF = 0;
    }
    main()
    {
    TMR1=0;
    PR1=0x2625A; //cho phep ngat sau 1 giay
    T1CON=0x8030; //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, 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
      • thuquynh April 7, 2012, 11:07 pm

        anh bắc cho em xem ngang với ạ.
        em đang lập trình arm trên vđk lpc2378 của kit mcb2300. vấn đề là em muốn truyền cả 1 xâu ký tự từ máy tính xuống thì làm thế nào ạ(em đã truyền được từng byte rồi). em đang vẫn chưa hiểu, mong anh giúp em.gmail của em thuquynh89@gmail.com
        cảm ơn anh rất nhiều!!

        Reply
        • thuquynh April 7, 2012, 11:11 pm

          đây là phần nhận data
          int getkey( void)
          {
          while(!(U1LSR & 0x01));
          return(U1RBR);
          }
          mong anh sớm trả lời cảm ơn anh

          Reply
  • Minh Toan November 19, 2009, 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, 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, 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, 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