?? main.c
字號:
//***************************************************
// filename: main.c
// Author: wen
// Rewrite:
// Date: 2007-01-10
// Version: V1.0
// Description: ALL main.c file
//****************************************************
//****************************************************
//修改
//文小龍
//提供接收及發送BUFFER,USB數據改為中斷上傳和批量下傳方式,即采用EP1IN,EP2OUT
//****************************************************
#include<include.h>
#include<reg52.h>
#include<string.h>
sbit LED_Low= P1^4;
//****************************************************
//CAN bus function
/*
//函數原型: bit CAN_CREATE_COMMUNATION(void)
// 0: 表示SJA1000接口正常
// 1: 表示SJA1000與處理器接口不正常
//說明:該函數用于檢測CAN控制器的接口是否正常
bit CAN_CREATE_COMMUNATION(void)
{
SJA_CANAdr= SJA_TEST; //訪問測試寄存器
*SJA_CANAdr=0xaa; //寫入測試值
if(*SJA_CANAdr== 0xaa) //回讀
return 0; //讀測試正確
else
return 1;
} */
//函數原型: bit CAN_ENTER_RETMODEL(void)
//返回值:
// 0 ; 表示成功進入復位工作模式
// 1 ; 表示不能進入復位工作模式 *
//說明: CAN控制器進入復位工作模式
bit CAN_ENTER_RETMODEL(void)
{
INT8U TempData;
SJA_CANAdr= SJA_MOD; //訪問地址指向模式寄存器
TempData= *SJA_CANAdr; //保存原始值
*SJA_CANAdr= (TempData|0x01); //置位復位請求
if((*SJA_CANAdr&0x01)== 1)
return 0;
else
return 1;
}
/*
//函數原型: bit CAN_QUIT_RETMODEL(void)
//返回值:
// 0: 表示成功退出復位工作模式
// 1: 表示不能退出復位工作模式
//說明: CAN控制器退出復位工作模式
bit CAN_QUIT_RETMODEL(void)
{
INT8U TempData;
SJA_CANAdr= SJA_MOD; //訪問地址指向模式寄存器
TempData= *SJA_CANAdr; //保存原始值
*SJA_CANAdr=(TempData&0xfe); //清除復位請求
if((*SJA_CANAdr&0x01) == 0)
return 0; //退出成功
else
return 1; //退出失敗
}
*/
//函數原型: bit CAN_DATA_WRITE(unsigned char *SendDataBuf)
//參數說明: 特定幀格式的數據發送
//返回值:
// 0 ; 表示將數據成功的發送至發送緩沖區
// 1 ; 表示上一次的數據正在發送,
// ; 表示發送緩沖區被鎖定,不能寫入數據
// ; 表示寫入數據錯誤
bit CAN_DATA_WRITE(unsigned char *SendDataBuf)
{
INT8U TempCount;
SJA_CANAdr= SJA_SR; //訪問地址指向狀態寄存器
if((*SJA_CANAdr&0x08)== 0) //判斷上次發送是否完成
return 1;
if((*SJA_CANAdr&0x04)== 0) //判斷發送緩沖區是否鎖定
return 1;
SJA_CANAdr= SJA_RXEFF;
switch(SendDataBuf[0]&0xC0) //對PelicCAN mode 數據格式進行判斷
{
case 0x40: //標準遠程幀
TempCount= 3;
break;
case 0x00: //標準數據幀
TempCount= (SendDataBuf[0]&0x0f)+ 3;
break;
case 0xC0: //擴展遠程幀
TempCount= 5;
break;
case 0x80: //擴展數據幀
TempCount= (SendDataBuf[0]&0x0f)+ 5;
break;
default: //退出,返回1
return 1;
break;
}
memcpy(SJA_CANAdr,SendDataBuf,TempCount); //將數據傳入SJA1000CAN數據發送緩沖區
SJA_CANAdr= SJA_CMR; //置位發送請求
*SJA_CANAdr= 0x01;
return 0;
}
//函數原型: bit CAN_DATA_RECEIVE(unsigned char *RcvDataBuf);
//參數說明: RcvDataBuf,存放微處理器保存數據緩沖區
//返回值: 0;接收成功
// 1;接收失敗
//說明:CAN控制器接收數據,僅限于接收數據
bit CAN_DATA_RECEIVE(INT8U *RcvDataBuf)
{
INT8U TempCount;
SJA_CANAdr= SJA_SR; //訪問地址指向狀態寄存器
if((*SJA_CANAdr&0x01)==0) //判斷報文是否有效
return 1;
SJA_CANAdr= SJA_RXEFF;
switch(*SJA_CANAdr&0xC0)
{
case 0x00: //標準數據幀
TempCount= (*SJA_CANAdr&0x0f)+ 3;
break;
case 0x40: //標準遠程幀
TempCount= 3;
break;
case 0x80: //擴展數據幀
TempCount= (*SJA_CANAdr&0x0f)+ 5;
break;
case 0xC0: //擴展遠程幀
TempCount= 5;
break;
default: break;
}
memcpy(RcvDataBuf,SJA_CANAdr,TempCount);//讀取接收緩沖區的報文
RecDataFromCanLength= TempCount; //置標志位
return 0;
}
//函數原型:void SJA_Init(void);
//無參數,無返回值
//說明:SJA初始化
void SJA_Init(void)
{
INT8U i;
EA= 0;
//進入復位模式
for(i= 0; i< 500; i++)
if(!CAN_ENTER_RETMODEL()) break;
SJA_CANAdr= SJA_IER;
*SJA_CANAdr= 0x00; //清除所有中斷
SJA_CANAdr= SJA_CDR;
*SJA_CANAdr= 0xC8; //設定PeliCAN模式,禁止CLKOUT,使能CBP
//設定ACR0~3 AMR0~3 EFF
SJA_CANAdr= SJA_ACR0;
for(i=0;i<8;i++)
{
*SJA_CANAdr= i2c_read(0x05+ i);
SJA_CANAdr++;
}
//test
//設定波特率
SJA_CANAdr= SJA_BTR0;
*SJA_CANAdr= 0x18; //i2c_read(0x01);
SJA_CANAdr= SJA_BTR1;
*SJA_CANAdr= 0x1c; //i2c_read(0x02);
//配置CAN輸出 TX1懸空 TX0推免
SJA_CANAdr= SJA_OCR;
*SJA_CANAdr= 0x1A; //0x00|0x18|0x02
SJA_CANAdr= SJA_RBSA;
*SJA_CANAdr= 0x00; //接收緩沖地址置零
SJA_CANAdr= SJA_RXERR;
*SJA_CANAdr= 0x00; //接收錯誤計數器置零
SJA_CANAdr= SJA_TXERR;
*SJA_CANAdr= 0x00; //發送錯誤計數器置零
//讀取錯誤代碼器,器件自動將錯誤代碼器歸零
SJA_CANAdr= SJA_ECC;
i= *SJA_CANAdr;
SJA_CANAdr= SJA_IER;
*SJA_CANAdr= 0xFF; //設置SJA1000中斷使能
//清除復位模式
//關閉自我測試及僅聽模式
//清除休眠模式
//選擇單濾波模式
SJA_CANAdr= SJA_MOD;
*SJA_CANAdr= 0x08;
EA= 1;
SJA_CANAdr= SJA_CMR;
*SJA_CANAdr= 0x0c; //釋放接收/發送緩存區
}
//CAN bus function end
//****************************************************
//***************************************************
//USB function define
#define DELAY_START_VALUE 1 //根據單片機的時鐘選擇延時初值
//IO位置定義
IOPORT CH375_CMD_PORT _at_ 0xFD00; // CH375命令端口的I/O地址
IOPORT CH375_DAT_PORT _at_ 0xFC00; // CH375數據端口的I/O地址
//延時1微秒,不精確
void Delay1us( )
{
#if DELAY_START_VALUE!= 0
INT8U i;
for ( i=DELAY_START_VALUE; i!=0; i-- );
#endif
}
//延時2微秒,不精確
void Delay2us( )
{
INT8U i;
for ( i=DELAY_START_VALUE*2+1; i!=0; i-- );
}
//與CH372/CH375有關的基本I/O操作
void CH375_WR_CMD_PORT(INT8U cmd) { //向CH372/CH375寫入命令
Delay2us();
CH375_CMD_PORT= cmd;
Delay2us();
}
void CH375_WR_DAT_PORT(INT8U dat) { //向CH372/CH375寫入數據
CH375_DAT_PORT= dat;
Delay1us();
}
INT8U CH375_RD_DAT_PORT( void ) { //讀CH372/CH375內部數據
Delay1us();
return(CH375_DAT_PORT);
}
//CH375初始化子程序
void CH375_Init( void )
{
INT8U i;
#ifdef MY_USB_VENDOR_ID
#ifdef MY_USB_PRODUCT_ID
CH375_WR_CMD_PORT( CMD_SET_USB_ID );
CH375_WR_DAT_PORT( (UINT8)MY_USB_VENDOR_ID );
CH375_WR_DAT_PORT( (UINT8)(MY_USB_VENDOR_ID>>8) );
CH375_WR_DAT_PORT( (UINT8)MY_USB_PRODUCT_ID );
CH375_WR_DAT_PORT( (UINT8)(MY_USB_PRODUCT_ID>>8) );
#endif
#endif
// 設置USB工作模式
CH375_WR_CMD_PORT( CMD_SET_USB_MODE );
CH375_WR_DAT_PORT( 2 ); // 設置為使用內置固件的USB設備方式
for (i= 100; i!= 0; i--)
if(CH375_RD_DAT_PORT()== CMD_RET_SUCCESS) break; // 等待操作成功
#ifdef ENABLE_USB_SUSPEND
// 設置檢查USB總線掛起狀態,便于在USB總線掛起時使CH375也進入低功耗狀態
CH375_WR_CMD_PORT( CMD_CHK_SUSPEND ); // 設置檢查USB總線掛起狀態的方式
CH375_WR_DAT_PORT( 0x10 );
CH375_WR_DAT_PORT( 0x04 ); // 以50mS為間隔檢查USB掛起
#endif
}
//USB function define end
//********************************************************
//********************************************************
//others function define
//函數原型:void USB_INT1(void) interrupt 2
//無參數,無返回值
//說明:外部中斷1服務函數
void USB_INT1(void) interrupt 2
{
INT8U IntStatus;
INT8U cnt;
PINT8U buf;
EA= 0;
CH375_WR_CMD_PORT(CMD_GET_STATUS); //獲取中斷狀態并取消中斷請求
IntStatus = CH375_RD_DAT_PORT( ); // 獲取中斷狀態
IE0 = 0; //清中斷標志
switch(IntStatus)
{ // 分析中斷狀態
case USB_INT_EP2_OUT: // 批量端點下傳成功,接收到數據
{
CH375_WR_CMD_PORT( CMD_RD_USB_DATA );
RecDataFromUsbLength = cnt = CH375_RD_DAT_PORT( ); // 首先讀取后續數據長度
if ( cnt ) { // 接收到數據放到緩沖區中
buf= RecDataFromUsb; // 指向緩沖區
do {
*buf = CH375_RD_DAT_PORT( ); // 接收命令包的數據
buf ++;
} while ( -- cnt );
}
}break;
case USB_INT_EP2_IN: // 批量端點上傳成功,數據發送成功
CH375_WR_CMD_PORT( CMD_UNLOCK_USB ); //釋放當前USB緩沖區,收到上傳成功中斷后,必須解鎖USB緩沖區,以便繼續收發
break;
case USB_INT_EP1_IN: // 中斷端點上傳成功,中斷數據發送成功
CH375_WR_CMD_PORT( CMD_UNLOCK_USB ); // 釋放當前USB緩沖區
break;
case USB_INT_EP1_OUT: // 輔助端點下傳成功,接收到輔助數據
CH375_WR_CMD_PORT( CMD_UNLOCK_USB ); // 釋放當前USB緩沖區
break;
#ifdef ENABLE_USB_SUSPEND //總線掛起狀態查詢
case USB_INT_USB_SUSPEND:
{
CH375_WR_CMD_PORT( CMD_UNLOCK_USB );
CH375_WR_CMD_PORT( CMD_ENTER_SLEEP );
}
break;
case USB_INT_WAKE_UP:
CH375_WR_CMD_PORT( CMD_UNLOCK_USB );
break;
#endif
default:
CH375_WR_CMD_PORT( CMD_UNLOCK_USB ); // 釋放當前USB緩沖區
break;
}
EA= 1;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -