This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
尊敬的 TI 专家:
现在、我正在设计 BMS、使用 MSP430F1611 UART1与一台主机进行通信、主机使用 Modbus 协议、仅使用两个器件、因此我使用异步通信格式、协议使用空闲线格式。
串行端口配置如下:波特率为9600、数据位为8、无奇偶校验位、两个停止位
Modbus 协议、如:0x01 0x03 address shi 地址插槽 numhi numlo crc16lo crc16hi
uart1配置如下:
void VMU_UART_init_9600 (void)
{
BCSCTL1 |= XTS;//高频模式
UCTL1 |= SWRST;//初始 UART
UTCTL1 = SSEL0;// ACLk (32768)、默认字符、而不是地址
UBR01 = 0xC0;//波特率:9600 ACLK:1843200/192 = 9600
UBR11 = 0x00;
UMCTL1 = 0x00;
UCTL1 |= CHAR + SPB;//8位、无奇偶校验、两个停止位
P3SEL |= 0xc0;//P3.7 RX、P3.6 TX
P3DIR |= 0x40;
P5DIR |= BIT4;//收发器 DE、RE 使能
P5OUT &=~BIT4;// DE=0、R/E/=0 RX 是默认状态、不是 TX
UCTL1 &=~SWRST;//启动 UART
ME2 = UTXE1 + URXE1;// uart1 TX 和 Rx 模块使能
IE2 |= URXIE1;
}
ISR 接收如下:
由于我无法判断数据包的开始和结束、我的想法是等待下一个字节设置为 URXIFG、并在接收到的第一个字节为0x01时读取接收缓冲寄存器、1200是超时值
#pragma vector=UART1RX_vector
_interrupt void RX_VMU_byte (void)
{
U8 I;
U16时间;
VMURS485Buf[0]=RXBUF1;
if (VMURS485Buf[0]= 0x01)
{
对于(时间=0;时间<1200 &&!(IFG2&URXIFG1);时间++)
IF (时间< 1200)
VMURS485Buf[1]= RXBUF1;
if (VMURS485Buf[1]= 0x03)
{
对于(I = 2;I < 8;I++)
{
对于(时间=0;时间<1200 &&!(IFG2&URXIFG1);时间++)
IF (时间< 1200)
VMURS485Buf[i]= RXBUF1;
}
}
UART_RESPONSE (VMURS485Buf);
}
}
当我使用串行端口软件发送命令0x01 0x03 0x00 0x01 0x00 0x06 crclo crchi 时
但 VMURS485Buf[1]= RXBUF1;为0x01而不是0x03
值1200为超时
您好!
超时值1200是您的 UART 数据的最大长度吗?
您是否尝试接收表中的所有数据存储、这些数据存储是否正确? 对吧?
我想、如果您希望使用0x01作为第一个字节、只需使用此代码即可:
if(RXBUF1 == 0x01) { } then { }
谢谢!
此致
Johnson
超时值1200是您的 UART 数据的最大长度吗?
是的、超时小于1200
您是否尝试接收表中的所有数据存储、这些数据存储是否正确? 对吧?
VMURS485Buf[VMU_Rec_Num]= RXBUF1;
if (VMU_Rec_Num < MAX_SIZE)
{
VMU_Rec_Num++;
}
在 ISR 中、我使用上述代码、没问题
我想、如果您希望使用0x01作为第一个字节、只需使用此代码即可:
我会尝试
以下代码、我在多进程地址位中使用、没问题、运行正常、我不知道为什么使用 异步通信格式失败。
#pragma vector=UART0RX_vector
_interrupt void UART0_RX0 (){
U8 I;
U16时间;
//U16 TempCRC;
if (URCTL0&URXWIE){
I=Buffer_URX;
if ((i =RAM_Module_ID)){//添加广播
URCTL0&=~URXWIE;
for (time=0;<UART_Time_out)&&!(IFG1&URXIFG0);time++);
if (<UART_Time_out) {
Recdata[0]=缓冲区_URX;
if (i ==RAM_Module_ID){
if (Recdata[0]=3){
for (i=1;i<7;i++){
for (time=0;<UART_Time_out)&&!(IFG1&URXIFG0);time++);
if (<UART_Time_out)
Recdata[i]=Buffer_URX;否则 I=7;
}
}否则
{
MMAddr0_Encle();
返回;
}
这是一种糟糕的接收串行数据的方式。 一直停留在 ISR 中、直到数据包完成。 讨厌。 我使用状态机编写了一个中断驱动的数据包接收器。 当一个完整的数据包到达时、ISR 向主例程发送一条消息。
我必须想知道这些 MCLK 相关超时。 什么是 MCLK? 超时周期是否足够大于字符时间? 为什么不使用__delay_cycles ()?
首先让事情正常工作、而不会超时。
另一件需要注意的事情是您的 RS485接收器。 当没有任何东西驱动总线时、它是否返回到标记(逻辑高电平)状态? 如果 UART 发生浮点或执行其他奇怪的操作、那么发送第一个字符时 UART 可能正忙于接收垃圾。