找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8376|回复: 5
打印 上一主题 下一主题
收起左侧

TLC1543交流电压测试(单片机)教训版

[复制链接]
跳转到指定楼层
楼主
本帖最后由 daming 于 2014-12-29 00:30 编辑

   (千万注意电压型电路供流能力问题,注意器件属于电压输入型还是电流输入型)



先说一下,交流电压,搞了我几个月,搞死我了,找了好几种方法转直流,进AD,就是不行。NND!!!!
在软件上仿真了好几个电路,都蛮好的波形。焊成板子就是不行,没出来电压,要么就是不滑,进了AD差天上去了,N次想砸了它GOUNIANGYANGDE!!!!!!
今天!!就在今(四声)天!!!!用的运放半波整流加RC滤波,不接入AD,调放大倍数后得到对应直流电压。接入AD后再看,MD!!!电压从珠穆朗玛都拉到贝加尔湖了!!中间串了个20K电阻(看TNND还拉低不!!)终于用表在线量OK了,程序OK了。TLC1543啊!!NNND!!!!让我一度认为运放不合适,想换其他运放,一度换电路,一度迷茫“为嘛仿真的和现实就不符昵”为嘛现实和理想差距这么大哩!!!!!一度认为仿真软件有问题!!!
所以:教训:(单片机) 教训版:
       注意电路供流能力,空载和负载的电压变化受到什么影响!
       注意器件属于电压输入型还是电流输入型,要“限流”,还是增大“供流”!!!
       不要总是考虑电阻大影响电压,人家电流小啊!!uA级别的,TLC1543就需要限流!!!
        以后再不注意这些问题!我就不姓少!!!!!!!!!!!!!
    还有一个待解决问题:运放做的正弦峰值检测电路,仿真蛮好的,焊成板子就是不行,电压直接奔最高了。为嘛!!这一切都是为嘛!!运放我用的LM358,用单电池供电不行,用俩电池供电,也不行!!!
  1. /********多周期测频法,精度与晶振和闸门时间有关。晶振越大,闸门时间越长,都可以提高精度。************************/
  2. #include <stc89c52.h>
  3. #include <intrins.h>
  4. #define uchar  unsigned char
  5. #define uint  unsigned int
  6. #define LCD12864_IO    P0
  7. #define CLERADISPLAY   LCD12864_command(0x01);

  8. int a1=0,a2=0,a3=0,a4=0,a5=0,a6=0;//存储电压值的每一位,设计a4,a5是小数位.
  9. const uchar num[]="0123456789. ";


  10. //AD转换控制脚

  11. sbit  CLK = P1^0; //TLC1543 18P
  12. sbit  ADDRESS = P1^1; //17P
  13. sbit  SDATA = P1^2; //16P
  14. sbit  CS  = P1^3; //15P

  15. /********************************************************************/

  16. sbit LCD12864_RS=P2^5;  // 12864-st7920 4P RS
  17. sbit LCD12864_RW=P2^6;  //RW(5P)
  18. sbit LCD12864_EN=P2^7;   //E(6P)   
  19. /********************************************************************/
  20. void LCD12864_busy(void);
  21. void LCD12864_command(unsigned char command);
  22. void LCD12864_data(unsigned char dat);
  23. void LCD12864_address(unsigned char row,unsigned char line);
  24. void LCD12864_string(unsigned char row,unsigned char line,unsigned char *s);
  25. void LCD12864_picture(unsigned char *gImage);
  26. void LCD12864_init(void);
  27. void LCD12864_char (unsigned char row,unsigned char line,unsigned char a);
  28. unsigned char LCD12864_ReadData();
  29. void LCD12864_Drawpoint(uchar X,uchar Y);
  30. void LCD12864_LineX(unsigned char X0, unsigned char X1, unsigned char Y);
  31. void LCD12864_LineY( unsigned char X, unsigned char Y0, unsigned char Y1);
  32. void LCD12864_DrawPicture( unsigned char code *pic);
  33. void clrgdram();

  34. /********************************************************************/

  35. //
  36. double DAT[7]={1150.0, 1150.1, 1150.2, 285.0,15000.0, 4000.0,31000.0}; //都放大了10倍   
  37. //       U     V      W      E     N     F   CINT     
  38. // 控制脚

  39. sbit CONTRL=P1^7; //测频控制脚

  40. sbit SCANF =P2^0; //键盘扫描控制脚
  41. sbit LED2  =P2^1; //状态显示控制脚1
  42. sbit LED1  =P2^2; //状态显示控制脚2
  43. sbit SHUCHU=P2^3; //继电器输出控制脚

  44. //
  45. bit FLAG; //测频标志位
  46. bit xunhuanflag;//显示方式标志位
  47. bit outflag; //允许输出标志
  48. bit  eding;//额定状态标志   
  49. // 按键存储   
  50. bdata uchar key; //键值存储

  51. sbit key0=key^0;//停机   
  52. sbit key1=key^1;//启动按钮
  53. sbit key2=key^2; //显示方式(高循环)
  54. sbit key3=key^3; //自检   
  55. sbit key4=key^4;//灯检   
  56. sbit key5=key^5;//复位   
  57. sbit key6=key^6;//应急  (高应急)  
  58. sbit key7=key^7;//油压(高有油压)   

  59. uint t1h,t1l,t2h,t2l;//测频变量
  60. double cnt1,cnt2;

  61. double AD; //定义为float 类型,可以防止下面做四则运算时每一步的值超出 范围
  62. unsigned long int  X;

  63. /****************************************************************/         

  64. uint rd1543(uchar address);//AD转换程序
  65. void voltage(); //电压检测
  66. void init();   //初始化
  67. void zhuansu();   //计算转速
  68. void reset();//测频计数定时复位
  69. uchar scanf(); //键盘扫描
  70. void keychuli();  //按键处理程序
  71. void baohu();
  72. void display(unsigned long int sx,uchar j); //显示函数
  73. void displayFX(unsigned long int sx);
  74. /*************************************************************/
  75. void delayus(uint);
  76. void delayms(uint);
  77. void delays(uint m); //延时秒


  78. unsigned char code Bmp019[]=
  79. {

  80. /*------------------------------------------------------------------------------
  81. ;  若数据乱码,请检查字模格式设置,注意选择正确的取模方向和字节位顺序。
  82. ;  源文件 / 文字 : C:\Documents and Settings\Administrator\桌面\888.bmp字模
  83. ;  宽×高(像素): 128×64
  84. ;  字模格式/大小 : 单色点阵液晶字模,横向取模,字节正序/1024字节
  85. ;  数据转换日期  : 2010-7-26 20:46:48
  86. ------------------------------------------------------------------------------*/
  87. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  88. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  89. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  90. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  91. 0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  92. 0x00,0x01,0xF8,0x00,0x00,0x00,0x3E,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  93. 0x00,0x00,0x08,0x00,0x00,0x00,0x03,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,
  94. 0x00,0x00,0x08,0x00,0x00,0x00,0x02,0x00,0x08,0x00,0x00,0x00,0x08,0x08,0x00,0x00,
  95. 0x00,0x20,0x18,0x00,0x00,0x00,0x08,0x00,0x1F,0x80,0x00,0x00,0x08,0x1F,0x80,0x00,
  96. 0x00,0x3D,0xF8,0x00,0x08,0x00,0x08,0xE0,0x02,0x00,0x00,0x7F,0xFF,0x00,0x80,0x00,
  97. 0x00,0x38,0x38,0x00,0x18,0x00,0x00,0x30,0x02,0x00,0x00,0x80,0x00,0x00,0x80,0x00,
  98. 0x00,0x30,0x08,0x01,0xF0,0x00,0x20,0x30,0x0F,0xF8,0x00,0x80,0x0F,0xE0,0x80,0x00,
  99. 0x00,0x30,0x38,0x00,0xFC,0x30,0x20,0xE0,0x83,0x80,0x00,0x00,0x00,0x20,0x00,0x00,
  100. 0x00,0x3F,0xF8,0x00,0x0C,0x30,0x01,0xE0,0x00,0xF0,0x00,0x02,0x00,0x20,0x00,0x00,
  101. 0x00,0x30,0x18,0x66,0xBF,0xF0,0x00,0xE0,0x0F,0xE0,0x00,0x07,0xFF,0xC0,0x00,0x00,
  102. 0x00,0x30,0x18,0x3F,0xFF,0xF0,0x00,0xC0,0x38,0x20,0x00,0x00,0x22,0x00,0x00,0x00,
  103. 0x00,0x20,0x00,0x00,0x00,0x30,0x00,0x80,0x00,0x00,0x00,0x00,0x83,0x00,0xFC,0x00,
  104. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xF0,0x00,
  105. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  106. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  107. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  108. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  109. 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,
  110. 0x03,0xFF,0xFF,0xFF,0xFE,0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,
  111. 0x03,0xFF,0xFF,0xFF,0xF0,0x00,0x7F,0xFF,0xFC,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,
  112. 0x03,0xFF,0xFF,0xFF,0xC3,0xF0,0x00,0x03,0xE0,0x00,0x3F,0xFF,0xFF,0xFF,0xFF,0xC0,
  113. 0x03,0xFF,0xFF,0xFF,0x8C,0x00,0x00,0x00,0x03,0xFF,0x0F,0xFF,0xFF,0xFF,0xFF,0xC0,
  114. 0x03,0xFF,0xFF,0xFE,0x00,0x03,0xFF,0xE0,0x0F,0xFF,0x87,0xFF,0xFF,0xFF,0xFF,0xC0,
  115. 0x03,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFE,0x1F,0xFF,0xC3,0xFF,0xFF,0xFF,0xFF,0xC0,
  116. 0x03,0xFF,0xFF,0xFE,0x03,0xFF,0xFF,0xFF,0x1F,0xFF,0xC3,0xFF,0xFF,0xFF,0xFF,0xC0,
  117. 0x03,0xFF,0xFF,0xF8,0x1F,0xFF,0xFF,0xFF,0x1F,0xFF,0xC3,0xFF,0xFF,0xFF,0xFF,0xC0,
  118. 0x03,0xFF,0xFF,0xF0,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0x87,0xFF,0xFF,0xFF,0xFF,0xC0,
  119. 0x03,0xFF,0xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x07,0xFF,0xFF,0xFF,0xFF,0xC0,
  120. 0x03,0xFF,0xFF,0xC1,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x81,0xFF,0xFF,0xFF,0xFF,0xC0,
  121. 0x03,0xFF,0xFF,0x83,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0xFF,0xFF,0xFF,0xFF,0xC0,
  122. 0x03,0xFF,0xFF,0x07,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x7F,0xFF,0xFF,0xFF,0xC0,
  123. 0x03,0xFF,0xFE,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0,0x3F,0xFF,0xFF,0xFF,0xC0,
  124. 0x03,0xFF,0xFE,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8,0x3F,0xFF,0xFF,0xFF,0xC0,
  125. 0x03,0xFF,0xFC,0x00,0x03,0xFF,0xFF,0xFD,0x80,0x0F,0xF8,0x1F,0xFF,0xFF,0xFF,0xC0,
  126. 0x03,0xFF,0xF8,0x00,0x03,0xFF,0xFF,0xF8,0xFF,0x87,0xFC,0x0F,0xFF,0xFF,0xFF,0xC0,
  127. 0x03,0xFF,0xF8,0x03,0xFF,0xFF,0xFF,0xFF,0x00,0x1F,0xFE,0x0F,0xFF,0xFF,0xFF,0xC0,
  128. 0x03,0xFF,0xF8,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x0F,0xFF,0xFF,0xFF,0xC0,
  129. 0x03,0xFF,0xF8,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x0F,0xFF,0xFF,0xFF,0xC0,
  130. 0x03,0xFF,0xF8,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x0F,0xFF,0xFF,0xFF,0xC0,
  131. 0x03,0xFF,0xF8,0x7F,0xF0,0x0F,0xFF,0xFF,0xFF,0xFF,0xFE,0x0F,0xFF,0xFF,0xFF,0xC0,
  132. 0x03,0xFF,0xF8,0x3F,0xF0,0x1F,0xFF,0xFF,0xFF,0xFF,0xFC,0x0F,0xFF,0xFF,0xFF,0xC0,
  133. 0x03,0xFF,0xF8,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8,0x1F,0xFF,0xFF,0xFF,0xC0,
  134. 0x03,0xFF,0xFC,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8,0x1F,0xFF,0xFF,0xFF,0xC0,
  135. 0x03,0xFF,0xFE,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0,0x3F,0xFF,0xFF,0xFF,0xC0,
  136. 0x03,0xFF,0xFE,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xC0,
  137. 0x03,0xFF,0xFF,0x87,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xC0,
  138. 0x03,0xFF,0xFF,0xC1,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x83,0xC0,0xFF,0xFF,0xFF,0xC0,
  139. 0x03,0xFF,0xFF,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x07,0xFF,0xFF,0xC0,
  140. 0x03,0xFF,0xFF,0xFC,0x1F,0xFF,0xFF,0xFF,0xFF,0xFC,0x07,0xFF,0xC3,0xFF,0xFF,0xC0,
  141. 0x03,0xFF,0xFF,0xFE,0x03,0xFF,0xFF,0xFF,0xFF,0xF0,0x3F,0xFF,0xE1,0xFF,0xFF,0xC0,
  142. 0x03,0xFF,0xFF,0xFE,0x00,0x1F,0xFF,0xFF,0xFF,0xC3,0xFF,0xFF,0xE1,0xFF,0xFF,0xC0,
  143. 0x03,0x01,0xFF,0xF0,0x7F,0x03,0xFF,0xFF,0xFF,0xFF,0xF0,0x00,0x03,0xFF,0xFF,0xC0,
  144. 0x00,0x00,0x00,0x03,0xFD,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0x3F,0xFF,0xFF,0xFF,0xC0,
  145. 0x00,0x3F,0x00,0x3F,0x80,0xFF,0xFF,0xFF,0xFF,0x10,0x1F,0xFF,0xFF,0xFF,0xFF,0xC0,
  146. 0x02,0x1F,0xFF,0xFE,0x03,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,
  147. 0x03,0x81,0xF8,0x00,0x03,0xFF,0xFF,0xFF,0xFE,0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,
  148. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  149. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  150. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

  151. };

  152. //
  153. void delayms(uint k)
  154. {
  155. uint data i,j;
  156. for(i=0;i<k;i++)
  157.   {
  158.     for(j=0;j<121;j++)
  159.      {;}
  160.    }
  161. }
  162. //
  163. void delayus(uint x)      
  164. {
  165.     while(--x);
  166. }
  167. /***********************/
  168. void delays(uint m)
  169. {
  170. uint i,j;
  171. for(i=0;i<m;i++)
  172.   {
  173.    for(i=0;i<1000;i++)
  174.   {
  175.     for(j=0;j<121;j++)
  176.      {;}
  177.    }
  178.    }
  179. }




  180. void Mcu_init(void)
  181. {

  182. LCD12864_init();


  183. CLERADISPLAY  
  184. CLERADISPLAY  
  185. LCD12864_init();
  186. }


  187. /*******************************************************************/
  188. void LCD12864_busy(void)
  189. {
  190.     bit BF = 0;
  191.     LCD12864_EN=0;
  192.     LCD12864_RS=0;
  193.     LCD12864_RW=1;
  194.     LCD12864_IO=0xff;  //单片机读数据之前必须先置高位
  195.     do
  196.     {
  197.      LCD12864_EN=1;
  198.         BF=LCD12864_IO&0x80;
  199.         LCD12864_EN=0;
  200.     } while(BF);
  201.    
  202. }
  203. /*******************************************************************/
  204. //          写入命令  
  205. /*******************************************************************/
  206. void LCD12864_command(unsigned char command)
  207. {
  208.     LCD12864_busy();
  209.     LCD12864_EN=0;
  210.     LCD12864_RS=0;
  211.     LCD12864_RW=0;  
  212.    LCD12864_IO=0xff;
  213.     LCD12864_EN=1;
  214.     LCD12864_IO=command;
  215.     LCD12864_EN=0;
  216. }


  217. //读数据函数
  218. unsigned char LCD12864_ReadData()
  219. {
  220.   unsigned char read_data;
  221.    LCD12864_busy();
  222.     LCD12864_IO=0xff;
  223. LCD12864_RS=1;
  224. LCD12864_RW=1;
  225. LCD12864_EN=0;
  226. LCD12864_EN=1;
  227. read_data=LCD12864_IO;
  228.     LCD12864_EN=0;
  229.    
  230. return(read_data);
  231. }

  232. /*******************************************************************/
  233. //          写入一字节数据
  234. /*******************************************************************/
  235. void LCD12864_data(unsigned char dat)
  236. {
  237.    
  238.     LCD12864_busy();
  239.     LCD12864_EN=0;
  240.     LCD12864_RS=1;
  241.     LCD12864_RW=0;
  242.     LCD12864_IO=0xff;
  243.     LCD12864_EN=1;
  244.     LCD12864_IO=dat;
  245.     LCD12864_EN=0;
  246. }


  247. /*******************************************************************/
  248. //          设置显示位置    row(1~4),line(1~8)
  249. /*******************************************************************/
  250. void LCD12864_address(unsigned char row,unsigned char line)
  251. {
  252.     switch(row)
  253.     {
  254.         case 1:LCD12864_command(0x7f + line);
  255.         break;
  256.         case 2:LCD12864_command(0x8f + line);
  257.         break;
  258.         case 3:LCD12864_command(0x87 + line);
  259.         break;
  260.         case 4:LCD12864_command(0x97 + line);
  261.         default:
  262.         break;
  263.     }
  264. }

  265. /*****************显示 一个 字符  **************/

  266.   void LCD12864_char (unsigned char row,unsigned char line,unsigned char a)
  267. {

  268.     LCD12864_address(row,line);
  269.     LCD12864_data(a);
  270. }

  271. /*******************************************************************/
  272. //          在指定位置显示字符串
  273. /*******************************************************************/
  274. void LCD12864_string(unsigned char row,unsigned char line,unsigned char *s)
  275. {
  276.     unsigned char LCD12864_temp;
  277.     LCD12864_address(row,line);
  278.     LCD12864_temp=*s;
  279.     while(LCD12864_temp != 0x00)
  280.     {
  281.         LCD12864_data(LCD12864_temp);
  282.         LCD12864_temp=*(++s);
  283.     }  
  284. }

  285. /****************************
  286. 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 上半屏行坐标,表示的是多少列

  287. 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 下半屏行坐标,每组8列,每列16位,共128位,

  288. 0x80
  289. 0x81
  290. 0x82
  291. 0x83
  292. ........
  293. 0x9f    //列坐标,共32个,表示的是行数 ,分两个半屏,每个32行,共64行
  294.          //Y坐标 只是用来确定具体坐标,在哪一行   
  295.    功能:图形模式下,显示(X,Y)点   
  296.         输入:X(0~127) Y(0~63) 相对屏幕坐标  
  297.         输出:无
  298. 点亮某一点的操作步骤: 1.求出水平坐标X对应的地址和是哪一位  0x80-----0x8f  (范围0-15) X/16求地址 X%16求该地址哪一位
  299.          2.求垂直坐标Y对应的地址和上下半屏  0x80------0x9f(范围0-63) Y本身就是8位地址,Y=63-Y ,Y--(0-31)
  300.          3.写入行列地址(Y是行X是列),0x80+Y  ,0X80+X/16
  301.                        4.读要显示的数据 DAT
  302.                        5.区分上下半屏(X%16<=7&&X%16>=0是上半屏)写入数据每一位 DAT|0x80 ;DAT<<1
  303.              注意:这个函数显示某一点时,可能会把上次显示的处于同一地址的其他位的点擦掉,所以先保存所有数据,最后显示,就连贯起来了


  304. *******************************/
  305. /*******************************************************************/
  306.   /**************************************************************/
  307. //------------------清整个GDRAM空间----------------------------
  308. /**************************************************************/
  309. void clrgdram()
  310. {
  311.     unsigned char x,y ;
  312.     for(y=0;y<64;y++)
  313.     for(x=0;x<16;x++)
  314.     {
  315.        LCD12864_command(0x34);
  316.        LCD12864_command(y+0x80);
  317.        LCD12864_command(x+0x80);
  318.        LCD12864_command(0x30);
  319.       LCD12864_data(0x00);
  320.       LCD12864_data(0x00);
  321.     }
  322. }

  323. /******************************************/

  324. /*******8==========================================================================
  325. 功能:图形模式下,显示(X,Y)点   
  326. 输入:X(0~127) Y(0~63)     
  327. 输出:无  

  328. 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 上半屏行坐标,表示的是多少列,X地址

  329. 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 下半屏行坐标,X地址 (水平地址 )     
  330. 0x80  (垂直地址)
  331. 0x81
  332. 0x82
  333. 0x83
  334. ........
  335. 0x9f    //列坐标,共32个,表示的是行数 ,分两个半屏,每个32行,共64行
  336. ====================================================================**********/   

  337. void LCD12864_Drawpoint(uchar X,uchar Y)
  338. {
  339.      uchar i= 0, j = 0,ok=0;
  340.      uchar temp1 = 0x00,temp2 = 0x00;   
  341.      LCD12864_command(0x34);  //8位,扩充指令,绘图关
  342.      LCD12864_command(0x36);  //8位,扩充指令,绘图开
  343.      i = X/16;  //计算出X字节地址(0X80-0X8F)
  344.      j = X%16;  //计算出该字节的具体位(0-15)      
  345.      //Y = 63 - Y;
  346.    if(Y>=0 && Y<=31)//判断上下半屏
  347.       {
  348.         ok=1;
  349.       }

  350.    else if(Y>=32 && Y<=63)//下半屏
  351.      {
  352.        Y = Y - 32;//Y只有0-31共32个 地址
  353.        i = i + 8;//X地址进入下半屏 (0X88-0X8F)
  354.     ok=1;
  355.      }
  356.       
  357.    if(ok)
  358.     {
  359.      //读数据操作
  360.         LCD12864_command(0x80+Y);   //第一步:设置Y坐标,读数据先写地址,写GDRAM时先写垂直地址(0X80-0X9F)
  361.         LCD12864_command(0x80+i);  //第二步:设置X坐标   

  362.         LCD12864_ReadData();    //第三步:空读取一次   
  363.         temp1 =LCD12864_ReadData();    //第四步:读取高字节,先读高字节
  364.         temp2 =LCD12864_ReadData();   //第五步:读取低字节   

  365.           //图形模式下的写数据操作   
  366.         LCD12864_command(0x80+Y);    //第一步:设置Y坐标  
  367.         LCD12864_command(0x80+i);   //第二步:设置X坐标  

  368.          if(j>=0 && j<=7)   //判断是高字节
  369.           {  
  370.          LCD12864_data(temp1|(0x80>>j));  //第三步:写高字节数据  
  371.          LCD12864_data(temp2);      //第四步:写低字节数据     
  372.           }
  373.          else if(j>7 && j<=15)   //判断是低字节
  374.            {   
  375.               j = j - 8;  
  376.             LCD12864_data(temp1);
  377.             LCD12864_data(temp2|(0x80>>j));  //改变字节里的位   
  378.            }   
  379.       }


  380.       
  381.    
  382. }
  383. /******************************************/
  384. //画线
  385. /********************************************/
  386. //画水平线
  387. void LCD12864_LineX(unsigned char X0, unsigned char X1, unsigned char Y)
  388. {
  389. unsigned char Temp ;
  390. if( X0 > X1 )
  391. {
  392. Temp = X1 ;    //交换X0 X1值  
  393. X1 = X0 ;     //大数存入X1
  394. X0 = Temp;   //小数存入X0
  395. }

  396. for( ; X0 <= X1 ; X0++ )
  397. LCD12864_Drawpoint(X0,Y);
  398. }
  399. //画垂直线  
  400. void LCD12864_LineY( unsigned char X, unsigned char Y0, unsigned char Y1)
  401. {
  402. unsigned char Temp ;
  403. if( Y0 > Y1 )//交换大小值
  404. {
  405. Temp = Y1 ;
  406. Y1 = Y0 ;
  407. Y0 = Temp ;
  408. }
  409. for(; Y0 <= Y1 ; Y0++)
  410. LCD12864_Drawpoint( X, Y0) ;
  411. }


  412. /******************************************/
  413. /**************画图************************/


  414.   void LCD12864_DrawPicture( unsigned char code *pic)
  415. {
  416.     unsigned char i, j, k ;
  417.         LCD12864_command(0x34);//开扩充指令
  418.         LCD12864_command(0x36);//开绘图功能   

  419. for( i = 0 ; i < 2 ; i++ )//分上下两屏写   
  420. {
  421. for( j = 0 ; j < 32 ; j++)//垂直地址递加 ,行扫方式
  422. {
  423.   LCD12864_command( 0x80 + j ) ;//写Y坐标(Y的范围: 0X80-0X9F )
  424. if( i == 0 ) //写X坐标
  425. {
  426. LCD12864_command(0x80);//上半屏
  427. }
  428. else
  429. {
  430. LCD12864_command(0x88);//下半屏开始地址
  431. }

  432. for( k = 0 ; k < 16 ; k++ ) //写一整行数据
  433. {
  434. LCD12864_data( *pic++ );//前面只写入首地址,后面依次写入数据,地址会自动递增  
  435. }

  436. }
  437. }
  438. LCD12864_command( 0x30);//恢复到一般模式
  439. }


  440. //          初始化设置
  441. /*******************************************************************/
  442. void LCD12864_init(void)
  443. {
  444.     CLERADISPLAY      //  clear DDRAM
  445.     LCD12864_command(0x30);     //  8 bits unsigned interface,basic instrument
  446.     LCD12864_command(0x02);     //  cursor return
  447.     LCD12864_command(0x0c);     //  display,cursor on
  448.     LCD12864_command(0x03);   
  449.     LCD12864_command(0x06);
  450.     CLERADISPLAY       //  clear DDRAM
  451. }

  452. //
  453. //显示函数
  454. void display(unsigned long int sx,uchar j)
  455. {

  456.       a1=sx/100000;
  457.       a2=sx%100000/10000;
  458.       a3=sx%10000/1000;//千位
  459.       a4=sx%1000/100;//百位
  460.       a5=sx%100/10;//十位
  461.    a6=sx%10;//个位

  462.    switch(j)
  463. {
  464.     case 0x00: LCD12864_string(2,5,"  Ua    ");break;
  465.     case 0x01: LCD12864_string(2,5,"  Ub    ");break;
  466.     case 0x02: LCD12864_string(2,5,"  Uc    ");break;
  467.     case 0x03: LCD12864_string(2,5,"  E     ");break;
  468.     case 0x04: LCD12864_string(2,5,"  转速  ");break;
  469. case 0x05: LCD12864_string(2,5,"  频率  ");break;
  470. case 0x06: LCD12864_string(2,5,"脉冲计数");break;
  471. case 0x07: LCD12864_string(2,5,"        ");break;
  472.   default :break;
  473. }
  474. LCD12864_command(0x90); //指定显示位置
  475. LCD12864_data(num[a1]); //从最高位开始显示
  476. LCD12864_data(num[a2]);
  477. LCD12864_data(num[a3]);
  478. LCD12864_data(num[a4]);
  479. LCD12864_data(num[a5]);
  480. LCD12864_data(num[10]);//小数点,前面测量计算时扩大了10倍,这里缩小回来
  481. LCD12864_data(num[a6]);

  482. }


  483. /*********************************
  484.                        主函数入口
  485. /********************************************/
  486. //主函数入口
  487. //
  488. main()
  489. {

  490. uchar ii=0;
  491. CONTRL=0;
  492. FLAG=0;
  493. P0=0x00;
  494. LED1=0;
  495. LED1=1;
  496. P0=0x00;
  497. LED2=0;
  498. LED2=1;
  499. P0=0x00;
  500. SHUCHU=0;//打开闸门
  501. SHUCHU=1;
  502. baohu();//判断采样数据保护
  503. Mcu_init();

  504. CLERADISPLAY
  505. delays(1);
  506. display(100000,7);
  507. LCD12864_char(1,2,'A');

  508. LCD12864_string(1,2,"shaozhanyu");
  509. delays(2);
  510. clrgdram();

  511. CLERADISPLAY
  512. delays(1);
  513. clrgdram();
  514. delays(1);
  515. LCD12864_LineX(8,113,25);
  516. clrgdram();

  517. CLERADISPLAY
  518. delays(2);
  519. clrgdram();
  520. LCD12864_LineY(55,29,57);
  521. delays(2);

  522. clrgdram();
  523. delays(1);

  524. LCD12864_DrawPicture(Bmp019);
  525. delays(3);


  526. Mcu_init();

  527. CLERADISPLAY

  528. LCD12864_string(3,1,"U V W E SP F CT");
  529. LCD12864_char(2,1,'D');
  530. LCD12864_string(4,1,"计数");
  531. LCD12864_string(1,2,"少占鱼做");
  532. delays(1);
  533. /***************8888
  534.     P0=0x10;//怠速,准备打开K5继电器,关闭其他输出继电器
  535.    SHUCHU=0;//打开输出闸门
  536. SHUCHU=1;//关闭闸门
  537. outflag=0;//输出标志位
  538. ******************/
  539.   AD=0.0;
  540. LCD12864_string(1,2,"灯光测试");

  541. P0=0x41;
  542. LED1=0;
  543. LED1=1;
  544. delayms(1000);
  545. P0=0x42;
  546. LED1=0;
  547. LED1=1;
  548. delayms(1000);
  549. P0=0x44;
  550. LED1=0;
  551. LED1=1;
  552. delayms(1000);
  553. P0=0x48;
  554. LED1=0;
  555. LED1=1;
  556. delayms(1000);
  557. P0=0x50;
  558. LED1=0;
  559. LED1=1;
  560. delayms(1000);
  561. P0=0x60;
  562. LED1=0;
  563. LED1=1;
  564. delayms(1000);

  565. P0=0x41;
  566. LED2=0;
  567. LED2=1;
  568. delayms(1000);

  569. P0=0x42;
  570. LED2=0;
  571. LED2=1;
  572. delayms(1000);
  573. P0=0x44;
  574. LED2=0;
  575. LED2=1;
  576. delayms(1000);
  577. P0=0x48;
  578. LED2=0;
  579. LED2=1;
  580. delayms(1000);
  581. P0=0x50;
  582. LED2=0;
  583. LED2=1;
  584. delayms(1000);
  585. P0=0x60;
  586. LED2=0;
  587. LED2=1;
  588. delayms(1000);
  589. P0=0x00;
  590. LED1=0;
  591. LED1=1;
  592. P0=0x00;
  593. LED2=0;
  594. LED2=1;
  595. delayms(500);
  596. LCD12864_string(1,2,"测继电器");


  597. P0=0x04;//启动
  598. SHUCHU=0;//打开闸门
  599. delays(3);
  600. SHUCHU=1;

  601.   P0=0x18;//停机
  602. SHUCHU=0;//打开闸门
  603. delays(3);
  604. SHUCHU=1;

  605. P0=0x40;//怠速,准备打开K5继电器,关闭其他输出继电器
  606. SHUCHU=0;//打开输出闸门

  607. delays(3);
  608.   SHUCHU=1;//关闭闸门
  609. P0=0xa0;//准备合闸(交流,直流 内控制 )   
  610. SHUCHU=0;

  611.   delays(3);
  612.    SHUCHU=1;
  613.   P0=0x00;
  614. SHUCHU=0;//打开闸门
  615. SHUCHU=1;


  616. keychuli(); //扫描并处理按键
  617. delayms(600);
  618. voltage();
  619. LCD12864_string(3,1,"U V W E SP F ");
  620. LCD12864_char(2,1,'D');
  621. LCD12864_string(1,2,"少氏出品");
  622. delays(11);
  623. ///初始化
  624. LCD12864_string(4,1,"直流正常");
  625. init();

  626. while(1)

  627. {
  628.    while(!FLAG); //等待频率测出
  629.   
  630.   keychuli(); //扫描并处理按键
  631. LCD12864_string(1,2,"测量电压");
  632. delayms(500);
  633. voltage();  //采样电压

  634. LCD12864_string(1,2,"转换完成");
  635. delayms(600);
  636. baohu();//判断采样数据保护

  637.   for(;ii<6;)
  638.      {
  639. if(xunhuanflag==0)  //定点
  640. {display(DAT[ii],ii);
  641.   LCD12864_string(1,2,"定点显示");
  642.   break;
  643.   }  
  644.   display(DAT[ii],ii);
  645.   LCD12864_string(1,2,"循环显示");
  646.      
  647.   delayms(2200);
  648.   keychuli();
  649.   ii++;

  650. }//循环 显示结束
  651.   if(ii==6)
  652.   ii=0;

  653. LCD12864_string(1,2,"下轮复位");
  654.    delayms(700);
  655.    init();

  656. }
  657. }
  658. /*************************************/
  659. //初始化函数  
  660. void init()

  661. {  
  662. /******T1定时器模式,外部INT1控制开启,T0计数器不允许中断,外部控制

  663. INTO开启,外部中断0允许(EX0=1),   
  664.      定时器T2中断允许 (ET2=1) ************/  
  665.    CONTRL=0;
  666.       FLAG=0;
  667.    EX0=0;
  668.       ET2=0;
  669.       //三个定时器方式设置
  670.       TMOD=0x9d; //T0T1方式控制   
  671.       T2MOD=0x00;
  672.       T2CON=0x00;//定时器2,16位定时方式,自动重装。      
  673.    
  674.       TH0= 0x00; // T0高8位
  675.       TL0= 0x00; // T0低8位
  676.                      
  677.       TH1= 0x00; // T1高8位
  678.       TL1= 0x00; // T1低8位
  679.    EXEN2=0;  
  680.       TH2=256/256;
  681.       TL2=256%256;
  682.    RCAP2H=256/256;
  683.    RCAP2L=256%256;

  684.       //中断设置        5
  685.       EX0=1;//允许外部0输入中断(INT0引脚)
  686.       ET2=1; //开定时中断2
  687.       IT0=1; //外部中断0边沿触发,下降沿到来触发
  688.       //优先级设置
  689.    PX0=1;
  690.       //预置T0,T1
  691.       TR1=1;//先允许T1定时,因T1的GATE=1,还要等外部INT1高电平才计数
  692.       TR0=1;//先允许T0计数 ,同T1一样,等待INTO高电平     
  693.       TR2=1;//启动T2定时,不用外部控制,直接启动   
  694.       EA=1; //开全局中断
  695.    CONTRL=1;

  696.       //初始化完成......
  697. }
  698. /**********************************
  699. void reset()
  700. {
  701.   CONTRL=0;
  702.   FLAG=0;
  703.   TL0=0x00;
  704.   TH0=0x00;
  705.   TL1=0x00;
  706.   TH1=0x00;
  707.   TF2=0;
  708.   TH2=256/256;
  709.   TL2=256%256;
  710.   TR1=1;//先允许T1定时,因T1的GATE=1,还要等外部INT1高电平才计数
  711.   TR0=1;//先允许T0计数 ,同T1一样,等待INTO高电平     
  712.   TR2=1;//启动T2定时,不用外部控制,直接启动     
  713.   EA=1; //开全局中断
  714.   CONTRL=1;
  715.   
  716. }
  717. *******************************/
  718. //键盘扫描
  719. uchar scanf()
  720. {
  721.   uchar value;
  722.   P0=0xff;
  723.   delayms(1);
  724.   SCANF=0;//打开键扫闸门
  725.   value=P0;
  726.   delayms(2);
  727.   value=P0;
  728.   SCANF=1;
  729.   return  value;
  730. }

  731. /********************************/
  732. //键处理
  733. void keychuli()
  734. {
  735.    uchar k;

  736.    //关于指示灯,交流是一组,直流是一组,其他状态用液晶显示
  737.     /***************************************/

  738.    /******************/
  739.    key=scanf();
  740.    /******************/
  741.    //启动键判断
  742.    if(key1==0&&key7==0&&DAT[4]==0)//启动位 ,油压和转速为0
  743. {
  744. for(k=0;k<3;k++)//三次启动循环
  745. {
  746.      P0=0x04;//准备 输出K6继电器
  747.      SHUCHU=0;//打开闸门
  748. delays(3);//隔三秒响应一次停机键   
  749. //响应停机键     
  750.   key=scanf();
  751.      if(key0==0&&key7==1&&DAT[4]>500)//停机开关状态,油压高,转速达到500,其他继电器都停止工作 ,所以 ,P0=0x08
  752.    {
  753.     P0=0x18;//准备输出K0,K9继电器
  754.    SHUCHU=0;//打开输出闸门
  755. SHUCHU=1;//关闭闸门
  756. outflag=0;//输出标志位
  757. }
  758. if(key1==0&&key7==1&&DAT[4]>430) //每启动一次都判断是否成功,成功直接跳出
  759. break ; //判断启动成功,立即跳出启动for 循环

  760.   delays(3);//没有启动成功,继续启动3秒
  761.   key=scanf();
  762.      if(key1==0&&key0==0&&key7==1&&DAT[4]>500)//停机,油压高,转速达到500,其他继电器都停止工作 ,所以 ,P0=0x08
  763.    {
  764.     P0=0x18;//准备输出K0,K9继电器
  765.    SHUCHU=0;//打开输出闸门
  766. SHUCHU=1;//关闭闸门
  767. outflag=0;//输出标志位
  768. }
  769.   if(key1==0&&key7==1&&DAT[4]>430) //每启动一次都判断是否成功,成功直接跳出
  770. break ;
  771.   delays(3);
  772.   key=scanf();
  773.      if(key0==0&&key7==1&&DAT[4]>500)//停机,油压高,转速达到500,其他继电器都停止工作 ,所以 ,P0=0x08
  774.    {
  775.     P0=0x18;//准备输出K0,K9继电器
  776.    SHUCHU=0;//打开输出闸门
  777. SHUCHU=1;//关闭闸门
  778. outflag=0;//输出标志位
  779. }
  780.      if(key1==0&&key7==1&&DAT[4]>430) //每启动一次都判断是否成功,成功直接跳出
  781. break ;
  782.    
  783.   P0=0x18;//停止
  784.   SHUCHU=0;
  785.   SHUCHU=1;
  786.   delays(9);
  787. }//for启动循环结束
  788.      SHUCHU=1;//关闭闸门

  789.    /**********************/
  790.    //启动失败判断
  791.     if(key7==0) //油压低
  792.     if(DAT[4]<440)
  793.      {
  794. P0=0x01;//点亮启动失败灯
  795. LED1=0;//开启573输入
  796. LED1=1;//关闭使能,74HC573锁定状态
  797. outflag=0;//输出标志位清0,表示输出未允许
  798.      }
  799. }

  800.    //停机键判断
  801.   /********************/
  802.    if(key0==0&&key7==1&&DAT[4]>500)//停机,油压高,转速达到500,其他继电器都停止工作 ,所以 ,P0=0x08
  803.    {
  804.      P0=0x00;//准备交直流断闸(交流,直流 内控制 )   
  805.   SHUCHU=0;
  806.   SHUCHU=1;
  807.   delayms(3);
  808.         P0=0x40;//怠速,准备打开K5继电器,关闭其他输出继电器
  809.        SHUCHU=0;//打开输出闸门
  810.      SHUCHU=1;//关闭闸门
  811.      outflag=0;
  812.   delays(29);
  813.     P0=0x18;//准备 输出K0和K9停油继电器
  814.    SHUCHU=0;//打开输出闸门
  815. SHUCHU=1;//关闭闸门
  816. outflag=0;//输出标志位
  817. }

  818. /*****************/
  819. //应急键判断
  820.        if(key6==1)//应急/正常,高电位应急
  821.        {
  822.     eding=1;//应急标志

  823.        }
  824.      else if(key6==0) //进入怠速
  825.           {
  826.         eding=0;//怠速标志
  827.           }
  828.    if(eding==0)//对怠速的处理
  829.     {
  830.         P0=0x40;//怠速,准备打开K5继电器,关闭其他输出继电器
  831.        SHUCHU=0;//
  832.      SHUCHU=1;//关闭闸门
  833.      outflag=0;
  834.        }
  835.   if(eding==1&&outflag==0)//对额定的处理
  836.     {
  837. P0=0x00;//额定,准备关闭K5继电器,进入额定,其他继电器都停止工作 ,所以 ,P0=0x00
  838.    SHUCHU=0;//打开输出闸门
  839. SHUCHU=1;//关闭闸门
  840. delayms(2);

  841. if(DAT[0]>110&&DAT[1]>110&&DAT[2]>110&&DAT[5]>390)//三相交流大于110 ,频率大于390
  842.      {
  843.   P0=0xa0;//准备合闸(交流,直流 内控制 )   
  844.   SHUCHU=0;
  845.   SHUCHU=1;
  846.   outflag=1;//合闸后,输出标志位置1
  847.      }
  848.      }
  849. /******************************/
  850. //循环键
  851. if(key2==1) //处理循环定点显示标志位
  852. xunhuanflag=1;
  853. else if(key2==0)
  854. xunhuanflag=0;

  855.    /*********************/
  856. //灯光检查键
  857.    if(key4==0)//灯光检查
  858.    {
  859.     LED1=1;
  860. LED2=1;
  861.     P0=0x7f;
  862.     LED1=0;
  863. delayus(10);
  864. LED1=1;
  865. delayms(1000);
  866. P0=0x7f;
  867. LED2=0;
  868. delayus(10);
  869. LED2=1;
  870. }

  871. /************************/
  872. //复位键
  873.    if(key5==0)//复位
  874.    {
  875.     P0=0x00;
  876.     LED1=0;
  877. delayus(10);

  878. LED1=1;
  879. P0=0x00;
  880. LED2=0;
  881. delayus(10);
  882. LED2=1;
  883. }

  884.    /****************/
  885.    //自检键
  886.    if(key3==0) //自检
  887.    { }

  888. }

  889. /**********保护函数*****************/
  890. void baohu()
  891. {
  892. if(outflag==1)//前提是已经输出
  893. {
  894. //立即保护值
  895. if((DAT[0]<800||DAT[1]<800||DAT[2]<800) || (DAT[0]>1800||DAT[1]>1800||DAT[2]>1800) || DAT[5]>4450||DAT[5]<3200)//立即断闸保护
  896.   {

  897.   P0=0x00;//准备断闸(交流,直流 内控制 )   
  898.   SHUCHU=0;
  899.   SHUCHU=1;
  900.   outflag=0;//断闸后,输出标志位清0
  901.   
  902.   if(DAT[0]>1800||DAT[1]>1800||DAT[2]>1800)
  903.   {
  904.   P0=0x80;//过压
  905.   LED1=0;
  906.   LED1=1;
  907.   }
  908.    if(DAT[5]>4450)
  909.   {
  910.   P0=0x80;//过频灯
  911.   LED2=0;
  912.   LED2=1;
  913.   }
  914.   if(DAT[0]<800||DAT[1]<800||DAT[2]<800)
  915.   {
  916.   P0=0x40;//欠压
  917.   LED1=0;
  918.   LED1=1;
  919.   }
  920.   if(DAT[5]<3200)
  921.   {
  922.   P0=0x40;//欠频灯
  923.   LED2=0;
  924.   LED2=1;
  925.   }

  926.    }//立即保护结束

  927.   // 延时保护值     
  928. if(DAT[0]<1000||DAT[1]<1000||DAT[2]<1000|| DAT[0]>1270||DAT[1]>1270||DAT[2]>1270|| DAT[5]>4300||DAT[5]<3700)
  929.    {  

  930.   if(DAT[0]>1270||DAT[1]>1270||DAT[2]>1270)
  931.   {

  932.   P0=0x80;//过压
  933.   LED1=0;
  934.   LED1=1;


  935.   }
  936.    if(DAT[5]>4300)
  937.   {
  938.   P0=0x80;//过频
  939.   LED2=0;
  940.   LED2=1;
  941.   }
  942.   if(DAT[0]<1000||DAT[1]<1000||DAT[2]<1000)
  943.   {

  944.   P0=0x40;//欠压
  945.   LED1=0;
  946.   LED1=1;
  947.   }
  948.   if(DAT[5]<3700)
  949.   {
  950.   
  951.   P0=0x40;//欠频
  952.   LED2=0;
  953.   LED2=1;
  954.   }
  955.   delays(4);//等待交流恢复
  956.   voltage();

  957. if(DAT[0]>1100&&DAT[1]>1100&&DAT[2]>1100&&DAT[5]>3900)//三相交流大于110 ,频率大于390
  958.      {
  959.   P0=0x00;
  960.   LED1=0;
  961.   LED1=1;
  962.   P0=0x00;
  963.   LED2=0;
  964.   LED2=1;
  965.   P0=0xa0;//准备合闸(交流直流内控制 )   
  966.   SHUCHU=0;
  967.   SHUCHU=1;
  968.   outflag=1;//合闸后,输出标志位置1     
  969.         }
  970. else
  971. {

  972.   P0=0x00;//准备断闸(交流,直流 内控制 )   
  973.   SHUCHU=0;
  974.   SHUCHU=1;
  975.   outflag=0;
  976. }

  977.    }//交流和频率保护结束
  978. //直流电压延时保护
  979.    if(DAT[3]>320||DAT[3]<170)
  980.    {if(DAT[3]>320)
  981.   {
  982.   LCD12864_string(4,1,"直流过压");
  983.   }
  984.   delays(4);//等待直流过压恢复
  985.   voltage();
  986. if(DAT[3]>170&&DAT[3]<320)
  987. {
  988.   LCD12864_string(4,1,"直流正常");
  989. }
  990. else
  991. {P0=0x80;//关闭直流只开交流,因为前面已经检测过交流了,这里就不管了,当他正常   
  992.   SHUCHU=0;
  993.   SHUCHU=1;
  994.   outflag=1;
  995.   LCD12864_string(4,1,"直流故障");
  996. }
  997.    if(DAT[3]<170)
  998.   {
  999.   LCD12864_string(4,1,"直流欠压");
  1000.   }
  1001.    delays(2);//等待直流 欠压恢复
  1002.    voltage();
  1003. if(DAT[3]>170&&DAT[3]<320)
  1004. {
  1005.   LCD12864_string(4,1,"直流正常");
  1006. }
  1007. else
  1008. {P0=0x80;//关闭直流只开交流,因为前面已经检测过交流了,这里就不管了,当他正常   
  1009.   SHUCHU=0;
  1010.   SHUCHU=1;
  1011.   outflag=1;
  1012.   LCD12864_string(4,1,"直流故障");
  1013. }
  1014.    }//直流延时保护结束
  1015. }//总 保护结束
  1016. }//总函数结束
  1017. /*******************************/
  1018. //转速计算  ,频率计算
  1019. void zhuansu()
  1020. {
  1021. t1h=TH0;
  1022. t1l=TL0;
  1023. t2h=TH1;
  1024. t2l=TL1;
  1025. cnt1=t1l+(t1h<<8);
  1026. cnt2=t2l+(t2h<<8);
  1027. DAT[6]=cnt1/cnt2*1000000.20*10.00;//计数值
  1028. DAT[4]=cnt1/cnt2*1000000.200/124.00*600.00*10.0; //计算转速,信号频率就是单片机计数频率的整数倍   ,这里这样写是怕cnt1 cnt2 超出范围
  1029. //注意这里: cnt1 cnt2  的类型不能是 uint 否则第一步计算除法会得0 , 如果你要先乘1000000.0,也不行。因为超出了uint 范围
  1030. DAT[5]=DAT[4]*16.00/60.000*10.0;//电压频率计算

  1031. }

  1032. /******************************/
  1033. //外部中断0,调用转速计算
  1034. void interint0()  interrupt 0 //using **
  1035.       //外部中断0处理      
  1036. {
  1037. EA=0;
  1038. zhuansu();//调用转速函数
  1039.   FLAG=1;
  1040. /***注意:因为TO T1是外部引脚控制的,所以,这时外部低电平,自动停止。不用软件停止**/  
  1041. }     
  1042. void intertimer2()  interrupt 5 //using **
  1043.       //T2定时中断处理      
  1044. {  
  1045.   TR2=0;
  1046.   CONTRL=0;//关闭闸门信号   
  1047. }     

  1048. /*******************************/
  1049. //AD转换程序

  1050. /************************************************/
  1051. //常测数据函数
  1052. void voltage() //电压测量
  1053. {
  1054. uchar i;

  1055. AD=0.00;
  1056. X=0;

  1057. for(i=0;i<10;i++)
  1058. {
  1059. AD+=rd1543(0x08); //读取AD值
  1060. }
  1061. //
  1062. AD=AD/10.0;
  1063. X=AD*46.0001*50.00/1023.00;//转换成电压值 ,分辨率是10位
  1064. DAT[0]=X;

  1065. AD=0.00;

  1066. //
  1067. for(i=0;i<10;i++)
  1068. {
  1069. AD+=rd1543(0x08); //读取AD值
  1070. }
  1071. //
  1072. AD=AD/10.0;
  1073. X=AD*46.0001*50.00/1023.00;//转换成电压值 ,分辨率是10位
  1074. DAT[1]=X;
  1075. //
  1076. AD=0.00;

  1077. //
  1078. for(i=0;i<10;i++)
  1079. {
  1080. AD+=rd1543(0x08); //读取AD值
  1081. }
  1082. //
  1083. AD=AD/10.0;
  1084. X=AD*46.0001*50.00/1023.00;//转换成电压值 ,分辨率是10位
  1085. DAT[2]=X;
  1086. //
  1087. /*********
  1088. for(i=0;i<20;i++)
  1089. {
  1090. AD+=rd1543(0x07); //读取AD值

  1091. }
  1092. //
  1093. AD=AD/20;
  1094. X=AD*50.000/1023.000*28.500/4.000;
  1095. DAT[3]=X;
  1096. //
  1097. **********/
  1098. }
  1099. /***********************************************/


  1100. //TLC1543输入模拟电压范围: 0-4.9152 V
  1101. //TLC1543AD 10个时钟方式  方式1 。 LC1543 有四位精度 。  输入 0.0024v 时,AD值为0000000001  
  1102. //0.0048时,还为1。  0.0072为 2    也就是0.0048 为一个 宽度  0.0048*AD 就是电压值 .

  1103. uint rd1543(uchar addr)
  1104. {
  1105.      uint date_out=0;
  1106.   uchar k;
  1107.    
  1108.     // uchar j;
  1109.      CLK=0;
  1110.      CS=0;

  1111.           ADDRESS=(bit)(addr&0x08); //用这种愚蠢的方法比用FOR循环快的多 。
  1112.     CLK=1;
  1113.     CLK=0;
  1114.           addr=addr*2; //用乘法比用左移快
  1115.      
  1116.           ADDRESS=(bit)(addr&0x08);
  1117.     CLK=1;
  1118.     CLK=0;
  1119.           addr=addr*2; //用乘法比用左移快
  1120.     ADDRESS=(bit)(addr&0x08);
  1121.     CLK=1;
  1122.     CLK=0;
  1123.           addr=addr*2; //用乘法比用左移快
  1124.     ADDRESS=(bit)(addr&0x08);
  1125.     CLK=1;
  1126.     CLK=0;
  1127.           addr=addr*2; //用乘法比用左移快
  1128.       
  1129.   

  1130. // for (j=0;j<6;j++)     //填充6 个CLOCK     
  1131.    // {
  1132.       CLK=1;CLK=0;   //这里不用循环,省时间
  1133.    CLK=1;CLK=0;
  1134.    CLK=1;CLK=0;
  1135.    CLK=1;CLK=0;
  1136.    CLK=1;CLK=0;
  1137.    CLK=1;CLK=0;
  1138.       CLK=0;
  1139.    // }
  1140.       CS=1;
  1141.       delayus(8);  //等待AD 转换
  1142.       CS=0;                  
  1143.   for(k=0;k<10;k++)
  1144.      {
  1145.     SDATA=1;                 //非P0口作为数据总线使用时,读入数据前要赋值1,特别
  1146.        CLK = 1;         //是既用于写有用于读的情况下.
  1147.        date_out<<=1;
  1148.        if(SDATA) date_out += 1;  //这样写法比下面的方法速度快(5us)
  1149.   // date_out=date_out|SDATA;//用时6US
  1150.        CLK = 0;
  1151.      }
  1152.      return(date_out);
  1153. }
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:70172 发表于 2014-12-31 22:33 | 只看该作者
楼租啊,丝天津人!
回复

使用道具 举报

板凳
ID:72128 发表于 2015-1-13 17:37 | 只看该作者
很好的资料
回复

使用道具 举报

地板
ID:72128 发表于 2015-1-13 17:38 | 只看该作者
没有原理图啊
回复

使用道具 举报

5#
ID:60306 发表于 2016-5-20 14:36 | 只看该作者
兄弟 你的电路挑出来了没  你看看我这图与你哪个有啥区别[

设计总图.jpg (1.52 MB, 下载次数: 173)

测Voltage current

测Voltage current
回复

使用道具 举报

6#
ID:236666 发表于 2019-1-2 14:19 | 只看该作者
1000多行程序。
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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