OpenEdv-开源电子网

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

串口发送字符正常,接收到的字符转发出来乱码

[复制链接]

16

主题

78

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2016-12-19
在线时间
50 小时
发表于 2017-1-10 09:57:42 | 显示全部楼层 |阅读模式
5金钱
本帖最后由 lsy3500 于 2017-1-10 15:33 编辑

如题,看原子哥的视频,用原子哥的代码,但是我调试就一直是乱码,不知道怎么回事,求助。附上我的代码和压缩包(其实主要还是原子哥的代码)~~~
附件是我的代码压缩包,恳请大大们帮我看看,谢谢。

程序结构:
main(){
    接收字符串:依靠中断接收字符并转发出来

    while(1){
         循环发送字符串:lsy
    }
}


[mw_shl_code=c,true]#include "stm32f10x.h"

//延时函数
void mydelay_ms(int ms) {  
  volatile int  i;  
  int k = ms * 2333 ;  
  for ( i=0; i<k; i++ ) {  
    ;
  }  
}  




//初始化函数
void LSY_USART1_Init(void)
{
  //三个相关结构体
  GPIO_InitTypeDef GPIO_InitStrue;
  USART_InitTypeDef USART_InitStrue;
  NVIC_InitTypeDef NVIC_InitStrue;
        
  //使能时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
        
  //配置引脚(usart1)
  //GPIOA_Pin_9
  GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;
  GPIO_InitStrue.GPIO_Pin=GPIO_Pin_9;
  GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;
  GPIO_Init(GPIOA,&GPIO_InitStrue);
  //GPIOA_Pin_10
  GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;
  GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10;
  GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;
  GPIO_Init(GPIOA,&GPIO_InitStrue);
        
        
  //串口参数配置
  USART_InitStrue.USART_BaudRate=9600;
  USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
  USART_InitStrue.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;
  USART_InitStrue.USART_Parity=USART_Parity_No;
  USART_InitStrue.USART_StopBits=USART_StopBits_1;
  USART_InitStrue.USART_WordLength=USART_WordLength_8b;
        
        
  USART_Init(USART1,&USART_InitStrue);//串口初始化
  USART_Cmd(USART1,ENABLE);//使能串口1
  USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//开启接收中断
        
  //中断参数配置
  NVIC_InitStrue.NVIC_IRQChannel=USART1_IRQn;
  NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;
  NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=1;
  NVIC_InitStrue.NVIC_IRQChannelSubPriority=1;
  NVIC_Init(&NVIC_InitStrue);
}


//中断处理函数:功能:转发接收到的字符串
void USART1_IRQHandler(void)
{
  u8 res;
  if(USART_GetITStatus(USART1,USART_IT_RXNE))
  {
  res= USART_ReceiveData(USART1);
  USART_SendData(USART1,res);   
  }
}

int main(void)
{        
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级配置
        
  LSY_USART1_Init();//调用初始化函数

        
  while(1){
      char buf[] = {"lsy"};
      char i = 0;
               
      USART_GetFlagStatus(USART1, USART_FLAG_TC);//解决串口发送首字母丢失的问题
      for (i=0; i<3; i++) {
          USART_SendData(USART1, buf);
          while( USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET );
      }
      USART_SendData(USART1, 0x0A); //"\n"
               
      mydelay_ms(3000);
  }
}
[/mw_shl_code]



XD7Y9KVAY`D6`CUKJKK2YW4.png

STM32_USART1_RXD_TXD_字符串接收并转发_STM32F103C8T6.rar

4.29 MB, 下载次数: 160

代码压缩包

最佳答案

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

接收到的,存起来再转发就没问题了
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

108

帖子

0

精华

高级会员

Rank: 4

积分
717
金钱
717
注册时间
2014-2-24
在线时间
257 小时
发表于 2017-1-10 09:57:43 | 显示全部楼层
接收到的,存起来再转发就没问题了
回复

使用道具 举报

16

主题

78

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2016-12-19
在线时间
50 小时
 楼主| 发表于 2017-1-10 10:12:46 | 显示全部楼层
又碰到新问题了,上面那个问题依然存在,如图,发送大概快一分钟,开始乱码,迅速发送到串口助手很多数据,全是乱码。点发送恢复正常,过一会儿又开始这样。

