OpenEdv-开源电子网

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

老哥们,请问一下。我用串口2接收sim8950(一个安卓模块的数据)

[复制链接]

20

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2020-5-6
在线时间
43 小时
发表于 2021-1-4 12:07:18 | 显示全部楼层 |阅读模式
10金钱
老哥们,请问一下。我用串口2接收sim8950(一个安卓模块的数据),然后通过串口2给安卓模块发送数据。本来的我想法是,测试时我接收到了安卓模块的数据,然后返回一个1给他。然后调试的时候,安卓模块接收到了,很奇怪的是,他那边接收到了1 ,但是先接收到22个1(原因是我猜测他发给我的数据确实有22位),然后再单独接收到一个1。就相当于每次他接收到两条数据。一条数据是22个1,一条数据是1.球老哥们指点指点。接收安卓模块的数据我用的是一个环形队列去接收。代码如下:
//环形队列的结构体,以及读写操作
typedef struct
{
  unsigned char headPosition;      
  unsigned char tailPositon;         
  unsigned char ringBuf[BUFSIZE2];
} ringBuffer_t;


void RingBuf_Write(unsigned char data)
{
  buffer.ringBuf[buffer.tailPositon]=data;     
  if(++buffer.tailPositon>=BUFSIZE2)         
     buffer.tailPositon=0;                     
  if(buffer.tailPositon == buffer.headPosition)
    if(++buffer.headPosition>=BUFSIZE2)
     buffer.headPosition=0;
}

ringBuffer_t buffer

u8 RingBuf_Read(unsigned char* pData)
{
  if(buffer.headPosition == buffer.tailPositon)   
    {
            return 1;   
    }
  else
  {
    *pData=buffer.ringBuf[buffer.headPosition];   
    if(++buffer.headPosition>=BUFSIZE2)
      buffer.headPosition=0;
    return 0;     
  }
}


//串口2的配置以及中断做接收
void uart2_init(u32 bound)
{
   GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
         
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);        //ê1ÄüUSART2£¬GPIOAê±Öó
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);        //ê1ÄüUSART1£¬GPIOAê±Öó  
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.9
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //¸′óÃíÆíìêä3ö
        GPIO_Init(GPIOA, &GPIO_InitStructure); //3õê¼»ˉPA9

        //USART1_RX          PA.10
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//¸¡¿Õêäèë
        GPIO_Init(GPIOA, &GPIO_InitStructure);  //3õê¼»ˉPA10

  //USART2 NVIC ÅäÖÃ
  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//ÇàÕ¼óÅÏè¼¶3
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;                //×óóÅÏè¼¶3
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQí¨μàê1Äü
        NVIC_Init(&NVIC_InitStructure);        //¸ù¾YÖ¸¶¨μÄ2Îêy3õê¼»ˉVIC¼Ä′æÆ÷

  //USART 3õê¼»ˉéèÖÃ
        USART_InitStructure.USART_BaudRate = bound;//ò»°ãéèÖÃÎa9600;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;//×Ö3¤Îa8λêy¾Y¸ñê½
        USART_InitStructure.USART_StopBits = USART_StopBits_1;//ò»¸öí£Ö1λ
        USART_InitStructure.USART_Parity = USART_Parity_No;//ÎTÆæÅ¼D£Ñéλ
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//ÎTó2¼têy¾Yá÷¿ØÖÆ
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;        //êÕ·¢Ä£ê½

        USART_Init(USART2, &USART_InitStructure); //3õê¼»ˉ′®¿ú
        USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//¿aÆôÖD¶Ï
        USART_Cmd(USART2, ENABLE);                    //ê1Äü′®¿ú1
}

void USART2_IRQHandler(void)  
{         
          u8 shet[]={1};
                u8 data_shet[22];
          u8 data;
           if(USART_GetITStatus(USART2, USART_IT_TC) != RESET)  
    {         
      USART_ClearITPendingBit(USART2,USART_IT_RXNE);                

      RingBuf_Write(USART_ReceiveData(USART2)); //往环形队列里面写。


       while (USART_GetFlagStatus(USART2, USART_IT_RXNE) == RESET);       
    }

}

