野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 18151|回复: 24

新手,想要把中断接收到的串口数据利用起来,怎么用一个数组来缓存?

[复制链接]
发表于 2016-3-21 16:49:22 | 显示全部楼层 |阅读模式
我试过直接返回,但是错误提示说,中断程序无法实现return,问一下 ,怎么样才能利用起来啊
回复

使用道具 举报

 楼主| 发表于 2016-3-21 16:50:36 | 显示全部楼层
本帖最后由 l19950220 于 2016-3-21 16:52 编辑

哎,发个图片都没弄好
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-3-21 16:53:03 | 显示全部楼层
就是这个,有懂的指点下呗
捕获14.PNG
回复 支持 反对

使用道具 举报

发表于 2016-3-21 17:16:54 | 显示全部楼层
如果你收的数据都知道多大的  那你可以不停的去收  设置一个标志位 直到那个BUF满了 然后去处理  如果不确定收的数据多少  那只能隔断时间主动去处理一次
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-3-21 18:14:13 | 显示全部楼层
zhao_zhao 发表于 2016-3-21 17:16
如果你收的数据都知道多大的  那你可以不停的去收  设置一个标志位 直到那个BUF满了 然后去处理  如果不确 ...

那我应该怎么弄呢?历程里是通过USART_ReceiveData()这个库函数接收到的返回值赋值给一个变量ch,然后再打印出来的。按你那样弄的话,是在中断函数里将数据给一个数组指针,然后设置个标志位,当数组接满的时候跳出中断,然后在主函数里面再利用这个指针么?
回复 支持 反对

使用道具 举报

发表于 2016-3-21 18:55:38 | 显示全部楼层
本帖最后由 wqy_1000 于 2016-3-21 18:57 编辑

USART字符串命令接收与响应
USART1中断服务函数( void USART1_IRQHandler(void) )的应用.
通过串口助手向stm32 USART1串口发送消息,USART1_IRQHandler函数中定义了消息的起止符,获取输入的消息内容。

#define CMD_SIZE 256


char cmd[CMD_SIZE];  //存放收到的消息字符串

int cmd_point=0;     //消息字符下标


void USART1_IRQHandler(void)

{

    u8 res;

    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断

    {

        res=USART_ReceiveData(USART1);  //读取接收到的数据

        if(res==’>’)
        {

            cmd_point=0;

            memset(cmd,0,CMD_SIZE);  //清除

        }
       else{

            cmd_point++;

            if(res==0x0d)
        {   //结束附加位 回车

                USART1_printf(“cmd:%s \n\r “,cmd);

                cmd_point=0;

            }
       else{

                cmd[cmd_point-1]=res;

            }

        }

    }

}
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-3-21 19:12:42 | 显示全部楼层
   if(res==’>’)
        {

            cmd_point=0;

            memset(cmd,0,CMD_SIZE);  //清除

        }
这个没看懂,为什么if的条件是res=='>'
回复 支持 反对

使用道具 举报

