STM8S003 -- LIN从机通讯 -- 程序代码讲解

 分享一些LIN的知识,我一开始是写的寄存器版本的从机通讯,但一直调试不通,出现了以下问题:

        1.在不开启中断的情况下,能发送数据,但开了中断就无法发送。

        2.一直无法检测到LIN断开符,即同步间隔段。

        后来通过查手册发现了问题所在,就改用了固件库函数版本,至于问题是什么,后面会提,先介绍一下STM8串口的LIN模式。

        相对于STM32,STM8在LIN通讯方面更有优势,因为STM8对LIN做了更详细的设计,通过寄存器可以更方便快捷地进行LIN通讯。STM8的LIN通讯可以配置主从模式,有自动重同步功能,在每次接收到LIN同步域后自动调整波特率发生器,还能LIN标识符奇偶校验自动检测等等。

目录

1. 主模式

2. 自动重同步功能禁用的从模式

3. 自动重同步功能启用的从模式

4. 从模式的寄存器配置

5. 寄存器版本代码问题所在

6. 从模式的库函数配置

7. 串口中断函数


1. 主模式

UART初始化:

        1. 设置UART_BRR2和UART_BRR1来选择期望的波特率。

        2. 将UART_CR3的LINEN位置1来使能LIN模式。

        3. 将UART_CR2的TEN位和REN位置1来使能发送器和接收器。

2. 自动重同步功能禁用的从模式

UART初始化:

        1. 设置UART_BRR2和UART_BRR1来选择期望的波特率。

        2. 将UART_CR2的TEN位和REN位置1来使能发送器和接收器。

        3. 使能UART_CR6的LSLV位

        4. 将UART_CR3的LINEN位置1来使能LIN模式

3. 自动重同步功能启用的从模式

        此模式与上面描述的从模式类似,只是要额外把LASE位置1使能的自动重同步功能。在此模式下, UART在每次接收到LIN同步域后,调整波特率发生器

4. 从模式的寄存器配置

        根据上面的步骤进行配置就好,如果想要开启接收中断或LIN断开符检测中断,只需要置位相关寄存器即可。

        一般置位只需 UART1->CR1 |= 0x01 ,这样UART1->CR1寄存器的第1位便置1了,库函数的话直接调用中断使能函数即可(提一嘴,无论是寄存器版本还是库函数版本,一定一定都要看手册进行配置)。

        中断函数是 INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18),18是UART1接收寄存器满的中断向量号。

5. 寄存器版本代码问题所在

   先看一下手册:

STM8S003 -- LIN从机通讯 -- 程序代码讲解_第1张图片       我所使用的STM8S003F4P6单片机只有一个UART口,即UART1,是不支持LIN从模式的,所以我寄存器配来配去LIN的从机模式都是不行的,因为它TM的根本就没有从机模式,哭了。。。所以大家下次写代码的时候请请请请请请一定要先看清楚手册!!!

6. 从模式的库函数配置

        虽然它没有从模式,但它有主模式阿!主模式一样可以检测LIN断开符,一样可以接收发送数据,我把主模式当从模式用,不知道这样做是不是有问题的,但我功能最后是成功实现了。

        注:库函数版本不用初始化GPIO口,不用使能UART。

//LIN初始化
void LIN_Init(uint32_t bau){ 
  /* 初始化UART1 */
  UART1_DeInit();
  UART1_Init((u32)bau, UART1_WORDLENGTH_8D, UART1_STOPBITS_1,          UART1_PARITY_NO,UART1_SYNCMODE_CLOCK_DISABLE, UART1_MODE_TXRX_ENABLE);
  UART1_ITConfig(UART1_IT_RXNE_OR, ENABLE);   //开启接收中断

  /* 启用LIN模式 */
  UART1_LINBreakDetectionConfig(UART1_LINBREAKDETECTIONLENGTH_11BITS);
  UART1_LINCmd(ENABLE);
  UART1_ITConfig(UART1_IT_LBDF, ENABLE);     //开启检测断路中断
}

初始化代码很短,因为少了主从模式的配置,但主从的配置也很简单,只需一条库函数:

        UART2_LINConfig(UART2_LIN_MODE_MASTER, UART2_LIN_AUTOSYNC_DISABLE, UART2_LIN_DIVUP_LBRR1);    //主模式  - 禁止自动同步 - LDIV在对BRR1写入以后立即更新

 具体参数配置可以自己看函数介绍。

7. 串口中断函数

  仅供参考:

//串口中断函数
INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18)
{
  uint8_t ReceiveData = 0;
  if(UART1_GetITStatus(UART1_IT_LBDF) == SET){               //检测断路中断
    LIN_RingBUF_ClearRxMsg(&LIN_RxDataBuff);                 //清空当前缓冲区
    UART1->SR;     
    UART1->DR;
    LIN_RxStateGet = SYNCH_GET;                              //更新LIN接收状态
    UART1_ClearITPendingBit(UART1_IT_LBDF);                                    
    UART1_ClearITPendingBit(UART1_IT_RXNE);
    return;
  }

  if(UART1_GetITStatus(UART1_IT_RXNE) == SET){                //接收中断
    ReceiveData = UART1_ReceiveData8();	                      //返回USARTx外设最近接收到的数据。
    if ((UART1->SR & 0x02) != 0x02){                          //判断帧错误	
      if ((ReceiveData==0x55)&&(LIN_RxStateGet==BREAK_GET)){  //处理无同步间隔信号的LIN数据  
        LIN_RingBUF_ClearRxMsg(&LIN_RxDataBuff);              //清空当前缓冲区//清空当前缓冲区
        LIN_RxStateGet = SYNCH_GET;
        return;   
       }
      LIN_MasterRxMsg(ReceiveData);     //消息处理函数
     }
    UART1_ClearITPendingBit(UART1_IT_RXNE);
  }  
}

        有需要的可以找我要代码!我是刚入门LIN通讯,能力不足!希望跟大家一起学习!

        过几天我再写一篇STM32F103的LIN通讯文章,会贴出完整代码,包括LIN的接收发送,以及串口接收环形缓冲区!请多多支持!!!

        注:STM8的接收发送串口接收环形缓冲区等内容编写跟STM32其实是一样的,只是初始化和调用的一些函数名不太一样而已,看懂了32的,8的自然也会写。

     已更新 :STM32F103 -- LIN从机通讯 -- 程序代码详细讲解(2万字长文) ,下面是链接!!!

                    http://t.csdn.cn/IRkcc

你可能感兴趣的:(LIN,STM8,物联网,单片机,stm32)