OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 14910|回复: 12

stm32串口如何发送接收数组

[复制链接]

7

主题

26

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2016-8-11
在线时间
17 小时
发表于 2016-10-16 15:28:06 | 显示全部楼层 |阅读模式
1金钱
看了原子哥的串口教程
我就想试着做一个最简单的密码锁

但是发现我不会用串口发送接收数组

这个是中断

void USART1_IRQHandler(void)
                        {
                                u16 password[4]={0,0,0,0};
                                u8 Res;
                        #ifdef OS_TICKS_PER_SEC                         //如果时钟节拍数定义了,说明要使用ucosII了.
                                OSIntEnter();   
                        #endif
                                if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)//接收中断(接收到的数据必须是0x0d 0x0a结尾)
                                {
                                                Res=USART_ReceiveData(USART1);//(USART1->DR);读取接收到的数据
                                                USART_SendData(USART1,Res);

                                                if(Res == password[4] )
                                                        {printf("密码正确");}
                                                else
                                                        {printf("密码错误");}
                                        }
                                }



我不知道如何让串口接收数组

最佳答案

查看完整内容[请看2#楼]

看看你的程序是不是存在逻辑问题,想实现发送多个字节,可以写一个发送字节数组的函数,下面的代码是我写的,在板子上试验过,没问题,你可以对照看一下,一定要自己找出自己的问题来,只有弄懂自己哪里错了,才能真正学会。 u8 Password[4]; u8 flag = 0; u8 i = 0; int main(void) { delay_init(); uart_init(115200); while(1) { if(1 == flag) { USART_SendString(USART1, ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

84

帖子

0

精华

高级会员

Rank: 4

积分
529
金钱
529
注册时间
2015-7-21
在线时间
47 小时
发表于 2016-10-16 15:28:07 | 显示全部楼层
本帖最后由 流水若冰 于 2016-10-18 13:21 编辑
wanxiang 发表于 2016-10-18 08:37
根据你的说法 我把它改了 但是它还是在串口助手打印不出数据
看看你的程序是不是存在逻辑问题,想实现发送多个字节,可以写一个发送字节数组的函数,下面的代码是我写的,在板子上试验过,没问题,你可以对照看一下,一定要自己找出自己的问题来,只有弄懂自己哪里错了,才能真正学会。

u8 Password[4];
u8 flag = 0;
u8 i = 0;
int main(void)
{
  delay_init();  
  uart_init(115200);
  while(1)
  {        

    if(1 == flag)
    {
        USART_SendString(USART1, (u8*)Password, sizeof(Password)/sizeof(Password[0]));
        memset(Password, 0, sizeof(Password)/sizeof(Password[0]));
        flag = 0;
        i = 0;
    }     
  }   
}

发送字节数组的函数
void USART_SendString(USART_TypeDef* USARTx, u8* pBuffer, u16 len)
{
   u16 i = 0;
   
   for (i = 0; i < len; i++)
   {            
       USART_SendData(USARTx, pBuffer);
       while (USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET);  //发送完成后TC位被硬件清0                                   
   }
}

extern u8 Password[4];
extern u8 flag;
extern u8 i;
void USART1_IRQHandler(void);
void USART1_IRQHandler(void)
{
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  
    {               
        Password = USART_ReceiveData(USART1);
        i++;
        if(i == 4)
        {
          flag = 1;
        }        
    }
    USART_ClearITPendingBit(USART1, USART_IT_RXNE);  
}
一名合格的工程师一定要做到,代码虐我千百遍依然待她如初恋!
回复

使用道具 举报

1

主题

84

帖子

0

精华

高级会员

Rank: 4

积分
529
金钱
529
注册时间
2015-7-21
在线时间
47 小时
发表于 2016-10-16 20:34:47 | 显示全部楼层
本帖最后由 流水若冰 于 2016-10-16 20:40 编辑

如果你理解串口接收一个数据,那么串口接收数组也不难,可以先定义一个计数的变量,然后在串口中断服务程序中,用这个累加的计数来作为存储数组的索引,例如
int nCount = 0;
void USART1_IRQHandler(void)
{
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  
    {               
            USART_ReData[nCount ] = USART_ReceiveData(USART1);               nCount++;
   }      USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}

在主函数的其他地方来 重置nCount ,并且把数组USART_ReData[]清0




一名合格的工程师一定要做到,代码虐我千百遍依然待她如初恋!
回复

使用道具 举报

7

主题

26

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2016-8-11
在线时间
17 小时
 楼主| 发表于 2016-10-17 19:22:57 | 显示全部楼层
流水若冰 发表于 2016-10-16 20:34
如果你理解串口接收一个数据,那么串口接收数组也不难,可以先定义一个计数的变量,然后在串口中断服务程序 ...

void USART1_IRQHandler(void)
                        {
                                u8 i,Res;
                                u16 password[128];
                               
                        #ifdef OS_TICKS_PER_SEC        //如果时钟节拍数定义了,说明要使用ucosII了.
                                OSIntEnter();   
                        #endif
                                if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)//接收中断(接收到的数据必须是0x0d 0x0a结尾)
                                {
                                                Res=USART_ReceiveData(USART1);//(USART1->DR);读取接收到的数据

                                                password = Res;
                                                i++;
                                        if(i>4){i=0;}
                                        USART_SendData(USART1,password);
                                               



                                        }
                                }

为什么我只能发送数据给串口 但是他打印不出来USART_SendData(USART1,password);这条语句有问题吗
回复

使用道具 举报

1

主题

84

帖子

0

精华

高级会员

Rank: 4

积分
529
金钱
529
注册时间
2015-7-21
在线时间
47 小时
发表于 2016-10-17 21:14:34 | 显示全部楼层
wanxiang 发表于 2016-10-17 19:22
void USART1_IRQHandler(void)
                        {
                                u8 i,Res;

1. 首先发送数据最好不要在中断里做,中断里可以当满足某一条件后置一个标志位,在外面的其他位置检测标志位,当标志位被置位时再用USART_SendData发送数据;
2. 不知道你这里是想要实现什么?你的i貌似没有什么用啊?不要在中断里 定义i,你这样每次进中断都会有一个新的i,不会达到你想要的效果
一名合格的工程师一定要做到,代码虐我千百遍依然待她如初恋!
回复

使用道具 举报

7

主题

26

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2016-8-11
在线时间
17 小时
 楼主| 发表于 2016-10-18 08:37:04 | 显示全部楼层
流水若冰 发表于 2016-10-17 21:14
1. 首先发送数据最好不要在中断里做,中断里可以当满足某一条件后置一个标志位,在外面的其他位置检测标 ...

根据你的说法 我把它改了 但是它还是在串口助手打印不出数据


#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"         
#include "rtc.h"
#include "stdlib.h"
u8 flag;
u16 password[128];
int main(void)
{
                delay_init();                     //延时函数初始化          
                uart_init(9600);          //串口初始化为9600
                NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
                while(1)
                {
                        if(flag==1)
                        {
                                flag=0;
                                USART_SendData(USART1,password[0]);
                                USART_SendData(USART1,password[1]);
                                USART_SendData(USART1,password[2]);
                                USART_SendData(USART1,password[3]);
                        }
                printf("现在时间是%d年%d月%d日%d时%d分%d秒\n",
                calendar.w_year,calendar.w_month,calendar.w_date,
                calendar.hour,calendar.min,calendar.sec);
                delay_ms(1000);
                RTC_Get();

                }
        }
void USART1_IRQHandler(void)
{
                                u8 i,Res;
               

                        #ifdef OS_TICKS_PER_SEC        //如果时钟节拍数定义了,说明要使用ucosII了.
                                OSIntEnter();   
                        #endif
                                if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)//接收中断(接收到的数据必须是0x0d 0x0a结尾)
                                {
                                                Res=USART_ReceiveData(USART1);//(USART1->DR);读取接收到的数据
                                                USART_ClearITPendingBit(USART1,USART_IT_RXNE);
                                                password = Res;
                                                i++;
                                                if(i>4)
                                                {
                                                i=0;
                                                flag=1;
                                                }
                                        }
                                }
回复

使用道具 举报

6

主题

94

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1581
金钱
1581
注册时间
2016-7-2
在线时间
277 小时
发表于 2016-10-18 08:59:12 | 显示全部楼层
wanxiang 发表于 2016-10-18 08:37
根据你的说法 我把它改了 但是它还是在串口助手打印不出数据

每进一次中断接收一个字节,用一个数据接收你要发的密码
回复

使用道具 举报

7

主题

26

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2016-8-11
在线时间
17 小时
 楼主| 发表于 2016-10-18 09:04:05 | 显示全部楼层
迪拜大呲花 发表于 2016-10-18 08:59
每进一次中断接收一个字节,用一个数据接收你要发的密码

我代码是不是每进一次中断接收一个字节吗 然后通过数组的形式把它打印出来
回复

使用道具 举报

6

主题

94

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1581
金钱
1581
注册时间
2016-7-2
在线时间
277 小时
发表于 2016-10-18 09:21:36 | 显示全部楼层
password[i] = Res;
i++;
另外,把u8 i改成static u8 i,或者在中断外定义i
回复

使用道具 举报

7

主题

26

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2016-8-11
在线时间
17 小时
 楼主| 发表于 2016-10-18 12:24:03 | 显示全部楼层
迪拜大呲花 发表于 2016-10-18 09:21
password = Res;
i++;
另外,把u8 i改成static u8 i,或者在中断外定义i

改了 我让他发送 1234 按一下发送 他打印一个1 再按下它打印2  而不是一次性打印1234
回复

使用道具 举报

0

主题

183

帖子

0

精华

高级会员

Rank: 4

积分
684
金钱
684
注册时间
2016-1-27
在线时间
184 小时
发表于 2016-10-18 12:36:01 | 显示全部楼层
wanxiang 发表于 2016-10-18 12:24
改了 我让他发送 1234 按一下发送 他打印一个1 再按下它打印2  而不是一次性打印1234

程序逻辑问题吧,好好看看,按一下是不是只响应一次发送
回复

使用道具 举报

6

主题

94

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1581
金钱
1581
注册时间
2016-7-2
在线时间
277 小时
发表于 2016-10-18 13:57:45 | 显示全部楼层
while(1)里每次发送后面加上这句
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
{
}
还有中断里判断条件应该是i>3
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
7
金钱
7
注册时间
2019-10-21
在线时间
3 小时
发表于 2019-10-21 16:24:44 | 显示全部楼层
请问楼主解决了吗?我现在也是在串口助手打印不出数据
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-2 20:19

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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