圣源电子制作

 找回密码
 立即注册
查看: 26253|回复: 12
打印 上一主题 下一主题

AVR单片机的DDS信号发生器V2.0-正弦波-方波-锯-三角形-心电图和噪音-转载自国外网站

[复制链接]
跳转到指定楼层
#
发表于 2011-11-11 23:24:56 | 只看该作者 |只看大图 回帖奖励 |正序浏览 |阅读模式
改进AVR DDS信号发生器是在这里。 第一AVR单片机的DDS V1.0发电机只是一个没有任何幅度控制运行的DDS算法的尝试。 这一次,我仍然想保持如普遍使用的电路元件,单面电路板上加上良好的功能来的最低计数简单的事情。
  AVR的DDS规范   AVR DDS信号发生器V2.0是基于DDS信号发生器,它使用稍加修改固件加斯帕的DDS行ASM AVR GCC的C程序算法适应。 信号发生器有两个输出 - DDS信号和高速[1 .. 8MHz的方波信号 - 以及可重温微控制器熔丝设置错误,或用于其他用途。 高速(HS)的信号是从ATMEGA16 OC1A(PD5)引脚直接输出。  DDS的输出用于其他信号所产生的所有通过的R2R电阻网络,并通过抵消LM358N和幅度调节电路调整。 偏移和幅度可以由两个电位器调节。 偏移,可调节范围+5 V .- 5V,而在幅度范围0 .. 10V。  DDS的频率范围是从0到65534Hz,足够用于测试音频电路和其他任务。
  V2.0的主要AVR的DDS信号发生器的功能:
  • 简单的电路,方便和便宜的组件;
  • 单面印刷电路板;
  • 框与外部的交流电源插头电源;
  • 专用高速(HS)的信号输出至8MHz;
  •   DDS的可变幅度和偏置信号;
  •   DDS的信号:正弦波,方波,锯,转看到,三角形,心电图和噪音。
  •   2 × 16 LCD菜单;
  • 直观的5键键盘。
  • 频率调整步骤:1,10,100,1000,10000HZ;
  • 电后恢复最后一次配置。
在框图中,你可能会看到信号generatorV2.0的逻辑结构
正如你可以看到设备需要几个电压:+5 V,- 12V,+12 V,GND。  - 12V和+12 V用于胶印和幅度控制。 在这种情况下,电源结构使用简单的变压器和稳压器很少。
电源模块是一个单独的原型PCB板组装。
如果你不想建立电源,您可以使用PC ATX电源供应器,在所有需要的电压。 您可能需要修改Molex连接器接线如下:
  LCD菜单控制 所有操作都可以被视为在LCD菜单。 菜单可控制5个按钮,液晶显示模块
向上和向下箭头按钮可用于浏览菜单,而左,右箭头按钮用于改变频率值。 当按下中间的按钮 - 信号产生开始。 按中间的按钮再次停止信号发生器。 下面是一个完整的菜单系统,信号发生器。

重要通知,有一个单独的菜单改变频率步进。 如果您需要更改发生器频率范围宽,这是很方便。 这允许设置任何频率相对较少的按钮点击。
噪音的产生,没有频率设置。 它使用简单兰特()函数,结果连续输出DDS输出。
高速信号有4个频率可供选择:1,2,4和8MHz。
电路图和PCB 的DDS发生器(不含电源)电路原理图,非常简单容易的访问组件。 它使用了以下几个部分:
  •   AVR单片机ATmega16单片机主频16MHz的外部晶体;
  • 标准HD44780的基于2 × 16液晶显示模块;
  •   R2R DAC,简单的电阻;
  •   LM358N低功耗双运算放大器;
  • 两个电位器;
  •   5个按钮;
  • 多个接头和插座。
电路图和PCB:
单面印刷电路板:
大会   DDS发生器组装塑料盒:
试运行:
  AVR DDS 2.0固件 正如我刚才所说的DDS功能是修改后的加斯帕的 DDS算法。 主要修改是增加了额外的ASM线,使停止DDS生成。 在1.0版中是唯一的选择是复位设备,DDS功能检查,如果CPHA位在SPCR寄存器的设置是在外部中断服务程序(停止按钮)设置。 所以,现在的算法需要10个CPU周期,而不是​​9。
  无效的静态内嵌Signal_OUT(CONST uint8_t uint8_t *信号,uint8_t AD2,uint8_t AD1,AD0) {
  ASM挥发(EOR R18,R18,R18 <-0“,” N  T“
  “EOR R19,R19,R19 <-0”的“ n  T”
  “1:” N  T“
  “添加R18,0%; 1个周期”的“ n  T”
  “ADC,1%R19; 1个周期”的“ n  T”
  “ADC%A3%2; 1个周期”的“ n  T”
  “防止山泥倾泻; 3个周期”的“ n  T”
  “%4 ​​出,__tmp_reg__; 1个周期”,“ N  T”
  “SBIS 5%,2,1个周期,如果没有跳过”,“ N  T
  “RJMP 1B,2个周期。  共有10个周期“,” N  T“
  
  :“R”(AD0),“R”(AD1),“R”(AD2),“E”(信号),“我”(_SFR_IO_ADDR(PORTA)),“我”(_SFR_IO_ADDR(SPCR))
  “R18”,“R19”
  );}
  DDS信号表放置在闪光路段地址与0xXX00开始。 因此,这些路段将在适当的内存位置的makefile定义:
  #定义路段存储信号表
  LDFLAGS + = - WL -节启动=. MySection1 = 0x3A00
  LDFLAGS + = - WL -节启动=. MySection2 = 0x3B00
  LDFLAGS + = - WL -节启动=. MySection3 = 0x3C00
  LDFLAGS + = - WL -节启动=. MySection4 = 0x3D00
  LDFLAGS + = - WL -节启动=. MySection5 = 0x3E00
  LDFLAGS + = - WL -节启动=. MySection6 = 0x3F00
  这里描述的LCD控制库。
我不想去代码讨论太深。 源代码的评论非常好,如果会有关于源代码的任何问题和建议 - 随意删除评论。
测试和讨论 我已经测试信号发生器,示波器和频率计数器。 信号看起来像所有频率的范围[1至65535Hz]预期。 振幅和偏移调节工程确定。 如果offset设置为5V,那么最大的明确信号幅度可能是5V另一5V已经用于抵消(相同的是如果偏移量为- 5V)。

下面是一些测试信号示波器屏幕上:
  正弦波信号
  方波信号
  三角形信号
  看到牙齿信号
  反向看到牙齿信号
  心电信号
  噪音
  高速1MHz的信号


回复

使用道具 举报

12#
发表于 2018-3-8 21:45:21 | 只看该作者
资料很详细
回复 支持 反对

使用道具 举报

11#
发表于 2015-12-10 09:47:44 | 只看该作者
资料很详细改天仿一个
回复 支持 反对

使用道具 举报

10#
发表于 2015-10-15 15:35:59 | 只看该作者
楼主发帖辛苦了,谢谢分享!!!!!!!!!
回复 支持 反对

使用道具 举报

9#
发表于 2012-6-19 23:21:17 | 只看该作者
楼主,熔丝怎么设置的呀,这个是关键
回复 支持 反对

使用道具 举报

8#
发表于 2012-6-19 21:38:00 | 只看该作者
楼主,熔丝怎么设置呀,这个关键
回复 支持 反对

使用道具 举报

7#
发表于 2012-5-4 17:13:29 | 只看该作者
很强大的功能!楼主是那里找的这么强劲的资料!
回复 支持 反对

使用道具 举报

6#
 楼主| 发表于 2012-5-3 12:30:36 | 只看该作者
墨齐 发表于 2012-5-3 12:21
isp reset 这两个是什么?

  现在口  和  复位开关
回复 支持 反对

使用道具 举报

5#
发表于 2012-5-3 12:21:40 | 只看该作者
isp reset 这两个是什么?
回复 支持 反对

使用道具 举报

地板
 楼主| 发表于 2012-5-3 12:13:07 | 只看该作者
墨齐 发表于 2012-5-3 12:07
原理图PCB图打不开,楼主能提供个清晰的原理图么

点击可以直接 放大~~~

回复 支持 反对

使用道具 举报

板凳
发表于 2012-5-3 12:07:29 | 只看该作者
原理图PCB图打不开,楼主能提供个清晰的原理图么
回复 支持 反对

使用道具 举报

沙发
 楼主| 发表于 2011-11-11 23:28:55 | 只看该作者
下载:

原理图 PCB文件EagleCAD.zip (45.84 KB, 下载次数: 134)

仿真文件syyyd.com-.zip (30.29 KB, 下载次数: 115)

C程序.zip (123.86 KB, 下载次数: 157)

回复 支持 反对

使用道具 举报

楼主
 楼主| 发表于 2011-11-11 23:28:08 | 只看该作者
C程序
  1. //*****************************************************************************
  2. //
  3. // File Name        : 'main.c'
  4. // Title                : AVR DDS2 signal generator
  5. // Author                : Scienceprog.com - Copyright (C) 2008
  6. // Created                : 2008-03-09
  7. // Revised                : 2008-03-09
  8. // Version                : 2.0
  9. // Target MCU        : Atmel AVR series ATmega16
  10. //
  11. // This code is distributed under the GNU Public License
  12. //                which can be found at http://www.gnu.org/licenses/gpl.txt
  13. //
  14. //*****************************************************************************
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <avr/io.h>
  18. #include <avr/pgmspace.h>
  19. #include <avr/eeprom.h>
  20. #include <avr/interrupt.h>
  21. #include <util/delay.h>
  22. #include <inttypes.h>
  23. #include "lcd_lib.h"
  24. //define R2R port
  25. #define R2RPORT PORTA
  26. #define R2RDDR DDRA
  27. //define button port and dedicated pins
  28. #define BPORT PORTD
  29. #define BPIN PIND
  30. #define BDDR DDRD
  31. #define DOWN 0//PORTD
  32. #define LEFT 1//PORTD
  33. #define START  2//PORTD
  34. #define RIGHT 3//PORTD
  35. #define UP 4//PORTD
  36. //Define Highs Speed (HS) signal output
  37. #define HSDDR DDRD
  38. #define HSPORT PORTD
  39. #define HS 5//PD5
  40. //define eeprom addresses
  41. #define EEMODE 0
  42. #define EEFREQ1 1
  43. #define EEFREQ2 2
  44. #define EEFREQ3 3
  45. #define EEDUTY 4
  46. #define EEINIT E2END
  47. #define RESOLUTION 0.095367431640625
  48. #define MINFREQ 0//minimum frequency
  49. #define MAXFREQ 65534//maximum DDS frequency
  50. #define MN_No 9// number of menu items

  51. //function prototypes
  52. void delay1s(void);
  53. void Timer2_Init(void);
  54. void Timer2_Start(void);
  55. void Timer2_Stop(void);
  56. void Main_Init(void);
  57. void Menu_Update(uint8_t);
  58. void Freq_Update(void);
  59. void Timer1_Start(uint8_t);
  60. void Timer1_Stop(void);
  61. void static inline Signal_OUT(const uint8_t *, uint8_t, uint8_t, uint8_t);
  62. //adjust LCDsendChar() function for strema
  63. static int LCDsendstream(char c, FILE *stream);
  64. //----set output stream to LCD-------
  65. static FILE lcd_str = FDEV_SETUP_STREAM(LCDsendstream, NULL, _FDEV_SETUP_WRITE);

  66. //Menu Strings in flash
  67. const uint8_t MN000[] PROGMEM="      Sine      \0";
  68. //menu 1
  69. const uint8_t MN100[] PROGMEM="     Square     \0";
  70. //menu 2
  71. const uint8_t MN200[] PROGMEM="    Triangle    \0";
  72. //menu 3
  73. const uint8_t MN300[] PROGMEM="    SawTooth    \0";
  74. //menu 4
  75. const uint8_t MN400[] PROGMEM="  Rev SawTooth  \0";
  76. //menu 5
  77. const uint8_t MN500[] PROGMEM="      ECG       \0";
  78. //menu 6
  79. const uint8_t MN600[] PROGMEM="    Freq Step   \0";
  80. //menu 7
  81. const uint8_t MN700[] PROGMEM="     Noise      \0";
  82. //menu 8
  83. const uint8_t MN800[] PROGMEM="   High Speed   \0";

  84. //Array of pointers to menu strings stored in flash
  85. const uint8_t *MENU[]={
  86.                 MN000,        //
  87.                 MN100,        //menu 1 string
  88.                 MN200,        //menu 2 string
  89.                 MN300,        //menu 3 string
  90.                 MN400,        //menu 4 string
  91.                 MN500,       
  92.                 MN600,
  93.                 MN700,
  94.                 MN800
  95.                 };
  96. //various LCD strings
  97. const uint8_t MNON[] PROGMEM="ON \0";//ON
  98. const uint8_t MNOFF[] PROGMEM="OFF\0";//OFF
  99. const uint8_t NA[] PROGMEM="       NA       \0";//Clear freq value
  100. const uint8_t CLR[] PROGMEM="                \0";//Clear freq value       
  101. const uint8_t MNClrfreq[] PROGMEM="           \0";//Clear freq value
  102. const uint8_t TOEEPROM[] PROGMEM="Saving Settings\0";//saving to eeprom
  103. const uint8_t ONEMHZ[] PROGMEM="      1MHz   \0";//saving to eeprom
  104. const uint8_t welcomeln1[] PROGMEM="AVR SIGNAL\0";
  105. const uint8_t RND[] PROGMEM="    Random\0";

  106. //variables to control TDA7313
  107. struct signal{
  108. volatile uint8_t mode;                //signal
  109. volatile uint8_t fr1;                //Frequency [0..7]
  110. volatile uint8_t fr2;                //Frequency [8..15]
  111. volatile int8_t fr3;                //Frequency [16..31]
  112. volatile uint32_t freq;                //frequency value
  113. volatile uint8_t flag;                //if "0"generator is OFF, "1" - ON
  114. volatile uint32_t acc;                //accumulator
  115. volatile uint8_t ON;
  116. volatile uint8_t HSfreq;                //high speed frequency [1...4Mhz]
  117. volatile uint32_t deltafreq;        //frequency step value
  118. }SG;

  119. //define signals
  120. const uint8_t  sinewave[] __attribute__ ((section (".MySection1")))= //sine 256 values
  121. {
  122. 0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,
  123. 0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,
  124. 0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf5,
  125. 0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,
  126. 0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,
  127. 0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,
  128. 0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb3,
  129. 0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83,
  130. 0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,0x67,0x63,0x60,0x5d,0x5a,0x57,0x54,0x51,
  131. 0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b,0x38,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,
  132. 0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x12,0x10,0x0f,0x0d,0x0c,0x0a,
  133. 0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
  134. 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,
  135. 0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23,
  136. 0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3b,0x3e,0x40,0x43,0x46,0x49,0x4c,
  137. 0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c
  138. };
  139. const uint8_t squarewave[] __attribute__ ((section (".MySection2")))= //square wave
  140. {
  141. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  142. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  143. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  144. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  145. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  146. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  147. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  148. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  149. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  150. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  151. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  152. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  153. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  154. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  155. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  156. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  157. };
  158. const uint8_t sawtoothwave[] __attribute__ ((section (".MySection3")))= //sawtooth wave
  159. {
  160. 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
  161. 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
  162. 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
  163. 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
  164. 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
  165. 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,
  166. 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
  167. 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
  168. 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
  169. 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
  170. 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
  171. 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,
  172. 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,
  173. 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf,
  174. 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,
  175. 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
  176. };
  177. const uint8_t rewsawtoothwave[] __attribute__ ((section (".MySection4")))= //reverse sawtooth wave
  178. {
  179. 0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0,
  180. 0xef,0xee,0xed,0xec,0xeb,0xea,0xe9,0xe8,0xe7,0xe6,0xe5,0xe4,0xe3,0xe2,0xe1,0xe0,
  181. 0xdf,0xde,0xdd,0xdc,0xdb,0xda,0xd9,0xd8,0xd7,0xd6,0xd5,0xd4,0xd3,0xd2,0xd1,0xd0,
  182. 0xcf,0xce,0xcd,0xcc,0xcb,0xca,0xc9,0xc8,0xc7,0xc6,0xc5,0xc4,0xc3,0xc2,0xc1,0xc0,
  183. 0xbf,0xbe,0xbd,0xbc,0xbb,0xba,0xb9,0xb8,0xb7,0xb6,0xb5,0xb4,0xb3,0xb2,0xb1,0xb0,
  184. 0xaf,0xae,0xad,0xac,0xab,0xaa,0xa9,0xa8,0xa7,0xa6,0xa5,0xa4,0xa3,0xa2,0xa1,0xa0,
  185. 0x9f,0x9e,0x9d,0x9c,0x9b,0x9a,0x99,0x98,0x97,0x96,0x95,0x94,0x93,0x92,0x91,0x90,
  186. 0x8f,0x8e,0x8d,0x8c,0x8b,0x8a,0x89,0x88,0x87,0x86,0x85,0x84,0x83,0x82,0x81,0x80,
  187. 0x7f,0x7e,0x7d,0x7c,0x7b,0x7a,0x79,0x78,0x77,0x76,0x75,0x74,0x73,0x72,0x71,0x70,
  188. 0x6f,0x6e,0x6d,0x6c,0x6b,0x6a,0x69,0x68,0x67,0x66,0x65,0x64,0x63,0x62,0x61,0x60,
  189. 0x5f,0x5e,0x5d,0x5c,0x5b,0x5a,0x59,0x58,0x57,0x56,0x55,0x54,0x53,0x52,0x51,0x50,
  190. 0x4f,0x4e,0x4d,0x4c,0x4b,0x4a,0x49,0x48,0x47,0x46,0x45,0x44,0x43,0x42,0x41,0x40,
  191. 0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,
  192. 0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,
  193. 0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,
  194. 0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,
  195. };

  196. const uint8_t trianglewave[] __attribute__ ((section (".MySection5")))= //triangle wave
  197. {
  198. 0x00,0x02,0x04,0x06,0x08,0x0a,0x0c,0x0e,0x10,0x12,0x14,0x16,0x18,0x1a,0x1c,0x1e,
  199. 0x20,0x22,0x24,0x26,0x28,0x2a,0x2c,0x2e,0x30,0x32,0x34,0x36,0x38,0x3a,0x3c,0x3e,
  200. 0x40,0x42,0x44,0x46,0x48,0x4a,0x4c,0x4e,0x50,0x52,0x54,0x56,0x58,0x5a,0x5c,0x5e,
  201. 0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6e,0x70,0x72,0x74,0x76,0x78,0x7a,0x7c,0x7e,
  202. 0x80,0x82,0x84,0x86,0x88,0x8a,0x8c,0x8e,0x90,0x92,0x94,0x96,0x98,0x9a,0x9c,0x9e,
  203. 0xa0,0xa2,0xa4,0xa6,0xa8,0xaa,0xac,0xae,0xb0,0xb2,0xb4,0xb6,0xb8,0xba,0xbc,0xbe,
  204. 0xc0,0xc2,0xc4,0xc6,0xc8,0xca,0xcc,0xce,0xd0,0xd2,0xd4,0xd6,0xd8,0xda,0xdc,0xde,
  205. 0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xee,0xf0,0xf2,0xf4,0xf6,0xf8,0xfa,0xfc,0xfe,
  206. 0xff,0xfd,0xfb,0xf9,0xf7,0xf5,0xf3,0xf1,0xef,0xef,0xeb,0xe9,0xe7,0xe5,0xe3,0xe1,
  207. 0xdf,0xdd,0xdb,0xd9,0xd7,0xd5,0xd3,0xd1,0xcf,0xcf,0xcb,0xc9,0xc7,0xc5,0xc3,0xc1,
  208. 0xbf,0xbd,0xbb,0xb9,0xb7,0xb5,0xb3,0xb1,0xaf,0xaf,0xab,0xa9,0xa7,0xa5,0xa3,0xa1,
  209. 0x9f,0x9d,0x9b,0x99,0x97,0x95,0x93,0x91,0x8f,0x8f,0x8b,0x89,0x87,0x85,0x83,0x81,
  210. 0x7f,0x7d,0x7b,0x79,0x77,0x75,0x73,0x71,0x6f,0x6f,0x6b,0x69,0x67,0x65,0x63,0x61,
  211. 0x5f,0x5d,0x5b,0x59,0x57,0x55,0x53,0x51,0x4f,0x4f,0x4b,0x49,0x47,0x45,0x43,0x41,
  212. 0x3f,0x3d,0x3b,0x39,0x37,0x35,0x33,0x31,0x2f,0x2f,0x2b,0x29,0x27,0x25,0x23,0x21,
  213. 0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x11,0x0f,0x0f,0x0b,0x09,0x07,0x05,0x03,0x01
  214. };
  215. const uint8_t ECG[] __attribute__ ((section (".MySection6")))= //ECG wave
  216. {
  217. 73,74,75,75,74,73,73,73,73,72,71,69,68,67,67,67,
  218. 68,68,67,65,62,61,59,57,56,55,55,54,54,54,55,55,
  219. 55,55,55,55,54,53,51,50,49,49,52,61,77,101,132,
  220. 169,207,238,255,254,234,198,154,109,68,37,17,5,
  221. 0,1,6,13,20,28,36,45,52,57,61,64,65,66,67,68,68,
  222. 69,70,71,71,71,71,71,71,71,71,72,72,72,73,73,74,
  223. 75,75,76,77,78,79,80,81,82,83,84,86,88,91,93,96,
  224. 98,100,102,104,107,109,112,115,118,121,123,125,
  225. 126,127,127,127,127,127,126,125,124,121,119,116,
  226. 113,109,105,102,98,95,92,89,87,84,81,79,77,76,75,
  227. 74,73,72,70,69,68,67,67,67,68,68,68,69,69,69,69,
  228. 69,69,69,70,71,72,73,73,74,74,75,75,75,75,75,75,
  229. 74,74,73,73,73,73,72,72,72,71,71,71,71,71,71,71,
  230. 70,70,70,69,69,69,69,69,70,70,70,69,68,68,67,67,
  231. 67,67,66,66,66,65,65,65,65,65,65,65,65,64,64,63,
  232. 63,64,64,65,65,65,65,65,65,65,64,64,64,64,64,64,
  233. 64,64,65,65,65,66,67,68,69,71,72,73
  234. };
  235. //array of pointers to signal tables
  236. const uint8_t *SIGNALS[] ={
  237.         sinewave,
  238.         squarewave,
  239.         trianglewave,
  240.         sawtoothwave,
  241.         rewsawtoothwave,
  242.         ECG
  243. };
  244. //adjust LCD stream fuinction to use with printf()
  245. static int LCDsendstream(char c , FILE *stream)
  246. {
  247. LCDsendChar(c);
  248. return 0;
  249. }
  250. //delay 1s
  251. void delay1s(void)
  252. {
  253.         uint8_t i;
  254.         for(i=0;i<100;i++)
  255.         {
  256.                 _delay_ms(10);
  257.         }
  258. }
  259. //initialize Timer2 (used for button reading)
  260. void Timer2_Init(void)
  261. {
  262.         TCNT2=0x00;
  263.         sei();
  264. }
  265. //start timer2
  266. void Timer2_Start(void)
  267. {
  268.         TCCR2|=(1<<CS22)|(1<<CS21); //prescaller 256 ~122 interrupts/s
  269.         TIMSK|=(1<<TOV2);//Enable Timer0 Overflow interrupts
  270. }
  271. //stop timer 2
  272. void Timer2_Stop(void)
  273. {
  274.         TCCR0&=~((1<<CS22)|(1<<CS21)); //Stop timer0
  275.         TIMSK&=~(1<<TOV2);//Disable Timer0 Overflow interrupts

  276. }

  277. //Initial menu
  278. //show initial signal and frequency
  279. //generator is off
  280. void Menu_Update(uint8_t on)
  281. {
  282.         LCDclr();
  283.         CopyStringtoLCD(MENU[(SG.mode)], 0, 0 );
  284.         LCDGotoXY(0, 1);
  285.         if (SG.mode==6)
  286.                 {
  287.                         CopyStringtoLCD(CLR, 0, 1 );
  288.                         LCDGotoXY(0, 1);
  289.                         printf("    %5uHz", (uint16_t)SG.deltafreq);
  290.                 }
  291.         if (SG.mode==7)
  292.                 {
  293.                         CopyStringtoLCD(CLR, 0, 1 );
  294.                         CopyStringtoLCD(RND, 0, 1 );
  295.                 }
  296.         if (SG.mode==8)
  297.                 {
  298.                 CopyStringtoLCD(CLR, 0, 1 );
  299.                 LCDGotoXY(0, 1);
  300.                 printf(" %5uMHz", SG.HSfreq);
  301.                 }
  302.         if((SG.mode==0)||(SG.mode==1)||(SG.mode==2)||(SG.mode==3)||(SG.mode==4)||(SG.mode==5))
  303.                 {
  304.                         CopyStringtoLCD(CLR, 0, 1 );
  305.                         LCDGotoXY(0, 1);
  306.                         printf(" %5uHz", (uint16_t)SG.freq);
  307.                 }
  308.         if (SG.mode!=6)
  309.         {
  310.                 if(on==1)
  311.                         CopyStringtoLCD(MNON, 13, 1 );
  312.                 else
  313.                         CopyStringtoLCD(MNOFF, 13, 1 );
  314.         }
  315. }
  316. //update frequency value on LCD menu - more smooth display
  317. void Freq_Update(void)
  318. {
  319. if (SG.mode==6)
  320. {
  321.         LCDGotoXY(0, 1);
  322.         printf("    %5uHz", (uint16_t)SG.deltafreq);
  323. }
  324. if (SG.mode==8)
  325. {
  326. //if HS signal
  327.         LCDGotoXY(0, 1);
  328.         printf(" %5uMHz", SG.HSfreq);
  329. }
  330. if((SG.mode==0)||(SG.mode==1)||(SG.mode==2)||(SG.mode==3)||(SG.mode==4)||(SG.mode==5))
  331.         {
  332.                 LCDGotoXY(0, 1);
  333.                 printf(" %5uHz", (uint16_t)SG.freq);
  334.         }
  335. }

  336. //External interrupt0 service routine
  337. //used to stop DDS depending on active menu
  338. //any generator is stopped by setting flag value to 0
  339. //DDs generator which is inline ASM is stopped by setting
  340. //CPHA bit in SPCR register
  341. ISR(INT0_vect)
  342. {
  343. SG.flag=0;//set flag to stop generator
  344. SPCR|=(1<<CPHA);//using CPHA bit as stop mark
  345. //CopyStringtoLCD(MNOFF, 13, 1 );
  346. SG.ON=0;//set off in LCD menu
  347. loop_until_bit_is_set(BPIN, START);//wait for button release
  348. }
  349. //timer overflow interrupt service tourine
  350. //checks all button status and if button is pressed
  351. //value is updated
  352. ISR(TIMER2_OVF_vect)
  353. {
  354. if (bit_is_clear(BPIN, UP))
  355. //Button UP increments value which selects previous signal mode
  356. //if first mode is reached - jumps to last
  357.         {
  358.         if (SG.mode==0)
  359.         {
  360.                 SG.mode=MN_No-1;
  361.         }
  362.         else
  363.         {
  364.                 SG.mode--;
  365.         }
  366.         //Display menu item
  367.         Menu_Update(SG.ON);
  368.         loop_until_bit_is_set(BPIN, UP);
  369.         }
  370. if (bit_is_clear(BPIN, DOWN))
  371. //Button Down decrements value which selects next signal mode
  372. //if last mode is reached - jumps to first
  373.         {
  374.         if (SG.mode<(MN_No-1))
  375.                         {
  376.                                 SG.mode++;
  377.                         }
  378.                 else
  379.                         {
  380.                                 SG.mode=0;
  381.                         }
  382.         //Display menu item
  383.         Menu_Update(SG.ON);
  384.         loop_until_bit_is_set(BPIN, DOWN);
  385.         }
  386. if (bit_is_clear(BPIN, RIGHT))
  387. //frequency increment
  388.         {
  389.                 if(SG.mode==6)
  390.                 {
  391.                         if(SG.deltafreq==10000)
  392.                                 SG.deltafreq=1;
  393.                         else
  394.                                 SG.deltafreq=(SG.deltafreq*10);
  395.                         Freq_Update();
  396.                         loop_until_bit_is_set(BPIN, RIGHT);
  397.                 }
  398.                 if (SG.mode==8)
  399.                         {
  400.                         //ifhigh speed signal
  401.                         if(SG.HSfreq==8)
  402.                                 SG.HSfreq=1;
  403.                         else
  404.                                 SG.HSfreq=(SG.HSfreq<<1);
  405.                         Freq_Update();
  406.                         loop_until_bit_is_set(BPIN, RIGHT);
  407.                         }
  408.                 if((SG.mode==0)||(SG.mode==1)||(SG.mode==2)||(SG.mode==3)||(SG.mode==4)||(SG.mode==5))
  409.                         {
  410.                                 if ((0xFFFF-SG.freq)>=SG.deltafreq)
  411.                                         SG.freq+=SG.deltafreq;
  412.                                 Freq_Update();
  413.                                 uint8_t ii=0;
  414.                                 //press button and wait for long press (~0.5s)
  415.                                 do{
  416.                                         _delay_ms(2);
  417.                                         ii++;
  418.                                 }while((bit_is_clear(BPIN, RIGHT))&&(ii<=250));//wait for button release
  419.                                 if(ii>=250)
  420.                                 {
  421.                                         do{
  422.                                                 if ((0xFFFF-SG.freq)>=SG.deltafreq)
  423.                                                         SG.freq+=SG.deltafreq;
  424.                                                 Freq_Update();
  425.                                         }while(bit_is_clear(BPIN, RIGHT));//wait for button release
  426.                                 }
  427.                         }
  428.         }
  429. if (bit_is_clear(BPIN, LEFT))
  430. //frequency decrement
  431.         {
  432.                 if(SG.mode==6)
  433.                 {
  434.                         if(SG.deltafreq==1)
  435.                                 SG.deltafreq=10000;
  436.                         else
  437.                                 SG.deltafreq=(SG.deltafreq/10);
  438.                         Freq_Update();
  439.                         loop_until_bit_is_set(BPIN, LEFT);
  440.                 }
  441.                 if (SG.mode==8)
  442.                         {
  443.                         //ifhigh speed signal
  444.                         if(SG.HSfreq==1)
  445.                                 SG.HSfreq=8;
  446.                         else
  447.                                 SG.HSfreq=(SG.HSfreq>>1);
  448.                         Freq_Update();
  449.                         loop_until_bit_is_set(BPIN, LEFT);
  450.                         }
  451.                 if ((SG.mode==0)||(SG.mode==1)||(SG.mode==2)||(SG.mode==3)||(SG.mode==4)||(SG.mode==5))
  452.                         {
  453.                                 if (SG.freq>=SG.deltafreq)
  454.                                         SG.freq-=SG.deltafreq;
  455.                                 Freq_Update();
  456.                                 uint8_t ii=0;
  457.                                 //press button and wait for long press (~0.5s)
  458.                                 do{
  459.                                         _delay_ms(2);
  460.                                         ii++;
  461.                                 }while((bit_is_clear(BPIN, LEFT))&&(ii<=250));//wait for button release
  462.                                 if(ii>=250)
  463.                                 {
  464.                                         do{
  465.                                                 if (SG.freq>=SG.deltafreq)
  466.                                                         SG.freq-=SG.deltafreq;
  467.                                                 Freq_Update();
  468.                                         }while(bit_is_clear(BPIN, LEFT));//wait for button release
  469.                                 }
  470.                         }
  471.         }
  472. if (bit_is_clear(BPIN, START))
  473.         {
  474. if(SG.mode!=6)
  475.         {
  476.                 //saving last configuration
  477.                 SG.fr1=(uint8_t)(SG.freq);
  478.                 SG.fr2=(uint8_t)(SG.freq>>8);
  479.                 SG.fr3=(uint8_t)(SG.freq>>16);
  480.                 if (eeprom_read_byte((uint8_t*)EEMODE)!=SG.mode) eeprom_write_byte((uint8_t*)EEMODE,SG.mode);
  481.                 if (eeprom_read_byte((uint8_t*)EEFREQ1)!=SG.fr1) eeprom_write_byte((uint8_t*)EEFREQ1,SG.fr1);
  482.                 if (eeprom_read_byte((uint8_t*)EEFREQ2)!=SG.fr2) eeprom_write_byte((uint8_t*)EEFREQ2,SG.fr2);
  483.                 if (eeprom_read_byte((uint8_t*)EEFREQ3)!=SG.fr3) eeprom_write_byte((uint8_t*)EEFREQ3,SG.fr3);
  484.                 //Calculate frequency value from restored EEPROM values
  485.                 SG.freq=(((uint32_t)(SG.fr3)<<16)|((uint32_t)(SG.fr2)<<8)|((uint32_t)(SG.fr1)));
  486.                 //calculate accumulator value
  487.                 SG.acc=SG.freq/RESOLUTION;
  488.                 SG.flag=1;//set flag to start generator
  489.                 SG.ON=1;//set ON on LCD menu
  490.                 SPCR&=~(1<<CPHA);//clear CPHA bit in SPCR register to allow DDS
  491.                 //Stop timer2 - menu inactive
  492.                 Timer2_Stop();
  493.                 //display ON on LCD
  494.                 Menu_Update(SG.ON);
  495.         }
  496.         loop_until_bit_is_set(BPIN, START);//wait for button release
  497.         }
  498. }
  499. /*DDS signal generation function
  500. Original idea is taken from
  501. http://www.myplace.nu/avr/minidds/index.htm
  502. small modification is made - added additional command which
  503. checks if CPHA bit is set in SPCR register if yes - exit function
  504. */
  505. void static inline Signal_OUT(const uint8_t *signal, uint8_t ad2, uint8_t ad1, uint8_t ad0)
  506. {
  507. asm volatile(        "eor r18, r18         ;r18<-0"        "\n\t"
  508.                                 "eor r19, r19         ;r19<-0"        "\n\t"
  509.                                 "1:"                                                "\n\t"
  510.                                 "add r18, %0        ;1 cycle"                        "\n\t"
  511.                                 "adc r19, %1        ;1 cycle"                        "\n\t"       
  512.                                 "adc %A3, %2        ;1 cycle"                        "\n\t"
  513.                                 "lpm                         ;3 cycles"         "\n\t"
  514.                                 "out %4, __tmp_reg__        ;1 cycle"        "\n\t"
  515.                                 "sbis %5, 2                ;1 cycle if no skip" "\n\t"
  516.                                 "rjmp 1b                ;2 cycles. Total 10 cycles"        "\n\t"
  517.                                 :
  518.                                 :"r" (ad0),"r" (ad1),"r" (ad2),"e" (signal),"I" (_SFR_IO_ADDR(PORTA)), "I" (_SFR_IO_ADDR(SPCR))
  519.                                 :"r18", "r19"
  520.         );
  521. }

  522. void Timer1_Start(uint8_t FMHz)
  523. {
  524. switch(FMHz){
  525.         case 1:
  526.                 //start high speed (1MHz) signal
  527.                 OCR1A=7;
  528.                 break;
  529.         case 2:
  530.                 OCR1A=3;//2MHz
  531.                 break;
  532.         case 4:
  533.                 OCR1A=1;//4MHz
  534.                 break;
  535.         case 8:
  536.                 OCR1A=0;//8MHz
  537.                 break;
  538.         default:
  539.                 OCR1A=7;//defauls 1MHz
  540.                 break;}
  541.         //Output compare toggles OC1A pin
  542.         TCCR1A=0x40;
  543.         //start timer without prescaler
  544.         TCCR1B=0b00001001;
  545. }
  546. void Timer1_Stop(void)
  547. {
  548.         TCCR1B=0x00;//timer off
  549. }
  550. //main init function
  551. void Main_Init(void)
  552. {
  553. //stderr = &lcd_str;
  554. stdout = &lcd_str;
  555. //--------init LCD----------
  556. LCDinit();
  557. LCDclr();
  558. LCDcursorOFF();
  559. //-------EEPROM initial values----------
  560. if (eeprom_read_byte((uint8_t*)EEINIT)!='T')
  561. {
  562. eeprom_write_byte((uint8_t*)EEMODE,0x00);//initial mode 0 ?OUT~~~~;
  563. eeprom_write_byte((uint8_t*)EEFREQ1,0xE8);//initial frequency 1kHz
  564. eeprom_write_byte((uint8_t*)EEFREQ2,0x03);
  565. eeprom_write_byte((uint8_t*)EEFREQ3,0x00);
  566. eeprom_write_byte((uint8_t*)EEINIT,'T');//marks once that eeprom init is done
  567. //once this procedure is held, no more initialization is performed
  568. }
  569. //------restore last saved values from EEPROM------
  570. SG.mode=eeprom_read_byte((uint8_t*)EEMODE);
  571. SG.fr1=eeprom_read_byte((uint8_t*)EEFREQ1);
  572. SG.fr2=eeprom_read_byte((uint8_t*)EEFREQ2);
  573. SG.fr3=eeprom_read_byte((uint8_t*)EEFREQ3);
  574. SG.freq=(((uint32_t)(SG.fr3)<<16)|((uint32_t)(SG.fr2)<<8)|((uint32_t)(SG.fr1)));
  575. SG.acc=SG.freq/RESOLUTION;
  576. SG.flag=0;
  577. //default 1MHz HS signal freq
  578. SG.HSfreq=1;
  579. SG.deltafreq=100;
  580. //------------init DDS output-----------
  581. R2RPORT=0x00;//set initial zero values
  582. R2RDDR=0xFF;//set A port as output
  583. //-------------set ports pins for buttons----------
  584. BDDR&=~(_BV(START)|_BV(UP)|_BV(DOWN)|_BV(RIGHT)|_BV(LEFT));
  585. BPORT|=(_BV(START)|_BV(UP)|_BV(DOWN)|_BV(RIGHT)|_BV(LEFT));
  586. //---------set ports pins for HS output---------
  587. HSDDR|=_BV(HS);//configure as output
  588. //-----------Menu init--------------
  589. SG.ON=0;//default signal is off
  590. Menu_Update(SG.ON);
  591. //-----------Timer Init-------------
  592. Timer2_Init();
  593. //Start Timer with overflow interrupts
  594. Timer2_Start();
  595. }

  596. int main(void)
  597. {
  598. //Initialize
  599. Main_Init();
  600. while(1)//infinite loop
  601.         {
  602.         if (SG.flag==1)
  603.                 {
  604.                 GICR|=(1<<INT0);//set external interrupt to enable stop
  605.                 if (SG.mode==7)
  606.                         {
  607.                         //Noise
  608.                         do
  609.                         {
  610.                                 R2RPORT=rand();
  611.                         }while(SG.flag==1);
  612.                         //set signal level to 0
  613.                         R2RPORT=0x00;
  614.                         //display generator OFF
  615.                         Menu_Update(SG.ON);
  616.                         //stop external interrupt
  617.                         GICR&=~(1<<INT0);
  618.                         //start timer menu active
  619.                         Timer2_Start();
  620.                         }
  621. /*                else if (SG.mode==6)
  622.                         {
  623.                         //freq step
  624.                         while((SG.flag==1))
  625.                         {
  626.                         //not implemented
  627.                         CopyStringtoLCD(NA, 0, 1 );
  628.                         }
  629.                         //set signal level to 0
  630.                         R2RPORT=0x00;
  631.                         //display generator OFF
  632.                         Menu_Update(SG.ON);       
  633.                         GICR&=~(1<<INT0);//|(1<<INT1);//stop external interrupt
  634.                         //start timer menu active
  635.                         Timer2_Start();
  636.                         }*/
  637.                 else if (SG.mode==8)
  638.                         {
  639.                         //High speed signal
  640.                         Timer1_Start(SG.HSfreq);
  641.                         while((SG.flag==1))
  642.                         {
  643.                         //not implemented
  644.                         CopyStringtoLCD(MNON, 13, 1 );
  645.                         }
  646.                         Timer1_Stop();//timer off
  647.                         //set HS pin to LOW
  648.                         HSPORT&=~(1<<HS);
  649.                         //display generator OFF
  650.                         Menu_Update(SG.ON);       
  651.                         GICR&=~(1<<INT0);//|(1<<INT1);//stop external interrupt
  652.                         //start timer menu active
  653.                         Timer2_Start();
  654.                         }
  655.                 else
  656.                         {
  657.                         //start DDS
  658.                         Signal_OUT(SIGNALS[SG.mode],
  659.                                                 (uint8_t)((uint32_t)SG.acc>>16),
  660.                                                 (uint8_t)((uint32_t)SG.acc>>8),
  661.                                                 (uint8_t)SG.acc);
  662.                         //set signal level to 0
  663.                         R2RPORT=0x00;
  664.                         //display generator OFF
  665.                         Menu_Update(SG.ON);
  666.                         GICR&=~(1<<INT0);//|(1<<INT1);//stop external interrupt
  667.                         //start timer menu active
  668.                         Timer2_Start();
  669.                         }
  670.                 }
  671.         }
  672.         return 0;
  673. }
复制代码
PCB图


本人亲测,仿真















回复 支持 反对

使用道具 举报

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

本版积分规则

QQ|手机版|联系我们|闽公网安备 35012102000020号|闽ICP备11020110号-1|圣源电子

GMT+8, 2024-11-23 16:22 , Processed in 0.057990 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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