问题2:发送数据快一分钟的时候迅速接收大量乱码数据

问题2:发送数据快一分钟的时候迅速接收大量乱码数据
回复

使用道具 举报

15

主题

866

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7542
金钱
7542
注册时间
2016-11-30
在线时间
642 小时
发表于 2017-1-10 11:14:57 | 显示全部楼层
应该用16进制显示你发送的内容吧
回复

使用道具 举报

16

主题

78

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2016-12-19
在线时间
50 小时
 楼主| 发表于 2017-1-10 11:38:45 | 显示全部楼层
lvkanger 发表于 2017-1-10 11:14
应该用16进制显示你发送的内容吧

不应该啊,因为我发的是字符串,用16进制显示出来我还是看不懂啊,而且我也是想要原封不动的发送回来。
而且视频里原子哥也是这样写的啊,一次就通,我却一直是乱码。
回复

使用道具 举报

23

主题

323

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1010
金钱
1010
注册时间
2016-11-8
在线时间
233 小时
发表于 2017-1-10 11:52:59 | 显示全部楼层
芯片的晶振改了吗
亦余心之所善,
虽九死其犹未悔。
回复

使用道具 举报

16

主题

78

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2016-12-19
在线时间
50 小时
 楼主| 发表于 2017-1-10 13:54:10 | 显示全部楼层

因为之前不知道怎么修改晶振的原因,所以也没有做修改,用的是默认的。刚看了一下开发板跟原理图,开发板用的是8M晶振。
所以是不是不用修改?

晶振

晶振
回复

使用道具 举报

23

主题

323

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1010
金钱
1010
注册时间
2016-11-8
在线时间
233 小时
发表于 2017-1-10 14:10:29 | 显示全部楼层
lsy3500 发表于 2017-1-10 13:54
因为之前不知道怎么修改晶振的原因,所以也没有做修改,用的是默认的。刚看了一下开发板跟原理图,开发板 ...

在编译软件里面的。。
图中的Xtal改为8.0~
捕获.PNG
亦余心之所善,
虽九死其犹未悔。
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11541
金钱
11541
注册时间
2014-4-1
在线时间
1315 小时
发表于 2017-1-10 14:13:09 | 显示全部楼层

用手动,一次只发一个字节,观察反应。
加上仿真器吧,很容易查的。


回复

使用道具 举报

16

主题

78

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2016-12-19
在线时间
50 小时
 楼主| 发表于 2017-1-10 14:25:56 | 显示全部楼层
南有乔木 发表于 2017-1-10 14:10
在编译软件里面的。。
图中的Xtal改为8.0~

是8.0没改
回复

使用道具 举报

16

主题

78

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2016-12-19
在线时间
50 小时
 楼主| 发表于 2017-1-10 14:32:01 | 显示全部楼层
xuande 发表于 2017-1-10 14:13
用手动,一次只发一个字节,观察反应。
加上仿真器吧,很容易查的。

发一个字节也是乱码。就是串口接到的再转发出来还是乱码。
仿真的话,中断不知道怎么仿真,我在中断里面打了一些断点,让程序跑起来,发送一个字符,调试助手上还是显示乱码,显示完又开始显示while循环中的循环输出“lsy”。


(PS:while循环里面的循环输出“lsy”字符串是好的,只是过一会儿会乱码,再过一会儿又恢复正常。)
回复

使用道具 举报

16

主题

78

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2016-12-19
在线时间
50 小时
 楼主| 发表于 2017-1-10 15:36:51 | 显示全部楼层
小小怪 发表于 2017-1-10 15:10
接收到的,存起来再转发就没问题了

我在中断里面是用一个u8类型的res接收的,然后再转发的。
这个附件是我的代码压缩包,跪求大大帮我看看。~~~灰常感谢。
[mw_shl_code=applescript,true]//中断处理函数:功能:转发接收到的字符串
void USART1_IRQHandler(void)
{
    u8 res;
    if(USART_GetITStatus(USART1,USART_IT_RXNE))
    {
         res= USART_ReceiveData(USART1);
         USART_SendData(USART1,res);   
    }
}[/mw_shl_code]

STM32_USART1_RXD_TXD_字符串接收并转发_STM32F103C8T6.rar

