OpenEdv-开源电子网

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

请教各位关于外部时钟上升沿触发中断的疑问

[复制链接]

19

主题

65

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
440
金钱
440
注册时间
2015-2-12
在线时间
40 小时
发表于 2015-5-8 10:48:59 | 显示全部楼层 |阅读模式
5金钱
现在我在做STM32单片机输出SSI信号的工作,希望能实现STM32采集编码器的SSI信号,并且以SSI信号输出,主要的困难现在是如何用STM32F103实现SSI信号的时序。
我自己想的是利用STM32的EXTI中断来实现,将外部时钟作为触发条件,外部时钟上升沿触发数据的传输,不知道我的这个想法在理论上是否是可行的?麻烦各位给我点意见和建议,感谢感谢。

看了EXTI中断的一些资料之后,发现主要步骤是配置包括RCC时钟,GPIO端口,NVIC嵌套向量中断的优先级,EXTI中断的管脚以及触发条件等等。这一部分应该问题不大。
那当中断的触发条件满足时,很多资料上都写着是在EXTI_IRQHandler函数中编写相应的动作语句,实现想要实现的功能。我的疑问主要如下:
1.如何在主程序中实现对于EXTI_IRQHandler函数的调用呢?
2.如何才能使程序进入EXTI_IRQHandler函数中执行?
3.如何可以实现外部时钟信号输入?

希望有好心人能帮我!!感谢!


PS: 
刚才用示波器测量了一下外部时钟脉冲的周期约为14us,高电平和低电平大致各一半时间,不知道7us时间能否让STM32单片机完成一位数据传输过程?






最佳答案

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

不懂 SSI 是什么,但这思路应当可行,只是时间上是否来得及?要你自己看了。 中断函数不是用来让主程序调的。 主程序设置中断以后,只要中断的条件出现,不论主程序在做什么,CPU都会暂停主程序,转身去执行中断函数,完事再返回。 LZ暂且这么理解吧。
从不脑残粉,也不跟风黑。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11555
金钱
11555
注册时间
2014-4-1
在线时间
1317 小时
发表于 2015-5-8 10:49:00 | 显示全部楼层
不懂 SSI 是什么,但这思路应当可行,只是时间上是否来得及?要你自己看了。

中断函数不是用来让主程序调的。
主程序设置中断以后,只要中断的条件出现,不论主程序在做什么,CPU都会暂停主程序,转身去执行中断函数,完事再返回。
LZ暂且这么理解吧。
回复

使用道具 举报

19

主题

65

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
440
金钱
440
注册时间
2015-2-12
在线时间
40 小时
 楼主| 发表于 2015-5-13 09:02:04 | 显示全部楼层
回复【2楼】xuande:
---------------------------------
谢谢您的回复。
SSI是一种信号传输协议,跟SPI等等类似,时序不一样。

您说的中断条件出现即执行中断函数的话,就是说我只要在中断函数中写入了发生中断时需要执行的动作,然后在程序中就不用管它了?CPU到时候会自动去执行中断的内容,是这个意思吗?

那如果我一次数据传输过程总共有25位数据,也就是说会有25个时钟上升沿触发数据传输,那我的中断函数中的内容应当如何编写呢?是只写一次时钟上升沿脉冲传输数据的代码,还是说一次性把25位数据传输的代码都写进去?希望您帮我解答解答,感谢。
从不脑残粉,也不跟风黑。
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11555
金钱
11555
注册时间
2014-4-1
在线时间
1317 小时
发表于 2015-5-13 11:37:07 | 显示全部楼层
回复【3楼】维拉帕克:
---------------------------------
1、对。
2、数组,全局变量做指针。。。
回复

使用道具 举报

19

主题

65

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
440
金钱
440
注册时间
2015-2-12
在线时间
40 小时
 楼主| 发表于 2015-5-13 11:39:21 | 显示全部楼层
回复【4楼】xuande:
---------------------------------
再次感谢。

您说的全局变量我懂,然后指针怎么用法我就不太了解了,您能不能给点提示或者给段例子?谢谢哦!
从不脑残粉,也不跟风黑。
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11555
金钱
11555
注册时间
2014-4-1
在线时间
1317 小时
发表于 2015-5-13 11:43:29 | 显示全部楼层
u32       R[10];
u32       a = 0;


main
{。。。。;}


ISR
{
。。。
R[ a ] = (新数据);
a++;
。。。
}
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11555
金钱
11555
注册时间
2014-4-1
在线时间
1317 小时
发表于 2015-5-13 11:45:49 | 显示全部楼层
这是个循环存储的例子,用于接收数据。
main函数要赶快把接收内容处理掉。否则。。。

发送,同理。


回复

使用道具 举报

19

主题

65

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
440
金钱
440
注册时间
2015-2-12
在线时间
40 小时
 楼主| 发表于 2015-5-13 13:29:03 | 显示全部楼层
回复【7楼】xuande:
---------------------------------
我写程序不太在行,您给的例子中ISR函数就是接收数据用的吧?然后接收到数据后在main函数中需要及时存储接收到的内容,否则会被新接收的数据覆盖?


发送和接收好像不太一样哦,接收的新数据是需要存储的,而我发送出去的数据是已经经过单片机处理后的数据,是本身就存储在单片机里的,这就不需要涉及到新内容的处理和存储这样一个过程吧?