主函数初始化
int main(void)
{
        u8 data;
        u8         index_buffer=-1;
        u8 shet[]={1};
        delay_init();                     //Ñóê±oˉêy3õê¼»ˉ          
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //éèÖÃNVICÖD¶Ï·Ö×é2:2λÇàÕ¼óÅÏè¼¶£¬2λÏìó|óÅÏè¼¶
        uart3_init(115200);                 //′®¿ú3õê¼»ˉÎa115200
        uart2_init(115200);
  //uart1_init(115200);
        LED_Init();                             //LED¶Ë¿ú3õê¼»ˉ
        KEY_Init();
        struct_init();

        while(1)

{
             if(0 == RingBuf_Read(&data))       //读取环形队列的数据,如果有数据     
        {
            USART_SendData(USART2,shet);//往串口2发送一个1                                                       
        }
}

最佳答案

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

原子哥,确实不好意思。麻烦了,我这边找到问题了,就是数据长度没接完我就去做处理了。感谢原子哥的耐心回答,谢谢。新年快乐
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

20

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2020-5-6
在线时间
43 小时
 楼主| 发表于 2021-1-4 12:07:19 | 显示全部楼层
正点原子 发表于 2021-1-7 01:42
你这贴这么多代码没用啊。
我前面说了,监控串口数据,你先确定下串口线上的数据是否OK
然后如果ok,就 ...

原子哥,确实不好意思。麻烦了,我这边找到问题了,就是数据长度没接完我就去做处理了。感谢原子哥的耐心回答,谢谢。新年快乐
回复

使用道具 举报

20

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2020-5-6
在线时间
43 小时
 楼主| 发表于 2021-1-4 13:06:31 | 显示全部楼层
@正点原子 原子哥,麻烦老哥能不能解答一下。感激不尽
回复

使用道具 举报

20

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2020-5-6
在线时间
43 小时
 楼主| 发表于 2021-1-4 15:22:54 | 显示全部楼层
@正点原子 原子哥,求指点。
回复

使用道具 举报

20

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2020-5-6
在线时间
43 小时
 楼主| 发表于 2021-1-4 15:23:28 | 显示全部楼层
@正点原子
求指点
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165508
金钱
165508
注册时间
2010-12-1
在线时间
2115 小时
发表于 2021-1-5 01:31:21 | 显示全部楼层
监控下串口上面的数据,搞个串口模块
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

20

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2020-5-6
在线时间
43 小时
 楼主| 发表于 2021-1-6 10:06:35 | 显示全部楼层
正点原子 发表于 2021-1-5 01:31
监控下串口上面的数据,搞个串口模块

我在中断里面做接受,我接受来自SIM8950的数据(其实就是自己内部定的协议有22位通过串口2接受),接受并解析,成功返回一个0XFF 失败返回一个0XF0(通过串口2发送)。同时我还主动通过按键给SIM8950发送消息。。。。。我总觉得是我的中断函数写的有问题,但是又不知道怎么写。。。。。单独的发送接受都可以,但是如果在接受的时候按了一下按键发送,感觉程序就崩了。。。。
void USART2_IRQHandler(void)  
{   
           if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)                       
    {
      USART_ClearITPendingBit(USART2,USART_IT_RXNE);
      // Write_RingBuff(USART_ReceiveData(USART2));
                  Uart2_Buffer[Uart2_Rx] = (USART_ReceiveData(USART2));
                        rcve_print((char*)&Uart2_Buffer);
    }
}
这个是中断
回复

使用道具 举报

20

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2020-5-6
在线时间
43 小时
 楼主| 发表于 2021-1-6 10:07:01 | 显示全部楼层
rcve_print((char*)&Uart2_Buffer)是做的解析
回复

使用道具 举报

20

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2020-5-6
在线时间
43 小时
 楼主| 发表于 2021-1-6 10:07:24 | 显示全部楼层
正点原子 发表于 2021-1-5 01:31
监控下串口上面的数据,搞个串口模块

rcve_print((char*)&Uart2_Buffer);
回复

使用道具 举报

20

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2020-5-6
在线时间
43 小时
 楼主| 发表于 2021-1-6 10:08:11 | 显示全部楼层
年糕 发表于 2021-1-6 10:06
我在中断里面做接受,我接受来自SIM8950的数据(其实就是自己内部定的协议有22位通过串口2接受),接受并 ...

void rcve_print(char *rcve_buffer){
                char title[17]={0};
          //char *title=NULL;
                memcpy(title,rcve_buffer,recv.headArraysLen); //Ö¡í·       
                if(strcmp(FRAME_HEAD,title)==0)
        {
                        u8 project = rcve_buffer[recv.project_offset];
                                                        if(project == recv.project_name)
                {
                                                                u16 data_count = (rcve_buffer[recv.data_count_offset]&0xff)|((rcve_buffer[recv.data_count_offset+1]<<8)&0xff);
                                                                int crc8_offset=recv.function_offset+data_count;
                                                                u8 crc8 = cal_crc_table((unsigned char *)rcve_buffer,crc8_offset);
                                                                if(*(rcve_buffer+crc8_offset)==crc8)
                {
                                                                recv.function_name=*(rcve_buffer+recv.function_offset);
                                                                        unsigned int extension_arrays_len=data_count-recv.function_arrays_len;
                                                                  recv.function_extension =(char*)malloc(extension_arrays_len*sizeof(char*));
                                  Uart2_Sta=1;
                                                                        annicy(recv.function_name,recv.function_extension);
                                                                }
                                                        }
        }
}
这个是做的解析
回复