发表于 2016-3-21 22:24:42 | 显示全部楼层
l19950220 发表于 2016-3-21 19:12
if(res==’>’)
        {

">"
这个是数据头,你可以改成你要的格式。
例如:printf(">firebbs.cn\n");
以">"开头,以"\n"结尾
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-3-22 12:25:35 | 显示全部楼层
wqy_1000 发表于 2016-3-21 22:24
">"
这个是数据头,你可以改成你要的格式。
例如:printf(">firebbs.cn\n");

好的,我仔细研究下,刚学的32,c语言不够扎实
回复 支持 反对

使用道具 举报

发表于 2016-3-22 16:53:12 | 显示全部楼层
l19950220 发表于 2016-3-21 18:14
那我应该怎么弄呢?历程里是通过USART_ReceiveData()这个库函数接收到的返回值赋值给一个变量ch,然后 ...

if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
  {
    /* Read one byte from the receive data register */
    RxBuffer1[RxCounter1++] = USART_ReceiveData(USART1);

    if(RxCounter1 == NbrOfDataToRead1)
    {
      /* Disable the USART1 Receive interrupt */
      USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
    }
  }
这段代码你可以参考下
NbrOfDataToRead1这个定义的一个收多少数据的全局变量
你自己在加一个标志 当串口收到NbrOfDataToRead1数据后  然后去处理一下
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-3-22 19:30:37 | 显示全部楼层
zhao_zhao 发表于 2016-3-22 16:53
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
  {
    /* Read one byte from the receive  ...

RxBuffer1[RxCounter1++] = USART_ReceiveData(USART1);这句话的意思是将串口发送过来的数保存在一个数组里,可是我实际弄的时候,貌似没保存进来啊,打印出来的全是0.
回复 支持 反对

使用道具 举报

发表于 2016-3-22 20:48:41 | 显示全部楼层
将串口接收的数据复制到一个缓冲的数组中保存,后边就对这个数组操作就好了

主函数

主函数

中断处理

中断处理
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-3-22 21:17:28 | 显示全部楼层
soledad0928 发表于 2016-3-22 20:48
将串口接收的数据复制到一个缓冲的数组中保存,后边就对这个数组操作就好了
  1.         if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
  2.   {  
  3.           extern uint8_t NbrOfDataToRead1;
  4.           extern u8 RxBuffer1[4];
  5.           u8 RxCounter1=0;
  6.           u8 i;
  7.     /* Read one byte from the receive data register */
  8.     RxBuffer1[RxCounter1++] = USART_ReceiveData(USART1);

  9.     if(RxCounter1 == NbrOfDataToRead1)
  10.     {  
  11.                 for(i=0;i<RxCounter1;i++)
  12.                   {
  13.                           printf("%c",RxBuffer1[i]);
  14.                   }
  15.       /* Disable the USART1 Receive interrupt */
  16.       USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
  17.     }
  18.   }
复制代码

这样子,为什么串口都打印不出已经缓存的数组?
回复 支持 反对

使用道具 举报

发表于 2016-3-22 21:51:07 | 显示全部楼层
soledad0928 发表于 2016-3-22 20:48
将串口接收的数据复制到一个缓冲的数组中保存,后边就对这个数组操作就好了

1.PNG

求问标记得那句话是什么意思?
回复 支持 反对

使用道具 举报

发表于 2016-3-23 09:47:36 | 显示全部楼层
l19950220 发表于 2016-3-22 21:17
这样子,为什么串口都打印不出已经缓存的数组?

你使用串口助手发送时,勾选上“发送新行”之类的选项,因为中断程序中用0x0a   0x0d(换行和回车)作为判断结束标志
回复 支持 反对

使用道具 举报

发表于 2016-3-23 09:48:04 | 显示全部楼层
11光辉岁月 发表于 2016-3-22 21:51
求问标记得那句话是什么意思?

0x0a   0x0d(换行和回车)作为判断结束标志
回复 支持 反对

使用道具 举报

发表于 2016-3-23 09:51:17 | 显示全部楼层
soledad0928 发表于 2016-3-23 09:47
你使用串口助手发送时,勾选上“发送新行”之类的选项,因为中断程序中用0x0a   0x0d(换行和回车)作为 ...

回复错了,这是我发的中断程序要检测 0x0a 0x0d
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-3-23 10:24:21 | 显示全部楼层
soledad0928 发表于 2016-3-23 09:51
回复错了,这是我发的中断程序要检测 0x0a 0x0d

你的那个程序实现的是发送一个 一个的数 然后换行。。。然后就直接进入主函数打印出数组么?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-3-23 10:26:12 | 显示全部楼层
zhao_zhao 发表于 2016-3-22 16:53
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
  {
    /* Read one byte from the receive  ...

里面的RxCounter1是一个全局变量么?初值是0?
回复 支持 反对

使用道具 举报

发表于 2016-3-23 13:27:02 | 显示全部楼层
l19950220 发表于 2016-3-23 10:26
里面的RxCounter1是一个全局变量么?初值是0?

对,初值是0
回复 支持 反对

使用道具 举报

发表于 2016-3-23 14:38:07 | 显示全部楼层
l19950220 发表于 2016-3-23 10:26
里面的RxCounter1是一个全局变量么?初值是0?

对的 全局变量,初值为0,把数据处理完了一点要把RxCounter1置为0.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-3-23 18:20:39 | 显示全部楼层
soledad0928 发表于 2016-3-22 20:48
将串口接收的数据复制到一个缓冲的数组中保存,后边就对这个数组操作就好了

你那个赋值句。。。在进入中断后,不是只赋值一次么?尽管你数组里用了len++可是只赋值一次啊?如果发送123应该直接就是rxbuff[1]=123啦,还是地址是自动加一的?
回复 支持 反对

使用道具 举报

发表于 2016-3-23 19:54:48 | 显示全部楼层
l19950220 发表于 2016-3-23 18:20
你那个赋值句。。。在进入中断后,不是只赋值一次么?尽管你数组里用了len++可是只赋值一次啊?如果发送1 ...

串口每次只能接受1个字节,你用串口助手发123,是发生了3次中断的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-3-23 20:19:35 | 显示全部楼层
soledad0928 发表于 2016-3-23 19:54
串口每次只能接受1个字节,你用串口助手发123,是发生了3次中断的

原来是这样哦~~我再看看,谢谢啦~~可能还有请教的呢
回复 支持 反对

使用道具 举报

发表于 2016-3-23 20:31:10 | 显示全部楼层
l19950220 发表于 2016-3-23 20:19
原来是这样哦~~我再看看,谢谢啦~~可能还有请教的呢

你用串口助手发的时候,你可以注意看一下上面统计的发送字节数
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-24 19:17 , Processed in 0.047670 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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