OpenEdv-开源电子网

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

USART1中断函数的问题,困扰了我一下午,希望获得帮助

[复制链接]

1

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
172
金钱
172
注册时间
2016-5-9
在线时间
22 小时
发表于 2016-6-5 11:06:05 | 显示全部楼层 |阅读模式
5金钱
  1,USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); 当接受数据完成时,RXNE被置1,此时触发中断
  USART_ITConfig(USART1, USART_IT_TC,ENABLE); 但是,库函数手册上面写着,当数据发送完成,TC被置位,此时也可以触发中断,那么问题来了,这两个标志位都可以触发中断,它们的中断函数都是USART1_IRQHandler()吗?如果都是这个函数,那么谁先谁后呢?对这两个标志位触发的中断函数思维很模糊。
2,设置中断优先级分组的意义在哪?我愣是没从中文手册里面读出来。

最佳答案

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

USART_ClearFlag(USART1,USART_FLAG_TC);//中断完成后清除TC 这句应该放在中断函数的最后一句吧
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

2178

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3323
金钱
3323
注册时间
2013-7-19
在线时间
195 小时
发表于 2016-6-5 11:06:06 | 显示全部楼层
Jzeng666 发表于 2016-6-5 15:42
void MyUsart_Init()
{
.......................//前面的和原子哥写的一样

USART_ClearFlag(USART1,USART_FLAG_TC);//中断完成后清除TC
这句应该放在中断函数的最后一句吧
回复

使用道具 举报

10

主题

36

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
301
金钱
301
注册时间
2016-1-6
在线时间
84 小时
发表于 2016-6-5 11:12:09 | 显示全部楼层
只有这一个中断服务函数,但是可以在中断服务函数中判断是哪种类型的中断,从而产生不同的操作。设置中断优先级分组,可以很方便的管理中断请求,相应的内容手册里都有,用过就知道了。
回复

使用道具 举报

1

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
172
金钱
172
注册时间
2016-5-9
在线时间
22 小时
 楼主| 发表于 2016-6-5 11:18:26 | 显示全部楼层
Nevermore 发表于 2016-6-5 11:12
只有这一个中断服务函数,但是可以在中断服务函数中判断是哪种类型的中断,从而产生不同的操作。设置中断优 ...

您的意思是RXNE和TC触发的中断可以设置优先级吗
回复

使用道具 举报

17

主题

344

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1280
金钱
1280
注册时间
2013-12-14
在线时间
567 小时
发表于 2016-6-5 11:25:58 | 显示全部楼层
Jzeng666 发表于 2016-6-5 11:18
您的意思是RXNE和TC触发的中断可以设置优先级吗

二楼的意思是你在串口中断中可以用if来判断是RXNE中断到来还是TC中断到来,然后执行相应的动作。
半导体->模拟电路->数字电路->单片机->汇编->C->操作系统->java
回复

使用道具 举报

1

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
172
金钱
172
注册时间
2016-5-9
在线时间
22 小时
 楼主| 发表于 2016-6-5 11:28:39 | 显示全部楼层
东北小辉辉 发表于 2016-6-5 11:25
二楼的意思是你在串口中断中可以用if来判断是RXNE中断到来还是TC中断到来,然后执行相应的动作。

好的 我试试
回复

使用道具 举报

1

主题

9

帖子

0

精华

新手上路

积分
22
金钱
22
注册时间
2016-5-10
在线时间
1 小时
发表于 2016-6-5 15:29:57 | 显示全部楼层
每个外设的中断都有好多种,比如定时器里溢出中断、输入捕获中断等等,用的都是一个IRQHandler()函数。这个函数是由启动文件定义好的,一旦中断系统自动调用,我们能做的就是在函数里判断不同中断相应的标志位是否置1,然后执行中断后需要的操作
回复

使用道具 举报

1

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
172
金钱
172
注册时间
2016-5-9
在线时间
22 小时
 楼主| 发表于 2016-6-5 15:36:35 | 显示全部楼层
wzfluid 发表于 2016-6-5 15:29
每个外设的中断都有好多种,比如定时器里溢出中断、输入捕获中断等等,用的都是一个IRQHandler()函数。这 ...

我还是不太懂 啊~~
回复

使用道具 举报

1

主题

9

帖子

0

精华

新手上路

积分
22
金钱
22
注册时间
2016-5-10
在线时间
1 小时
发表于 2016-6-5 15:42:02 | 显示全部楼层
Jzeng666 发表于 2016-6-5 15:36
我还是不太懂 啊~~

呐,再举个栗子。发送后和接受完都有标志位被置1的。你的函数就是这样
USART1_IRQHandle()
{
if(USART_GetFlagStatus(USART1, USART_FLAG_TC)!=RESET){...};
if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE)!=RESET){...};
}
就是在系统规定的中断调用函数里处理自己需要的中断
回复

使用道具 举报

1

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
172
金钱
172
注册时间
2016-5-9
在线时间
22 小时
 楼主| 发表于 2016-6-5 15:42:09 | 显示全部楼层
void MyUsart_Init()
{
.......................//前面的和原子哥写的一样

  USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);  //设置中断标志RXNE
  delay_ms(50000);
  USART_ITConfig(USART1, USART_IT_TC,ENABLE);    //设置标志TC
        USART_ClearFlag(USART1,USART_FLAG_TC);//中断完成后清除TC
}
void USART1_IRQHandler()
{
        u8 res;

                if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==1)//串口发送数据
                {       
                                res=USART_ReceiveData(USART1);
                                USART_SendData(USART1,res);
                }
                if(USART_GetFlagStatus(USART1,USART_FLAG_TC)==1)//如果发送完成。则发生中断 并且蜂鸣器响
                {
                        GPIO_SetBits(GPIOB,GPIO_Pin_8);
                        delay_ms(100);
                        GPIO_ResetBits(GPIOB,GPIO_Pin_8);
                }       
}       
int main(void)           //主函数
{       
   beep_Init();         
         delay_init();
         delay_ms(5000);
   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);    //  
         MyUsart_Init();
         
         while(1);
}

这个函数我快写了一天了,每次把程序直接输进去,蜂鸣器就一直响,实在不知道错在哪,求指点啊,,困扰一天了
回复

使用道具 举报

1

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
172
金钱
172
注册时间
2016-5-9
在线时间
22 小时
 楼主| 发表于 2016-6-5 15:44:27 | 显示全部楼层
wzfluid 发表于 2016-6-5 15:42
呐,再举个栗子。发送后和接受完都有标志位被置1的。你的函数就是这样
USART1_IRQHandle()
{

对呀我和您的理解是一样的啊 我在你的楼下贴出了我的程序 您能帮我看看哪里出问题了吗~~~我的蜂鸣器一直响,我被搞了 一天了 ,,,真心感觉很狂躁啊。。。。
回复

使用道具 举报

1

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
172
金钱
172
注册时间
2016-5-9
在线时间
22 小时
 楼主| 发表于 2016-6-5 15:48:39 | 显示全部楼层
ricefat 发表于 2016-6-5 15:45
USART_ClearFlag(USART1,USART_FLAG_TC);//中断完成后清除TC
这句应该放在中断函数的最后一句吧

我试试
回复

使用道具 举报

1

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
172
金钱
172
注册时间
2016-5-9
在线时间
22 小时
 楼主| 发表于 2016-6-5 15:51:18 | 显示全部楼层
void MyUsart_Init()
{
.......................//前面的和原子哥写的一样

  USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);  //设置中断标志RXNE
  delay_ms(50000);
  USART_ITConfig(USART1, USART_IT_TC,ENABLE);    //设置标志TC
        USART_ClearFlag(USART1,USART_FLAG_TC);//中断完成后清除TC
}
void USART1_IRQHandler()
{
        u8 res;

                if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==1)//串口发送数据
                {        
                                res=USART_ReceiveData(USART1);
                                USART_SendData(USART1,res);
                }
                if(USART_GetFlagStatus(USART1,USART_FLAG_TC)==1)//如果发送完成。则发生中断 并且蜂鸣器响
                {
                        GPIO_SetBits(GPIOB,GPIO_Pin_8);
                        delay_ms(100);
                        GPIO_ResetBits(GPIOB,GPIO_Pin_8);
                }        
}        
int main(void)           //主函数
{        
   beep_Init();         
         delay_init();
         delay_ms(5000);
   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);    //  
         MyUsart_Init();
         
         while(1);
}

我就是想当数据接收完成的时候,把它发送出去,发送完成后,TC置1的蜂鸣器响一下,然后清楚TC,再发送下一个数据,就这么一个简单的过程。。。这个函数我快写了一天了,每次把程序直接输进去,蜂鸣器就一直响,实在不知道错在哪,求指点啊,,困扰一天了。。。。
回复

使用道具 举报

1

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
172
金钱
172
注册时间
2016-5-9
在线时间
22 小时
 楼主| 发表于 2016-6-5 15:53:49 | 显示全部楼层
ricefat 发表于 2016-6-5 15:45
USART_ClearFlag(USART1,USART_FLAG_TC);//中断完成后清除TC
这句应该放在中断函数的最后一句吧

牛逼闪闪啊~~解决了  谢谢您
回复

使用道具 举报

1

主题

9

帖子

0

精华

新手上路

积分
22
金钱
22
注册时间
2016-5-10
在线时间
1 小时
发表于 2016-6-5 15:56:52 | 显示全部楼层
在中断程序最后加一个中断标志位清除试试
回复

使用道具 举报

1

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
172
金钱
172
注册时间
2016-5-9
在线时间
22 小时
 楼主| 发表于 2016-6-5 16:03:28 | 显示全部楼层
wzfluid 发表于 2016-6-5 15:56
在中断程序最后加一个中断标志位清除试试

嗯嗯,对的,就是加一个清除
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-14 03:07

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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