电子大神的日记本,供应链专家的功夫茶盘,在这里记录、分享与共鸣。

登录以开始

R8C2K的LIN总线设置

来源:瑞萨单片机论坛

仅写了底层驱动,简单的主机和从机的收发,供参考!
主机:
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();
   }
}

博主
zhangguobian2008@163.com
空外之旅博客
点击跳转