OpenEdv-开源电子网

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

STM32F103串口接收16进制数据用于控制延时

[复制链接]

4

主题

22

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2020-7-28
在线时间
10 小时
发表于 2020-8-5 18:55:18 | 显示全部楼层 |阅读模式
1金钱
问题描述如下:
我买了一个HIM屏幕,HMI屏幕通过RS232协议给单片机串口发送十六进制数据,目前确定能够通过串口收到 5A A5 06 83 54 36 01 00 FF这样的连窜十六进制数,现在需要通过串口接收到这些数据后,去取出里面的两个数据,需要使用这个数据去控制延时拉高GPIO,自己实验了多次只能够通过IF语句实现识别一个数,取出数字始终实现不了,首先识别一个数字的代码如下:
void USART1_IRQHandler(void)                        //串口1中断服务程序
{    u16 r;
        uint16_t rx_buf[1024];
uint16_t num = 0;

        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断
        {
                 r=USART_ReceiveData(USART1);//(USART1->DR);        //读取接收到的数据
    if( r==0xff )                                                        //比较字符串
                {
                        GPIO_ResetBits(GPIOC,GPIO_Pin_1);                 
                  GPIO_SetBits(GPIOC,GPIO_Pin_2);
                        GPIO_SetBits(GPIOC,GPIO_Pin_3);
                        GPIO_SetBits(GPIOC,GPIO_Pin_4);
                        GPIO_SetBits(GPIOC,GPIO_Pin_5);
                        GPIO_SetBits(GPIOC,GPIO_Pin_6);
                        GPIO_SetBits(GPIOC,GPIO_Pin_7);
                        GPIO_SetBits(GPIOC,GPIO_Pin_8);
                        GPIO_SetBits(GPIOC,GPIO_Pin_9);
                        GPIO_SetBits(GPIOC,GPIO_Pin_10);
                        GPIO_SetBits(GPIOC,GPIO_Pin_11);
                        GPIO_SetBits(GPIOC,GPIO_Pin_12);
                }
       
       
        }               
        }

这个中断函数能够识别一个十六进制数,连续发送也能实现,现在想取出来一个的进行判断的代码如下:
void USART1_IRQHandler(void)                        //串口1中断服务程序
{u8 tx1;
        u8 ch;
        u16 r;
uint16_t Uart1_Buffer[1024];
uint16_t Uart1_Rx ;
uint16_t Uart1_Tx ;
uint16_t Uart1_Len ;
uint16_t Uart1_Sta ;
       
        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断
        {                  
                Uart1_Buffer[Uart1_Rx]=USART_ReceiveData(USART1);//(USART1->DR);        //读取接收到的数据
    Uart1_Rx++;
    Uart1_Rx &= 0xFF;
        }
         if(Uart1_Buffer[Uart1_Rx-1] == 0x5A) //头
        Uart1_Tx = Uart1_Rx-1;
if((Uart1_Buffer[Uart1_Tx] == 0x5A)&&(Uart1_Buffer[Uart1_Rx-1] == 0xA5)) //检测到头的情况下检测到尾
     {
            Uart1_Len = Uart1_Rx-1- Uart1_Tx; //长度
            Uart1_Sta=1; //标志位
     }
     if(USART_GetFlagStatus(USART1,USART_FLAG_ORE) == SET) //溢出
     {
            USART_ClearFlag(USART1,USART_FLAG_ORE); //读SR
            USART_ReceiveData(USART1); //读DR
     }
if( Uart1_Sta )
{
        for(tx1=0;tx1 <= Uart1_Len;tx1++,Uart1_Tx++)
        USART_SendData(USART1, Uart1_Buffer[Uart1_Tx]); //发送数据
        Uart1_Rx = 0; //初始化
        Uart1_Tx = 0;
        Uart1_Sta = 0;
}

                if(Uart1_Buffer[Uart1_Rx]==0xFF )                                                        //比较字符串
                {
                        GPIO_ResetBits(GPIOC,GPIO_Pin_1);                 
                  GPIO_ResetBits(GPIOC,GPIO_Pin_2);
                        GPIO_ResetBits(GPIOC,GPIO_Pin_3);
                        GPIO_SetBits(GPIOC,GPIO_Pin_4);
                        GPIO_SetBits(GPIOC,GPIO_Pin_5);
                        GPIO_SetBits(GPIOC,GPIO_Pin_6);
                        GPIO_SetBits(GPIOC,GPIO_Pin_7);
                        GPIO_SetBits(GPIOC,GPIO_Pin_8);
                        GPIO_SetBits(GPIOC,GPIO_Pin_9);
                        GPIO_SetBits(GPIOC,GPIO_Pin_10);
                        GPIO_SetBits(GPIOC,GPIO_Pin_11);
                        GPIO_SetBits(GPIOC,GPIO_Pin_12);
                }
               
        }

