找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1340|回复: 3
打印 上一主题 下一主题
收起左侧

求解STM32的串口中断接收数组出现接收失败(程序很简单,是否有逻辑问题)

[复制链接]
跳转到指定楼层
楼主
ID:966387 发表于 2021-9-23 11:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
程序功能就是单片机接收上位机(串口助手)发送的 adbcd ;将接收的数据放入数组 Rec_array[]
通过 if(0 == memcmp(Rec_array, "abc", 3)) 语句,翻转 LED ;

正常情况是数组存放了 {a,b,c,d,e}; 前三项 abc对应正确,led翻转

但是接收数据,在 if(0 == memcmp(Rec_array, "abc", 3)) 识别时数组里只存放了 {b,0,0,0,0};
想做到 发送-abcde-五位,led翻转,再发送-aaaaa-不翻转,再发送-abcee-翻转


程序结构很简单:一个usart函数,一个mian函数
usart.c文件
  1. #include "usart.h"
  2. #include "string.h"
  3. #include "led.h"

  4. #define Code_Max 5//最大值 5
  5. u8 Rec_array[Code_Max];//存放数组
  6. unsigned int Code_Cnt = 0;//数组变量

  7. /*中断初始化*/
  8. static void USART1_NVIC_Configuration(void)
  9. {
  10.         NVIC_InitTypeDef NVIC_InitStructure;
  11.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
  12.         NVIC_InitStructure.NVIC_IRQChannel = USART_IRQ;
  13.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  14.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  15.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  16.       
  17.         NVIC_Init(&NVIC_InitStructure);
  18. }
  19. void USART1_GPIO_Configuration(void)
  20. {
  21.         GPIO_InitTypeDef GPIO_InitStructure;
  22.         /*开启串口GPIO时钟*/      
  23.         USART_APBxClkCmd(USART_GPIO_CLK,ENABLE);      
  24.         GPIO_InitStructure.GPIO_Pin = USART_TX_GPIO_PIN;
  25.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  26.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  27.         GPIO_Init(USART_TX_GPIO_PORT,&GPIO_InitStructure);
  28.         GPIO_InitStructure.GPIO_Pin = USART_RX_GPIO_PIN;
  29.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  30.         GPIO_Init(USART_RX_GPIO_PORT,&GPIO_InitStructure);
  31. }
  32. /*串口GPIO初始化*/
  33. void USART1_Configuration(void)
  34. {      
  35.         USART1_NVIC_Configuration();
  36.         USART1_GPIO_Configuration();
  37.         USART_InitTypeDef USART_InitStructure;
  38.         /*开启串口时钟*/
  39.         USART_APBxClkCmd(USART_CLK,ENABLE);
  40.         USART_InitStructure.USART_BaudRate = USART_Baudrate;
  41.         USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  42.         USART_InitStructure.USART_StopBits = USART_StopBits_1;
  43.         USART_InitStructure.USART_Parity = USART_Parity_No;
  44.         USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  45.         USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  46.         USART_Init(USARTx,&USART_InitStructure);
  47.       
  48.         USART_ITConfig(USARTx,USART_IT_RXNE,ENABLE);
  49.         USART_ITConfig(USARTx,USART_IT_TXE,DISABLE);
  50.       
  51.         USART_Cmd(USARTx,ENABLE);
  52. }
  53. /*串口接收中断*/
  54. void USART1_IRQHandler(void)
  55. {
  56.         u8 data;
  57.         if(USART_GetITStatus(USARTx,USART_IT_RXNE) != RESET)
  58.         {
  59.                 data = USART_ReceiveData(USARTx);
  60.                 Rec_array[Code_Cnt] = data;//存放到数组
  61.                 Code_Cnt++;
  62.                 if(Code_Cnt >= Code_Max)
  63.                 {        Code_Cnt = 0;
  64.                 }
  65.     USART_ClearITPendingBit(USARTx, USART_IT_RXNE);
  66.         }
  67. }
  68. /*串口接收数据函数*/
  69. void USART1_Recive(void)
  70. {
  71.         Code_Cnt = 0;
  72.         if(0 == memcmp(Rec_array, "abc", 3))
  73.         {
  74.                 LED_BLUE;
  75.         }
  76.         if(0 == memcmp(Rec_array, "bca", 3))
  77.         {
  78.                 LED_RED;
  79.         }
  80.         Rec_array[0] = Rec_array[1] = Rec_array[2] = Rec_array[3] = Rec_array[4] = 0;
  81. }

复制代码
usart.h

  1. #ifndef __USART_H
  2. #define        __USART_H

  3. #include "stm32f10x.h"
  4. #include <stdio.h>

  5. #define USARTx                       USART1
  6. #define USART_CLK                    RCC_APB2Periph_USART1
  7. #define USART_Baudrate               115200

  8. #define        USART_GPIO_CLK                                RCC_APB2Periph_GPIOA
  9. #define USART_APBxClkCmd                        RCC_APB2PeriphClockCmd

  10. #define USART_TX_GPIO_PORT                GPIOA
  11. #define USART_TX_GPIO_PIN                        GPIO_Pin_9
  12. #define USART_RX_GPIO_PORT                GPIOA
  13. #define USART_RX_GPIO_PIN                        GPIO_Pin_10

  14. #define USART_IRQ                                                        USART1_IRQn
  15. #define USART_IRQHandler                        USART1_IRQHandler

  16. void USART1_Configuration(void);
  17. void USART1_Recive(void);

  18. #endif
复制代码

main.c



  1. #include "stm32f10x.h"
  2. #include "led.h"
  3. #include "usart.h"

  4. int main(void)
  5. {      
  6.         LED_GPIO_Config();
  7.         USART1_Configuration();
  8.         while (1)
  9.         {
  10.                 USART1_Recive();
  11.         }
  12. }

复制代码




分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:702863 发表于 2021-9-23 14:34 | 只看该作者
void USART1_Recive(void)
{
    Code_Cnt = 0;    //错误:该全局变量一直被清除;导致只有Rec_array[0]值
}
回复

使用道具 举报

板凳
ID:161164 发表于 2021-9-23 15:32 | 只看该作者
若要比较串口接收的字串
加上结束符或定时器来确认传输结束比较好
结束符:
每次传输都在结尾加上特定字符如:';'分号(abcde;)
if(data == ';')Trans_Done = 1;

定时器:
建立一个1ms定时器,在串口中断中重载定时器并开始计时
在定时器中关闭定时器并Trans_Done = 1;

while(1)
{
if(Trans_Done)
{
Trans_Done = 0;
USART1_Recive();
}
}
回复

使用道具 举报

地板
ID:123289 发表于 2021-9-23 17:31 | 只看该作者
画个流程图,先走通流程,而后再写程序。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表