PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   Giao tiếp USB, CAN, I2C, SPI, USART... (http://www.picvietnam.com/forum/forumdisplay.php?f=45)
-   -   Đồ án giao tiếp CAN - Cần giúp đỡ (http://www.picvietnam.com/forum/showthread.php?t=17406)

vaa_pic 05-05-2012 09:50 AM

Đồ án giao tiếp CAN - Cần giúp đỡ
 
1 Attachment(s)
Em đang làm đồ án về giao tiếp can cần được giúp đỡ về lập trình.
Về phần cứng thì em có mạch gồm PIC6F887 + MCP2515 + MCP2551 và LCD hiển thị (Sơ đồ mạch trong file CAN Demo.pdf đính kèm)

Về code thì em viết như sau:

Code:

#include <htc.h>
#include <stdlib.h>
#include <ctype.h>
#include "LCD.c"
#include "MCP2515.c"
#include "MCP2515.h"

#define _XTAL_FREQ        20000000

__CONFIG ( FOSC_HS & WDTE_OFF & PWRTE_OFF & MCLRE_ON & CP_OFF & CPD_OFF & BOREN_OFF & IESO_OFF & FCMEN_ON & LVP_OFF & DEBUG_OFF );

unsigned char command;


void init()
{
        unsigned char temp;

        // ======================= Cau hinh cac chan vao ra cho PIC ==========================
        ANSEL = 0x00;
        TRISA = 0x00;
        ADCON1 = 0x07;
        PORTA = 0x00;
        TRISE = 0x00;
        PORTE = 0x00;
        TRISD = 0x07;
        PORTD = 0x08;        // Put RD3 (CS) in high level

        TRISB = 0x00;        // test       
        PORTB = 0x00;        // test
        // ====================================================================================

        // ============================ Cau hinh module SPI ===================================
        // Enabling SPI I/O
        TRISC = 0x10;                // SDO, SCK -> output
        SSPEN = 0;                        // Turn off SPI
       
        SMP = 0;                        // Sample bit

        // CPI Mode 0,0
        CKP = 0;                        // Clock polarity select bit: low
        CKE = 1;                        // SPI Clock Edge Select bit
        WCOL = 0;                        // Write collision detect bit
        SSPOV = 0;                        // Receive overflow indicator bit

        SSPM3 = 0;                        // Synchronous Serial Port Mode select bit
        SSPM2 = 0;                        // SPI master mode, Fosc/64 ~ 20MHz/64
        SSPM1 = 1;                        //
        SSPM0 = 0;                        //       

        SSPEN = 1;                        // Turn on SPI
        //temp = SSPBUF;                // to clear BF bit!
        // ====================================================================================/

       
        // ============================ Khoi tao LCD ==========================================
        lcd_init();
        // ====================================================================================

        mcp_reset();                // reset MCP2515
        mcp_write(MCP_CANCTRL, MODE_CONFIG);        // Cau hinh che do hoat dong : CONFIG
        mcp_write(MCP_RXM0SIDH, 0x00);                        // Cau hinh mat na cho RXB0
        mcp_write(MCP_RXM0SIDL, 0x00);                        // Cau hinh mat na cho RXB0
        mcp_write(MCP_TXRTSCTRL, 0x00);                // Cau hinh cac chan RTS cua MCP2515
        mcp_write(MCP_CANCTRL, MODE_LOOPBACK);        // Cau hinh che do hoat dong : LOOPBACK
}

void MCP_Send(unsigned char c)
{
        MCP_CS = 1;
        mcp_write(MCP_TXB0CTRL, 0x02);        // Cau hinh do uu tien cua goi tin TXP0 & TXP1
        mcp_write(MCP_TXB0SIDH, 0x00);        // Cau hinh ID cua goi tin
        mcp_write(MCP_TXB0SIDL, 0x00);        // Cau hinh ID cua goi tin
        mcp_write(MCP_TXB0DLC, 0x08);        // cau hinh so luong byte cua goi tin
        mcp_write(MCP_TXB0D0, c);                // Byte du lieu 0
        mcp_write(MCP_TXB0D1, 0x02);
        mcp_write(MCP_TXB0D2, 0x03);
        mcp_write(MCP_TXB0D3, 0x04);
        mcp_write(MCP_TXB0D4, 0x05);
        mcp_write(MCP_TXB0D5, 0x06);
        mcp_write(MCP_TXB0D6, 0x07);
        mcp_write(MCP_TXB0D7, 0x08);
        mcp_rts(0x01);                                // Bat bit TXB0CTRL.TXREQ
}

void main()
{
        init();
        lcd_gotoxy(1,0);
        lcd_puts("CAN Demo Board ");
        lcd_gotoxy(1,1);
        lcd_puts("Firmware v1.01");
        __delay_ms(500);

        while(1)
        {
                command = 0;
                if (!RD0) command = command + 0x11;
                if (!RD1) command = command + 0x22;
                if (!RD2) command = command + 0x44;
                MCP_Send(command);
                lcd_gotoxy(0,0);
                lcd_puts(" Tx: ");
                lcd_put_binary(command);
                command = 0;

                lcd_gotoxy(0,1);
                lcd_puts(" Rx: ");
                command = mcp_read(MCP_TXB0D0);
                lcd_put_binary(command);

                __delay_ms(10);
        }       
}

Một số hàm trong thư viện MCP2515.c em viết như sau:

Code:

void mcp_reset()
{
        unsigned char temp;
       
        MCP_CS = 0;
        SSPBUF = 0xC0;
        while(!BF);
        temp = SSPBUF;
        SSPIF = 0;
       
        SSPBUF = 0x00;
        while(!BF);
        temp = SSPBUF;
        SSPIF = 0;
       
        MCP_CS = 1;       
}

void mcp_write(unsigned char addr, unsigned char data)
{
        unsigned char temp;
        temp = SSPBUF;        // doc du lieu trong SSPBUF ra de xoa bit BF
        MCP_CS = 0;

       
        SSPBUF = 0x02;        // Write command
        while(!BF);
        temp = SSPBUF;
        SSPIF = 0;
       
        SSPBUF = addr;        // write addr
        while(!BF);
        temp = SSPBUF;
        SSPIF = 0;
       
        SSPBUF = data;        // write data               
        while(!BF);
        temp = SSPBUF;
        SSPIF = 0;       
       
        SSPBUF = 0x00;        // push data out of SSPSR
        while(!BF);
        temp = SSPBUF;
        SSPIF = 0;

        MCP_CS = 1;
}

void mcp_rts(unsigned char txn)
{
        unsigned char temp;
        temp =SSPBUF;
        SSPIF = 0;

        temp = 0x80 + txn;
       
        if (temp >= 0x81 && temp <= 0x87){        // kiem tra lenh co hop le hay khong
                MCP_CS = 0;
                SSPBUF = temp;
                while(!BF);
                temp = SSPBUF;
                SSPIF = 0;
                MCP_CS = 1;
        }
}

unsigned char mcp_read(unsigned char addr)
{
        unsigned char temp;

        MCP_CS = 0;
       
        SSPBUF = 0x03;        // read command
        while(!BF);
        temp = SSPBUF;
        SSPIF = 0;
       
        SSPBUF = 0x00;       
        while(!BF);
        temp = SSPBUF;
        SSPIF = 0;

        MCP_CS = 1;
       
        return(temp);
}

Vấn đề của em là khi em thực hiện mô phỏng trên Proteus thì ngõ ra SCK và SDO đều có tín hiệu nhưng khi nạp vào mạch thật thì không đọc được giá trị các thanh ghi như mong muốn, nó chỉ hiển thị giá trị đọc về là 0b00000000.
Như vậy lỗi của em là lỗi ở phần giao tiếp SPI hay lỗi cấu hình MCP2515 không đúng ? Nhờ các bác đã làm qua cái này chỉ giúp em.

vaa_pic 07-05-2012 01:17 AM

Hình như em đã nối sai chân SPI, đúng ra phải là SDI --> SO và SDO --> SI. Đã sửa lại và thử nạp code. Vẫn không chạy, vậy là sao nhỉ ?
Thử đo tín hiệu SDO trên PIC thì vẫn thấy kim đồng hồ nhảy lên nhảy xuống nhưng chân SCK thì khi có khi không ? Tại sao ?

P.S: post topic mà không có ai giúp đỡ, nản quá!

clarkcao 29-05-2012 01:28 PM

pic877 có hỗ trợ CAN hả bạn mình cũng đang làm cái CAN @@

clarkcao 29-05-2012 01:49 PM

mà mình thấy dòng 18f mới hỗ trợ CAN

vaa_pic 02-06-2012 11:33 AM

Trích:

Nguyên văn bởi clarkcao (Post 64956)
mà mình thấy dòng 18f mới hỗ trợ CAN

đúng rồi PIC6F887 không hỗ trợ CAN, dòng 16F hình như không có con nào hỗ trợ CAN. Dòng 18F thì có con 18F458, 18F4580....
Phần cứng này mình dùng PIC6F887 + MCP2515 + MCP2551. Bạn có thể dùng PIC12F cũng ok, miễn là có giao tiếp SPI.

hein_ts 18-06-2012 10:32 PM

Không có SPI cứng thì có thể dùng SPI mềm mà?

thaihevip 27-06-2012 05:29 PM

Hiện nay mình có các mạch điện sau:
1.Giải mã remote sony điều khiển các thiết bị điện từ xa,mạch đã chạy ngon,đã từng bán ra thị trường.
2.Giải mã pt2262/pt2272 điều khiển thiết bị từ xa bằng sóng RF
3.Giải mã pt2248/pt2249 điều khiển thiết bị từ xa dùng sóng hồng ngoại
4.Lập trình đồng hồ có phím chỉnh giờ,phút,giây,hẹn giờ.
5.Lập trình điều khiển led đơn,tạo và thay đổi cường độ sáng cho led,lập trình sáng dồn,sáng chạy,sáng dần 32 led,...
6.Lập trình điều khiển hệ thống đèn giao thông
7.Lập trình chạy chữ trên led ma trận
8.Lâp trình giao tiếp máy tính
9.Lập trình và làm mạch điều khiển xe từ xa,điều khiển động cơ DC
10.Lập trình và điều khiển volume từ xa
11.Dạy vẽ hình ảnh,dạng sóng,đồ thị hàm số,hệ mặt trời và các hành tinh đang chuyển động trên Pascal,C,C++,C#
12.Dạy lập trình vi điều khiển
13.Dạy lập trình PLC bằng ngôn ngữ LAD
14.Dạy vẽ mạch in trên phần mềm protues,vẽ bằng tay,vẽ tự động,tạo chân linh kiện.
15.Làm mạch nguồn hạ áp trực tiếp không dùng biến áp
16.Lập trình làm đồng hồ thời gian thực giao tiếp ds1307,làm đồng hồ vạn niên,lập trình trên 8051 và pic.
17.Hướng dẫn sử dụng các phần mềm liên quan.Bao gồm các phần mềm lập trình cho chip,các phần mềm lập trình hình ảnh và các phần mềm mô phỏng,vẽ mạch in,vẽ mạch nguyên lý.
18.Hiển thị ký tự,hiển thị số đếm trên LCD
...
số phone liên hệ: 0166.495.1093


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