TI中文支持网
TI专业的中文技术问题搜集分享网站

TDA4VM: 由于TDA4没有Lin的驱动器,我现在想通过UART来模拟Lin信号,从而进行通讯。

Part Number:TDA4VM

eg.

由于在UART来模拟Lin信号过程中,Lin信号需要 >=13bit的信号,UART无法一次性发送个13bit的数据,我尝试通过降低波特率的方式来实现。

但是,在实现过程中在切换波特率过程比较耗时,导致发送的信号无法连续,从而导致失败。使用的linux的接口代码

static speed_t speed_arr[] = {B230400, B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1200, B600, B300};
static intname_arr[] = { 230400,  115200,  57600,  38400,  19200, 9600,  4800,  2400,  1200, 600,  300};

static uint32_t uart_fd;

struct serial_t {intfd;char*device;/*/dev/ttyS0,...*/intbaud;intdatabit;/*5,6,7,8*/charparity;/*O,E,N*/intstopbit;/*1,2*/intstartbit;/*1*/struct termiosoptions;
};

#define FILE"/dev/ttyS6"

static struct serial_t __seri_conf[] = {[0] = {//connect with b board, ttyS6.device = FILE,.baud =9600,.databit = 8,.parity = 'N',.stopbit = 1,},[1] = {//connect with b board, ttyS6.device = FILE,.baud =19200,.databit = 8,.parity = 'N',.stopbit = 1,},
};




/**
 *@brief  设置串口通信速率
*@param  fd类型 int  打开串口的文件句柄
*@param  speed  类型 int  串口速度
*@return  void
*/
void set_speed(int fd, int speed)
{inti;intstatus;struct termiosOpt;tcgetattr(fd, &Opt);for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++){if  (speed == name_arr[i]){tcflush(fd, TCIOFLUSH);cfsetispeed(&Opt, speed_arr[i]);cfsetospeed(&Opt, speed_arr[i]);status = tcsetattr(fd, TCSANOW, &Opt);if  (status != 0)perror("tcsetattr fd1");return;}tcflush(fd,TCIOFLUSH);}
}

