1838039453@qq.c 发表于 2017-7-11 10:38:32

STM32F107VCT6 LIN通信

STM32F107VCT6   TJA1021接到串口4
实现LIN的主模式
目前功能仍然没有调试通过,希望有相关经验的能指导一下。
static void lin_gpio_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitGPIOC&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitGPIOC&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
}

static void lin_nvic_init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}

static void lin_uart_init(void)
{
USART_InitTypeDef USART_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
USART_InitStructure.USART_BaudRate = 19200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(macUSARTx, &USART_InitStructure);

USART_LINBreakDetectLengthConfig(macUSARTx, USART_LINBreakDetectLength_11b);

USART_LINCmd(UART4,ENABLE);
USART_ITConfig(UART4, USART_IT_LBD, ENABLE);
//USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);
USART_Cmd(UART4, ENABLE);
}

void LINInit(void)
{
lin_gpio_init();
lin_nvic_init();
lin_uart_init();
}

void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch )
{
/* 发送一个字节数据到USART1 */
USART_SendData(pUSARTx, ch);

/* 等待发送完毕 */
while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
}

static unsigned char LINCalcParity(unsigned char id)
{
unsigned char parity, p0, p1;
parity = id;
p0 = (BIT(parity, 0)^BIT(parity, 1)^BIT(parity, 2)^BIT(parity, 4)) << 6; //偶校验位
p1 = (!(BIT(parity, 1)^BIT(parity, 3)^BIT(parity, 4)^BIT(parity, 5))) << 7; //奇校验位
parity |= (p0 | p1);
return parity;
}

/*************************************************************/
/*                     计算和校验位                        */
/*************************************************************/
static unsigned char LINCalcChecksum(unsigned char *data)
{
unsigned int sum = 0;
unsigned char i;

for(i = 0; i < 8; i++)
{
    sum += data;
    if(sum & 0xFF00)
    {
      sum = (sum & 0x00FF) + 1;
    }
}
sum ^= 0x00FF;
return (unsigned char)sum;
}

#if 0
msg_send.identifier = 0x30;
msg_send.data = 'F';
msg_send.data = 'R';
msg_send.data = 'E';
msg_send.data = 'E';
msg_send.data = 'F';
msg_send.data = 'L';
msg_send.data = 'Y';
msg_send.data = '!';
#endif
void LINSendTest(void)
{
unsigned char check_sum, parity_id, i;

USART_SendBreak(UART4);
Usart_SendByte(UART4, 0x55);

parity_id = LINCalcParity(msg_send.identifier);

LINSendChar(parity_id);

for(i = 0; i < 8; i++)
{
    if(!LINSendChar(msg_send.data))
    {
      return(FALSE);
    }
}

check_sum = LINCalcChecksum(msg_send.data);
// 发送校验和场
LINSendChar(check_sum);

}

MrJiu 发表于 2017-7-11 13:54:03

没搞过LIN,只能帮顶啦!!!!;P;P;P

斜阳 发表于 2017-10-23 09:29:34

没调通,描述详细点。有逻辑分析仪的话吧分析数据也贴上来。

ropepeng 发表于 2017-10-23 11:04:17

单独串口能用么?

无薪税绵 发表于 2017-10-23 13:52:48

请下载以下网址的:STM32中文参考手册.pdf
http://www.openedv.com/thread-7111-1-1.html

再打开手册,跳到第528页,LIN( 局域互联网) 模式
请按手册的步骤操作。

wenshijian 发表于 2018-4-15 15:49:34

F1的不知道怎么搞,不过我用过F0的做LIN产品,F030+TJA1020.
校验函数有两种,LIN V1.3是经典校验,就是校验的时候不要算PID;V2.0以上采用的增强校验,要把PID算进去。对于诊断用的PID(63,64)都采用经典校验,就是不计算PID,这是为了向下兼容。你的校验函数太简单了。
串口4好像不支持LIN,你要看库文件里面的描述,串口4是普通UART,不是增强型的USART。而且你的代码中要打开串口的RXNE中断,这是每个字节接收的中断,LBD只是识别BREAK的中断,相当于帧间隔,数据内容还是要用RXNE。有些人也用IDLE中断代替LBD中断。
我的代码是F0XX+TJA1020的,估计不适用F1XX。F0XX对LIN的支持度比较好点。

1838039453@qq.c 发表于 2019-9-25 12:32:43

软件没问题,是硬件的问题,结贴。

bucunzai 发表于 2020-5-21 16:48:42

wenshijian 发表于 2018-4-15 15:49
F1的不知道怎么搞,不过我用过F0的做LIN产品,F030+TJA1020.
校验函数有两种,LIN V1.3是经典校验,就是校 ...

hi,请问一下,你的F030+TJA1020 方案是否可行呢?也是使用的 UART 连接TJA1020,是吧?可以分享我一下吗?谢谢。

onlytwohand 发表于 2020-7-11 21:51:43

所有STM32发送LIN帧都存在问题,对比发出帧的时序和LIN规范就明白
我卖的LIN转USB设备用了特殊的方法才实现了标准的LIN发送时序,在车上用了接近200套

onlytwohand 发表于 2020-7-11 21:52:23

STM32发送LIN时序都存在问题,不过我解决了

onlytwohand 发表于 2020-7-12 13:36:44

STM32F1和F0系列发送上都存在问题,需要采用特殊方法实现时序

cplFF 发表于 2022-3-3 16:55:06

笑对人生-2015164 发表于 2020-7-12 13:36
STM32F1和F0系列发送上都存在问题,需要采用特殊方法实现时序

我现在使用stm32f0和TJA1020自制lin通信做master,发送数据是没问题了,接收不到Slave返回的数据,是什么原因?

页: [1]
查看完整版本: STM32F107VCT6 LIN通信