这个代码判断也实现不了,我还需要取出缓冲数组里面的数据用于设置延时,请各位帮助一下,C语言基础比较差,考了二级就放下,
然后库函数的使用也是稀烂,都不知道哪些变量库函数有,哪些需要定义全局变量?还望各位大佬指教。十分感谢。

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

使用道具 举报

4

主题

22

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2020-7-28
在线时间
10 小时
 楼主| 发表于 2020-8-6 10:44:32 | 显示全部楼层
改成这个样子了,还是不行,感觉单个变量就能识别,数组就不能识别了
void USART1_IRQHandler(void)                        //串口1中断服务程序
{u8 a=0;
        u8 ch=0;
                u8 b=0;
        u16 r[1024];

       
        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断
        {                  
                USART_RX_BUF[ch]=USART_ReceiveData(USART1);//(USART1->DR);        //读取接收到的数据
    r[a]=USART_RX_BUF[ch];
                ch++;
                a++;
        }
for(b=0;b<a;b++)
        {
                if(r[b]==0xFF )                                                        //比较字符串
                {
                        GPIO_ResetBits(GPIOC,GPIO_Pin_1);                 
                  GPIO_ResetBits(GPIOC,GPIO_Pin_2);
                        GPIO_ResetBits(GPIOC,GPIO_Pin_3);
                        GPIO_SetBits(GPIOC,GPIO_Pin_4);
                        GPIO_SetBits(GPIOC,GPIO_Pin_5);
                        GPIO_SetBits(GPIOC,GPIO_Pin_6);
                        GPIO_SetBits(GPIOC,GPIO_Pin_7);
                        GPIO_SetBits(GPIOC,GPIO_Pin_8);
                        GPIO_SetBits(GPIOC,GPIO_Pin_9);
                        GPIO_SetBits(GPIOC,GPIO_Pin_10);
                        GPIO_SetBits(GPIOC,GPIO_Pin_11);
                        GPIO_SetBits(GPIOC,GPIO_Pin_12);
                }
        }
        }
回复

使用道具 举报

3

主题

808

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3888
金钱
3888
注册时间
2017-3-7
在线时间
1694 小时
发表于 2020-8-6 11:05:36 | 显示全部楼层
学会使用static
回复

使用道具 举报

20

主题

450

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4917
金钱
4917
注册时间
2017-7-6
在线时间
721 小时
发表于 2020-8-6 11:18:31 | 显示全部楼层
因为你接收中断是一次一次的,你这样肯定不行的,所以是只能识别单个  数组却不行
我是小白,很白很白的小白!!!
回复

使用道具 举报

4

主题

22

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2020-7-28
在线时间
10 小时
 楼主| 发表于 2020-8-6 12:47:42 | 显示全部楼层
本帖最后由 程序猿15号 于 2020-8-6 15:25 编辑

还是有问题
回复

使用道具 举报

0

主题

79

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1937
金钱
1937
注册时间
2018-10-11
在线时间
256 小时
发表于 2020-8-6 13:04:49 | 显示全部楼层
HMI好像发的数据是三个0xff结尾的...
static void UART_one_Interrupt_Receive(void) interrupt 4
{
  if(TI) TI=0;
  else if(RI==1)
    {  
      RI=0;                  
      Receive_table[n]=SBUF;        
      n++;
                  if((Receive_table[n-1]==0xff)&&(Receive_table[n-2]==0xff)&&(Receive_table[n-3]==0xff))
                          {
                                        n=0;
        }
    }
}
反正我的串口中断是这么来的,然后取出你想要的Receive_table[n]就OK了,没那么复杂...
回复

