/*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
LINtongxun.rar_LIN通讯_lin_lin 通讯
版权申诉
169 浏览量
2022-09-24
00:20:09
上传
评论
收藏 4KB RAR 举报
钱亚锋
- 粉丝: 90
- 资源: 1万+
最新资源
- 百度地图,显示闸站分布,以及切换闸站位置,上传闸站图片信息的cordova插件,包含百度地图和百度定位库文件
- 基于合泰单片机的智能夹球小车(esp8266代码+k210代码+合泰单片机代码)
- 一个天气查询的安卓APP
- 基于CC2530+DHT11温湿度传感器实现物联网多传感器火灾报警系统
- 基于51单片机的简易计算器 / 具有加减乘除四则运算功能
- 学校端午节比赛dwj-master.zip
- 基于qt实现简单的加减乘除四则运算
- python爬虫案例python-graphs.rar
- python爬虫案例python-graphics.rar
- python爬虫案例python-geometry.rar
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