Professional Documents
Culture Documents
Training
Training
Training
Tài liệu
Hướng dẫn lập trình
Vi điều khiển PIC16LF15376
www.rpc.vn
Training
Mục lục
www.rpc.vn
Training
www.rpc.vn
Training
www.rpc.vn
Training Page 1
www.rpc.vn
Training Page 2
www.rpc.vn
Training Page 3
Hình 1. 2 Sơ đồ nguyên lý
UNI Bus
Hình 1. 3 Unibus
Hình 1. 4 PIC16LF15376
www.rpc.vn
Training Page 4
1. GPIO
Dự án đầu tiền sử dụng nút nhấn BT1 là Input và đèn LED1 là Output
Nhấn và giữ nút BT1 làm LED1 sáng, khi nhả tay ra thì LED1 tắt
www.rpc.vn Page 4
Training Page 5
Mở Pin Manager: Gird View. Chọn ổ khóa RA5 ở hàng input của Pin Module
để đặt pin RA5 là input tương tự chọn ổ khóa RE0 ổ hàng output để đặt pin
RE0 là output
Đóng cửa sổ Pin Manager: Grid View. Sau đó, bấm chuột vào Pin Module ở
trong Project Resources area
Phần trung tâm sẽ hiển thị RE0 và RA5 được liệt kê trên biểu đồ I / O.
RE5 sẽ là đầu vào sẽ đọc công tắc.
RA5 sẽ là một đầu ra và điều khiển đèn LED. Nhấp vào hộp Output để tạo
đầu ra ghim và tích vào hộp Analog để tạo đầu ra tương tự.
Thay đổi tên của các chân thành LED1 cho RA5 và SW1 cho RE0.
www.rpc.vn Page 5
Training Page 6
Trong phần này, cài đặt bộ dao động và cài đặt cấu hình được chọn.
Bộ tạo dao động
Chọn HFINTOSC từ menu thả xuống Oscillator Select.
Chọn lựa chọn 8MHz từ menu thả xuống HF Internal Clock.
Chọn giá trị Clock Driver là 4.
Điều này sẽ kích hoạt bộ dao động nội bộ 2 MHz bên trong hoạt động
như là xung đồng hồ hệ thống.
Ngoài ra, hãy đảm bảo rằng chế độ Low-voltage Programming Enable được
chọn ở cuối màn hình Module System.
Note : Cấu hình của System Module này được sử dụng ở tất cả dự án của
nội dung Training
Nhấp vào nút Generate để MCC tạo thư viện phần mềm cho dự án này.
www.rpc.vn Page 6
Training Page 7
Dự án bây giờ sẽ có cả Header Files và Source Files được tạo. Nó cũng phải có
một tệp main.c được tạo
Nhấp đúp vào tệp main.c để mở tệp đó trong cửa sổ trình chỉnh sửa:
www.rpc.vn Page 7
Training Page 8
www.rpc.vn Page 8
Training Page 9
2. Button
www.rpc.vn Page 9
Training Page 10
www.rpc.vn Page 10
Training Page 11
Main.c
#include "mcc_generated_files/mcc.h"
uint8_t button(uint8_t numbutt) //hàm button lưu trạng thái nút nhấn
{
static uint8_t press=0;
if(numbutt == 0 && press == 0)
{
press = 1;
return 1;
}
else if(numbutt == 1)
{
press = 0;
}
return 0;
}
void main(void)
{
// initialize the device
SYSTEM_Initialize();
// Enable the Global Interrupts
INTERRUPT_GlobalInterruptEnable();
// Enable the Peripheral Interrupts
INTERRUPT_PeripheralInterruptEnable();
IOCAF5_SetInterruptHandler(led_toggle); // RA5 Interrupt-on-change
while (1)
{
CLRWDT();
// Add your application code
if(button(SW2_GetValue())) // Đọc trạng thái BT2
{
LED2_Toggle();
}
}
}
www.rpc.vn Page 11
Training Page 12
3. Timer
Dự án sử dụng LED1
LED1 sẽ bật/tắt liên tục trong 1s
www.rpc.vn Page 12
Training Page 13
www.rpc.vn Page 13
Training Page 14
Main.c
#include "mcc_generated_files/mcc.h"
void main(void)
{
// initialize the device
SYSTEM_Initialize();
www.rpc.vn Page 14
Training Page 15
Dự án sử dụng Timer1 làm bộ đếm Counter, LCD 16x2 để hiển thị bộ đếm
số thập phân và nút nhấn BT1 làm T1CKI cho bộ đếm
Khi nhấn BT1 bộ đếm sẽ đếm lên 1 lần
Nhấn BT3 bộ đếm sẽ được làm mới
Sơ đồ nguyên lý
www.rpc.vn Page 15
Training Page 16
Hình 2. 21 Cấu hình Pin Manager Gird View của Counter and LCD
www.rpc.vn Page 16
Training Page 17
www.rpc.vn Page 17
Training Page 18
LCD.h
#include <xc.h>
#include "pin_manager.h"
#define LCD_RS LCD_RS_LAT
#define LCD_E LCD_E_LAT
#define LCD_DB4 LCD_DB4_LAT
#define LCD_DB5 LCD_DB5_LAT
#define LCD_DB6 LCD_DB6_LAT
#define LCD_DB7 LCD_DB7_LAT
LCD.c
#include "LCD4bit.h"
#include "device_config.h"
www.rpc.vn Page 18
Training Page 19
www.rpc.vn Page 19
Training Page 20
Main.c
#include "mcc_generated_files/mcc.h"
#include "mcc_generated_files/LCD4bit.h"
char LCD_print[20];
uint16_t previous=0;
void main(void)
{
// initialize the device
SYSTEM_Initialize();
INTERRUPT_GlobalInterruptEnable();
INTERRUPT_PeripheralInterruptEnable();
LCD_Init();
sprintf(LCD_print, "Bo dem :%u",TMR1_ReadTimer()); //print counter
LCD_gotoxy(0,0);
LCD_String(LCD_print);
while (1)
{
CLRWDT();
www.rpc.vn Page 20
Training Page 21
www.rpc.vn Page 21
Training Page 22
Hình 3. 2 Kích thước board và chức năng pin của module L298N
Unibus
www.rpc.vn Page 22
Training Page 23
Hình 3. 5 Cấu hình Pin Manager Gird View của dự án điều khiển động cơ
www.rpc.vn Page 23
Training Page 24
www.rpc.vn Page 24
Training Page 25
Main.c
#include "mcc_generated_files/mcc.h"
void main(void)
{
SYSTEM_Initialize();
while (1)
{
CLRWDT();
if(SW1_GetValue()==0) //reverse motor
{
if(((uint16_t)(PWM3DCH << 2) | (uint16_t)(PWM3DCL>>6))<=0)
{
PWM3_LoadDutyValue((uint16_t)(PWM4DCH << 2) | (uint16_t)(PWM4DCL>>6));
PWM4_LoadDutyValue(0x00);
}
www.rpc.vn Page 25
Training Page 26
else
{
PWM4_LoadDutyValue((uint16_t)(PWM3DCH << 2) | (uint16_t)(PWM3DCL>>6));
PWM3_LoadDutyValue(0x00);
}
__delay_ms(500);
}
www.rpc.vn Page 26
Training Page 27
Cảm biến ánh sáng xung quanh và cảm biến tiệm cận Mô-đun này bao gồm
cảm biến ánh sáng xung quanh, cảm biến tiệm cận quang học và đèn LED hồng
ngoại. Nó cho phép giảm mức tiêu thụ hiện tại và / hoặc cải thiện khả năng
hiển thị của màn hình trong môi trường sáng.
www.rpc.vn Page 27
Training Page 28
www.rpc.vn Page 28
Training Page 29
www.rpc.vn Page 29
Training Page 30
www.rpc.vn Page 30
Training Page 31
Khai báo địa chỉ giao tiếp I2C với RPR-0521RS sensor :
www.rpc.vn Page 31
Training Page 32
www.rpc.vn Page 32
Training Page 33
www.rpc.vn Page 33
Training Page 34
Main.c
#include "mcc_generated_files/mcc.h"
#include "mcc_generated_files/examples/i2c1_master_example.h"
#define RPR_0521RS_ADDRESS 0x38
uint8_t getdata[10];
www.rpc.vn Page 34
Training Page 35
void main(void)
{
printf("Hello\n");
Proximity_Sensor_Init();
Proximity_Interupt_Init (0x05);
Set_PS_ThresholdHigh(1500);
__delay_ms(300);
while (1)
{
CLRWDT();
//GetdataProximitySensor(getdata, 0x44, 2);
//printf("%u\n", (getdata[1]<<8) | (getdata[0]));
if(INT_GetValue() == 0)
{
LED1_SetHigh();
}
else
{
LED1_SetLow();
}
__delay_ms(300);
}
}
#include “mcc_generated_files/examples/i2c1_master_example.h”
www.rpc.vn Page 35
Training Page 36
2. ADC Sensor
www.rpc.vn Page 36
Training Page 37
www.rpc.vn Page 37
Training Page 38
www.rpc.vn Page 38
Training Page 39
Main.c
#include "mcc_generated_files/mcc.h"
uint16_t result_ADC;
/*
Main application
*/
void main(void)
{
SYSTEM_Initialize();
while (1)
{
CLRWDT();
// Add your application code
result_ADC = ADC_GetConversion(channel_ANB4); // Đọc ADC
printf("%u\n",result_ADC); // in ra giá trị đọc được
if(result_ADC <= 100 )
{
printf("Detect light\n");
}
__delay_ms(200);
}
}
www.rpc.vn Page 39
Training Page 40
3. EEPROM 25AA1024
www.rpc.vn Page 40
Training Page 41
www.rpc.vn Page 41
Training Page 42
www.rpc.vn Page 42
Training Page 43
’
Hình 4. 23 Cấu hình module EUSART1 của dự án EEPROM 25AA1024
www.rpc.vn Page 43
Training Page 44
Hình 4. 25 Cấu hình các bit hướng dẫn của EEPROM 25AA1024
www.rpc.vn Page 44
Training Page 45
www.rpc.vn Page 45
Training Page 46
uint8_t Read_StatusRegister(void)
{
uint8_t Stt;
SPI1_Open(SPI1_DEFAULT);
CS_SetLow();
SPI1_ExchangeByte(0b00000101);
Stt = SPI1_ExchangeByte(0x00);
CS_SetHigh();
__delay_ms(100); // Trel >100us
SPI1_Close();
return Stt;
}
www.rpc.vn Page 46
Training Page 47
www.rpc.vn Page 47
Training Page 48
}
void Chip_Erase (void)
{
SPI1_Open(SPI1_DEFAULT);
CS_SetLow();
SPI1_ExchangeByte(0b11000111);
CS_SetHigh();
__delay_ms(100); // Trel >100us
SPI1_Close();
}
Main.c
#include "mcc_generated_files/mcc.h"
#include <stdio.h>
#include <string.h>
#define FALSE_SYNTAX_ADDRESS 1
#define FALSE_SYNTAX_DATA 2
#define FALSE_SYNTAX_LENGTH 3
#define DATA_EMPTY 4
#define FALSE_SYNTAX_REG_VALUE 5
char receive[64];
uint8_t receive_SPI[64];
uint8_t transmitt_SPI[64];
uint32_t addressUART=0;
uint8_t dataUART[64];
uint8_t datareg=0;
uint16_t lengthUART;
www.rpc.vn Page 48
Training Page 49
uint8_t error1;
uint8_t error2;
uint8_t error3;
uint8_t error4;
www.rpc.vn Page 49
Training Page 50
CS_SetHigh();
__delay_ms(100); // Trel >100us
SPI1_Close();
}
www.rpc.vn Page 50
Training Page 51
www.rpc.vn Page 51
Training Page 52
SPI1_ExchangeByte(0b11000111);
CS_SetHigh();
__delay_ms(100); // Trel >100us
SPI1_Close();
}
if(typenum==1)
{
i=i+2;
t=i;
while(t<64&&in[t]!=',')
{
if((in[t]<'0'||in[t]>'9')&&(in[i]<'A'|| in[i]>'F')&&(in[i]<'a'|| in[i]>'f'))
{
return FALSE_SYNTAX_ADDRESS;
}
t++;
}
while(((in[i]>='0'&& in[i]<='9')||(in[i]>='A'&& in[i]<='F')||(in[i]>='a'&& in[i]<='f'))&&i<64)
{
char img_in = in[i];
www.rpc.vn Page 52
Training Page 53
switch(img_in)
{
case 'A':
img_in = 10+48;
break;
case 'B':
img_in = 11+48;
break;
case 'C':
img_in = 12+48;
break;
case 'D':
img_in = 13+48;
break;
case 'E':
img_in = 14+48;
break;
case 'F':
img_in = 15+48;
break;
case 'a':
img_in = 10+48;
break;
case 'b':
img_in = 11+48;
break;
case 'c':
img_in = 12+48;
break;
case 'd':
img_in = 13+48;
break;
case 'e':
img_in = 14+48;
break;
case 'f':
img_in = 15+48;
break;
default:
break;
}
*out = *out*16 + (uint32_t)(img_in-48);
i++;
}
}
else if(typenum == 2)
{
i=i+2;
t=i;
while(t<64&&in[t]!=',')
www.rpc.vn Page 53
Training Page 54
{
if(in[t]<'0' || in[t]>'1')
{
return FALSE_SYNTAX_ADDRESS;
}
t++;
}
while((in[i]>='0'&& in[i]<='1')&&i<64)
{
*out = *out*2 + (uint32_t)(in[i]-48);
i++;
}
}
else
{
t=i;
while(t<64&&in[t]!=',')
{
if(in[t]<'0' || in[t]>'9')
{
return FALSE_SYNTAX_ADDRESS;
}
t++;
}
if(t==i)
{
return FALSE_SYNTAX_ADDRESS;
}
while((in[i]>='0'&& in[i]<='9')&&i<64)
{
*out = *out*10 + (uint32_t)(in[i]-48);
i++;
}
}
return 0;
}
www.rpc.vn Page 54
Training Page 55
if(first>0)
{
if(in[i]>='0'&& in[i]<='9')
{
out[j]= (uint8_t)(in[i]-48);
}
else
{
out[j]= (uint8_t)in[i];
}
}
if(in[i] ==')')
{
j=0;
}
else
{
j++;
i++;
}
}
if(j<=0)
{
return DATA_EMPTY;
}
else
{
return 0;
}
}
www.rpc.vn Page 55
Training Page 56
else
{
return FALSE_SYNTAX_LENGTH ;
}
}
j++;
i++;
}
return 0;
}
uint8_t TakeStatusDATAFromUART(char in[], uint8_t *out) //Lấy trạng thái dữ liệu từ UART
{
int i=0;
char *start;
int t=0;
uint8_t typenum=0;
*out=0;
start = strstr(receive, "0x");
if(start != NULL)
{
typenum=1;
}
start = strstr(receive, "0b");
if(start!=NULL)
{
typenum=2;
}
while((start != &in[i])&&i<64)
{
i++;
}
if(start == NULL)
{
i=0;
while((in[i]<'0'||in[i]>'9')&& i<64 && in[i-1] !='(')
{
i++;
}
}
if(typenum==1)
{
i=i+2;
t=i;
while(t<64&&in[t]!=')')
{
if((in[t]<'0'||in[t]>'9')&&(in[i]<'A'|| in[i]>'F')&&(in[i]<'a'|| in[i]>'f'))
{
return FALSE_SYNTAX_REG_VALUE;
}
www.rpc.vn Page 56
Training Page 57
t++;
}
while(((in[i]>='0'&& in[i]<='9')||(in[i]>='A'&& in[i]<='F')||(in[i]>='a'&& in[i]<='f'))&&i<64)
{
char img_in = in[i];
switch(img_in)
{
case 'A':
img_in = 10+48;
break;
case 'B':
img_in = 11+48;
break;
case 'C':
img_in = 12+48;
break;
case 'D':
img_in = 13+48;
break;
case 'E':
img_in = 14+48;
break;
case 'F':
img_in = 15+48;
break;
case 'a':
img_in = 10+48;
break;
case 'b':
img_in = 11+48;
break;
case 'c':
img_in = 12+48;
break;
case 'd':
img_in = 13+48;
break;
case 'e':
img_in = 14+48;
break;
case 'f':
img_in = 15+48;
break;
default:
break;
}
*out = *out*16 + (uint8_t)(img_in-48);
i++;
}
}
else if(typenum == 2)
www.rpc.vn Page 57
Training Page 58
{
i=i+2;
t=i;
while(t<64&&in[t]!=')')
{
if(in[t]<'0' || in[t]>'1')
{
return FALSE_SYNTAX_REG_VALUE;
}
t++;
}
while((in[i]>='0'&& in[i]<='1')&&i<64)
{
*out = *out*2 + (uint8_t)(in[i]-48);
i++;
}
}
else
{
t=i;
while(t<64&&in[t]!=')')
{
if(in[t]<'0' || in[t]>'9')
{
return FALSE_SYNTAX_REG_VALUE;
}
t++;
}
if(t==i)
{
return FALSE_SYNTAX_REG_VALUE;
}
while((in[i]>='0'&& in[i]<='9')&&i<64)
{
*out = *out*10 + (uint8_t)(in[i]-48);
i++;
}
}
return 0;
}
www.rpc.vn Page 58
Training Page 59
void main(void)
{
// initialize the device
SYSTEM_Initialize();
INTERRUPT_GlobalInterruptEnable();
INTERRUPT_PeripheralInterruptEnable();
EEPROM_Init();
IOCAF5_SetInterruptHandler(PressSPI);
Write_StatusRegister(0b10000000);
Write_Enable();
for(uint8_t i = 0; i<32;i++)
{
transmitt_SPI[i] = i + 32;
}
Write_Sequence(0x00, transmitt_SPI, 32);
printf("hello\n");
printf("//all to show all instruction \n");
while (1)
{
CLRWDT();
receive_uart (receive);
char *read_check = strstr(receive,"read(");
char *write_check = strstr(receive,"write(");
char *read_status_check = strstr(receive,"read_status(");
char *write_status_check = strstr(receive,"write_status(");
char *page_erase_check = strstr(receive,"erase_page(");
char *sector_erase_check = strstr(receive,"erase_sector(");
char *chip_erase_check = strstr(receive,"erase_chip(");
char last = receive[strlen(receive)-1];
www.rpc.vn Page 59
Training Page 60
www.rpc.vn Page 60
Training Page 61
Page_Erase(addressUART);
printf("ok\n");
}
}
www.rpc.vn Page 61
Training Page 62
4. I2C_RTCC_MCP7941x
Dự án sử dụng LCD 16x2 hiển thị thời gian thực của module RTCC, trong
dự án này chỉ gồm giờ, phút, giây.
Nhấn BT1 cho phép điều chỉnh thời gian thực bằng tay.
Nhấn BT2 thay đổi con trỏ điều chỉnh thời gian từ giờ -> phút -> giây.
Nhấn BT3 thay đổi thời gian của RTCC: giờ(0 -> 23),
phút(0 -> 59), giây(0 -> 59).
Nhấn giữ BT1 xác nhận thời gian mới đã chỉnh sửa.
Yêu cầu phần cứng
Board UMB1P.0-15376 V 1.0
LCD 16x2
Module RTC MCP79410
Yêu cầu phầm mềm
MPLAB X IDE
www.rpc.vn Page 62
Training Page 63
www.rpc.vn Page 63
Training Page 64
www.rpc.vn Page 64
Training Page 65
www.rpc.vn Page 65
Training Page 66
www.rpc.vn Page 66
Training Page 67
www.rpc.vn Page 67
Training Page 68
Các thanh ghi cấu hình giá trị giây,giờ, phút của đồng hồ
www.rpc.vn Page 68
Training Page 69
www.rpc.vn Page 69
Training Page 70
data[0] = 0x00;
data[1] = (uint8_t)((second/10)<<4) | (uint8_t)(second % 10);
data[2] = (uint8_t)((minute/10)<<4) | (uint8_t)(minute % 10);
data[3] = (uint8_t)((hour/10)<<4) | (uint8_t)(hour % 10);
I2C1_WriteNBytes( ADDRESSWrite_RTCC_MCP7941x , data, 4);
}
Thêm vào project file LCD.h và LCD.c đã giới thiệu ở bài training 1.4
Main.c
#include "mcc_generated_files/mcc.h"
#include "mcc_generated_files/examples/i2c1_master_example.h"
#include "LCD4bit.h"
#include <stdio.h>
uint8_t recieve;
uint8_t datasendreg[4];
uint8_t datareceive[4] = {9, 9, 9, 9};
char printLCD[20];
char printLCD2[2];
uint8_t volatile mode = 0;
uint8_t volatile modetiming = 0;
uint8_t volatile presstiming = 0;
uint8_t volatile kk=0;
uint8_t volatile ss;
#define ADDRESSRead_RTCC_MCP7941x 0b1101111
#define ADDRESSWrite_RTCC_MCP7941x 0b1101111
www.rpc.vn Page 70
Training Page 71
void main(void)
{
SYSTEM_Initialize();
INTERRUPT_GlobalInterruptEnable();
www.rpc.vn Page 71
Training Page 72
INTERRUPT_PeripheralInterruptEnable();
IOCAF5_SetInterruptHandler(mode_value);
LCD_Init();
printf("Hellooooo\n");
LCD_String_xy(0, 4, "Hello");
RTCC_MCP7941x_Settime(21, 0, 0, datasendreg);
RTCC_MCP7941x_TriggerOSC(1);
__delay_ms(500);
while (1)
{
CLRWDT();
if(mode==0)
{
RTCC_MCP7941x_ReadtimeRaw(datareceive); //read time
Convert_timeRaw(datareceive); //convert time
printf(" %u : %u : %u \n", datareceive[2], datareceive[1], datareceive[0]);
sprintf(printLCD,"%u : %u : %u", datareceive[2], datareceive[1], datareceive[0]);
if(datareceive[0]==0)
{
LCD_Clear();
}
LCD_String_xy(0, 3, printLCD); //print
__delay_ms(50);
}
www.rpc.vn Page 72
Training Page 73
LCD_Clear();
sprintf(printLCD,"%u : %u : %u", datareceive[2], datareceive[1], datareceive[0]);
LCD_String_xy(0, 3, printLCD);
sprintf(printLCD2,"%c", (char)94);
LCD_String_xy(1, 8, printLCD2);
modetiming++;
break;
}
case 4 : //sec
{
LCD_Clear();
sprintf(printLCD,"%u : %u : %u", datareceive[2], datareceive[1], datareceive[0]);
LCD_String_xy(0, 3, printLCD);
sprintf(printLCD2,"%c", (char)94);
LCD_String_xy(1, 13, printLCD2);
modetiming++;
break;
}
default:
break;
}
if(SW2_GetValue()==0) //change pointer time
{
modetiming++;
if(modetiming >6)
{
modetiming = 0;
}
__delay_ms(100);
}
if(SW3_GetValue()==0) //change time
{
if(modetiming ==1)
{
datareceive[2]++;
if(datareceive[2]>=24)
{
datareceive[2]=0;
}
modetiming = 0;
}
else if(modetiming ==3)
{
datareceive[1]++;
if(datareceive[1]>=60)
{
datareceive[1]=0;
}
modetiming = 2;
}
else if(modetiming ==5)
www.rpc.vn Page 73
Training Page 74
{
datareceive[0]++;
if(datareceive[0]>=60)
{
datareceive[0]=0;
}
modetiming = 4;
}
__delay_ms(100);
}
}
}
}
Chương trình sau đây mổ tả việc sử dụng giao thức CAN điểu khiển bật tắt các
đèn trên board MCU các đèn LED trên board 1 sẽ được điều khiển các nút
nhấn trên board 2 và ngược lại
Yêu cầu phần cứng
2 board UMB1P.0-15376
2 module CAN MCP2515
Yêu cầu phần mềm
MPLAB IDE
Advcance Serial Port Terminal
www.rpc.vn Page 74
Training Page 75
Hình 5. 2 Sơ đồ nguyên lý
Giao thức CAN thông qua module CAN MCP2515 được kết nối với MCU
giao tiếp giữa MCU với module là giao tiếp SPI theo sơ đồ sau :
www.rpc.vn Page 75
Training Page 76
Kết nối các node với nhau bằng 2 dây theo mô hình CAN_H <–> CAN_H,
CAN_L <–> CAN_L .
Mỗi board module CAN cung cấp 2 cặp cổng CAN_H và CAN_L.
www.rpc.vn Page 76
Training Page 77
www.rpc.vn Page 77
Training Page 78
IC CAN MCP2515 sử dụng giao tiếp CAN2.0B bao gồm 3 bộ truyền dữ liệu
riêng biệt TXB0 -> TXB3 cho phép truyền dữ liệu độc lập hoặc lần lượt theo
mức độ tiên được người dùng tự cài đặt trong thanh ghi có sẵn. Phần nhận dữ
liệu bao gồm 2 bộ nhận RXB0 và RXB1, mỗi bộ nhận được thiết kế các bộ lọc
tin nhắn, 2 bộ ở bộ nhận RXB0 và 6 ở RXB1(RXB1 có thể sử dụng được 2 bộ
nhận của RXB0) các bộ bọc này kết hợp với 2 mặt nạ lọc RXM0 và RXM1 cho
phép thiết bị chọn thông điệp có liên quan đến node, cách thức tạo độ liên quan
thông điệp người do người dung tự qui định.
Nguyên lý nhận thông điệp(tin nhắn): Các tin nhắn được truyền đi sẽ có trường
định danh Arbitration Field 12 bit ở khung chuẩn và 32 bit ở khung mở rộng,
bộ nhận sẽ so sánh trường này của thông điệp nhận với các bit trong bộ lọc của
bộ nhận để xem xét có nhận thông điệp hay không. Các mặt nạ nhận đùng để
xác định các bit nào trong trường định danh thông điệp được yêu cầu phải khớp
với các bit của bộ lọc. Tuy trường định danh có 12 đến 32 bit nhưng có thể chỉ
www.rpc.vn Page 78
Training Page 79
cần ít hơn số bit này khớp với các vị trí tương ứng của bộ lọc thì thông điệp sẽ
được nhận đây là chức năng của mặt nạ nhận. Xem thêm hình bên dưới.
Nếu set 2 bit RXM[1:0] trong thanh ghi RXBxCTRL = 11 mặt nạ nhận và bộ
lọc sẽ bị tắt, bộ nhận sẽ nhận tất cả tin nhắn.
www.rpc.vn Page 79
Training Page 80
Module được thiết kế để có thể dùng MCU giao tiếp được bằng giao thức SPI
cho tốc độ giao tiếp lên đến 20Mb/s, Một số chức năng có thể được thực hiện
qua lệnh như gửi tin nhắn, lệnh Bit Modify cho phép set rời rạc các bit trong 1
thanh ghi giúp ta đơn giản hoá việc lập trình.
www.rpc.vn Page 80
Training Page 81
www.rpc.vn Page 81
Training Page 82
www.rpc.vn Page 82
Training Page 83
www.rpc.vn Page 83
Training Page 84
www.rpc.vn Page 84
Training Page 85
www.rpc.vn Page 85
Training Page 86
www.rpc.vn Page 86
Training Page 87
Mặc dù module có nhiều hơn 2 bộ cho nhận và truyền nhưng trong ví dụ này ta
chỉ xét với Buffer0 cho cả 2 bộ nhận và truyền
void Sensor_Init (void)
{
// Reset_sensor();
Set_sensor(0x30, 0x00); // Clear TXREQ
Set_sensor(0x31, 0xAA); // Use ID TX type Standard
Set_sensor(0x32, 0xA0); // ID : 0b10101010101
Set_sensor(0x35, 0x08); // Transmitt data frame, data lenght 8 byte
for(uint8_t i=0;i < 8;i++)
{
Set_sensor(0x36 + i,i);
www.rpc.vn Page 87
Training Page 88
}
Set_sensor(0x00, 0xAA); // Use ID RX type Standard
Set_sensor(0x01, 0xA0); // ID : 0b10101010101
Set_sensor(0x20, 0xFF); // Use MASK full bits
Set_sensor(0x21, 0xE0);
Set_sensor(0x2B, 0x01); // Use Interrupt Buffer RX0
Set_sensor(0x2A, 0x0F); // Tq = 0.000004s
Set_sensor(0x0F, 0x07); // Sets Normal Operation mode
}
Để thiết lập các thông số của bộ nhận ta cần xoá bit TXREQ trước khi thực
hiện, mặc định module khi khởi động sẽ ở chế độ cấu hình nên sau khi cài đặt
xong các thông số ta cần đặt module trở lại trạng thái hoạt động bình thường ở
thanh ghi CANCTRL địa chỉ 0x0F. 1 số thanh ghi để thiết lập cần phải đưa
module vào chế độ cấu hình.
Thiết lập báo ngắt khi nhận được tin nhắn, tín hiệu ngắt sẽ báo ra chân INT
module bằng cách kéo chân này xuống thấp nối chân này với các chân IO của
MCU để nhận tín hiệu ngắt.
LED3_Toggle();
receive_flag = ~receive_flag;
}
Reset_sensor();
Sensor_Init ();
STBY_SetLow();
IOCCF7_SetInterruptHandler(receive_led);
www.rpc.vn Page 88
Training Page 89
Read_sensor(0x66 + i, &receiveframe[i]);
}
}
Phần này dùng để đọc dữ liệu từ module khi có ngắt nhận xảy ra.
if(SW1_GetValue()==0 && press == 0)
{
Send_messenger(sendframe1,0,8);
press = 1;
}
else if(SW2_GetValue()==0 && press == 0)
{
Send_messenger(sendframe2,0,8);
press = 1;
}
else if (SW3_GetValue()==0 && press == 0)
{
Send_messenger(sendframe3,0,8);
press = 1;
}
else if(SW1_GetValue()== 1 && SW2_GetValue() == 1 &&
SW3_GetValue()== 1)
{
press=0;
}
Phần chương trình dùng để gửi các thông điệp khác nhau theo nút nhấn.
if(strcmp((char*)receiveframe,"abcdefgh")==0)
{
LED1_SetHigh();
LED2_SetLow();
LED3_SetLow();
}
else if (strcmp((char*)receiveframe,"ijklmnop")==0)
{
LED1_SetLow();
LED2_SetHigh();
LED3_SetLow();
}
else if (strcmp((char*)receiveframe,"qrstuvwx")==0)
{
LED1_SetLow();
LED2_SetLow();
LED3_SetLow();
}
www.rpc.vn Page 89
Training Page 90
Phần chương trình sẽ so sánh dữ liệu nhận được với lệnh tương ứng để thực
hiện bật tắt đèn.
Main.c
#include "mcc_generated_files/mcc.h"
#include <string.h>
#define RESET_INS 0b11000000
#define READ 0b00000011
#define WRITE 0b00000010
#define READ_STATUS 0b10100000
#define RX_STATUS 0b10110000
#define BIT_MODIFY 0b00000101
#define READ_RX_BUFFER_SID0 0b10010000
#define READ_RX_BUFFER_DT0 0b10010010
#define READ_RX_BUFFER_DT1 0b10010110
#define READ_RX_BUFFER_SID1 0b10010100
#define LOAD_TX_BUFFER_SID0 0b01000000
#define LOAD_TX_BUFFER_DT0 0b01000001
#define LOAD_TX_BUFFER_SID1 0b01000010
#define LOAD_TX_BUFFER_DT1 0b01000011
#define LOAD_TX_BUFFER_SID2 0b01000100
#define LOAD_TX_BUFFER_DT2 0b01000101
#define REQUEST_TO_SEND_TXBUFF0 0b10000001
#define REQUEST_TO_SEND_TXBUFF1 0b10000010
#define REQUEST_TO_SEND_TXBUFF2 0b10000100
#define BIT_MODIFY 0b00000101
uint8_t press = 0;
uint8_t receive = 0;
uint8_t sendframe1[8] = "abcdefgh";
uint8_t sendframe2[8] = "ijklmnop";
www.rpc.vn Page 90
Training Page 91
www.rpc.vn Page 91
Training Page 92
www.rpc.vn Page 92
Training Page 93
data++;
}
REQUEST_TO_SEND_BUFF(buff);
}
void receive_led(void)
{
LED3_Toggle();
receive_flag = ~receive_flag;
}
void main(void)
{
SYSTEM_Initialize();
Reset_sensor();
Sensor_Init ();
STBY_SetLow();
IOCCF7_SetInterruptHandler(receive_led);
printf("hello\n");
while (1)
{
CLRWDT();
if(receive_flag != receive_pre)
{
receive_pre = receive_flag;
uint8_t DLC = 0;
Bit_Modify( 0x2C, 0b00000001, 0x00);
Read_sensor(0x65,&DLC);
for(uint8_t i=0; i < (DLC&0x0F);i++)
{
Read_sensor(0x66 + i, &receiveframe[i]);
}
}
if(SW1_GetValue()==0 && press == 0)
{
Send_messenger(sendframe1,0,8);
press = 1;
}
else if(SW2_GetValue()==0 && press == 0)
{
Send_messenger(sendframe2,0,8);
press = 1;
}
else if (SW3_GetValue()==0 && press == 0)
{
Send_messenger(sendframe3,0,8);
press = 1;
}
else if(SW1_GetValue()== 1 && SW2_GetValue() == 1 && SW3_GetValue() == 1)
{
www.rpc.vn Page 93
Training Page 94
press=0;
}
if(strcmp((char*)receiveframe,"abcdefgh")==0)
{
LED1_SetHigh();
LED2_SetLow();
LED3_SetLow();
}
else if (strcmp((char*)receiveframe,"ijklmnop")==0)
{
LED1_SetLow();
LED2_SetHigh();
LED3_SetLow();
}
else if (strcmp((char*)receiveframe,"qrstuvwx")==0)
{
LED1_SetLow();
LED2_SetLow();
LED3_SetLow();
}
}
}
www.rpc.vn Page 94
Training Page 95
Phụ lục
Chọn COM kết nối với kit, chọn Baudrate, Data bits, Parity, Stop bits, Flow
control sau đó chọn Open để mở Port
www.rpc.vn Page 95
Training Page 96
www.rpc.vn Page 96
Training Page 97
Datasheet MCP2515
https://ww1.microchip.com/downloads/aemDocuments/documents/APID/Prod
uctDocuments/DataSheets/MCP2515-Family-Data-Sheet-DS20001801K.pdf
Datasheet MCP79410
http://ww1.microchip.com/downloads/en/devicedoc/20002266h.pdf
Datasheet 25AA1024
https://ww1.microchip.com/downloads/aemDocuments/documents/MPD/Produ
ctDocuments/DataSheets/1-Mbit-SPI-Bus-Serial-EEPROM-Data-Sheet-
20001836K.pdf
Datasheet RPR-0521RS
https://fscdn.rohm.com/en/products/databook/datasheet/opto/optical_sensor/opt
o_module/rpr-0521rs-e.pdf
L298N Dual H-Bridge Motor Driver User Guide
http://www.handsontec.com/dataspecs/L298N%20Motor%20Driver.pdf
www.rpc.vn Page 97