?? 3d can例程.c
字號:
#include <reg51.h>
#include <math.h>
#include <intrins.h>
#include<absacc.h>
/*****************************************************************/
#define XBYTE ((unsigned char volatile xdata *) 0)
#define uchar unsigned char
#define uint unsigned int
#define True 1
#define False 0
/*****************************************************************/
sbit RUNLED = P3^3 ; //RUN指示,頻率輸出測試指示。
sbit ADCLK = P1^6;
sbit ADIN = P1^7;
sbit ADOUT = P1^2;
sbit ResetCAN = P1^3;
sbit ADCS = P1^4;
sbit DACS = P1^5;
sbit DACLK = P1^6;
sbit DADAT = P1^7;
sfr P4 = 0xE8;
sbit DI0 = P4^0;
sbit DI1 = P4^1;
sbit DI2 = P4^2;
sbit DI3 = P4^3;
sbit DO0 = P1^0;
sbit DO1 = P1^1;
sbit DO2 = P3^4;
sbit DO3 = P3^5;
sbit LEDCH3 = P3^0;
sbit LEDCH2 = P3^1;
#define WDG XBYTE [0x8400] /*外部wtachdog*/
sfr WDT_CONTR = 0xe1 ; /*定義CPU 看門狗地址*/
sfr AUXR = 0x8e ; /*聲明寄存器的地址*/
/* ********* CAN控制器的控制及狀態寄存器地址定義 ************** */
#define ModeControlReg XBYTE[0x8000] /* 控制寄存器 */
#define RM_RR_BIT 0x01 /* Reset Mode ( Request ) bit */
#define InterruptEnReg XBYTE[0x8000] /* 地址和位定義 中斷允許和控制寄存器 */
#define ClrByte 0x00 /* 默認的寄存器復位值,清除寄存器 */
#define ClrIntEnSJA ClrByte | RM_RR_BIT
#define RIE_Bit 0x02 /* 接收中斷允許模式位 */
#define TIE_Bit 0x04 /* 發送中斷允許模式位 */
#define EIE_Bit 0x08 /* 錯誤(故障)中斷允許模式位 */
#define DOIE_Bit 0x10 /* 超載中斷允許模式位 */
#define CommandReg XBYTE[0x8001] /* 命令寄存器地址和位定義 */
#define TR_Bit 0x01 /* 發送請求位 */
#define AT_Bit 0x02 /* 終止傳送位 */
#define ERB_Bit 0x04 /* 釋放接收緩沖器位 */
#define CDO_Bit 0x08 /* 清除數據超載位 */
#define GTS_Bit 0x10 /* 進入睡眠狀態位 */
#define StatusReg XBYTE[0x8002] /* 狀態寄存器地址和位定義 */
#define RBS_Bit 0x01 /* 接收緩沖器狀態位 */
#define DOS_Bit 0x02 /* 數據超載狀態位 */
#define TBS_Bit 0x04 /* 發送緩沖器狀態位 */
#define TCS_Bit 0x08 /* 傳送完成狀態位 */
#define RS_Bit 0x10 /* 接收狀態位 */
#define TS_Bit 0x20 /* 發送狀態位 */
#define ES_Bit 0x40 /* 錯誤狀態位 */
#define BS_Bit 0x80 /* 總線狀態位 */
#define InterruptReg XBYTE[0x8003] /* 中斷寄存器地址和位定義 */
#define RI_Bit 0x01 /* 接收中斷位 */
#define TI_Bit 0x02 /* 發送中斷位 */
#define EI_Bit 0x04 /* 錯誤警告中斷位 */
#define DOI_Bit 0x08 /* 數據超載中斷位 */
#define WUI_Bit 0x10 /* 喚醒中斷位 */
#define BusTiming0Reg XBYTE[0x8006] /* 總線時序地址和位定義 */
#define BusTiming1Reg XBYTE[0x8007]
#define SAM_Bit 0x80 /* 采樣模式位:1==采樣三次
0==采樣一次 */
#define OutControlReg XBYTE[0x8008] /* 輸出控制寄存器地址和位定義 */
#define BiphaseMode 0x00 /* 雙向輸出模式 */
#define NormalMode 0x02 /* 正常輸出模式 */
#define ClkOutMode 0x03 /* 時鐘輸出模式 */
/* 輸出引腳配置 TX1 */
#define OCPOL1_Bit 0x20 /* 輸出極性控制位 */
#define Tx1Float 0x00 /* 配置為浮空 */
#define Tx1PullDn 0x40 /* 配置為下拉 */
#define Tx1PullUp 0x80 /* 配置為上拉 */
#define Tx1PshPull 0xc0 /* 配置為推挽模式 */
/* 輸出引腳配置 TX0 */
#define OCPOL0_Bit 0x04 /* 輸出極性控制位 */
#define Tx0Float 0x00 /* 配置為浮空 */
#define Tx0PullDn 0x08 /* 配置為下拉 */
#define Tx0PullUp 0x10 /* 配置為上拉 */
#define Tx0PshPull 0x18 /* 配置為推挽模式 */
#define AcceptCodeReg XBYTE[0x8004] /* 接收過濾碼和屏蔽寄存器地址和位定義 */
#define AcceptMaskReg XBYTE[0x8005]
#define TxBuffer1 XBYTE[0x800a] /* 發送緩沖器地址定義 */
#define TxBuffer2 XBYTE[0x800b]
#define TxBuffer3 XBYTE[0x800c]
#define TxBuffer4 XBYTE[0x800d]
#define TxBuffer5 XBYTE[0x800e]
#define TxBuffer6 XBYTE[0x800f]
#define TxBuffer7 XBYTE[0x8010]
#define TxBuffer8 XBYTE[0x8011]
#define TxBuffer9 XBYTE[0x8012]
#define TxBuffer10 XBYTE[0x8013]
#define RxBuffer1 XBYTE[0x8014] /* 接收緩沖器地址定義 */
#define RxBuffer2 XBYTE[0x8015]
#define RxBuffer3 XBYTE[0x8016]
#define RxBuffer4 XBYTE[0x8017]
#define RxBuffer5 XBYTE[0x8018]
#define RxBuffer6 XBYTE[0x8019]
#define RxBuffer7 XBYTE[0x801a]
#define RxBuffer8 XBYTE[0x801b]
#define RxBuffer9 XBYTE[0x801c]
#define RxBuffer10 XBYTE[0x801d]
#define ClockDivideReg XBYTE[0x801f] /* 時鐘分頻器地址和位定義 */
#define DivBy1 0x07 /* CLKOUT = Fosc */
#define DivBy2 0x00 /* CLKOUT = 1/2 Fosc */
#define ClkOff_Bit 0x08 /* CLKOUT OFF 控制時鐘輸出位 */
#define RXINTEN_Bit 0x20 /* TX1引腳配置成接收中斷輸出 */
#define CBP_Bit 0x40 /* CAN比較器旁路控制位 */
#define CANMode_Bit 0x80 /* CAN模式定義位 0==BasicCAN Mode*/
uchar data SelfStationNo ; /*接收站號*/
/* CAN 通訊速度因子表 kbps 80KBPS */
#define DBT0 0x83
#define DBT1 0xff
uchar data rxdbuff [ 15 ] ; // _at_ 0x0000 ; /* 從SJ1000接收來的每個站的數據 */
uchar data txdbuff [ 10 ] ; // _at_ 0x0010 ; /* 從SJ1000要發送的數據 */
/* ********* CAN控制器的控制及狀態寄存器地址定義 ************** */
uchar data SendOverTime ;
uchar data i ;
uchar data runcount ;
uchar data dbt0 , dbt1 ;
uchar data StatusReg_ES ;
uchar data StatusReg_RX ;
uchar data StatusReg_TX ;
uchar data berkControl_P;
uchar data inth_h ;
uchar data inth_l ;
unsigned char xdata DAT_FX[32768] ;
unsigned int XDAVLM ;
unsigned int dacs01 ;
unsigned int dacs02 ;
unsigned int dacsvl ;
unsigned char data ch = 0,ch2 = 0; //A/D read
unsigned long data TPtimer ;
unsigned long data TPAtimer ;
unsigned long data TPAcount ; //頻率輸出周期控制,(低頻)
unsigned long data ZSGcount ; //從CAN總線上,收不到 車速 報文 計時控制時間。
unsigned long data FKYcount ; //從CAN總線上,收不到 壓力 報文 計時控制時間。
unsigned long data zhuanS ;
unsigned long data Contrtimer ; //制動信號定時發送
unsigned int advalue[4]; //A/D indata
bit Rcv_Head_Flag0 , Rcv_Head_Flag1 , Rcv_Head_Flag2 , Rcv_Head_Flag3 , Rcv_Head_Flag4 ;
bit Rcv_Head_Flag4 ;
bit Sending , senddataflag ; /* 正在發送標志和內部RAM中有報文要發送 */
uchar berkControl ;
bit berkControl_B7 ;
bit berkControl_b32 ;
bit F_outfpot ;
bit RXDbuf_Er ; //Receive Erro
bit TXTbuf_Er ; //Transmit Erro
#define berkc_Bit 0x80
extern void _nop_ ( void ) ;
void clrwdt ( void )
{
_nop_ ( ) ;
}
// 延時子函數
void DELAYFOR(unsigned long mDATA)
{
unsigned long i ;
for (i=0;i<mDATA;i++) ;
}
//計算輸出頻率對應的周期
float fout_t(unsigned long speed)
{
float timer_t ;
timer_t=((speed*0.01315)*45/40) ;
timer_t=1000000/timer_t ;
timer_t=timer_t / 2 ;
return (timer_t) ;
}
//定時器預置初值計算(對應的周期)
unsigned long fout_tt(unsigned long speed)
{
unsigned long timer_tt ;
timer_tt = (12*65536-speed*22)/12 ;
return (timer_tt) ;
}
// 換算D/A輸出值
unsigned long DA_out(unsigned long MPA_Z)
{
unsigned long MPA_V ;
MPA_V = (MPA_Z*4095)/5000 ;
return (MPA_V) ;
}
// Send CAN
void Send_CAN ( void ) //制動信息送CAN總線
{
do { StatusReg_TX = StatusReg ;
StatusReg_TX = StatusReg_TX & TBS_Bit ;
}while ( !( StatusReg_TX ==0x04 ) ) ; //等待發送寄存器釋放,是則發送
TxBuffer1 = txdbuff [ 0x00 ] ; //0x25 ID:128
TxBuffer2 = txdbuff [ 0x01 ] ; //0x01
TxBuffer3 = txdbuff [ 0x02 ] ;
CommandReg = CDO_Bit | TR_Bit | ERB_Bit ; // 請求數據發送,同時清除數據超載,釋放接收緩沖區
Sending = False ;
}
// Send CAN 調試用
//void SendTT_CAN ( void ) //輸出頻率送CAN總線
//{
// do { StatusReg_TX = StatusReg ;
// StatusReg_TX = StatusReg_TX & TBS_Bit ;
// }while ( !( StatusReg_TX ==0x04 ) ) ; //等待發送寄存器釋放,是則發送
// TxBuffer1 = txdbuff [ 0x00 ] ; //0x25 ID:128
// TxBuffer2 = txdbuff [ 0x01 ] ; //0x02
// TxBuffer3 = txdbuff [ 0x02 ] ;
// TxBuffer4 = txdbuff [ 0x03 ] ;
// SendOverTime = 0x00 ;
// CommandReg = CDO_Bit | TR_Bit | ERB_Bit ; // 請求數據發送,同時清除數據超載,釋放接收緩沖區
// Sending = False ;
//}
void init ( void )
{
Rcv_Head_Flag0 = Rcv_Head_Flag1 = Rcv_Head_Flag2 = Rcv_Head_Flag3 = Rcv_Head_Flag4 =False ;
Rcv_Head_Flag4 = False ;
ResetCAN = 1 ;
SelfStationNo = 0x67 ; //接收站號 24和63
Sending = False ;
senddataflag = False ;
SendOverTime = 0x00 ;
berkControl = 0x00 ;
berkControl_P = 0x08 ;
berkControl_B7 = False ;
DI0=1,DI1=1,DI2=1,DI3=1 ; //輸入初始化
DO0=1,DO1=1,DO2=0,DO3=0 ; //輸出初始化
Rcv_Head_Flag2 = 1 ; //制動信息輸入端初值,如果初始狀態此輸入端為1,則初值為1;否則相反。
LEDCH2 = LEDCH3 = RUNLED = 1 ; //Rxd,Txd 關暗 RUN關暗
ZSGcount =0 ; //轉速收不到,計時單元
Contrtimer = 0 ; //制動信號定時發送
FKYcount =0 ; //壓力收不到,計時單元
WDG=0;WDG=1; //清除watchdog
WDT_CONTR = 0x37 ; //喂狗
}
// 多主模式,固定通訊速度=80Kbps
void init_can ( void )
{
unsigned char i ;
ModeControlReg = RIE_Bit | RM_RR_BIT | EIE_Bit | DOIE_Bit | TIE_Bit ;
while ( ( ModeControlReg & RM_RR_BIT ) == ClrByte )
{
ModeControlReg = RIE_Bit | RM_RR_BIT | EIE_Bit | DOIE_Bit | TIE_Bit ;
_nop_ ( ) ;
_nop_ ( ) ;
}
DELAYFOR (3);
AcceptCodeReg = SelfStationNo ; // 高3位為類型,低5位為站號
AcceptMaskReg = 0x67 ; // 驗收屏蔽碼
BusTiming0Reg = dbt0 ; // 80Kbps
BusTiming1Reg = dbt1 ;
OutControlReg = Tx1Float | Tx0PshPull | NormalMode ;
ClockDivideReg = 0x00 ; // CAN模式定義位 0==BasicCAN Mode
ModeControlReg = RIE_Bit | 0x60 ; // 允許CAN接收中斷,同步
for ( i = 0x00 ; i < 3 ; i ++ )_nop_ ( );
CommandReg = CDO_Bit | ERB_Bit | TR_Bit ; // 釋放接收緩沖區,清除超載,允許CAN接收,發送請求
SendOverTime = 0x00 ;
while ( SendOverTime < 2 ) _nop_ ( ) ; // 20 ms
}
//CAN 接收函數
uchar Receive ( void )
{
StatusReg_ES=StatusReg ;
if ((StatusReg_ES&ES_Bit)==0x40)
{
Sending= False;
}
StatusReg_ES=StatusReg ;
if (( StatusReg_ES & DOS_Bit ) == 0x20)
{
Sending= False;
}
StatusReg_RX = StatusReg ; /*狀態寄存器*/
if ((StatusReg_RX & RBS_Bit)==0x01) /* 接收緩沖器狀態位*/
{
do
{
rxdbuff [ 0x00 ] = RxBuffer1 ; /* 消息正常接收中斷時執行*/
rxdbuff [ 0x01 ] = RxBuffer2 ;
rxdbuff [ 0x02 ] = RxBuffer3 ;
rxdbuff [ 0x03 ] = RxBuffer4 ;
rxdbuff [ 0x04 ] = RxBuffer5 ;
rxdbuff [ 0x05 ] = RxBuffer6 ;
rxdbuff [ 0x06 ] = RxBuffer7 ;
rxdbuff [ 0x07 ] = RxBuffer8 ;
rxdbuff [ 0x08 ] = RxBuffer9 ;
rxdbuff [ 0x09 ] = RxBuffer10 ;
if ( rxdbuff [ 0x00 ] == 0x24 ) // 收到 轉速 報文
{
Rcv_Head_Flag4 = True ;
}
if ( rxdbuff [ 0x00 ] == 0x63 ) // 收到 壓力反饋 報文
{
Rcv_Head_Flag3 = True ;
}
CommandReg = ERB_Bit ; /* 釋放接收緩沖*/
StatusReg_RX = StatusReg ; /*狀態寄存器*/
} while ((StatusReg_RX & RBS_Bit)==0x01) ; /* 若隊列中還有消息,則反復讀取,直到將隊列清空**/
rxdbuff [ 10 ] = InterruptReg ; /* 清除接收中斷 */
return True ;
}
else
{
rxdbuff [ 10 ] = InterruptReg ; /* 清除接收中斷 */
CommandReg = CDO_Bit | ERB_Bit ; /* 釋放接收緩沖區,清除超載,允許CAN接收 */
RXDbuf_Er = True ; /* 接收錯誤標識 */
return False ; /* 不做接收數據處理 */
}
}
//A/D輸入函數
//unsigned int readad(unsigned char channel)
//{
// unsigned int i=0,ndata=0;
// ADCLK = 0;
// ADCS = 0;
// ADOUT = 1;
// for(i=0;i<12;i++)
// {
// if ((channel & 0x08) == 0)
// ADIN = 0;
// else
// ADIN = 1;
// channel = channel << 1;
// ADCLK = 1;
// ndata = ndata << 1;
// ndata = ndata | ADOUT;
// ADCLK = 0;
// }
// ADCS = 1;
// return ndata;
//}
// D/A OUT
void writeda(unsigned int ndata1,ndata2)
{
unsigned int i=0;
ndata2 |= 0x1000;
DACLK = 1;
DACS = 0;
for(i=0;i<16;i++)
{
if ((ndata2 & 0x8000) == 0)
DADAT = 0;
else
DADAT = 1;
DACLK = 0;
ndata2 = ndata2 << 1;
DACLK = 1;
}
DACS = 1;
DACLK = 0;
ndata1 |= 0x8000;
DACLK = 1;
DACS = 0;
for(i=0;i<16;i++)
{
if ((ndata1 & 0x8000) == 0)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -