新手入门
- 积分
- 19
- 金钱
- 19
- 注册时间
- 2018-3-14
- 在线时间
- 3 小时
|
1金钱
目前架构:
PC下连了两个STM32模块,用STM32的UART通过RS485模块互连。
实现功能:
只是想实现正常通讯(简单读写寄存器),两个STM32烧录同样的东西(除了ID)。
UART使用DMA收发,IDLE中断。
在正常写寄存器后,应答“AAAA”(字符)
问题描述:
正常时:此时两片的代码都插入了一些printf,从UART2中打印出调试信息,可以清楚看到:电脑发送1号STM32的写命令,1号识别ID进行写操作,2号ID不匹配,不应答。然后1号回复了“AAAA”。重复多次操作无异常。之后同时去掉了两片中的printf,运行变快,也无异常。
异常时:只去掉1号的printf,保留2号的printf(1号快,2号慢)。进行写操作,第一遍正常,1号完成了写操作(是从点灯看出来的),2号的调试信息表示ID不匹配,不应答。1号回复“AAAA”。但从第二次开始,1号仍然正常工作,但2号收到的数据就不对了。
以下是2号收到正常与异常的数据:
A857A857001F00295732570B040134300100000049884AC4
57A857411F0029A832570B000134305700000004884AC40100000049
我用示波器看了UART线上的数据,是正常的。而二号中断后收到的很奇怪,多出来一些数据,而且头一个“A8”不见了,中间还有错的。
===========================================现象就是这样↑
我非常怀疑是1号回复的"AAAA"被2号收到后影响的。平时两片同时开或关printf,使得两片速度一样,同时接受数据后触发IDLE中断,开始处理,2号早早处理完了,等1号发“AAAA”时,2号是空闲的,可以正常接受一次,做不应答处理。
但当1号快2号慢时,2号还未处理完第一条命令,1号的“AAAA”就来了,这时我感觉就出了问题,但不知道为啥。
我本意是2号处理时,不再接受其它东西,但显然还是有影响的,下面是代码:
_it.c
[mw_shl_code=c,true]void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
uint32_t temp;
/* 如果是串叿1中断 */
if(USART1 == huart1.Instance)
{ /* 如果是串叿1IDLE中断 */
if(RESET != __HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE))
{
/* 清除中断标志 */
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
/* 停止DMA接收 */
HAL_UART_DMAStop(&huart1);
/* 获取DMA当前还有多少未填兿 */
temp = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
/* 计算串口接收到的数据个数 */
Rx_len = BUFFERSIZE - temp;
recv_end_flag = 1;
}
}
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}[/mw_shl_code]
main.c
main函数中就是普通的循环:
[mw_shl_code=c,true]__HAL_UART_CLEAR_FLAG(&huart1, UART_CLEAR_IDLEF | UART_CLEAR_NEF);
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); /* 使能串口1 IDLE中断 */
HAL_UART_Receive_DMA(&huart1,pR,BUFFERSIZE);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
uartdmaget();
}
/* USER CODE END 3 */[/mw_shl_code]
uartdmaget这个函数处理所有东西:
[mw_shl_code=c,true]void uartdmaget(void)
{
if(recv_end_flag ==1)
{
memset(LocalBuff,0,sizeof(LocalBuff));
memcpy(LocalBuff,ReceiveBuff,sizeof(ReceiveBuff));
Local_len = Rx_len;
if(Local_len>=21) //只对完整命令译码,否则会出错
{
if(decode()==1)
{
opcode();
}
}
/* 清空接收缓存匿 */
for(int i = 0; i < Rx_len ; i++)
ReceiveBuff=0;
/* 接收数据长度清零 */
Rx_len=0;
recv_end_flag=0;
/* 开启下次接收 */
HAL_UART_Receive_DMA(&huart1,pR,BUFFERSIZE);
}
}[/mw_shl_code]
我刚接触STM32不久,对DMA和中断的用法不是很熟,不知道为什么上次没处理的数据会影响下次,或者是我没有完全关闭DMA的接收或是没清缓存?请大牛指点我的问题所在,谢谢!
|
|