OpenEdv-开源电子网

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

串口通信实验

[复制链接]

2

主题

8

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2018-7-14
在线时间
0 小时
发表于 2018-7-16 15:31:00 | 显示全部楼层 |阅读模式
5金钱
想要接收此模块的数据,但在中断服务函数那里接收不到正确的数据,望各位解答

分贝数据命令
如:BB AA 01 7F 02 E7
起始符:BB AA,表示一帧的开始。
命令:01,表示此帧为返回分贝值数据。
数据:7F 02,表示检测到的分贝值为63.9dB。低字节在前,高字节在后,且每单位为0.1dB。
校验值:E7,为BB AA 01 7F 02的的算术和校验值。
注:此帧为模块上电返回固件版本号命令帧后每约500ms返回一次此帧。
void HH_0603_Config(void)
{       
        GPIO_InitTypeDef GPIO_InitStructure;       
        NVIC_InitTypeDef NVIC_InitStructure;       
        USART_InitTypeDef  USART_InitStructure;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);

        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//TX
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
        GPIO_Init(GPIOB,&GPIO_InitStructure);
       
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11;//RX
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOB,&GPIO_InitStructure);


        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
        NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);


        USART_InitStructure.USART_BaudRate=115200;   
        USART_InitStructure.USART_WordLength=USART_WordLength_8b;
        USART_InitStructure.USART_StopBits=USART_StopBits_1;
        USART_InitStructure.USART_Parity=USART_Parity_No;
        USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
        USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
        USART_Init(USART3,&USART_InitStructure);
        USART_Cmd(USART3, ENABLE);
        USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
        //每收到一个字节进入一次中断!
        USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);
        //每收到一帧数据进入一次中断!
       
}

