?? lintongxun.cpp
字號:
/*define*/
#define MAX_DATA 1 // Max bytes lin frame data
#define SCI_BAUDRATE 19200 // SCI baud rate
#define SCI_CLOCK 200 0000 // Bus clock in Hz
#define EVER (;;)
#define FALSE -1
#define TRUE 0
#define DEBOUNCE 1 /* 20.5ms x (1+1) = 41ms */
#define LOW_POWER 195 /* 20.5ms x (195+1) = 4s */
l_bool sleep_mode = 0;
static l_u16 previous_start_time = 0; /* Wraps around but usage is safe */
enum lin_state { IDLE, _BREAK, SYNCH, PROTECTED_IDENTIFIER, DATA_0, DATA_1,
DATA_2, DATA_3, DATA_4, DATA_5, DATA_6, DATA_7, CHECKSUM };
struct message {
unsigned char identifier;
unsigned char data_field[MAX_DATA];
};
struct frame {
unsigned char protected_id;
unsigned char data[MAX_DATA];
unsigned char check;
enum lin_state state;
unsigned char error;
};
struct frame rx;
// Functions
/////////////////////////////////////////////////////////////////////////////////////////
void LINInit(void);
Bool LINGetMsg(Bool get_data, struct message *msg);
Bool LINSendMsg(Bool master, Bool send_data, struct message msg);
enum lin_state LINCheckState(void);
/*LIN初始化*/
void LINInit(void)
{
int sbr,i;
sbr=(SCI_CLOCK/SCI_BAUDRATE/16); //設置波特率
SCI1BDH =(unsigned char)(sbr>>8);
SCI1BDL =(unsigned char)sbr;
SCI1C2 =0x2C; //SCI中斷使能
// Break character is 13 or 14 bit long
SCI1S2=0x04; // 設置中斷字節長度 (13或14位)
// Initializes LIN receive frames
rx.protected_id=0; //初始化LIN的接收幀
rx.state=IDLE;
rx.error=0;
rx.check=0;
for (i=0;i<MAX_DATA;I++)
msg- FALSE;
return PROTECTED_IDENTIFIER)
if (get_data)
{
if(rx.state == CHECKSUM)
{
for(i = 0; i < MAX_DATA; i++)
msg->data_field[i] = rx.data[i];
rx.state = IDLE;
}
else
for(i = 0; i < MAX_DATA; i++)
msg->data_field[i] = 0;
}
return(TRUE);
}
/*SCI接收中斷子程序*/
interrupt void SCI1_RX(void) // SCI 的接收中斷子程序
{
if(!LINGetChar()) // 如果LIN 未接收到字符
{
rx.error = 1;
rx.state = IDLE;
}
}
/*LIN發送字符子程序*/
Bool LINSendChar(Bool brk, unsigned char ch) // LIN的發送字符子程序
{
// Waits until transmit data registry is empty (TDRE=1)
while(!(SCI1S1&0x80))
;
// If break field, transmits one break character (13-14 bits of dominant value)
if(brk)
{
SCI1C2 |= 0x01;
SCI1C2 &= ~0x01;
}
else
SCI1D = ch;
return(TRUE);
/*LIN 發送校驗子程序*/
Bool LINCheckSend(enum lin_state status, unsigned char val) //LIN發送校驗發送子程序
{
// While until sci data has been received
while(rx.state < status)
if(rx.error)
return(FALSE);
switch(status)
{
case _BREAK:
case SYNCH:
break;
case PROTECTED_IDENTIFIER:
if(rx.protected_id != val)
return(FALSE);
break;
case DATA_0:
case DATA_1:
case DATA_2:
case DATA_3:
case DATA_4:
case DATA_5:
case DATA_6:
case DATA_7:
if(rx.data[status-DATA_0] != val)
return(FALSE);
break;
case CHECKSUM:
if(rx.check != val)
return(FALSE);
break;
}
return(TRUE);
}
/*LIN發送幀子程序*/
Bool LINSendMsg(Bool master, Bool send_data, struct message msg) // LIN 發送幀子程序
{
unsigned char check_sum, parity_id, i;
rx.error = 0;
if(master)
{
// Sends break feald
if(!LINSendChar(TRUE, 0x00))
return(FALSE);
// Check break sending
if(!LINCheckSend(_BREAK, 0x00))
return(FALSE);
// Sends synch feald
if(!LINSendChar(FALSE, 0x55))
return(FALSE);
// Checks synch sending
if(!LINCheckSend(SYNCH, 0x55))
return(FALSE);
parity_id=LINCalcParity(msg.identifier);
// Sends protected identifier field
if(!LINSendChar(FALSE, parity_id))
return(FALSE);
// Checks protected identifier sending
if(!LINCheckSend(PROTECTED_IDENTIFIER, parity_id))
return(FALSE);
}
if(send_data)
{
for(i=0; i < MAX_DATA; i++)
{
// Sends data field
if(!LINSendChar(FALSE, msg.data_field[i]))
return(FALSE);
// Checks data sending
if(!LINCheckSend(DATA_0+i, msg.data_field[i]))
return(FALSE);
}
check_sum = LINCalcChecksum(msg.data_field);
// Sends checksum field
if(!LINSendChar(FALSE, check_sum))
return(FALSE);
// Checks checksum sending
if(!LINCheckSend(CHECKSUM, check_sum))
return(FALSE);
rx.state = IDLE;
}
return(TRUE);
}
/*LIN 校驗狀態*/
enum lin_state LINCheckState(void) // LIN 的校驗狀態(結果)
return rx.state;
}
/*校驗是否為睡眠模式*/
void CheckLowPower(void)
{
l_u16 status;
status = l_ifc_read_status_i1();
/* Sleep command received? */
if ((status & 0x0008)== L_SLEEP_REQUEST) /* 判斷是否為睡眠模式*/
{
LIN_EN_PIN = 0; /* yes, disable MC33399 LIN interface turn off */
/* LT1121 to reache low power consumption */
}
if ((status & 0x00FF) == 0x00) /* No activity on LIN? */
{
low_power_delay--; /* yes, decrement the counter */
}
else
{
low_power_delay = LOW_POWER;
}
if (low_power_delay == 0) /* no activity on LIN for 4 seconds? */
{
LIN_EN_PIN = 0; /* yes, disable MC33399 LIN interface turn off */
/* LT1121 to reache low power consumption */
}
}
/*校驗返回值*/
void Check (l_bool return_value)
{
if (return_value)
{
NodeFailure();
}
}
/*返回值不正確進入死循環*/
void NodeFailure (void)
{
for EVER /* To avoid warning message */
{
/* forever */
}
}
/*進入睡眠模式
*/void GotoSleep (void)
{
while (l_sch_tick_i1() != 1) /* one round */
{
BusyWaitUntilNextPeriod();
}
l_ifc_goto_sleep_i1(); /* send the sleep commnand */
sleep_mode = 1; /* set the sleep mode flag */
}
void BusyWaitUntilNextPeriod (void)
{
l_u16 t_now; /* The time counter value for now */
l_u16 elapsed; /* Time elapsed since previous ideal start time */
do
{
#ifdef PET_WATCHDOG
PET_WATCHDOG();
#endif
t_now = l_get_us_counter();
elapsed = (l_u16) (t_now - previous_start_time);
}
while (elapsed < HW_DELAY);
previous_start_time += HW_DELAY;
/* This construct avoids time drift, previous_start_time = t_now, wouldn't */
}
/*主函數 main */
void main (void)
{
l_u8 button_request_id = 0;
l_bool result;
low_power_delay = LOW_POWER; /* initialize the low power counter */
BUTTON_DDR = 0; /* set the button pin as input */
LED_DDR |= LED_MASK; /* set LED port as output */
LED_PORT &= ~LED_MASK; /* turn the LED off */
LIN_EN_DDR = 1; /* set LIN enable pin as output */
LIN_EN_PIN = 1; /* enable 33399 LIN interface */
init_target();
result = l_sys_init();
Check(result);
l_ifc_init_i1();
ENABLE_INTS(); /* turn on interrupts */
result = l_ifc_connect_i1();
Check(result);
TSC = 0x00; /* timer prescaler /1 */
TSC &= ~(0x20); /* start timer */
l_u8_wr_SlaveRespB0_demo_net(0x81); /* set the slave response */
for EVER
{
PET_WATCHDOG();
if (l_flg_tst_res_done()) /* conflict resolving done flag set? */
{
/* yes, clear the slave response */
l_u8_wr_SlaveRespB0_demo_net(0x80);
l_flg_clr_res_done(); /* clear the flag */
}
if (TSC & 0x80) /* is overflow flag set? */
{
TSC &= ~(0x80); /* yes, clear it */
count++; /* used for LED flashing */
ReadButton(); /* read button on button port */
LedDisplay(); /* update LEDs on LED port */
LinResponse(); /* provide LIN response */
CheckLowPower(); /* check the low power mode */
}
}
}
void main (void)
{
/* Initialize the LIN interface */
if (l_sys_init ())
{
/* The init of the LIN software failed */
}
else
{
l_ifc_init_MyLinIfc (); /* Initialize the interface */
if (l_ifc_connect_MyLinIfc ())
{
/* Connection of the LIN interface failed */
}
else
{
/* Connected, now ready to send/receive set the normal
/* schedule to run from beginning for this specific interface */
l_sch_set_MyLinIfc (MySchedule1, 0);
}
}
start_main_application (); /* Ready with init, start actual applic */
}
/* main */
/* 10 ms based on the minimum LIN tick time, in LIN description file... */
void main_application_10ms (void)
{
/* Do some application specific stuff... */
/* Just a small example of signal reading and writing */
if (l_flg_tst_RxInternalLightsSwitch ())
{
l_u8_wr_InternalLightsRequest (l_u8_rd_InternalLightsSwitch());
l_flg_clr_RxInternalLightsSwitch ();
}
/* In-/output of signals, do not care about the return value, as we
/* will never switch schedule anyway... */
(void) l_sch_tick_MyLinIfc();
} /* main_application_10ms */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -