OpenEdv-开源电子网

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

串口通信

[复制链接]

3

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
53
金钱
53
注册时间
2017-4-1
在线时间
14 小时
发表于 2017-5-16 16:00:57 | 显示全部楼层 |阅读模式
1金钱
我想要实现STM32开发板不断的通过串口给PC发数据,芯片是F103c8t6的,结果串口助手显示一直返回的是01 01 01 01,但其实我想发送的是1,2,3,4,5,,6,,7,,8,9。求教这是什么原因。代码如下:
usart配置函数如下:[mw_shl_code=applescript,true]
void My_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);
       
        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);//②
       
        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_TXE,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);
       

}[/mw_shl_code]主函数和中断函数如下:
[mw_shl_code=c,true]void USART1_IRQHandler(void)
{
        int   string[] ={1,2,3,4,5,6,7,8,9};
        int i=0;
        if(USART_GetITStatus( USART1, USART_IT_TXE)!=RESET)
        {
                if(i<9)
                {
                        USART_SendData(USART1 ,string);
                        i++;
                }
                else
                {
                        i=0;
                        USART_SendData(USART1 ,string);
                        i++;       
                }
                USART_ClearFlag(USART1,USART_FLAG_TXE);
     }

}
int main(void)
{       
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        My_USART1_Init();
         
        while(1);
       
}[/mw_shl_code]


最后串口助手显示如下:
D[)047R4N38M2D~GJT9YYL2.png

最佳答案

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

你的“i”是局部变量,每次进入中断的时候值都为“0”,所以每次都只发第一个数据“1”
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

29

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
286
金钱
286
注册时间
2017-5-15
在线时间
42 小时
发表于 2017-5-16 16:00:58 | 显示全部楼层
你的“i”是局部变量,每次进入中断的时候值都为“0”,所以每次都只发第一个数据“1”
回复

使用道具 举报

62

主题

903

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3567
金钱
3567
注册时间
2016-1-8
在线时间
544 小时
发表于 2017-5-16 16:08:54 | 显示全部楼层
大兄弟啊,你C语言不过关啊, int   string[] ={1,2,3,4,5,6,7,8,9};你这个是局部变量,每次都要初始化,你肯定是一直发送1,而且你在接收中断函数中,发送字符,是什么鬼啊。直接在wihle中for循环send就行
回复

使用道具 举报

3

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
53
金钱
53
注册时间
2017-4-1
在线时间
14 小时
 楼主| 发表于 2017-5-16 16:12:34 | 显示全部楼层
板板 发表于 2017-5-16 16:06
你的“i”是局部变量,每次进入中断的时候值都为“0”,所以每次都只发第一个数据“1”

一言惊醒梦中人,抱拳了,老铁。昨天想到大半夜,都没想的出来。看来还需要恶补C的知识。
回复

使用道具 举报

3

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
53
金钱
53
注册时间
2017-4-1
在线时间
14 小时
 楼主| 发表于 2017-5-16 16:22:53 | 显示全部楼层
Sun_Fly 发表于 2017-5-16 16:08
大兄弟啊,你C语言不过关啊, int   string[] ={1,2,3,4,5,6,7,8,9};你这个是局部变量,每次都要初始化,你 ...

首先非常感谢大兄弟的热心回帖。第一个,局部变量的错误我已经更正。第二,我的中断函数中就是要把那个数组里面的内容发送出去啊。第三,你说的在while()中for循环是这样的吗?
while(1)
{
for(i=0;string!='\0';i++)
{
USART_SendData(USART1,string);
}
}

我C是很一般。。最近想恶补。。
回复

使用道具 举报

3

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
53
金钱
53
注册时间
2017-4-1
在线时间
14 小时
 楼主| 发表于 2017-5-16 16:24:24 | 显示全部楼层
loser1 发表于 2017-5-16 16:22
首先非常感谢大兄弟的热心回帖。第一个,局部变量的错误我已经更正。第二,我的中断函数中就是要把那个数 ...

USART_SendData(USART1,string);
漏写了。。。
回复

使用道具 举报

62

主题

903

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3567
金钱
3567
注册时间
2016-1-8
在线时间
544 小时
发表于 2017-5-16 16:53:55 | 显示全部楼层
for(i = 0;i<10;i++){
     while(*****TX == ***);
     USART_SendData(USART1 ,string[i]);
}
你看例程 有
回复

使用道具 举报

3

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
53
金钱
53
注册时间
2017-4-1
在线时间
14 小时
 楼主| 发表于 2017-5-16 17:14:15 | 显示全部楼层

你写的while语句是什么意思啊。。历程里是这么写的
for(i=0;i<10;i++)
{
  USART_SendData(USART1,string);
  while(USART_GetFlagDtatus(USART1,USART_FLAG_TC)!=SET);
}
这里的while语句意思我知道,是检测USART1上的发送中断标志位,以此来判断发送出去的一个数据是否被发送完成了。
回复

使用道具 举报

62

主题