使用道具 举报

20

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2020-5-6
在线时间
43 小时
 楼主| 发表于 2021-1-6 10:09:15 | 显示全部楼层
annicy(recv.function_name,recv.function_extension);这个就是对应的数据位,做的LED控制。
回复

使用道具 举报

20

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2020-5-6
在线时间
43 小时
 楼主| 发表于 2021-1-6 10:12:43 | 显示全部楼层
按键发送
void send_print(u8 function_name,u8 function_extension)       
{   
  unsigned        int data_count=2;
  unsigned char send_buf[ send.function_offset+data_count+1];
       
         u8 crc8;
         u8 index=0;
         memcpy(&send_buf,FRAME_HEAD,strlen(FRAME_HEAD)); //&#213;íè&#229;í·
   index+=send.headArraysLen;
  //&#187;o3&#229;&#199;&#248;
  send_buf[index++]=send.project_name;

        send_buf[index++]= data_count&0xff;
        send_buf[index++]=  (data_count >>8)&0xff;

//        send_buf[index++]= 7;
//        send_buf[index++]= 8;

        send_buf[index++] = function_name;
  send_buf[index++] = function_extension;
//char *dd=new char[122];
  crc8 = cal_crc_table(send_buf,((sizeof send_buf)/(sizeof send_buf[0]))-1);
  send_buf[index++] = crc8;
        USART2Write ((u8*)send_buf,((sizeof send_buf)/(sizeof send_buf[0])));
        //UART2_SendOneData(USART2,*send_buf);
        //printf("%s",send_buf);
}
按键发送调用
u8 KEY15_Scan(void)
{
        int key15 ;
        int key_button15 ;
  key15 = KeyPin;
        delay_ms(80);
        key_button15 = KeyPin;
       
        if(key15==key_button15&&key15==0)
        {
         send_print(ALARM_FUNCTION,0);       
        }
}
发送函数
void USART2Write(u8 * data, u16 len)
{
        u16 i;
        for (i=0; i<len; i++)
        {
                while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);          
                USART_SendData(USART2,data[i]);
        }
        while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);
}       

void UART2_SendOneData(uint16_t SendOneData)
{
        USART_SendData(USART2, SendOneData);
        while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)
        {}
}
一个是发送多字节,一个是发送单字节。单字节主要用于接受数据后解析成功与否。
@正点原子 麻烦了老哥
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165508
金钱
165508
注册时间
2010-12-1
在线时间
2115 小时
发表于 2021-1-7 01:42:21 | 显示全部楼层
年糕 发表于 2021-1-6 10:12
按键发送
void send_print(u8 function_name,u8 function_extension)       
{   

你这贴这么多代码没用啊。
我前面说了,监控串口数据,你先确定下串口线上的数据是否OK
然后如果ok,就仿真,看MCU收到的数据是否OK
如果OK,就看各个函数的处理,是否OK
肯定有一个地方不OK导致你有问题
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

1

主题

77

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
388
金钱
388
注册时间
2020-11-7
在线时间
44 小时
发表于 2021-1-7 17:00:37 | 显示全部楼层
提几个建议吧:1.先确定你的模块发送数据是怎么发送(一位一位发,还是8位8位发)--可以通过示波器看到。2.再uart中断函数中,可以省略USART_ClearITPendingBit(USART2,USART_IT_RXNE); ,因为寄存器规定,你读取了数据寄存器中的数据,会自动清除挂起位。3.先确定硬件发送数据没问题的话,再找软件上是否有问题(按照原子哥的方法做)。
回复

使用道具 举报

20

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2020-5-6
在线时间
43 小时
 楼主| 发表于 2021-1-7 17:26:41 | 显示全部楼层
游走在01的海洋 发表于 2021-1-7 17:00
提几个建议吧:1.先确定你的模块发送数据是怎么发送(一位一位发,还是8位8位发)--可以通过示波器看到。2.再 ...

原因就是数据没接完,数据是一位一位接的。没接完我就去做解析了。所以出错了。谢谢老哥
回复

使用道具 举报

1

主题

77

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
388
金钱
388
注册时间
2020-11-7
在线时间
44 小时
发表于 2021-1-7 22:23:25 | 显示全部楼层
年糕 发表于 2021-1-7 17:26
原因就是数据没接完,数据是一位一位接的。没接完我就去做解析了。所以出错了。谢谢老哥

没事,倒也没帮上什么忙。能解决问题就好
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-14 23:03

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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