4.29 MB, 下载次数: 155

代码压缩包

回复

使用道具 举报

3

主题

108

帖子

0

精华

高级会员

Rank: 4

积分
717
金钱
717
注册时间
2014-2-24
在线时间
257 小时
发表于 2017-1-10 16:19:27 | 显示全部楼层
lsy3500 发表于 2017-1-10 15:36
我在中断里面是用一个u8类型的res接收的,然后再转发的。
这个附件是我的代码压缩包,跪求大大帮我看看 ...

我的意思是收完再发出去,不要在中断转发,试一下,没问题再考虑中断
回复

使用道具 举报

21

主题

387

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1043
金钱
1043
注册时间
2016-9-8
在线时间
213 小时
发表于 2017-1-10 16:35:05 | 显示全部楼层
因为你的程序有问题....................
shop60994719.taobao.com
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11541
金钱
11541
注册时间
2014-4-1
在线时间
1315 小时
发表于 2017-1-10 17:10:27 | 显示全部楼层
lsy3500 发表于 2017-1-10 14:32
发一个字节也是乱码。就是串口接到的再转发出来还是乱码。
仿真的话,中断不知道怎么仿真,我在中断里面 ...


这里有两个物理过程,收和发,
要一个个调试,别指望一次全搞定,高手也未必行。

在中断函数里设断点,收一个字节就应当停在断点处,
然后检查接收数据是否等于发送方的数据。
正确则说明接收功能基本正常。再往后面查。


回复

使用道具 举报

3

主题

108

帖子

0

精华

高级会员

Rank: 4

积分
717
金钱
717
注册时间
2014-2-24
在线时间
257 小时
发表于 2017-1-10 20:04:14 | 显示全部楼层
本帖最后由 小小怪 于 2017-1-10 20:10 编辑

之前学习寄存器版本,现在用库函数感觉很方便....
下面代码能实现,感觉中断转发不怎么可靠...楼主可以自己试一下多中断或多任务的情况下

[mw_shl_code=applescript,true]int main(void) {
        uint32_t del;

        GPIO_InitTypeDef uGPIO;
        USART_InitTypeDef uUSART;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE);

        uGPIO.GPIO_Pin                = GPIO_Pin_9;
        uGPIO.GPIO_Mode                = GPIO_Mode_AF_PP;
        uGPIO.GPIO_Speed        = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &uGPIO);

        uGPIO.GPIO_Pin                = GPIO_Pin_10;
        uGPIO.GPIO_Mode                = GPIO_Mode_IN_FLOATING;
        uGPIO.GPIO_Speed        = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &uGPIO);

        USART_DeInit(USART1);
        /* USART_InitStruct members default value */
        uUSART.USART_BaudRate = 9600;
        uUSART.USART_WordLength = USART_WordLength_8b;
        uUSART.USART_StopBits = USART_StopBits_1;
        uUSART.USART_Parity = USART_Parity_No ;
        uUSART.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
        uUSART.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  
        USART_Init(USART1, &uUSART);

        NVIC_SetPriorityGrouping(2);
        NVIC_SetPendingIRQ(USART1_IRQn);
        NVIC_EnableIRQ(USART1_IRQn);
        NVIC_SetPriority(USART1_IRQn, 2);

        USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
        USART_Cmd(USART1, ENABLE);
        
        while(1) {
                del = 1000000;
                while(del--) {;}
        }
}

void USART1_IRQHandler(void) {
        uint8_t Res;
        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
                Res = USART_ReceiveData(USART1);
                USART1->DR = Res;
                //while((USART1->SR&0X40)==0);
                USART_ClearFlag(USART1, USART_FLAG_RXNE);
  }
}[/mw_shl_code]


回复

使用道具 举报

16

主题

78

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2016-12-19
在线时间
50 小时
 楼主| 发表于 2017-1-11 09:41:10 | 显示全部楼层
密耳 发表于 2017-1-10 16:35
因为你的程序有问题....................

