首先请大家拜读这个朋友写的https://359303267.github.io/STM32_UART_TxRx_noDMA/。
我基于他的日志调试的,首先表示感谢。他文中说转载的X全家,我这也不知道算不算。为了技术交流,也方便我以后巩固学习我就贴链接了。
如果感觉到本文对你有帮助,你不需要点赞或者打赏。请留住感激,也把你的工作调试经验上传,方便同行们互相学习与借鉴。只有贡献的人多起来,得到帮助的人多起来,电子行业才能更加蓬勃发展。
工作中用到陶晶驰的液晶屏,他们官方给的参考程序在解释带小数点的键盘参数的时候,发现不能传送小数点。并且参考程序好像只能7个数据作为1个队列解码。 我用小键盘输入带小数点参数数据超过了7个。所以就需要修改串口接收程序为不定长的空闲中断方式。
串口初始化后接着就使能了串口空闲中断。
void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //使能IDLE中断
/* USER CODE END USART1_Init 2 */
}
----------------------------------------------------------------
在stm32f0xx.it.c中找到void USART1_IRQHandler 进入去添加
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET) /*判断是空闲中断标志位,要注意的是这个语句不要写到HAL_UART_RxCpltCallback函数中,因为HAL_UART_RxCpltCallback只是接收回调函数,不是接收的情况下是不会调用的,如果写到HAL_UART_RxCpltCallback中永远也处理不了空闲中断*/
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1); //清除空闲中断标志
RxFlag1 = 1; //接收标志置1,表示收到了一帧数据
}
/* USER CODE END USART1_IRQn 1 */
}
----------------------------------------------------------------------------
陶晶驰给的hmi,c中有这个程序找到,如果你没有自己在MAIN文件中找个位置自己复制粘贴过去就行。
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == TJC_UART_INS) // �ж������ĸ����ڴ������ж�
{
rx1_du[rx1_cishu] = RxBuffer[0];
rx1_cishu++;
// HAL_UART_Transmit_IT(&TJC_UART, RxBuffer, 1);
// write1ByteToRingBuffer(RxBuffer[0]);
HAL_UART_Receive_IT(&TJC_UART,RxBuffer,1); // ����ʹ�ܴ���2�����ж�
}
return;
}
---------------------------------------------------------
然后最重要的来了,找到main文件,参考我的,串口收到数据以后,会在主循环中检测到空闲中断过的标志位,然后打印本次接收到的对应数量的数据。 ------那敲黑板------
// rx1_du[2]=3; rx1_du[3]=4;rx1_du[4]=5;rx1_du[5]=6; rx1_du[6]=7;rx1_du[7]=8;//你猜猜我这条是验证什么的,我是搜了好多网络费了好久才猜到可能需要加延时的。
HAL_UART_Transmit_IT(&TJC_UART, rx1_du, rx1_cishu);
HAL_Delay(ms_10);//一定加这个延时呀。要不打印2个数据后,再后面数据都是00.
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC_Init();
MX_DAC_Init();
MX_USART1_UART_Init();
MX_TIM17_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim17);
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 2000);
HAL_DAC_Start(&hdac,DAC_CHANNEL_1);
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_2, DAC_ALIGN_12B_R, 3000);
HAL_DAC_Start(&hdac,DAC_CHANNEL_2);
initRingBuffer(); //初始化环形缓冲区
HAL_UART_Receive_IT(&TJC_UART, RxBuffer, 1); //打开串口接收中断
__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE); //使能空闲中断
int a = 100;
char str[100];
uint32_t nowtime = HAL_GetTick();
HAL_GPIO_WritePin(GPIOB, FangDianJinZhi_Pin, GPIO_PIN_SET); //放电禁止关闭
a = 0;
HAL_Delay(100);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if(RxFlag1 == 1) //如果串口1收到了一帧数据
{
// rx1_du[2]=3; rx1_du[3]=4;rx1_du[4]=5;rx1_du[5]=6; rx1_du[6]=7;rx1_du[7]=8;
HAL_UART_Transmit_IT(&TJC_UART, rx1_du, rx1_cishu);
HAL_Delay(ms_10);
memset(rx1_du,0,sizeof(rx1_du)); //清空缓冲区,一定要清空
RxFlag1 = 0; //接收标志置0
rx1_cishu = 0; //清零计数
}
/*
if (HAL_GetTick() - nowtime >= 30)
{
nowtime = HAL_GetTick();
//printf("x0.val=456\xff\xff\xff");
a = 1234;
sprintf(str, "x0.val=%d", a);
tjc_send_string(str);
sprintf(str, "x3.val=%d", miao);
tjc_send_string(str);
sprintf(str, "x1.val=%d", a);
tjc_send_string(str);
sprintf(str, "t0.txt=\"%d\"", a);
tjc_send_string(str);
sprintf(str, "click b0,1");
tjc_send_string(str);
HAL_Delay(50);
sprintf(str, "click b0,0");
tjc_send_string(str);
}
*/
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
//END 欢迎转载。转载请写明我和那个朋友的链接。我不要求转载的怎么样。
这里再提醒下,串口助手打开发送和接收都选择十六进制,我看了好久才反应过来,必须十六进制。