903

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3567
金钱
3567
注册时间
2016-1-8
在线时间
544 小时
发表于 2017-5-16 17:20:03 | 显示全部楼层
loser1 发表于 2017-5-16 17:14
你写的while语句是什么意思啊。。历程里是这么写的
for(i=0;i

对,你 看例程 USART_SendData(USART1,string);
回复

使用道具 举报

62

主题

903

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3567
金钱
3567
注册时间
2016-1-8
在线时间
544 小时
发表于 2017-5-16 17:20:43 | 显示全部楼层
Sun_Fly 发表于 2017-5-16 17:20
对,你 看例程 USART_SendData(USART1,string);

【  i 】
回复

使用道具 举报

3

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
53
金钱
53
注册时间
2017-4-1
在线时间
14 小时
 楼主| 发表于 2017-5-16 17:37:10 | 显示全部楼层
Sun_Fly 发表于 2017-5-16 17:20
对,你 看例程 USART_SendData(USART1,string);

没懂你的意思。。。我原来是想实现开发板不停的发送一串数据给PC,经过刚刚和你的一番讨论,你觉得我不该在中断里发送字符,在while()里写比较好。具体的该怎么写呢?请给个具体的main()函数。谢谢了
回复

使用道具 举报

62

主题

903

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3567
金钱
3567
注册时间
2016-1-8
在线时间
544 小时
发表于 2017-5-16 17:55:53 | 显示全部楼层
loser1 发表于 2017-5-16 17:37
没懂你的意思。。。我原来是想实现开发板不停的发送一串数据给PC,经过刚刚和你的一番讨论,你觉得我不该 ...

你知道那个中断函数什么时候才会调用吗?你自己都写出来代码了,还让我给你写
回复

使用道具 举报

62

主题

903

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3567
金钱
3567
注册时间
2016-1-8
在线时间
544 小时
发表于 2017-5-16 17:56:40 | 显示全部楼层
while(1)
  for(i=0;i<10;i++)
  {
    USART_SendData(USART1,string[ i ]);
    while(USART_GetFlagDtatus(USART1,USART_FLAG_TC)!=SET);
  }
}
回复

使用道具 举报

3

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
53
金钱
53
注册时间
2017-4-1
在线时间
14 小时
 楼主| 发表于 2017-5-16 19:22:45 | 显示全部楼层
Sun_Fly 发表于 2017-5-16 17:55
你知道那个中断函数什么时候才会调用吗?你自己都写出来代码了,还让我给你写

我写的中断程序一开始有一个判断语句if(USART_GetITStatus( USART1, USART_IT_TXE)!=RESET);这句话的意思是,读取状态寄存器USART_SR的TXE位,看它是不是为1,如果为1,则执行下面的语句,就是说,这是在TXE位为1的时候才会调用,即,数据发送完成之后调用中断。


还有,大兄弟,我不是伸手党。。只是觉得你的建议很好,我想把程序改进一下,另外,我参照你底下给出的代码。。没法实现数据发送。。
回复

使用道具 举报

22

主题

213

帖子

0

精华

高级会员

Rank: 4

积分
682
金钱
682
注册时间
2015-2-13
在线时间
74 小时
发表于 2017-5-17 08:58:48 | 显示全部楼层
int i=0; 改成  static int i = 0;
回复

使用道具 举报

62

主题

903

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3567
金钱
3567
注册时间
2016-1-8
在线时间
544 小时
发表于 2017-5-17 09:38:07 | 显示全部楼层
loser1 发表于 2017-5-16 19:22
我写的中断程序一开始有一个判断语句if(USART_GetITStatus( USART1, USART_IT_TXE)!=RESET);这句话的意 ...

这个语句的意思是是否有发送中断产生,只有调用senddata才会这个位置1,懂了把,一般不会这样用的,串口的中断函数一般都是做接收中断用的,你下载原子哥的例程看吧。不行就看视频
回复

使用道具 举报

4

主题

380

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3088
金钱
3088
注册时间
2015-10-17
在线时间
320 小时
发表于 2017-5-17 10:45:05 | 显示全部楼层
大家回复的很清楚了,中断函数就是一个子函数,每次进入都要重新初始化的,所以你的i永远都是0的,15楼说的没错,弄成全局变量就可以
回复

使用道具 举报

3

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
53
金钱
53
注册时间
2017-4-1
在线时间
14 小时
 楼主| 发表于 2017-5-17 11:10:38 | 显示全部楼层
hgr211 发表于 2017-5-17 10:45
大家回复的很清楚了,中断函数就是一个子函数,每次进入都要重新初始化的,所以你的i永远都是0的,15楼说的 ...

谢谢回帖。已经改好了。
回复

使用道具 举报

3

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
53
金钱
53
注册时间
2017-4-1
在线时间
14 小时
 楼主| 发表于 2017-5-17 11:13:04 | 显示全部楼层
Sun_Fly 发表于 2017-5-17 09:38
这个语句的意思是是否有发送中断产生,只有调用senddata才会这个位置1,懂了把,一般不会这样用的,串口 ...

好的。我是看了视频才写程序的,原来以为自己掌握的很好了。。后来发现原来串口能收发数据的原理没深入理解。。。谢谢大兄弟的热心回帖
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-8-21 04:41

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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