程序确实有点问题,板子也有点问题,昨天找到原因了,板子是新做的,发现TXD和RXD焊接反了,缓过来以后基本正常了。但是我的发送函数有点问题:(接头用的485所以传输速度可能会有点慢)
我在中断函数中不加延时的话,给他发送,他再转发出来是乱码,加一点延时只能输出字符串的前两个字符。
所以这就不知道该怎么处理了~~
[mw_shl_code=c,true]//中断处理函数:功能:转发接收到的字符串
void USART1_IRQHandler(void)
{
    u8 res;
    if(USART_GetITStatus(USART1,USART_IT_RXNE))
    {
        res= USART_ReceiveData(USART1);

        mydelay_ms(100);  //就是这句延时,没有就乱码,有了就只能输出前两个字符,而且延时短了也是乱码,时间太长了没输出(偶尔会输出一个乱码的符号)
        
        USART_SendData(USART1,res);   
    }
}[/mw_shl_code]
回复

使用道具 举报

16

主题

78

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2016-12-19
在线时间
50 小时
 楼主| 发表于 2017-1-11 09:42:42 | 显示全部楼层
小小怪 发表于 2017-1-10 16:19
我的意思是收完再发出去,不要在中断转发,试一下,没问题再考虑中断

哦哦 ,明白了,我试试。
回复

使用道具 举报

16

主题

78

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2016-12-19
在线时间
50 小时
 楼主| 发表于 2017-1-11 09:56:29 | 显示全部楼层
小小怪 发表于 2017-1-10 20:04
之前学习寄存器版本,现在用库函数感觉很方便....
下面代码能实现,感觉中断转发不怎么可靠...楼主可以自 ...

乱码,寄存器我还是不太会,比较菜,我先调试下我的程序,昨天找到原因是硬件的RXD跟TXD焊接反了,现在换过来我的程序基本对了,就出了一点小问题,发送的时候只能发送前两个字节,我先单步调试下,找找原因。完了再研究下寄存器。

灰常感谢哈。
回复

使用道具 举报

3

主题

108

帖子

0

精华

高级会员

Rank: 4

积分
717
金钱
717
注册时间
2014-2-24
在线时间
257 小时
发表于 2017-1-11 09:59:35 | 显示全部楼层
lsy3500 发表于 2017-1-11 09:56
乱码,寄存器我还是不太会,比较菜,我先调试下我的程序,昨天找到原因是硬件的RXD跟TXD焊接反了,现在换 ...

我配置CODE我有试过,OK,没乱码
回复

使用道具 举报

16

主题

78

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2016-12-19
在线时间
50 小时
 楼主| 发表于 2017-1-11 10:30:21 | 显示全部楼层
小小怪 发表于 2017-1-11 09:59
我配置CODE我有试过,OK,没乱码

还是那个问题,我不加延时的话,输出乱码。加延时了也只能输出第一个字节。(我用的是485接口,是不是因为485接口传输速率慢的原因?)
还有,我单步调式,进去以后发现只能进一次中断,之后就再没进来过。而且单步调试的时候,我发现中断函数里面res接收的确实是0x31,正确的(我发送的十进制1234),可是直接受到了第一个字节,并且中断也就只能进这一次,之后再也进不来。不知道为什么。

你能帮我看看我是不是把你的代码哪里改的不对?

非常感谢。


M6WP38CF4A419OJ[~GXZ6TI.png

STM32_USART1_RXD_TXD_字符串接收并转发-------------------.rar

4.26 MB, 下载次数: 110

回复

使用道具 举报

17

主题

344

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1280
金钱
1280
注册时间
2013-12-14
在线时间
567 小时
发表于 2017-1-11 10:39:37 | 显示全部楼层
没怎么看程序,楼上有人已经给过建议,建议还是不要在接收中断中进行发送行为。

搞一个全局数组或者队列,接收到数据就放到里面,接收完以后,前台主函数里面慢慢发。
半导体->模拟电路->数字电路->单片机->汇编->C->操作系统->java
回复

使用道具 举报

3

主题

108

帖子

0

精华

高级会员

Rank: 4

积分
717
金钱
717
注册时间
2014-2-24
在线时间
257 小时
发表于 2017-1-11 10:49:40 | 显示全部楼层
lsy3500 发表于 2017-1-11 10:30
还是那个问题,我不加延时的话,输出乱码。加延时了也只能输出第一个字节。(我用的是485接口,是不是因 ...

是485的问题,485收发是谁控制的?
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-30 11:31

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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