找回密码
 立即注册
查看: 28|回复: 0

51-LIN总线从机收发测试-USART1,STC32G144K246实验箱演示程序

[复制链接]
  • 打卡等级:常住居民I
  • 打卡总天数:78
  • 最近打卡:2026-07-21 13:27:09
已绑定手机

231

主题

168

回帖

1069

积分

版主

积分
1069
发表于 2026-7-3 14:20:18 | 显示全部楼层 |阅读模式
51-LIN总线从机收发测试-USART1,STC32G144K246实验箱演示程序
主程序main.C代码如下(汇编版本在附件中):


/*---------------------------------------------------------------------*/
/* --- Web: www.STCAI.com ---------------------------------------------*/
/* --- BBS: www.STCAIMCU.com  -----------------------------------------*/
/*---------------------------------------------------------------------*/

/*************  功能说明    **************

本例程基于STC32G144K246为主控芯片的实验箱进行编写测试。

使用Keil C251编译器,Memory Model推荐设置XSmall模式,默认定义变量在edata,单时钟存取访问速度快。

edata建议保留1K给堆栈使用,空间不够时可将大数组、不常用变量加xdata关键字定义到xdata空间。

USART类型Lin从机总线收发测试用例,默认通信脚:P4.3 P4.4(实验箱需飞线测试).

收到一个非本机应答的完整帧后通过USB-CDC串口输出, 并保存到数据缓存.

收到一个本机应答的帧头后(例如:ID=0x13), 发送据进行应答.

默认传输速率:9600波特率, 用户可自行修改.

下载时, 默认时钟 48MHz (用户可自行修改频率).

******************************************/

#include "..\comm\STC32G144K246.h"
#include "ai_usb.h"

/****************  用户定义宏  ****************/

#define MAIN_Fosc        48000000UL
#define Baudrate         9600UL
#define TM               (65536 -(MAIN_Fosc/Baudrate/4))

/****************  本地引脚定义  **************/

sbit SLP_N  = P4^2;     //0: Sleep

/****************  本地常量声明  **************/

#define FRAME_LEN           8    //数据长度: 8 字节
#define UART1_BUF_LENGTH    64

/****************  本地变量声明  **************/

u8 Lin_ID;
u8 TX_BUF[8];

bit B_RX1_Flag; //接收标志
bit B_TX1_Busy; //发送忙标志
bit RX1_TimeOut;
u8  TX1_Cnt;    //发送计数
u8  RX1_Cnt;    //接收计数

u8  RX1_Buffer[UART1_BUF_LENGTH]; //接收缓冲
u8  tmp_Buffer[16]; //接收缓冲

/****************  本地函数声明  **************/

void LinInit();
void LinSendData(u8 *pdat);
void LINSendChecksum(u8 *dat);
void LinSetBaudrate(u16 brt);

/********************* 主函数 *************************/
void main(void)
{
    u8 i;

    EAXFR = 1; //扩展寄存器(XFR)访问使能
    CKCON = 0; //提高访问XRAM速度

    P4M1 = 0x00;   P4M0 = 0x14;   //设置为准双向口,P4.2,P4.4推挽输出

    P4PU = 0x18;    //LIN1_TX, LIN1_RX 脚开启内部上拉

    Lin_ID = 0x32;
    LinInit();
    usb_init();
    EA = 1;         //打开总中断

    SLP_N = 1;
    TX_BUF[0] = 0x81;
    TX_BUF[1] = 0x22;
    TX_BUF[2] = 0x33;
    TX_BUF[3] = 0x44;
    TX_BUF[4] = 0x55;
    TX_BUF[5] = 0x66;
    TX_BUF[6] = 0x77;
    TX_BUF[7] = 0x88;

    printf_usb("STC32G144K246 USART to LIN Test Programme!\r\n");

    while(1)
    {
        if((B_RX1_Flag) && (RX1_Cnt >= 2))
        {
            B_RX1_Flag = 0;

            if((RX1_Buffer[0] == 0x55) && ((RX1_Buffer[1] & 0x3f) == 0x13)) //PID -> ID
            {
                LinSendData(TX_BUF);
                LINSendChecksum(TX_BUF);
            }
        }

        if(RX1_TimeOut)     //超时计数
        {
            RX1_TimeOut = 0;

            printf_usb("Read ID = 0x%02X.\r\n",RX1_Buffer[1]&0x3f);
            for(i=0; i<RX1_Cnt; i++)    printf_usb("0x%02x ",RX1_Buffer);    //输出收到的从机数据
            RX1_Cnt  = 0;   //清除字节数
            printf_usb("\r\n");
        }

        if (bUsbOutReady) //USB调试及复位所需代码
        {
            usb_OUT_done();
        }
    }
}

