找回密码
 注册会员
更新自动建库工具PCB Footprint Expert 2024.04 Pro / Library Expert 破解版

M16捕捉及12位PWM输出试验

[复制链接]
慧龙 发表于 2010-5-15 00:06:26 | 显示全部楼层 |阅读模式

本文包含原理图、PCB、源代码、封装库、中英文PDF等资源

您需要 登录 才可以下载或查看,没有账号?注册会员

×
经过一段时间的摸索,ICP及PWM终于取得了收获。我要做的实验是要求ICP进行捕捉来测量脉冲的频率,计算出的结果显示在5位LED数码管上,同时利用12位的PWM输出测量结果。测量电路与以前做过的“M16频率测量及PWM”一文的电路相同,脉冲信号输入到T0及ICP引脚。各计数器的作用如下:
Timer0:对外部脉冲进行计数,使用溢出中断,在其中断服务程序中对溢出次数进行计数;
Timer1:ICP捕捉及PWM控制,工作在方式15,OCR1A的值定为0x0FFF,使用ICP捕捉中断和溢出中断。 溢出中断服务程序中对Timer1的溢出次数进行计数,ICP中断服务程序中读出Timer0的TCNT0及其溢出次数、Timer1的溢出次数及ICR1的值,并且允许中断嵌套;
Timer2:工作在CTC方式,产生1mS的定时中断,用于LED数码管的动态扫描和测量闸门的控制。
在开始试验时,由于开放的中断比较多,其实际的响应与我的设想存在偏差,因此测量的结果总是不稳定,表现为显示值随机跳动比较的大。通过JTAG的观察发现,引起这种原因的根源在于,T0、T1及ICP的中断可能同时触发,而根据AVR的中断优先级设定,ICP会抢先进入中断,导致了ICP中断服务程序中读到的T0或T1的溢出值不正确,最终影响依次计算结果。当采用了中断嵌套方式后,这个问题基本上得到了解决,出现异常的情况已经无法用肉眼观察到。
程序用CVAVR编写,源码如下:

  1. /*********************************************
  2. This program was produced by the
  3. CodeWizardAVR V1.23.8d Professional
  4. Automatic Program Generator
  5. ?Copyright 1998-2003 HP InfoTech s.r.l.
  6. http://www.hpinfotech.ro
  7. e-mail:office@hpinfotech.ro

  8. Project :
  9. Version :
  10. Date    : 2005-5-23
  11. Author  : Bucker
  12. Company :
  13. Comments:


  14. Chip type           : ATmega16L
  15. Program type        : Application
  16. Clock frequency     : 8.000000 MHz
  17. Memory model        : Small
  18. External SRAM size  : 0
  19. Data Stack size     : 256
  20. *********************************************/

  21. #include <mega16.h>
  22. #include <sbit.h>
  23. #define EnableICP 10

  24. flash char LedDat[]={/*0,1,2,3,4,5,6,7,8,9,A,b,C,d,E,F,-,*/
  25. 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x58,0x5E,0x79,0x71,0x40};
  26. unsigned char LED[6],Status=0,Time0H,Time0L,Timer0H=0;
  27. unsigned int Timer1H=0,Time1H,Time1L,Na=0;

  28. // Timer 0 overflow interrupt service routine
  29. interrupt [TIM0_OVF] void timer0_ovf_isr(void)
  30. {
  31. // Place your code here
  32. Timer0H++;
  33. }

  34. // Timer 1 overflow interrupt service routine
  35. interrupt [TIM1_OVF] void OldTimer1_ovf_isr(void)
  36. {
  37. // Place your code here
  38. Timer1H++;
  39. }

  40. #pragma savereg-

  41. // Timer 1 input capture interrupt service routine
  42. interrupt [TIM1_CAPT] void OldTimer1_capt_isr(void)
  43. {
  44. // Place your code here
  45. unsigned char sREG;
  46. #asm("sei")
  47. #asm("st -y,r30")
  48. sREG=SREG;
  49. Time0L=TCNT0;
  50. Time1L=ICR1;
  51. Time1H=Timer1H;
  52. Time0H=Timer0H;
  53. BitSet(Status,0);
  54. BitClr(TIMSK,5);
  55. Na=0;
  56. SREG=sREG;
  57. #asm("ld r30,y+")
  58. }

  59. #pragma savereg+

  60. // Timer 2 output compare interrupt service routine
  61. interrupt [TIM2_COMP] void timer2_comp_isr(void)
  62. {
  63. // Place your code here
  64. static char Nb=0;
  65. #asm("sei")
  66. if (Nb<5)
  67. {
  68. PORTA=LED[Nb];
  69. PORTD&=0xF8;
  70. PORTD|=Nb;
  71. }
  72. else PORTA=0x00;
  73. if (++Nb>10) Nb=0;
  74. if (Na<60000)
  75. {
  76. if (Na++>EnableICP)
  77. {
  78. BitSet(TIFR,5);
  79. BitSet(TIMSK,5);
  80. }
  81. }
  82. }

  83. // Declare your global variables here

  84. void main(void)
  85. {
  86. // Declare your local variables here
  87. unsigned int a,b=0,OldTimer0,Timer0;
  88. unsigned long L,OldTimer1,Timer1,Temp1,Temp0;
  89. // Input/Output Ports initialization
  90. // Port A initialization
  91. // Func0=Out Func1=Out Func2=Out Func3=Out Func4=Out Func5=Out Func6=Out Func7=Out
  92. // State0=0 State1=0 State2=0 State3=0 State4=0 State5=0 State6=0 State7=0
  93. PORTA=0x00;
  94. DDRA=0xFF;

  95. // Port B initialization
  96. // Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In
  97. // State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T
  98. PORTB=0x00;
  99. DDRB=0x00;

  100. // Port C initialization
  101. // Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In
  102. // State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T
  103. PORTC=0x00;
  104. DDRC=0x00;

  105. // Port D initialization
  106. // Func0=Out Func1=Out Func2=Out Func3=In Func4=Out Func5=In Func6=In Func7=In
  107. // State0=0 State1=0 State2=0 State3=T State4=T State5=T State6=T State7=T
  108. PORTD=0x00;
  109. DDRD=0x07;

  110. // Timer/Counter 0 initialization
  111. // Clock source: T0 pin Rising Edge
  112. // Mode: Normal top=FFh
  113. // OC0 output: Disconnected
  114. TCCR0=0x07;
  115. TCNT0=0x00;
  116. OCR0=0x00;

  117. // Timer/Counter 1 initialization
  118. // Clock source: System Clock
  119. // Clock value: 8000.000 kHz
  120. // Mode: Fast PWM top=OCR1A
  121. // OC1A output: Discon.
  122. // OC1B output: Non-Inv.
  123. // Noise Canceler: Off
  124. // Input Capture on Falling Edge
  125. TCCR1A=0x23;
  126. TCCR1B=0x19;
  127. TCNT1H=0x00;
  128. TCNT1L=0x00;
  129. ICR1H=0x00;
  130. ICR1L=0x00;
  131. OCR1AH=0x0F;
  132. OCR1AL=0xFF;
  133. OCR1BH=0x00;
  134. OCR1BL=0x00;
  135. // Timer/Counter 2 initialization
  136. // Clock source: System Clock
  137. // Clock value: 250.000 kHz
  138. // Mode: CTC top=OCR2
  139. // OC2 output: Disconnected
  140. ASSR=0x00;
  141. TCCR2=0x0B;
  142. TCNT2=0x00;
  143. OCR2=0xF9;

  144. // External Interrupt(s) initialization
  145. // INT0: Off
  146. // INT1: Off
  147. // INT2: Off
  148. MCUCR=0x00;
  149. MCUCSR=0x00;

  150. // Timer(s)/Counter(s) Interrupt(s) initialization
  151. TIMSK=0xA5;

  152. // Analog Comparator initialization
  153. // Analog Comparator: Off
  154. // Analog Comparator Input Capture by Timer/Counter 1: Off
  155. // Analog Comparator Output: Off
  156. ACSR=0x80;
  157. SFIOR=0x00;

  158. // Global enable interrupts
  159. #asm("sei")

  160. while (1)
  161. {
  162. // Place your code here
  163. if (BitTst(Status,0))
  164. {
  165. Timer0=Time0L|(unsigned int)Time0H<<8;
  166. Timer1=Time1L|(unsigned long)Time1H<<16;
  167. L=8e6/59986*60000/(Temp1=(Timer1-OldTimer1))*(Temp0=(Timer0-OldTimer0));
  168. if (L/10!=9932)
  169. {
  170. if (b++>2)
  171. {
  172. PORTA=0x00;
  173. b=0;
  174. }
  175. }
  176. OldTimer1=Timer1;
  177. OldTimer0=Timer0;
  178. LED[0]=LedDat[L/10000];
  179. a=L % 10000;
  180. LED[1]=LedDat[a/1000];
  181. a%=1000;
  182. LED[2]=LedDat[a/100];
  183. a%=100;
  184. LED[3]=LedDat[a/10];
  185. LED[4]=LedDat[a % 10] | 0x80;
  186. BitClr(Status,0);
  187. }
  188. }
  189. }

复制代码


原理图.pdf (14.28 KB, 下载次数: 16)
lxqlzj 发表于 2010-9-7 14:29:50 | 显示全部楼层
dddddddddddddddddddddddddddddddddddddddddddddddddddddddd
cylnpy 发表于 2011-11-28 13:40:48 | 显示全部楼层
hhhhhhhhhhhhhhhhhhhh
jiuhanfeng 发表于 2016-5-12 16:40:19 | 显示全部楼层
非常感谢, 准备学呢,但不知道能不能坚持
*滑块验证:
您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

QQ|手机版|MCU资讯论坛 ( 京ICP备18035221号-2 )|网站地图

GMT+8, 2024-12-23 08:41 , Processed in 0.059169 second(s), 11 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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