通过串口助手模拟PC发串口帧给STM32无返回
大神们。又遇到一个问题,我用串口助手PC发串口帧给STM32无返回。
我的帧定义如下:
单片机接收的数据帧(其中不包括帧头:0x55)
typedef struct
{
unsigned charucIndex; //从器件编号
unsigned charucOprType; //操作类型,读00写01
unsigned charucOprAddr2; //Addr2 地址低位
unsigned charucOprAdd1; //Addr1 地址中间
unsigned charucOprAdd0; //Addr0 地址高位
unsigned charucOprDataLen; //len 数据长度(ucDataBuffer内的数据长度)
unsigned charucXorValue; //Xor 校验数据(异或)
unsigned charucDataBuffer[256]; //DataBuffer 数据
}
所有数据均为16进制即HEX,请自觉在前面加上0x)
第一个字节为帧头0x55
第二个字节代表操作从器件编码:
00:selfTestResult(0xffff的状态字,如发55 00 则返回,后面位没用到)
01: ADC
02: IIC_INA220
03: IIC_EEPROM
04: EPLD_GPIO
05: Ethernet(KSZ8041)
06: FSMC_Flash(暂留)
07: FSMC_SRAM(暂留)
第三个字节代表读写操作类型:00-读,01-写
第四个字节代表待读写寄存器的地址低位
第五六个字节代表待读写寄存器的地址高位
第七个字节代表数据长度
第八个字节为第2,3,4,5,6,7,9个字节数据的异或,用于数据校验
第九个字节代表往对应寄存器写入的数据(读命令下该字节无意义)
注:所有命令下发正确后都会首先返回:AA 50 FF(EE),文中描述的返回值皆是指在这之后的数据。AA:收到帧头 50:校验正确 FF:写入正确(EE:写入错误)
我的串口采用接收中断:
串口配置:
static void USART_Config(void)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
u32 tm;
/* USARTx configured as follows:
- BaudRate = 115200 baud
- Word Length = 8 Bits
- One Stop Bit
- No parity
- Hardware flow control disabled (RTS and CTS signals)
- Receive and transmit enabled
*/
USART_InitStructure.USART_BaudRate = 115200;
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;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9,GPIO_AF_USART1); //PA9
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1); //PA10
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_9|GPIO_Pin_10);
GPIO_Init(GPIOA,&GPIO_InitStructure);
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
tm = GetTimeBaseMs();
while((GetTimeBaseMs() - tm) < 1){}
USART_ClearFlag(USART1,USART_FLAG_TC);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
///********************USART4**************************/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_UART4); //PC10
GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_UART4); //PC11
GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_10|GPIO_Pin_11);
GPIO_Init(GPIOC,&GPIO_InitStructure);
USART_Init(UART4, &USART_InitStructure);
//USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);
USART_Cmd(UART4, ENABLE);
}
串口中断配置
static void NVIC_config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* NVIC configuration */
/* Configure the Priority Group to 2 bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* Enable the USARTx Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
判断帧有无接收完全
u8 IsUART1FrameReady()
{
u8 ucSum = 0;
u8 Txbuf[1];
if(RecComplete == 0)
{
return 0;
}
else
{
RecComplete = 0;
ucSum ^= Uartpkt.ucPortType;
ucSum ^= Uartpkt.ucOprType;
ucSum ^= Uartpkt.ucOprDUT;
ucSum ^= Uartpkt.ucOprChannel;
ucSum ^= Uartpkt.ucOprControl;
ucSum ^= Uartpkt.ucOprDataLen;
ucSum ^= Uartpkt.ucDataBuffer[0];
if(Uartpkt.ucXorValue == ucSum)
{
Txbuf[0] = 0x50; //校验正确返回50
UART1_SendData(Txbuf,sizeof(Txbuf));
return 1;
}
else
{
return 0;
}
}
}
串口中断函数
void USART1_IRQHandler(void)
{
u8 ReceiveChar;
u8 buf[1];
/* 接收 */
if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET) //收到字符
{
ReceiveChar = USART_ReceiveData(USART1);
if(ReceiveChar == PKT_HEAD)
{
RxIndex = 0;
buf[0] = 0xaa; //收到帧头返回AA
UART1_SendData(buf,1);
}
else if(RxIndex < 7) //
{
*((u8*)&Uartpkt + RxIndex) = ReceiveChar;
RxIndex++;
}
else if((RxIndex-7) < Uartpkt.ucOprDataLen)
{
Uartpkt.ucDataBuffer[RxIndex-7] = ReceiveChar;
RxIndex++;
}
else
{
//USART_ClearFlag(USART1,USART_FLAG_RXNE);
RecComplete = 1; //
}
}
/* 发送*/
if (USART_GetITStatus(USART1, USART_IT_TXE) == SET)
{
if (TxIndex < DataLength)
{
/* Send Transaction data */
USART_SendData(USART1, TxBuf[TxIndex++]);
}
else
{
/* Disable the Tx buffer empty interrupt */
USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
TxBufEmpty = 1; //
}
}
}
主函数
while (1)
{
if(IsUART1FrameReady() == 1)
{
ParsePaket();//分析串口帧
}
}
目前只能实现用串口助手发55返回AA,如果我在串口助手里发整串帧命令,比如第一个获取selftestresult的命令:
55 00 00 00 00 00 00 00 00 也只能返回AA,而返回不了0xffff的状态量
串口帧有长有短,比如第一个其实只发55 00就应该有返回的,帧里面余下的字节定义都没用到,而其他的第二以后的命令有的会用到余下的字节定义,现在是用串口助手模拟发整个帧命令无返回,不知道各位大神是否明白我的意思?
我的代码是否有问题?为啥不到返回值呢?
/* 发送*/
while(TxIndex < DataLength)
{
while(USART_GetITStatus(USART1, USART_IT_TXE) != SET);
USART_SendData(USART1, TxBuf[TxIndex++]);
}
/* 发送*/
关掉串口中断
while(TxIndex < DataLength)
{
while(USART_GetITStatus(USART1, USART_IT_TXE) != SET);
USART_SendData(USART1, TxBuf[TxIndex++]);
}
开启出口中断
USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
while(TxIndex < DataLength)
{
while(USART_GetITStatus(USART1, USART_IT_TXE) != SET);
USART_SendData(USART1, TxBuf[TxIndex++]);
}
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
}
这样改的也不行啊……