找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1716|回复: 7
打印 上一主题 下一主题
收起左侧

stm32串口通信问题

[复制链接]
回帖奖励 1 黑币 回复本帖可获得 1 黑币奖励! 每人限 1 次(中奖概率 90%)
跳转到指定楼层
楼主
ID:551154 发表于 2019-11-4 12:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 forcexda 于 2019-11-4 12:23 编辑

1、大佬们,我想去掉0x0a和0x0d的判断协议,改为这样可以吗?(里面的蜂鸣器是我用来判断程序是否跑死,手头只有isp下载器。。。)如果可以,我会卡在中断中,这是为啥呢,是因为ore吗,有没有可能是因为没有清中断造成的,还有一个问题在下面
void USART2_IRQHandler(void)                        //串口2 中断服务程序
{
u8 Res;//(这句我放在usart.c中最开始的include后面了)if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
                {
                        Res =USART_ReceiveData(USART2);        //读取接收到的数据
                        USART2->DR;
                        beep=1;
                        delay_ms(100);
                        beep=0;
                Res =USART_ReceiveData(USART1);        //读取接收到的数据
                                        USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
                                        USART_RX_STA++;
                                        if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收
                        USART_ClearFlag(USART2,USART_IT_RXNE);
        
               
                }
}


2、还有,我想在tft中显示串口发来的数据,百度很久,发现网上都说应该用sprintf函数,但是我在使用过程中,发现没法显示,但是我已经强制转换变量为字符串了,代码如下

char a;
sprintf(a,"%s",USART_RX_BUF[t]);   LCD_ShowString (0,0,a);

不知道写法有没有问题,麻大佬指点一下,在此谢过大佬,新手没人一起学习讨论,遇到问题解决起来真困难。。。。




分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:434390 发表于 2019-11-4 14:47 | 只看该作者
问题没讲清楚;
                beep=1;
                        delay_ms(100);
                        beep=0;
这段程序不要放到UART接收中断,否则串口接收丢数严重
回复

使用道具 举报

板凳
ID:551154 发表于 2019-11-4 15:52 | 只看该作者
snni00 发表于 2019-11-4 14:47
问题没讲清楚;
                beep=1;
                        delay_ms(100);

那这段程序可以放在接受完成之后吗,我主要是用来判断程序运行情况,额额,还有这个问题是基于原子串口历程的,原本是有判断的,我想把0x0d,和0x0a这两个用来判断发送完成的代码去掉,改成上面那段代码可以吗
回复

使用道具 举报

地板
ID:434390 发表于 2019-11-4 16:23 | 只看该作者
如果要去掉判断0x0d,0x0a作为接收完成的话,可以设个定时器,假设每1ms中断,计数加1,串口接收中断收到字符则清除计数,主程序判断如果计数>100ms,则无数据发送,可以认为此帧结束
回复

使用道具 举报

5#
ID:434390 发表于 2019-11-4 16:38 | 只看该作者
void TIM2_IRQHandler(void)      //1ms中断
{
  if (rx_flag) rx_timeout++;
  else rx_timeout=0;
}

void USART2_IRQHandler(void)                        //串口2 中断服务程序
{
  rx_flag=1;
  rx_timeout=0;
  ...
}

void main()
{
  ...
while (1)
{
   if (rx_timeout>100)   //100ms字符超时
  {
      rx_flag=0;
      ... //接收完成处理程序
  }
}
}
回复

使用道具 举报

6#
ID:551154 发表于 2019-11-4 18:06 | 只看该作者
snni00 发表于 2019-11-4 16:38
void TIM2_IRQHandler(void)      //1ms中断
{
  if (rx_flag) rx_timeout++;

原来是这样,感谢大佬,那第二个问题中可否用sprintf显示变量在tft上呢,我原本的想法是把接收的数据保存在buf里,然后再主程序里用sprintf函数一位一位输出到tft上,不知这样是否可行
回复

使用道具 举报

7#
ID:434390 发表于 2019-11-5 09:30 | 只看该作者
不清楚你的环境,如果是个串口接收显示TFT,且在程序中定义sprintf输出到对应串口的话,应该可以的,在接收完成处理程序处添加即可,收到数据则显示到TFT
回复

使用道具 举报

8#
ID:551154 发表于 2019-11-6 23:33 | 只看该作者
snni00 发表于 2019-11-5 09:30
不清楚你的环境,如果是个串口接收显示TFT,且在程序中定义sprintf输出到对应串口的话,应该可以的,在接收 ...

我的编译环境是keil5,我想接受蓝牙串口过来的数据,然后单片机处理后显示在tft上。

开始是学习用历程usart1来操作,发现buf里面的数据无法显示在tft上,sprintf函数也使用了,参考的tft历程和视频和手头tft的历程的不一样,在确定usart1电脑和单片机通信没问题以后,看两种tft历程也没看出个所以然。。。

这个是我手头tft的历程

void LCD_ShowString(u16 x,u16 y,const u8 *p)
{         
    while(*p!='\0')
    {      
        if(x>LCD_W-16){x=0;y+=16;}
        if(y>LCD_H-16){y=x=0;LCD_Clear(RED);}
        LCD_ShowChar(x,y,*p,0);
        x+=8;
        p++;
    }  
}

void LCD_ShowChar(u16 x,u16 y,u8 num,u8 mode)
{
    u8 temp;
    u8 pos,t;
        u16 x0=x;
        u16 colortemp=POINT_COLOR;      
    if(x>LCD_W-16||y>LCD_H-16)return;            
                          
        num=num-' ';
        Address_set(x,y,x+8-1,y+16-1);
        if(!mode)
        {
                for(pos=0;pos<16;pos++)
                {
                        temp=asc2_1608[(u16)num*16+pos];
                        for(t=0;t<8;t++)
                    {                 
                        if(temp&0x01)POINT_COLOR=colortemp;
                                else POINT_COLOR=BACK_COLOR;
                                LCD_WR_DATA(POINT_COLOR);       
                                temp>>=1;
                                x++;
                    }
                        x=x0;
                        y++;
                }       
        }else
        {
                for(pos=0;pos<16;pos++)
                {
                    temp=asc2_1608[(u16)num*16+pos];               
                        for(t=0;t<8;t++)
                    {                 
                        if(temp&0x01)LCD_DrawPoint(x+t,y+pos);     
                        temp>>=1;
                    }
                }
        }
        POINT_COLOR=colortemp;                                          
}

void LCD_DrawPoint(u16 x,u16 y)
{
        Address_set(x,y,x,y);//设置光标位置
        LCD_WR_DATA(POINT_COLOR);             
}

然后就操作不明白了,不知道为什么人家就是sprintf+lcd_showstring两句话就能解决,为啥我不行呢,真是一头雾水,能麻烦大佬看一眼吗,谢谢大佬
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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