//设置非标准波特率,比如13292
int serial_set_speci_baud(struct serial_t *tty,int baud)
{struct serial_struct ss,ss_set;tcgetattr(tty->fd,&tty->options);cfsetispeed(&tty->options,B38400);cfsetospeed(&tty->options,B38400);tcflush(tty->fd,TCIFLUSH);/*handle unrecevie char*/tcsetattr(tty->fd,TCSANOW,&tty->options);if((ioctl(tty->fd,TIOCGSERIAL,&ss))<0){printf("BAUD: error to get the serial_struct info:%s\n",strerror(errno));return -1;}ss.flags = ASYNC_SPD_CUST;ss.custom_divisor = ss.baud_base / baud;printf("ss.custom_divisor = %d \r\n",ss.custom_divisor);if((ioctl(tty->fd,TIOCSSERIAL,&ss))<0){printf("BAUD: error to set serial_struct:%s\n",strerror(errno));//return -2;}ioctl(tty->fd,TIOCGSERIAL,&ss_set);printf("BAUD: success set baud to %d,custom_divisor=%d,baud_base=%d\n",baud,ss_set.custom_divisor,ss_set.baud_base);return 0;
}

/*get serial's current attribute*/
static int serial_get_attr(struct serial_t *tty)
{if(tcgetattr(tty->fd,&tty->options) != 0){printf("SERIAL: can't get serial's attribute\n");return -1;
}return 0;
}

/*update serial's attrbute*/
static int serial_attr_update(struct serial_t *tty)
{tcflush(tty->fd,TCIFLUSH);/*handle unrecevie char*/if((tcsetattr(tty->fd,TCSANOW,&tty->options)) < 0){return -1;
}return 0;
}

static int serial_init_databit(struct serial_t *tty)
{if(serial_get_attr(tty)<0)return -1;tty->options.c_cflag &= ~CSIZE;switch(tty->databit){case 5: tty->options.c_cflag |= CS5;break;case 6: tty->options.c_cflag |= CS6;break;case 7: tty->options.c_cflag |= CS7;break;case 8: tty->options.c_cflag |= CS8;break;default:printf("SERIAL: unsupported databit %d\n",tty->databit);return -2;
}if(serial_attr_update(tty) < 0)return -3;printf("SERIAL: set databit to %d\n",tty->databit);return 0;
}

static int serial_init_parity(struct serial_t *tty)
{if(serial_get_attr(tty)<0)return -1;/*ignore framing and parity error*/tty->options.c_iflag = IGNPAR;switch (tty->parity){case 'n':case 'N':/* Clear parity enable */tty->options.c_cflag &= ~PARENB;/* Enable parity checking */tty->options.c_iflag &= ~INPCK;break;case 'o':case 'O':/* 设置为奇校检*/tty->options.c_cflag |= (PARODD|PARENB);/* Disnable parity checking */tty->options.c_iflag |= (INPCK|ISTRIP);break;case 'e':case 'E':/* Enable parity */tty->options.c_cflag |= PARENB;/* 转换为偶效验*/tty->options.c_cflag &= ~PARODD;/* Disnable parity checking */tty->options.c_iflag |= (INPCK|ISTRIP);break;default:printf("SERIAL: unsupported parity %c\n",tty->parity);return -2;
}if(serial_attr_update(tty) < 0)return -3;printf("SERIAL: set parity to %c\n",tty->parity);return 0;
}

static int serial_init_stopbit(struct serial_t *tty)
{if(serial_get_attr(tty)<0)return -1;switch(tty->stopbit){case 1:tty->options.c_cflag &= ~CSTOPB;break;case 2:tty->options.c_cflag |= CSTOPB;break;default:printf("SERIAL: unsupported stopbit %d\n",tty->stopbit);return -2;
}if(serial_attr_update(tty) < 0)return -3;printf("SERIAL: set stopbit to %d\n",tty->stopbit);return 0;
}

static void uart_init(struct serial_t* seri_conf)
{uart_fd = open(FILE, O_RDWR | O_NOCTTY | O_NONBLOCK);seri_conf->fd = uart_fd;set_speed(seri_conf->fd,seri_conf->baud);if(serial_init_databit(seri_conf)<0)printf("serial_init_databit error\n");if(serial_init_parity(seri_conf)<0)printf("serial_init_parity error\n");if(serial_init_stopbit(seri_conf)<0)printf("serial_init_stopbit error\n");//struct termios opt;tcgetattr(seri_conf->fd,&seri_conf->options);seri_conf->options.c_iflag &=~(BRKINT|ICRNL|INPCK|ISTRIP|IXON);seri_conf->options.c_lflag &=~(ICANON|ECHO|ECHOE|ECHONL|ISIG|IEXTEN);seri_conf->options.c_oflag &=~(OPOST);if(tcsetattr(seri_conf->fd,TCSANOW,&seri_conf->options)!=0)printf("error");
}

static int8_t BoardDiag_linSend(uint32_t  fd, uint8_t *writeBuf,uint32_t byteCount)
{int8_t  ret = 0;ret = write(fd, (uint8_t *)&writeBuf[0], byteCount);if(!ret){close(fd);return -1;}return 0;
}


static int8_t BoardDiag_linReceive(uint32_t fd, uint8_t *readBuf,uint8_t byteCount)
{int8_t  ret = 0;ret = read(fd, (uint8_t *)&readBuf[0], byteCount);if(!ret){close(fd);return -1;}return 0;
}

typedef struct
{uint8_t sync;uint8_t pid;uint8_t data[7];uint8_t checksum;
}linData_t;

void Lin_SendBreak(void)
{uint8_tbreakfield1;int8_tstatus= 0;linData_tlinMasterData;//breakuart_init(&__seri_conf[0]);breakfield1 = 0x00;//usigned char breakfieldBoardDiag_linSend(uart_fd, (uint8_t *)(&breakfield1),sizeof(breakfield1));close(uart_fd);//重置波特率
	uart_init(&__seri_conf[1]);set_speed(uart_fd,19200);linMasterData.sync= 0x55;linMasterData.pid= 0xC1;//PID:0xC1 1100 0001ID: 0x01linMasterData.data[0]= 0x07;// 0000 0111protectId = 0x01;linMasterData.checksum = LIN_MakeChecksum(protectId,sizeof(linMasterData.data),(uint8_t *)(&linMasterData.data));status = BoardDiag_linSend(uart_fd, (uint8_t *)(&linMasterData),sizeof(linMasterData));
}

int main(void)
{Lin_SendBreak();close(uart_fd);
	return 0;
}

请问:

问题1.在TDA4上通过UART来模拟Lin信号是否是可行的?

如果可行,有什么比较好的方法来降低波特率的切换耗时的问题吗?

如果不行,有什么别的好的方法可以实现呢?

问题2.我用devmem2工具来读取UART4     地址0x02840000寄存器的数据正常,但是我用devmem2工具向寄存器地址0x02840000写值时,提示写入成功,但是重新读取时值未发生改变。

请问这个寄存器是不让修改的吗?

Annie Liu:

感谢您对TI产品的关注!为更加有效地解决您的问题,我们将问题发布在E2E英文技术论坛上,将由资深的英文论坛工程师为您提供帮助。您也可以查看下帖了解进展:

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1136636/tda4vm-since-tda4-does-not-have-a-driver-for-lin-i-now-want-to-use-uart-to-simulate-the-lin-signal-and-thus-execute-the-communication 

,

Annie Liu:

zhu he 说:问题1.在TDA4上通过UART来模拟Lin信号是否是可行的?

是的,这应该是可能的,但这尚未得到验证。

zhu he 说:由于在UART来模拟Lin信号过程中,Lin信号需要 >=13bit的信号,UART无法一次性发送个13bit的数据,我尝试通过降低波特率的方式来实现。

为什么要切换波特率?切换波特率如何帮助您接收连续的 13 位数据?

zhu he 说:问题2.我用devmem2工具来读取UART4     地址0x02840000寄存器的数据正常,但是我用devmem2工具向寄存器地址0x02840000写值时,提示写入成功,但是重新读取时值未发生改变。

您使用的是哪个 SDK 版本,我们需要检查 UART4 是由 Linux 拥有还是为 RTOS 保留。

,

zhu he:

1.为什么要切换波特率?切换波特率如何帮助您接收连续的 13 位数据?

由于需要满足13个bit,uart无法一次性发13个bit,由于接受方是19200波特率,发送方需要拉低波特率来满足13个bit。

2.您使用的是哪个 SDK 版本?

a.使用的是ti-processor-sdk-rtos-j721e-evm-08_01_00_13这个SDK版本,

b.同时UART5     UART_DLL地址0x02850000 和UART_DLH 0x02850004 寄存器也是无法写入的。帮忙查看一下为什么不能写。

3.如何通过寄存器来修改UART5的波特率,麻烦告知我UART_DLH 和UART_DLL 的寄存器地址。

赞(0)
未经允许不得转载:TI中文支持网 » TDA4VM: 由于TDA4没有Lin的驱动器,我现在想通过UART来模拟Lin信号,从而进行通讯。
分享到: 更多 (0)