使用道具 举报

62

主题

903

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3566
金钱
3566
注册时间
2016-1-8
在线时间
544 小时
发表于 2020-8-6 14:48:36 | 显示全部楼层
         
回复

使用道具 举报

4

主题

22

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2020-7-28
在线时间
10 小时
 楼主| 发表于 2020-8-6 15:17:59 | 显示全部楼层
spritels 发表于 2020-8-6 13:04
HMI好像发的数据是三个0xff结尾的...
static void UART_one_Interrupt_Receive(void) interrupt 4
{

兄弟,麻烦能发全你的代码吗?
回复

使用道具 举报

4

主题

22

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2020-7-28
在线时间
10 小时
 楼主| 发表于 2020-8-6 15:19:50 | 显示全部楼层
程功之道 发表于 2020-8-6 11:18
因为你接收中断是一次一次的,你这样肯定不行的,所以是只能识别单个  数组却不行

兄弟,请问怎么改
回复

使用道具 举报

4

主题

22

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2020-7-28
在线时间
10 小时
 楼主| 发表于 2020-8-6 15:41:39 | 显示全部楼层
程功之道 发表于 2020-8-6 11:18
因为你接收中断是一次一次的,你这样肯定不行的,所以是只能识别单个  数组却不行

兄弟请问怎么改?
回复

使用道具 举报

77

主题

203

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1208
金钱
1208
注册时间
2017-8-25
在线时间
167 小时
发表于 2020-8-6 15:46:33 | 显示全部楼层
你有没有清除中断标志位
回复

使用道具 举报

77

主题

203

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1208
金钱
1208
注册时间
2017-8-25
在线时间
167 小时
发表于 2020-8-6 15:47:26 | 显示全部楼层
逍遥1 发表于 2020-8-6 15:46
你有没有清除中断标志位

串口中断里尽量只接收数据,不要做其他操作
回复

使用道具 举报

4

主题

22

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2020-7-28
在线时间
10 小时
 楼主| 发表于 2020-8-6 15:51:41 | 显示全部楼层
逍遥1 发表于 2020-8-6 15:47
串口中断里尽量只接收数据,不要做其他操作

请问怎么改??
回复

使用道具 举报

77

主题

203

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1208
金钱
1208
注册时间
2017-8-25
在线时间
167 小时
发表于 2020-8-6 15:58:34 | 显示全部楼层

进一次串口中断就清一下中断标志位,并把数据存到全局数组里,在Main程序进行解析
回复

使用道具 举报

4

主题

22

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2020-7-28
在线时间
10 小时
 楼主| 发表于 2020-8-6 16:19:48 | 显示全部楼层
本帖最后由 程序猿15号 于 2020-8-6 16:35 编辑
逍遥1 发表于 2020-8-6 15:58
进一次串口中断就清一下中断标志位,并把数据存到全局数组里,在Main程序进行解析

void USART1_IRQHandler(void)                        //串口1中断服务程序
{
        u8 ch=0;
        
        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断
        {                  
                USART_RX_BUF[ch]=USART_ReceiveData(USART1);//(USART1->DR);        //读取接收到的数据
                ch++;
        USART_ClearITPendingBit(USART1,USART_IT_RXNE);        
        
        }

        }



int main()
{
        u8 b=0;
        u8 a;  
  u8 r[200];
        u8 i=0;
        u8 c;       
        SysTick_Init(72);
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //中断优先级分组 分2组
        LED_Init();
        USART1_Init(115200);
for(a=0;a<=200;a++ )
        {

if(USART_RX_BUF[a]==0xFF )                                                        //比较字符串
                {
                        c=USART_RX_BUF[a+1];
                        GPIO_ResetBits(GPIOC,GPIO_Pin_1);                 
                  delay_ms(c);
                        GPIO_SetBits(GPIOC,GPIO_Pin_1);
                }                       
                }

你看这样行不?发送这样一串代码还是不行,5A A5 05 82 5420 FFFA,不能点亮LED。
回复

使用道具 举报

0

主题

79

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1937
金钱
1937
注册时间
2018-10-11
在线时间
256 小时
发表于 2020-8-6 16:35:06 | 显示全部楼层
本帖最后由 spritels 于 2020-8-6 16:39 编辑
程序猿15号 发表于 2020-8-6 15:17
兄弟,麻烦能发全你的代码吗?

整个中断服务就这么多了,我买的HMI发一次是七个数据,后三个是0xff,这段程序就把七个数全放在Receive_table[]里面了,其中Receive_table[4]~Receive_table[6]都是0xff,至于前面Receive_table[0]~Receive_table[3],不很容易就拿来判断然后执行相应操作了嘛...
回复

使用道具 举报

4

主题

22

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2020-7-28
在线时间
10 小时
 楼主| 发表于 2020-8-6 16:41:15 | 显示全部楼层
spritels 发表于 2020-8-6 16:35
整个中断服务就这么多了,我买的HMI发一次是七个数据,后三个是0xff,至于前面Receive_table[0]~Receive_tab ...

不是后面判断的问题,我的问题是怎样接收到串口发送过来的数据,将他存放数据里面,就是你的Receive_table[0]是怎么接受到十六进制数据的
回复

使用道具 举报

0

主题

79

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1937
金钱
1937
注册时间
2018-10-11
在线时间
256 小时
发表于 2020-8-6 16:51:31 | 显示全部楼层
程序猿15号 发表于 2020-8-6 16:41
不是后面判断的问题,我的问题是怎样接收到串口发送过来的数据,将他存放数据里面,就是你的Receive_tabl ...

n初始为0,Receive_table[0]就收了第一个数啊,然后n++,下一个数据过来产生中断,Receive_table[1]收第二个数.余照类推,直到收完三个0xff后,把n清0,等待下一组数据...
回复

使用道具 举报

4

主题

22

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2020-7-28
在线时间
10 小时
 楼主| 发表于 2020-8-6 16:58:08 | 显示全部楼层
spritels 发表于 2020-8-6 16:51
n初始为0,Receive_table[0]就收了第一个数啊,然后n++,下一个数据过来产生中断,Receive_table[1]收第二个 ...

void USART1_IRQHandler(void)                        //串口1中断服务程序
{
        u8 ch=0;
       
        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断
        {                  
                USART_RX_BUF[ch]=USART_ReceiveData(USART1);//(USART1->DR);        //读取接收到的数据
               
        USART_ClearITPendingBit(USART1,USART_IT_RXNE);
               
        ch++;
        }
       
        }
看我这个接收函数,感觉就是你发送AA FF 12  FF  A5 5A 这一串数字,他把这一串数字都存在USART_RX_BUF[0]里面,当我取出来进行判断的时候,不能实现
回复

使用道具 举报

0

主题

79

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1937
金钱
1937
注册时间
2018-10-11
在线时间
256 小时
发表于 2020-8-7 08:01:38 | 显示全部楼层
程序猿15号 发表于 2020-8-6 16:58
void USART1_IRQHandler(void)                        //串口1中断服务程序
{
        u8 ch=0;

你每次进中断都重新定义一次ch,他的值一直都是0啊....
回复

使用道具 举报

20

主题

450

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4917
金钱
4917
注册时间
2017-7-6
在线时间
721 小时
发表于 2020-8-7 09:58:28 | 显示全部楼层

等一帧数据接收完再处理
我是小白,很白很白的小白!!!
回复

使用道具 举报

4

主题

22

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2020-7-28
在线时间
10 小时
 楼主| 发表于 2020-8-7 11:14:30 | 显示全部楼层
程功之道 发表于 2020-8-7 09:58
等一帧数据接收完再处理

具体实现的兄弟,怎呢编写中断函数?
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-13 01:53

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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