仅写了底层驱动,简单的主机和从机的收发,供参考!
主机:
void LIN_Mater_Config(void)
{
tstop_tracr = 1; // 强制timerRA终止/LIN 流程
while(tcstf_tracr == 1) // 等待timerRA直到计数停止
{
}
tedgsel_traioc = 1; // 脉冲始于低电平/LIN 流程
tiosel_traioc = 1; // p1_5 作为traio/LIN 流程
tipf1_traioc = 0; // 忽略
tipf0_traioc = 0;
tmod2_tramr = 0; // TMOD2-TMOD0: 000, 定时器模式/LIN 流程
tmod1_tramr = 0;
tmod0_tramr = 0;
tck2_tramr = 0; // f1/LIN 流程
tck1_tramr = 0;
tck0_tramr = 0;
tckcut_tramr = 0; // 忽略
// break width 20M*13/9600=106*256, break width 13 bits./LIN 流程
trapre = 256 - 1; //256-1
tra = 53 - 1;
smd2_u0mr = 1; // UART模式发送8bit数据
smd1_u0mr = 0;
smd0_u0mr = 1;
ckdir_u0mr = 0; // 采用内部时钟
stps_u0mr = 0; // 1 停止位
prye_u0mr = 0; // 不用奇偶校验
// 选择f1
clk1_u0c0 = 0;
clk0_u0c0 = 0;
nch_u0c0 = 0; // TXD0 pin CMOS输出
ckpol_u0c0 = 1; // 上升沿发送数据,下降沿接收数据
uform_u0c0 = 0; // LSB
u0irs_u0c1 = 1; // 发送中断时机:发送完毕
u0rrm_u0c1 = 0; // 不用连续接收模式
// baud rate 20M/(9600*16) = 130
u0brg = 65 - 1; // UART波特率设置
line_lincr = 0; //stop硬件LIN模块
mst_lincr = 1; // 主机模式
bce_lincr2 = 1; // 冲突检测有效
line_lincr = 1;
// 将LIN模块支持的三个利用timerRA的中断关掉;若用户希望利用中断处理,需要使能以下。
bcie_lincr = 1; // 总线冲突检测中断关掉,该sample为了简化,没有作总线冲突检测
sbie_lincr = 1; // 检测到break时发出的中断关掉,该sample用查询
sfie_lincr = 1; // 测量完同步段(Sync)时发出的中断关掉(只应用于从机),该sample用查询
// 清除状态标志
b2clr_linst = 1; // BCDCT 总线冲突检测标志位清零
b1clr_linst = 1; // 检测到break的标志位清零
b0clr_linst = 1; // 测量完同步段(Sync)的标志位清零
traic=5;
tstart_tracr = 1; // 启动timerRA
while(tcstf_tracr != 1) // 确认timerRA启动
{;}
}
/************************************************************************
*函数原型: TA_int
*功能 : Timer A 中断 中断向量22
************************************************************************/
#pragma INTERRUPT TA_int() vect=22;
void TA_int(void)
{
unsigned char Reset_uart0_bitrate;
ir_traic = 0;
if(sbdct_linst == 1)//检测Synch Break结束
{
tstart_tracr=0;
RELAY_UP=RELAY_DOWN=1;
}
if(tcstf_tracr == 0)//测量Synch Field结束
{
RELAY_UP=RELAY_DOWN=0;
te_u0c1=1;
u0tb=0x55;
s0tic=5;
}
}
#pragma INTERRUPT S0t_int() vect=17;
void S0t_int(void)
{
ir_s0tic=0;
u0tb=Tan_Buf[P_Tan_Buf];
P_Tan_Buf++;
if(P_Tan_Buf==3)
{
P_Tan_Buf=0;s0tic=0;
}
}
从机:
/*------------------------------------------------------
名称 : LIN_Synch_Break_Detect_Config
功能 : timerRA接收break信号(判断显性电平持续至少11bit)的初始化工作
入口 : 无
出口 : 无
调用 : 无
寄存器 : timerRA,LIN相关
------------------------------------------------------*/
void LIN_Synch_Break_Detect_Config(void)
{
tstop_tracr = 1; // 强制timerRA终止/LIN flow
while(tcstf_tracr == 1) // 等待timerRA直到计数停止
{;}
ir_traic = 0; // 清零TA中断标志位
tundf_tracr = 0; // 定时器RA下溢标志 无下溢
tedgf_tracr = 0; // 定时器有效边沿判断标志 无有效沿
pd1_5 = 0; // p1_5输入
tedgsel_traioc = 0; // 脉冲开始为低电平/LIN flow
tiosel_traioc = 1; // p1_5 作为traio/LIN flow
// TMOD2-TMOD0: 011,脉冲宽度测量模式/LIN flow
tmod2_tramr = 0;
tmod1_tramr = 1;
tmod0_tramr = 1;
//f8/LIN flow
tck2_tramr = 0;
tck1_tramr = 0;
tck0_tramr = 0;
tckcut_tramr = 0; // 忽略
// 测试break宽度 20M*11/9600=90*256, break宽度11 bits./LIN flow
trapre = 100;
tra = 90;
line_lincr = 0;
mst_lincr = 0; // 从机模式
line_lincr = 1; // 启动LIN功能
sbe_lincr = 0; // 在检测到break后去掉RxD0屏蔽
// 将LIN模块支持的三个利用timerRA的中断
bcie_lincr = 1; // 总线冲突检测中断
sbie_lincr = 1; // 检测到break时发出的中断
sfie_lincr = 1; // 测量完同步段(Sync)时发出的中断(只应用于从机)
// 清除状态标志
b2clr_linst = 1; // BCDCT 总线冲突检测标志位清零
b1clr_linst = 1; // 检测到break的标志位清零
b0clr_linst = 1; // 测量完同步段(Sync)的标志位清零
traic=5;
tstart_tracr = 1; // 启动timerRA
while(tcstf_tracr != 1) // 确认timerRA启动
{;}
lstart_lincr = 1; // 禁止UART接收/ LIN FLOW
while(rxdsf_lincr != 1) // 确认uart接收禁止
{;}
}
/************************************************************************
*函数原型: TA_int
*功能 : Timer A 中断 中断向量22
************************************************************************/
#pragma INTERRUPT TA_int() vect=22;
void TA_int(void)
{
unsigned char Reset_uart0_bitrate;
ir_traic = 0;
if(sbdct_linst == 1)//检测Synch Break结束
{
b1clr_linst=1;p0_0=1;
b2clr_linst=1;
b0clr_linst=1;
}
if(sfdct_linst == 1)//测量Synch Field结束
{
b1clr_linst=1;p0_0=0;
b2clr_linst=1;
b0clr_linst=1;
sbe_lincr=1;
/*==================================================*/
smd2_u0mr = 1; // UART模式发送8bit数据
smd1_u0mr = 0;
smd0_u0mr = 1;
ckdir_u0mr = 0; // 采用内部时钟
stps_u0mr = 0; // 1 停止位
prye_u0mr = 0; // 不用奇偶校验
// 选择f1
clk1_u0c0 = 0;
clk0_u0c0 = 0;
nch_u0c0 = 0; // TXD0 pin CMOS输出
ckpol_u0c0 = 1; // 上升沿发送数据,下降沿接收数据
uform_u0c0 = 0; // LSB
u0irs_u0c1 = 1; // 发送中断时机:发送完毕
u0rrm_u0c1 = 1; // 连续接收模式
// initial: baud rate 20M/(9600*16) = 130
//u0brg = INIT_UART0_BITRATE - 1; // UART波特率设置
/*==================================================*/
// 根据SYNC测量结果,重新计算UART波特率,timerRA的当前值为8个bit所用的时间
Reset_uart0_bitrate = ((90 - tra) * 100 + 100 - trapre) >> 7;
u0brg = (unsigned char)Reset_uart0_bitrate - (unsigned char)1;
pd1_5 = 0; // 设置RXD0端口:输入
pd1_4 = 0; // 设置TXD0端口:输入
re_u0c1 = 1; // 允许uart接收
te_u0c1 = 0; // 禁止uart发送
s0ric=5;
traic=0;
//trapre = 100;
//tra = 90;
}
if(bcdct_linst == 1)//总线冲突
{;}
}
#pragma INTERRUPT S0_int() vect=18;
void S0_int(void)
{
unsigned char i;
unsigned char error1;
ir_s0ric=0;
p0_0=!p0_0;
i=u0rbl;
if(i==0x55){P_Rcv_Buf=0;}
Rcv_Buf[P_Rcv_Buf]=i;
error1=u0rbh;
P_Rcv_Buf++;
if(P_Rcv_Buf==10)
{
P_Rcv_Buf=0;
LIN_Synch_Break_Detect_Config();
}
}
文章评论(0条评论)
登录后参与讨论