/*****************************(abc928-18326.c)***
* CANモジュールテスト
*************************************************/
#include "myProject.h"
#include "myFunction.h"
#include "mcp_can_dfs.h"
#include "skMCP25xx.h"
#define GET_SW() SW0_GetValue() // スイッチはSW0を使用
//#define GET_SW() RA3_GetValue() // スイッチはRA3を使用
#define USE_HCHAR // 半角文字表示指定
#ifdef USE_HCHAR
#define OLED_MX_LN 4 // 画面最下部に半角文字表示
#else
#define OLED_MX_LN 7 // 画面フルスクロール
#endif
//----- シリアル通信用データ
char RBuf[EU_BFSIZE]; // SIZEはmyProject.hで宣言
uint8_t SFlg; // シリアル受信フラグ
//---- CAN用共通変数の宣言
unsigned char flagRecv = 0 ; // CAN受信有無フラグ
unsigned char len = 0 ; // CAN受信データサイズ
unsigned char RcvBuf[8]; // CAN受信データ
//---- Font data -----
const char hk[11][16] ={
{ 0x00,0xF8,0x04,0x02,0xC2,0x24,0xF8,0x00,
0x00,0x0F,0x14,0x23,0x20,0x10,0x0F,0x00 }, // 0
{ 0x00,0x10,0x08,0xFE,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00 }, // 1
{ 0x00,0x18,0x04,0x02,0x82,0x44,0x38,0x00,
0x00,0x38,0x26,0x21,0x20,0x20,0x20,0x00 }, // 2
{ 0x18,0x04,0x82,0x82,0x82,0x44,0x38,0x00,
0x0C,0x10,0x20,0x20,0x20,0x11,0x0E,0x00 }, // 3
{ 0x00,0xC0,0x30,0x0C,0xFE,0x00,0x00,0x00,
0x03,0x02,0x02,0x02,0x3F,0x02,0x02,0x00 }, // 4
{ 0xE0,0x5E,0x22,0x22,0x22,0x42,0x80,0x00,
0x0C,0x10,0x20,0x20,0x20,0x10,0x0F,0x00 }, // 5
{ 0xF0,0x8C,0x42,0x42,0x42,0x84,0x00,0x00,
0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00 }, // 6
{ 0x02,0x02,0x02,0x02,0xE2,0x1A,0x06,0x00,
0x00,0x00,0x00,0x7E,0x01,0x00,0x00,0x00 }, // 7
{ 0x38,0x44,0x82,0x82,0x82,0x44,0x38,0x00,
0x0E,0x11,0x20,0x20,0x20,0x11,0x0E,0x00 }, // 8
{ 0x78,0x84,0x02,0x02,0x02,0x84,0xF8,0x00,
0x08,0x10,0x21,0x21,0x21,0x10,0x0F,0x00 }, // 9
{ 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,
0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00 } // :
};
const char sp[16] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; // space
const char as[6][16] ={
{ 0x00,0xC0,0x38,0x06,0x38,0xC0,0x00,0x00,
0x3C,0x03,0x02,0x02,0x02,0x03,0x3C,0x00 }, // A
{ 0xFE,0x82,0x82,0x82,0xC4,0x38,0x00,0x00,
0x3F,0x20,0x20,0x20,0x20,0x11,0x0E,0x00 }, // B
{ 0xF0,0x0C,0x02,0x02,0x02,0x04,0x08,0x00,
0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00 }, // C
{ 0xFE,0x02,0x02,0x02,0x04,0x18,0xE0,0x00,
0x3F,0x20,0x20,0x20,0x10,0x0C,0x03,0x00 }, // D
{ 0xFE,0x82,0x82,0x82,0x82,0x82,0x02,0x00,
0x3F,0x20,0x20,0x20,0x20,0x20,0x20,0x00 }, // E
{ 0xFE,0x82,0x82,0x82,0x82,0x82,0x02,0x00,
0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } // F
};
/*--------------------------------------------------*
* 割り込み処理関数 *
*--------------------------------------------------*/
//---- MCP2515のINTピン割り込み
void IOCAF2_Process(void){
flagRecv = 1 ; // CAN割込有りフラグセット
}
/*--------------------------------------------------*
* OLED表示用関数 *
*--------------------------------------------------*/
//---- 半角文字列の表示
void i2cPrint_Hstr(uint8_t py, uint8_t x, char *str){
uint8_t n;
uint8_t xpos;
xpos = x;
while(*str){
n = *str;
if((0x30<=n)&(n<=0x3A)){
xpos = i2cOLED_Ptn(py,xpos,2,8,(char *)hk[n-0x30]);
}else if((0x41<=n)&(n<=0x46)){
xpos = i2cOLED_Ptn(py,xpos,2,8,(char *)as[n-0x41]);
}else{
xpos = i2cOLED_Ptn(py,xpos,2,8,(char *)sp);
}
str++;
}
return xpos;
}
//---- スクロール付き表示 (スクロール範囲は[0-OLED_MX_LN])
void i2cOLED_Prt(char *str){
i2cOLED_posPX(CrtLn,0);
i2cOLED_str(str);
if(CrtLn < OLED_MX_LN) CrtLn++;
else CrtLn = 0;
i2cOLED_Clr(CrtLn,CrtLn,0);
}
/*------------------------------------------------*
* CAN受信の処理 *
*------------------------------------------------*/
void CheckReceiveProcess(void) {
union { unsigned char c[2] ;
unsigned int i ;
} data ;
unsigned long id ;
char buf[16];
// INTピン割り込みが有れば処理する
if(flagRecv) {
flagRecv = 0 ; // 割り込みフラグをクリア
while (CAN_MSGAVAIL == mcp_checkReceive()) {
// 受信したメッセージを読み込む,
mcp_readMsgBuf(&len, RcvBuf);
// データフレームなら処理する
if (mcp_isRemoteRequest() == 0) {
id = mcp_getCanId() ;
switch (id) {
case 0x123 : // 可変抵抗値の識別子ID
data.c[0] = RcvBuf[0] ;
data.c[1] = RcvBuf[1] ;
sprintf(buf,"%03X:%8d",(uint16_t)id,data.i);
// --- sprintfを使わない場合
// my_xtoa(buf,id,3); buf[3]=':'; buf[4]=' ';
// my_utoa(buf + 5, data.i);
i2cOLED_Prt(buf) ; EU_Puts(buf);
#ifdef USE_HCHAR
i2cOLED_Clr(6,7,0); // 表示エリ消去
i2cPrint_Hstr(6, 0, buf); // 半角文字表示
#endif
break ;
default : // その他の識別子ID
i2cOLED_Prt(" Unknown") ;
break ;
}
}
}
}
}
//---- CAN送受信テスト
void test_CAN(uint8_t *buf){
mcp_sendMsgBuf(0x123,CAN_STDID,CAN_RMTFRM,0,buf,1) ;
}
/*------------------------------------------------*
* Main application *
*------------------------------------------------*/
void main(void){
uint8_t cmd; // コマンド
uint8_t buf[8] ; // CANデータ用
uint8_t sw, sw_lst; // スイッチ情報
char msg[] = "ready!";
SYSTEM_Initialize();
SSP1CON1bits.SSPEN = 1; //SPI1を有効に
IOCAF2_SetInterruptHandler(IOCAF2_Process);
INTERRUPT_GlobalInterruptEnable();
INTERRUPT_PeripheralInterruptEnable();
i2cOLED_init();
i2cOLED_Clr(0,7,0); i2cOLED_str(msg);
EU_Puts(msg);
// MCP2515によるCAN通信の初期化
// CANバス通信速度=100Kbps MCP2515のクロック=8MHz
while (CAN_OK != mcp_begin(CAN_100KBPS,MCP_8MHz)) {
i2cOLED_str("InitFail") ;
while(1) ; // 終了
}
i2cOLED_str("Init OK!") ;
// MASK0->Filter0->RXB0(オーバフローでRXB1)のみ使用します。
mcp_init_Mask(0, 0, 0x3ff) ; // 全て受付る
mcp_init_Filt(0, 0, 0x123) ; // ID:0x123のみ受け取る
// MCP2515のINTピン割り込みの設定
IOCAN2 = 1 ; // RA2で立下げエッジ割込み
IOCAF2 = 0 ; // RA2割込フラグをクリア
IOCIF = 0 ; // 割込フラグをクリア
IOCIE = 1 ; // 状態変化割り込みを有効に
sw_lst = GET_SW() ; // 現在のキー状態を記憶
while (1) {
sw = GET_SW() ;
if((sw == 0)&(sw_lst==1)){ // スイッチの立ち下がりで実行
sw_lst = sw; // 現在スイッチ値を記憶
test_CAN(buf); // CAN受信処理
while( GET_SW() ); // キーが離れるまで待つ
__delay_ms(100); // チャタリング防止に100mS程待つ
sw_lst = 1;
}
// 受信しているメッセージデータを調べる
CheckReceiveProcess() ;
if(SFlg){ // シリアル入力があれば
cmd = RBuf[0];
switch(cmd){
case 'C': i2cOLED_Clr(0,7,0); CrtLn = 0; break;
case 'R': test_CAN(buf); break;
}
SFlg = 0;
}
}
}
/*************** End of File **********************/
|