//中断处理函数
void USART3_IRQHandler(void)       
{
        u8 clear = clear;
        USART_ClearFlag(USART3,USART_FLAG_TC);

        if(USART_GetITStatus(USART3,USART_IT_RXNE)!=Bit_RESET)        
        {

                RX_Buffer[RX_Counter++] = USART3->DR;
                printf("接收数据为:%x",RX_Buffer[RX_Counter]);
                delay_ms(1000);
               
                switch(RX_Counter)
                {
                        case 1://校验起始符1字节
                                if(USART3->DR != UART_BEGIN_STX1)
                                {
                                        RX_Counter=0;
                                }
                                break;
                        case 2://校验起始符2字节
                                if(USART3->DR != UART_BEGIN_STX2)
                                {
                                        RX_Counter=0;
                                }
                                break;
                        case 6://校验                                       
                                if(CheckSum(RX_Buffer,5) != RX_Buffer[5])
                                {
                                        RX_Counter=0;
                                }
                                else
                                {
                                        RX_Counter=0;
                                        Uart_RecvFlag=1;
                                }               
                                break;                                                                                               
                }
               
        }                 
        else if(USART_GetFlagStatus(USART3,USART_FLAG_IDLE)!=Bit_RESET)
        {                                       
                clear=USART3->SR;
                clear=USART3->DR;                                               
                RX_Counter=0;
        }       
                                       


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

1155

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7464
金钱
7464
注册时间
2015-1-15
在线时间
1368 小时
发表于 2018-7-16 15:51:08 | 显示全部楼层
接收第五个字节就要开始判断了,你为什么要等到第六个才判断处理
一分耕耘一分收获。
回复

使用道具 举报

39

主题

535

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1065
金钱
1065
注册时间
2018-3-27
在线时间
378 小时
发表于 2018-7-16 15:53:52 | 显示全部楼层
void USART3_IRQHandler(void)        
{
        u8 clear = clear;

        if(USART_GetITStatus(USART3,USART_IT_RXNE)!=Bit_RESET)        
        {

                clear= USART3->DR;
                printf("接收数据为:%x",clear);
        }   
}   
这样试试看数据对不对
回复

使用道具 举报

51

主题

2166

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10653
金钱
10653
注册时间
2017-4-14
在线时间
2780 小时
发表于 2018-7-16 15:56:54 | 显示全部楼层
不降处理的对不对,你删了delay_ms(1000); 吧,延时这么久,后面的都没收到
回复

使用道具 举报

2

主题

8

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2018-7-14
在线时间
0 小时
 楼主| 发表于 2018-7-16 16:12:15 | 显示全部楼层
qiuzhicheng 发表于 2018-7-16 15:53
void USART3_IRQHandler(void)        
{
        u8 clear = clear;

现象是这样的,后面的数据接收不到

接收数据为:bb接收数据为:aa接收数据为:bb接收数据为:aa
接收数据为:bb接收数据为:aa接收数据为:bb接收数据为:aa
回复

使用道具 举报

2

主题

8

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2018-7-14
在线时间
0 小时
 楼主| 发表于 2018-7-16 16:12:53 | 显示全部楼层
275891381 发表于 2018-7-16 15:56
不降处理的对不对,你删了delay_ms(1000); 吧,延时这么久,后面的都没收到

不可以,效果一样的
回复

使用道具 举报

20

主题

200

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
462
金钱
462
注册时间
2015-11-28
在线时间
89 小时
发表于 2018-7-16 16:30:21 | 显示全部楼层
长龙 发表于 2018-7-16 16:12
不可以,效果一样的

你这个 是 删了不一定可以.
但是不删 一定不可以啊~~
虽然不知道你的模块串口通信时间多少.
回复

使用道具 举报

20

主题

200

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
462
金钱
462
注册时间
2015-11-28
在线时间
89 小时
发表于 2018-7-16 16:34:06 | 显示全部楼层
本帖最后由 森海有眼泉 于 2018-7-16 16:38 编辑

改到楼下
回复

使用道具 举报

20

主题

200

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
462
金钱
462
注册时间
2015-11-28
在线时间
89 小时
发表于 2018-7-16 16:37:31 | 显示全部楼层
本帖最后由 森海有眼泉 于 2018-7-16 16:41 编辑

不要 直接判断 usart->DR 的数据. 先定义一个 变量,用来再刚进入中断立刻保存 DR的值.
不然鬼知道等你判断的时候DR有没有被改变(中断程序过长会产生的错误.因为你delay了一下.建议还是第一时间保存DR)

还有 我的天唉...我一直都是用库函数的.不用寄存器的.但是我印象中..好像 发送接受 都是 DR 寄存器.你在接收中断里面 发送?是不是DR的值 也被改写了?


不要在中断里面 这么搞啊.
回复

使用道具 举报

9

主题

87

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1435
金钱
1435
注册时间
2015-5-19
在线时间
132 小时
发表于 2018-7-16 16:38:14 | 显示全部楼层
看看原子的串口例程吧,不要在串口接收中断处理函数里面进行判断。中断服务函数里面延时,这时候串口发送的东西早就发完了。理论上除了bb后面应该都收不到,但你的结果里面出现了aa,不知道原因是什么。
你在串口中断服务函数里面,把一次发送的所有数据存好了,然后再在主程序里面进行判断。(注意原子的串口接收程序需要发送时候数据以0d0a结束,这里需要注意)
回复

使用道具 举报

39

主题

535

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1065
金钱
1065
注册时间
2018-3-27
在线时间
378 小时
发表于 2018-7-16 17:34:47 | 显示全部楼层
长龙 发表于 2018-7-16 16:12
现象是这样的,后面的数据接收不到

接收数据为:bb接收数据为:aa接收数据为:bb接收数据为:aa

你用串口助手发送数据给串口3,然后回发给串口助手这样可以做到吗?
可以的话你要确认你发的数据是不是这样的了
回复

使用道具 举报

2

主题

8

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2018-7-14
在线时间
0 小时
 楼主| 发表于 2018-7-16 19:20:25 | 显示全部楼层
胖子阳 发表于 2018-7-16 16:38
看看原子的串口例程吧,不要在串口接收中断处理函数里面进行判断。中断服务函数里面延时,这时候串口发送的 ...

好的哦,非常感谢
回复

使用道具 举报

2

主题

8

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2018-7-14
在线时间
0 小时
 楼主| 发表于 2018-7-16 19:21:33 | 显示全部楼层
qiuzhicheng 发表于 2018-7-16 17:34
你用串口助手发送数据给串口3,然后回发给串口助手这样可以做到吗?
可以的话你要确认你发的数据是不是 ...

不行的
回复

使用道具 举报

39

主题

535

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1065
金钱
1065
注册时间
2018-3-27
在线时间
378 小时
发表于 2018-7-17 08:06:31 | 显示全部楼层

那你串口的收发有问题吧
回复

使用道具 举报

4

主题

98

帖子

0

精华

初级会员

Rank: 2

积分
195
金钱
195
注册时间
2018-6-27
在线时间
45 小时
发表于 2018-7-17 08:50:25 | 显示全部楼层
中断处理还是建议只处理标志,具体实现不要放在中断
回复

使用道具 举报

15

主题

866

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7563
金钱
7563
注册时间
2016-11-30
在线时间
643 小时
发表于 2018-7-17 09:43:56 | 显示全部楼层
中断里边不要加打印和延时。中断里边处理时间要尽量短,越短越好,要有这个概念。串口中断里边一般只接收数据,数据接收后,去主程序打印你接收到的数据再看一下吧。
回复

使用道具 举报

69

主题

978

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3772
金钱
3772
注册时间
2015-4-26
在线时间
765 小时
发表于 2018-7-17 14:02:15 | 显示全部楼层
中断里的延时什么鬼?那个模块可不会等你1秒钟的。人家早就发完了,你还在傻傻的接收第2个字符呢
我有故事,你有酒吗
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-16 07:30

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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