还有您说的中断不需要在主程序中调用,那如果是外部时钟脉冲上升沿触发中断的话,那我的中断部分的动作就必须在外部时钟下降沿发生之前完成,这样用于中断动作的时间就是高电平的持续时间,是这个意思吗?还是说只要在下一个上升沿发生之前完成都可以,这样中断可以利用的时间就是整个时钟脉冲周期了?
还希望您不厌其烦的为我解答!
从不脑残粉,也不跟风黑。
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11555
金钱
11555
注册时间
2014-4-1
在线时间
1317 小时
发表于 2015-5-13 13:41:02 | 显示全部楼层
1、完全对。

2、同理!自己画个图,很快就会明白。用循环方式,无论收发都是比较好的方法。

3、在下一个上升沿之前完成就可以。但是,中断里面要尽量少纠缠,一闪就退。要养成这个习惯。否则就要分析各种可能性。


问题描述的清楚,别人就有兴趣回答!你做得比较好。
回复

使用道具 举报

19

主题

65

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
440
金钱
440
注册时间
2015-2-12
在线时间
40 小时
 楼主| 发表于 2015-5-13 16:23:03 | 显示全部楼层
 回复【9楼】 xuande :
---------------------------------
1.再次感谢您不厌其烦的解答我的疑惑。

2.您说的循环方式收发数据的思想我明白,我觉得是不是也可以用for循环来完成这样一个过程呢?个人感觉for循环比起您说的数组指针而言的话要更为容易理解。

3.看了您的第一条回复,您说的主程序中设置中断后当出现中断条件后就会执行中断。那么主程序中应当如何设置中断呢?

4.还有一点我比较困惑的是我现在需要传输的数据是25位的一个数据,假如我顺利实现了利用中断来传输数据的想法的话,当最后一位数据传输完成后,距离下一次数据传输过程之间应该是有一段时间的时钟低电平,这段时间应当怎样利用程序来实现呢?(时钟波形和数据波形见我的附图)还是说完全取决于外部的时钟脉冲?单片机自身无法改变?

5.您说的中断一闪就退是什么意思?我没有理解,麻烦您给我细说。我的中断就是为了实现传输数据的功能,您帮我看看我中断函数内容是不是正确的?

extern unsigned long jsdata;  //jsdata就是我需要用单片机传输的数据
void EXTI9_5_IRQHandler(void)

  asm("nop");
   if(EXTI_GetITStatus(EXTI_Line9)!=RESET)
  {
    if(counter<=24)
    {
      if(jsdata&0x01000000)//取JSDATA的最高位,从MSB开始传输
      {
        DATAOUT=1;
      }
      else
      {
        DATAOUT=0;
      }
      jsdata<<1;
      counter++;
    }
  }
但是在代码中我还是没能想出应当怎样写 数据传输过程完成后的那段代码,不知您是不是可以帮帮忙?



从不脑残粉,也不跟风黑。
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11555
金钱
11555
注册时间
2014-4-1
在线时间
1317 小时
发表于 2015-5-13 17:13:10 | 显示全部楼层
1、尽我所能。

2、如果数据已经是现成的,for 当然没问题;但如果数据隔好久才收到一个,for循环就要死等,那怎么做别的事?这牵扯到整体运行思路问题。

3、每种物理外设都有自己的设置方法,内容可太多了。感觉你不是做硬件的,或者没有做过单片机?

4、是按 bit 传输数据?!每次中断只传一个bit。。。还以为每次一个byte,话有点拧了。

可以做到。用一个全局变量做计数器,每次中断加 1;在最后一位时,等这个计数器达到一定数值,再发送。如此就可以延时较长的时间。 

5、闪,就是在中断里逗留的时间要尽量短,越短越好。
回复

使用道具 举报

19

主题

65

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
440
金钱
440
注册时间
2015-2-12
在线时间
40 小时
 楼主| 发表于 2015-5-13 17:35:18 | 显示全部楼层
回复【11楼】xuande:
---------------------------------
1.我现在写这个程序的目的就是接受数据并且传输数据,基本不用干其他事情
2.我确实是才开始做单片机的,而且之前只接触过51单片机,STM32是才开始学习的,所以很多基本的东西都不太熟悉,可是工作上也没有太多时间让我熟悉了解了再去做,所以只能边看边做,碰到一些问题想不透的就只能来论坛看看有没有帮助了,幸好能遇到您这样热心的人,谢谢。
3.其实我也不知道是不是按bit传输,只要是按照我上个回复中附图的时序完成数据传输就可以,方法没有限制,我也不知道我的理解对不对。
4.之前问您的主程序中如何设置中断这个问题您还没回答,还请您解答一下?
5.中断应该要做到逻辑尽量简洁,功能尽量单一,时间尽量短暂吧?
从不脑残粉,也不跟风黑。
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11555
金钱
11555
注册时间
2014-4-1
在线时间
1317 小时
发表于 2015-5-13 18:42:25 | 显示全部楼层
3、你好像就是要实现这样的目的。

4、不同中断的设置方法不同,有共性,也有很大差别。

5、最关键是时间要短!
回复

使用道具 举报

19

主题

65

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
440
金钱
440
注册时间
2015-2-12
在线时间
40 小时
 楼主| 发表于 2015-5-13 19:24:11 | 显示全部楼层
回复【13楼】xuande:
---------------------------------
那您说我这个思路是不是对的呢?

设置中断这个我之前确实没有接触过,现在知道的都是这两天看了资料才稍微明白一点点,您能不能再给点例子启发一下我?

时间短确实很重要,关键是要在外部时钟脉冲的有效时间内完成相应的动作。
从不脑残粉,也不跟风黑。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-22 22:13

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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