//========================================================================
// 函数: void LinSendByte(u8 dat)
// 描述: 发送一个字节函数。
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2024-08-15
// 备注:
//========================================================================
void LinSendByte(u8 dat)
{
    B_TX1_Busy = 1;
    SBUF = dat;
    while(B_TX1_Busy);
}

//========================================================================
// 函数: u16 LinSendData(u8 *pdat)
// 描述: Lin发送数据函数。
// 参数: *pdat: 设置数据缓冲区.
// 返回: Lin ID.
// 版本: VER1.0
// 日期: 2024-08-15
// 备注:
//========================================================================
void LinSendData(u8 *pdat)
{
    u8 i;

    for(i=0;i<FRAME_LEN;i++)
    {
LinSendByte(pdat);
    }
}

//========================================================================
// 函数: void LINSendChecksum(u8 *dat)
// 描述: 计算校验码并发送。
// 参数: 数据场传输的数据.
// 返回: none.
// 版本: VER1.0
// 日期: 2024-08-15
// 备注:
//========================================================================
void LINSendChecksum(u8 *dat)
{
    u16 sum = 0;
    u8 i;

    for(i = 0; i < FRAME_LEN; i++)
    {
        sum += dat;
        if(sum & 0xFF00)
        {
            sum = (sum & 0x00FF) + 1;
        }
    }
    sum ^= 0x00FF;
    LinSendByte((u8)sum);
}

//========================================================================
// 函数: void LinSetBaudrate(u16 brt)
// 描述: Lin总线波特率设置函数。
// 参数: brt: 波特率.
// 返回: none.
// 版本: VER1.0
// 日期: 2024-08-15
// 备注:
//========================================================================
void LinSetBaudrate(u16 brt)
{
    u16 tmp;

    tmp = (MAIN_Fosc >> 4) / brt;
    USARTBRH = (u8)(tmp>>8);
    USARTBRL = (u8)tmp;
}

//========================================================================
// 函数: void LinInit()
// 描述: Lin初始化函数。
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2024-08-15
// 备注:
//========================================================================
void LinInit()
{
    P_SW1 = (P_SW1 & 0x3f) | 0xc0;  //USART1 switch to, 0x00: P3.0 P3.1, 0x40: P3.6 P3.7, 0x80: P1.6 P1.7, 0xC0: P4.3 P4.4

    SCON = (SCON & 0x3f) | 0x40;    //USART1模式, 0x00: 同步移位输出, 0x40: 8位数据,可变波特率, 0x80: 9位数据,固定波特率, 0xc0: 9位数据,可变波特率
    TI = 0;
    REN = 1;    //允许接收
    ES  = 1;    //允许中断

    LinSetBaudrate(9600);   //设置波特率
    SMOD = 1;               //串口1波特率翻倍
    USARTCR1 |= 0x80;       //LIN Mode Enable
    USARTCR5 |= 0x20;       //LIN Slave Mode

    USARTCR5 |= 0x10;       //AutoSync

    UR1TOCR = 0xc0;         //bit7:使能超时接收,bit6:使能超时中断,bit5:超时时钟选择 1:系统时钟  0:串口数据位率(波特率)
    UR1TOTL = 0x20;
    UR1TOTH = 0x00;
    UR1TOTE = 0x00;         //需要写 UR1TOTE 后,新的TM值才会生效
}

//========================================================================
// 函数: void USART1_int (void) interrupt UART1_VECTOR
// 描述: USART1中断函数。
// 参数: nine.
// 返回: none.
// 版本: VER1.0
// 日期: 2024-08-15
// 备注:
//========================================================================
void USART1_int (void) interrupt 4
{
    u8 Status;

    if(RI)
    {
        RI = 0;             //Clear Rx flag

        Status = USARTCR5;
        if(Status & 0x02)   //if LIN header is detected
        {
            B_RX1_Flag = 1;
        }

        if(Status & 0xc0)   //if LIN break is detected / LIN header error is detected
        {
            RX1_Cnt = 0;
        }

        USARTCR5 &= ~0xcb;  //Clear flag
        RX1_Buffer[RX1_Cnt++] = SBUF;
        if(RX1_Cnt >= UART1_BUF_LENGTH)   RX1_Cnt = 0;
    }

    if(TI)
    {
        TI = 0;             //Clear Tx flag
        B_TX1_Busy = 0;
    }

    if(UR1TOSR & 0x01)
    {
        RX1_TimeOut = 1;
        UR1TOSR = 0x80;     //设置 RTOCF 清除超时标志位 TOIF
    }
}

51-LIN总线从机收发测试-USART1.zip (37.42 KB, 下载次数: 0)


回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-7-22 10:20 , Processed in 0.066231 second(s), 42 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表