久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2035|回復: 13
收起左側

為什么我的單片機程序輸出波形的頻率最大只能30HZ

[復制鏈接]
ID:494908 發表于 2022-4-14 13:38 | 顯示全部樓層 |閱讀模式
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #define uint unsigned int
  4. #define uchar unsigned char
  5. #define AddWr 0x90                           //PCF8591地址1001 0000


  6. sbit SCL=P3^6;      
  7. sbit SDA=P3^7;
  8. sbit RS=P2^0;
  9. sbit RW=P2^1;
  10. sbit E =P2^2;
  11. sbit sin=P1^0;
  12. sbit square=P1^1;
  13. sbit triangle=P1^2;
  14. sbit juchi=P1^3;
  15. sbit key1=P1^4;
  16. sbit key2=P1^5;
  17. sbit key3=P1^6;
  18. sbit key4=P1^7;
  19. bit ack;

  20. uchar pinlv,shi,ge;                 //頻率變量//
  21. uchar change;                        //波形切換變量//
  22. uchar num;                                 //波形表輸出個數變量//
  23. uint TH0_PL,TL0_PL;                   //重設初值//
  24. uint timer_value;                        //初值變量//
  25. uchar fd;
  26. uchar code table[]="0123456789";  

  27. void delay_ms(unsigned int n)  //12MHZ晶振時延時1ms,若用11.0592MHZ,則j=110
  28. {
  29.   unsigned int i=0,j=0;
  30.    for(i=n;i>0;i--)
  31.     for(j=0;j<123;j++);
  32. }

  33. void delay_8591()
  34. {
  35.    _nop_();   _nop_(); _nop_(); _nop_();           //起始條件建立時間大于4.7us,延時
  36. }         


  37. uchar code sin_table[]={0x7F,0x98,0xB0,0xC6,0xD9,0xE9,0xF5,0xFC,
  38.                                                 0xFE,0xFC,0xF5,0xE9,0xD9,0xC6,0xB0,0x98,
  39.                                                 0x7F,0x66,0x4E,0x38,0x25,0x15,0x09,0x02,
  40.                                                 0x00,0x02,0x09,0x15,0x25,0x38,0x4E,0x66};

  41. uchar code square_table[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  42.                                                    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  43.                                                    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  44.                                                    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};

  45. uchar code triangle_table[]={0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,
  46.                                                         0x80,0x90,0xa0,0xb0,0xc0,0xd0,0xe0,0xf0,
  47.                                                         0xff,0xf0,0xe0,0xd0,0xc0,0xb0,0xa0,0x90,
  48.                                                         0x80,0x70,0x60,0x50,0x40,0x30,0x20,0x10};

  49. uchar code juchi_table[]={0x00,0x07,0x10,0x17,0x20,0x27,0x30,0x37,
  50.                                                         0x40,0x47,0x50,0x57,0x60,0x67,0x70,0x77,
  51.                                                         0x80,0x87,0x90,0x97,0xa0,0xa7,0xb0,0xb7,
  52.                                                         0xc0,0xc7,0xd0,0xd7,0xe0,0xe7,0xf0,0x00};



  53. /*******************************************PCF8591DA轉換模塊**************************/////////////////////
  54. /****************************************************************************************///////////
  55.    void start()//開始信號  
  56. {  
  57.     SDA=1;            //確保SDA線為高電平,開始        之前都確保為高電平
  58.     delay_8591();         
  59.     SCL=1;                             //確保SCL為高電平
  60.      delay_8591();                    
  61.     SDA=0;                     //在SCL為高時拉低SDA線,即為起始信號
  62.     delay_8591();  
  63.         SCL=0;                                   //將SCL線拉低,為后面SDA的傳數據時電平變化做準備
  64. }  

  65. void stop() //停止信號  
  66. {  
  67.     SDA=0;                    //確保SDA線為低電平
  68.      delay_8591();   
  69.     SCL=1;                          //確保SCL線為高電平
  70.      delay_8591();   
  71.     SDA=1;                      //在SCL為高時拉高SDA線,即為停止信號,此時SDA和SCL均為高,同時完成IIC初始化過程
  72.      delay_8591();  
  73. }  

  74. void ack_check(bit a)
  75. {
  76.         if(a==0)
  77.                   SDA=0;              //*在此發出應答或非應答信號 *//
  78.     else
  79.                 SDA=1;
  80.                 _nop_();   
  81.                 SCL=1;
  82.                 delay_8591();  
  83.                 SCL=0;
  84.                 _nop_();
  85.                 _nop_();                     //*清時鐘線,鉗住I2C總線以便繼續接收*//
  86.                 SDA=1;        
  87. }
  88. void send_byte(uchar date)
  89. {
  90.         uchar i;
  91.         for(i=0;i<8;i++)  //*要傳送的數據長度為8位*//
  92.     {
  93.      if((date<<i)&0x80)
  94.                     SDA=1;                                           //*判斷發送位*//
  95.      else  
  96.                          SDA=0;               
  97.                         _nop_();
  98.                SCL=1;                               //*置時鐘線為高,通知被控器開始接收數據位*/
  99.                delay_8591();         
  100.                SCL=0;
  101.             }
  102.                     SDA=1;                //*8位發送完后釋放數據線,準備接收應答位*/
  103.                         _nop_();
  104.                     SCL=1;
  105.                     if(SDA==1)
  106.                                 ack=0;     
  107.                     else ack=1;        //*判斷是否接收到應答信號*/
  108.                             SCL=0;
  109.                            
  110. }
  111. void write_add()
  112. {
  113.         start();
  114.         send_byte(AddWr);
  115.         if(ack==0)                                                //判斷有無應答信號
  116.         {                                                                //有應答信號應該給低電平
  117.                  stop();
  118.                 return;
  119.         }
  120.          send_byte(0x40);                         //01000000 寫入控制位,使能DA輸出
  121. }




  122. /*********************************************************顯示模塊*///////////////////////////////////////////////
  123. /**********************************************************************************************//////////            
  124. void LCD12864_BusyCheck()        //讀一下當前代碼是否在忙,最高位為0為不忙,1為忙
  125.     {
  126.        unsigned char temp;
  127.        P0=0xff;        //釋放整個口,全部為高電平
  128.        RS=0;         //RS為0是讀狀態 ,為1是寫數據
  129.        RW=1;          //高讀低寫
  130.        delay_ms(10);
  131.      while(1)             //一直檢測知道不忙為止
  132.       {
  133.           E=1;             //E是使能口,由1到0才可寫入數據
  134.           temp=P0;
  135.           E=0;
  136.           if((temp&0x80)==0)  //如果等于零意味著最高位為0,不忙
  137.           break;          //結束(如果上面代碼不為0,則循環一直檢測
  138.      }
  139.    }

  140. void LCD12864_wcmd(unsigned char cmd)      //命令函數
  141. {
  142.     LCD12864_BusyCheck();
  143.     RS=0;           //高數低命
  144.     RW=0;
  145.     delay_ms(1);
  146.     P0=cmd;  //命令把想寫的內容送到數據口
  147.     delay_ms(1);
  148.     E=1;
  149.     E=0;          //產生一個下降沿寫數據
  150.    }

  151. void LCD12864_wdat(unsigned char dat)     //寫數據函數
  152. {
  153.     LCD12864_BusyCheck();
  154.     RS=1;   //寫數據
  155.     RW=0;
  156.     delay_ms(1);
  157.     P0=dat;                 //把想寫的內容送到數據口
  158.     E=1;
  159.     delay_ms(1);
  160.     E=0;
  161. }

  162. void LCD12864_SetPos(unsigned char x,unsigned char y)     //x是行,y是列
  163. {
  164.    unsigned char pos;

  165.    switch(x)
  166.      {
  167.       case 0:x=0x80;break;     //第一行從0x80開始
  168.       case 1:x=0x90;break;
  169.       case 2:x=0x88;break;
  170.       case 3:x=0x98;break;
  171.       default:break;
  172.       }
  173.       pos=x+y;    //x范圍:0-3,y范圍:0-7 (因為一行只能寫八個漢字)
  174.       LCD12864_wcmd(pos);
  175.       }

  176. void LCD12864_DisHZ_Str(unsigned char*s)
  177.     {
  178.      while(*s)
  179.      LCD12864_wdat(*s++);  //指針++,指針指向下一個
  180.      }

  181. void LCD12864_init()
  182.    {
  183.      LCD12864_wcmd(0x01);     //清屏指令
  184.      delay_ms(3);
  185.      LCD12864_wcmd(0x30);
  186.      delay_ms(5);
  187.      LCD12864_wcmd(0x30);
  188.      delay_ms(5);
  189.      LCD12864_wcmd(0x0c);
  190.      delay_ms(3);
  191.      LCD12864_wcmd(0x01);
  192.      delay_ms(3);
  193.      LCD12864_wcmd(0x80);
  194.      delay_ms(3);
  195.      LCD12864_wcmd(0x06);                          //游標右移,地址自動加一
  196.      delay_ms(3);
  197.     }



  198. //*******定時器程序*********//
  199. //*定時次數=(1/pinlv*32)/(1/12/12)=31250/pinlv*//  更改頻率原理:單片機12MHZ晶振,所以產生1s的時鐘,也就是1000000us,而輸出波形表內有32個數據,
  200.                                                                                                 //           所以用1000000/(頻率*32),得出數值作為定時器初值,每隔一個時間輸出一個數值。
  201. void timer0_init()
  202. {
  203.         uchar a;                        //頻率儲存
  204.         shi=pinlv/10;
  205.         ge=pinlv%10;
  206.         a=shi*10+ge;
  207.         timer_value=31250/a;                //定時次數計算
  208.         timer_value=timer_value-28;           //誤差補償
  209.         TMOD=0x01;
  210.         TH0_PL=(65535-timer_value)/256;
  211.         TL0_PL=(65535-timer_value)%256;
  212.         TH0=TH0_PL;
  213.         TL0=TL0_PL;
  214.         TF0=0;
  215.         EA=1;
  216.         ET0=1;
  217.         TR0=1;
  218. }



  219. /***************************************按鍵模塊********************************************/
  220. /******************************************************************************************/
  221. void key()
  222. {        
  223.                 if(key1==0)//按下鍵盤
  224.                         {        
  225.                                 delay_ms(10);        //消抖動
  226.                                 if(key1==0);//在確認一次
  227.                         {        pinlv++;//發光二極管點亮
  228.                                 if(pinlv==51)                   //*設置頻率調節范圍1~50
  229.                                 pinlv=1;
  230.                                 }
  231.                                 while(!key1)//松手
  232.                                 delay_ms(10);          ////消抖動
  233.                                 while(!key1);                }
  234.                 if(key2==0)//按下鍵盤
  235.                         {        
  236.                                 delay_ms(10);        //消抖動
  237.                                 if(key2==0);//在確認一次
  238.                         {
  239.                                 pinlv--;//發光二極管點亮
  240.                                 if(pinlv==1)                                  //*設置頻率調節范圍1~50
  241.                                 pinlv=50;
  242.                                 }
  243.                                 while(!key2)//松手
  244.                                 delay_ms(10);          ////消抖動
  245.                                 while(!key2);                }
  246.                 if(key3==0)//按下鍵盤
  247.                         {        
  248.                                 delay_ms(10);        //消抖動
  249.                                 if(key3==0);//在確認一次
  250.                         {
  251.                                 fd++;
  252.                                 if(fd==11)                                                //*設置幅度調節范圍1~10
  253.                                 fd=1;
  254.                                 }
  255.                                 while(!key3)//松手
  256.                                 delay_ms(10);          ////消抖動
  257.                                 while(!key3);                }
  258.            if(key4==0)//按下鍵盤
  259.                         {        
  260.                                 delay_ms(10);        //消抖動
  261.                                 if(key4==0);//在確認一次
  262.                         {
  263.                             fd--;
  264.                                 if(fd==1)
  265.                                 fd=10;
  266.                                 }
  267.                                 while(!key4)//松手
  268.                                 delay_ms(10);          ////消抖動
  269.                                 while(!key4);                }
  270. }
  271. void wave_KEY()
  272. {
  273.         if(square==0)//按下鍵盤
  274.                         {        
  275.                                 delay_ms(10);        //消抖動
  276.                                 if(square==0);//在確認一次
  277.                         {        
  278.                                 change=2;        
  279.                                 }
  280.                                 while(square)//松手
  281.                                 delay_ms(10);          ////消抖動
  282.                                 while(square);                }
  283.         else if(sin==0)//按下鍵盤
  284.                         {        
  285.                                 delay_ms(10);        //消抖動
  286.                                 if(sin==0);//在確認一次
  287.                         {        
  288.                                 change=1;        
  289.                                 }
  290.                                 while(sin)//松手
  291.                                 delay_ms(10);          ////消抖動
  292.                                 while(sin);                }
  293.         else if(triangle==0)//按下鍵盤
  294.                         {        
  295.                                 delay_ms(10);        //消抖動
  296.                                 if(triangle==0);//在確認一次
  297.                         {        
  298.                                 change=3;        
  299.                                 }
  300.                                 while(triangle)//松手
  301.                                 delay_ms(10);          ////消抖動
  302.                                 while(triangle);                }
  303.         else if(juchi==0)//按下鍵盤
  304.                         {        
  305.                                 delay_ms(10);        //消抖動
  306.                                 if(juchi==0);//在確認一次
  307.                         {        
  308.                                 change=4;        
  309.                                 }
  310.                                 while(juchi)//松手
  311.                                 delay_ms(10);          ////消抖動
  312.                                 while(juchi);                }               
  313. }



  314. void display()                             //顯示子程序
  315. {

  316.    LCD12864_init();
  317.    LCD12864_wcmd(0x0c);    //開顯示
  318.    LCD12864_wcmd(0x30);

  319.       LCD12864_SetPos(0,0);                  //在第一行第一個漢字輸出
  320.       delay_ms(1);
  321.       LCD12864_DisHZ_Str("  波形發生器");
  322.           LCD12864_SetPos(1,0);                  //第二行
  323.       delay_ms(1);
  324.       LCD12864_DisHZ_Str("波形:");
  325.                                             
  326.          LCD12864_SetPos(2,0);           //第三行         
  327.      delay_ms(1);
  328.      LCD12864_DisHZ_Str("頻率:");
  329.                                     
  330.                                                             LCD12864_SetPos(2,7);                       
  331.                                 LCD12864_DisHZ_Str("HZ");
  332.          LCD12864_SetPos(3,0);                          //第四行
  333.      delay_ms(1);
  334.      LCD12864_DisHZ_Str("幅度:");
  335.                                                                
  336.                                      LCD12864_SetPos(3,7);                       
  337.                                 LCD12864_DisHZ_Str("V");
  338.                                                                 }

  339. void state_init()                        //*初始波形數據設置(正弦波,頻率5hz,幅度5v*//
  340. {
  341.         pinlv=5;
  342.         change=1;
  343.         fd=10;
  344.         write_add();        
  345. }


  346. /****************************************主程序*********************************//////
  347. /************************************************************************///////////////
  348. void main()
  349. {        
  350.                 state_init();
  351.             P0=0xff;
  352.         display();           
  353.                    while(1)
  354.                 {
  355.                  if(change==1)                                                                                                   // 此處數據是隨按鍵改變的數據程序,因此放入while循環中,隨波形轉換而改變顯示
  356.                                                                                   {
  357.                                                                                                   LCD12864_SetPos(1,4);

  358.                                                    LCD12864_DisHZ_Str("sin");
  359.                                                                                                    }
  360.                                                                  if(change==2)  
  361.                                                    {
  362.                                                                                                    LCD12864_SetPos(1,4);

  363.                                                    LCD12864_DisHZ_Str("方波");
  364.                                                                                                    }
  365.                                                                  if(change==3)   {
  366.                                                                                    LCD12864_SetPos(1,4);

  367.                                                    LCD12864_DisHZ_Str("角波");
  368.                                                                                                    }
  369.                                                                  if(change==4)   {
  370.                                                                                     LCD12864_SetPos(1,4);

  371.                                                    LCD12864_DisHZ_Str("鋸齒");        
  372.                                                                                                    }  
  373.                                                                                                    LCD12864_SetPos(2,4);
  374.                                                                  shi=pinlv/10;
  375.                                                                  ge=pinlv%10;
  376.                                                                  if(shi==0)
  377.                                                                  LCD12864_wdat(' ');
  378.                                                                  else
  379.                                                             LCD12864_wdat(table[shi]);
  380.                                                                  if(shi==0&&ge==0)
  381.                                                                  LCD12864_wdat(' ');
  382.                                             else
  383.                                                             LCD12864_wdat(table[ge]);
  384.                                                                  LCD12864_SetPos(3,4);
  385.                                                             LCD12864_wdat(table[fd*5/10]);                                               
  386.                                 LCD12864_DisHZ_Str(".");
  387.                                                                 LCD12864_wdat(table[fd*5%10]);
  388.                         wave_KEY();
  389.                          key();
  390.                         delay_ms(10);
  391.                         timer0_init();
  392.                         delay_ms(10);
  393.                         }
  394. }
  395. void timer0() interrupt 1        //改變頻率
  396. {        
  397.         TH0=TH0_PL;
  398.         TL0=TL0_PL;
  399.         if(change==1)
  400.                 send_byte(sin_table[num]*0.1*fd);                         //單片機輸出為5V,因此FD變化1~10,在乘以0.1后,可編程0~5的調節
  401.         else if(change==2)
  402.                 send_byte(square_table[num]*0.1*fd);                //假如不加幅度程序,則輸出頻率可靈活調制1~40hz!!,即去掉*0.1*fd
  403.         else if(change==3)
  404.                 send_byte(triangle_table[num]*0.1*fd);
  405.         else if(change==4)
  406.                 send_byte(juchi_table[num]*0.1*fd);           
  407.         if(num>=31)
  408.                 num=0;
  409.         else
  410.                 num++;

  411. }


復制代碼
回復

使用道具 舉報

ID:161164 發表于 2022-4-14 17:30 | 顯示全部樓層
因為89C52太慢了
當50Hz時
定時器的更新時間是31250/50 = 625us
但計算  square_table[num]*0.1*fd  耗時394us
傳送數據  send_byte(XXX)  又耗時331
加起來共耗時725us
已經超出定時器的溢出時間了
于是不斷進出中斷
回復

使用道具 舉報

ID:494908 發表于 2022-4-14 17:44 | 顯示全部樓層
lkc8210 發表于 2022-4-14 17:30
因為89C52太慢了
當50Hz時
定時器的更新時間是31250/50 = 625us

那這要怎么改呀,求大神幫幫忙
回復

使用道具 舉報

ID:494908 發表于 2022-4-14 18:45 | 顯示全部樓層
lkc8210 發表于 2022-4-14 17:30
因為89C52太慢了
當50Hz時
定時器的更新時間是31250/50 = 625us

怎么省去square_table[num]*0.1*fd  這個時間
回復

使用道具 舉報

ID:161164 發表于 2022-4-14 22:56 | 顯示全部樓層
米霽113 發表于 2022-4-14 17:44
那這要怎么改呀,求大神幫幫忙

換芯片吧~
回復

使用道具 舉報

ID:494908 發表于 2022-4-14 23:03 | 顯示全部樓層

你說的這個耗時725us是怎么計算的??
回復

使用道具 舉報

ID:494908 發表于 2022-4-14 23:14 | 顯示全部樓層

不換芯片的話,程序可以做改動嗎?
回復

使用道具 舉報

ID:491577 發表于 2022-4-14 23:16 | 顯示全部樓層
中斷函數要盡量簡單,復雜運算放在主函數中運行。晶振用30M的。最好換單片機,新一點的單片機都有定時器對外輸出管腳,定時器可以直接對外輸出方波,連中斷都不需要。輸出10MHz都可以。89C52只是學習用,做產品扔了吧。
回復

使用道具 舉報

ID:494908 發表于 2022-4-14 23:58 | 顯示全部樓層
hhh402 發表于 2022-4-14 23:16
中斷函數要盡量簡單,復雜運算放在主函數中運行。晶振用30M的。最好換單片機,新一點的單片機都有定時器對 ...

那我這個square_table[num]*0.1*fd 運算改怎么在主函數改,求求大神幫幫忙!做設計的,感謝!
回復

使用道具 舉報

ID:123289 發表于 2022-4-15 11:29 | 顯示全部樓層
波形極限周期:T=DAC轉換時間 * 波形周期點數
點數32是死的,就看DA的時間了,需要查手冊,看看DA的時間。
升頻要點:
下達DA轉換命令后,不要死等轉換完成。!,浪費時間,而是利用這段時間準備好下一個轉換數據,這樣DA完成后,下個數據就可以立即給到DA了。這樣最快!

回復

使用道具 舉報

ID:625730 發表于 2022-4-15 11:48 | 顯示全部樓層
米霽113 發表于 2022-4-14 23:58
那我這個square_table[num]*0.1*fd 運算改怎么在主函數改,求求大神幫幫忙!做設計的,感謝!

你最好把你的設計要達到的目標講一講,你放到主函數也未必能解決你的問題,設計上有空間的話,單獨用一個單片機來輸出波形,別讓一個單片機干這么多事。
回復

使用道具 舉報

ID:494908 發表于 2022-4-16 18:12 | 顯示全部樓層
yzwzfyz 發表于 2022-4-15 11:29
波形極限周期:T=DAC轉換時間 * 波形周期點數
點數32是死的,就看DA的時間了,需要查手冊,看看DA的時間 ...

這樣的話程序應該怎么改呢?
回復

使用道具 舉報

ID:494908 發表于 2022-4-16 18:14 | 顯示全部樓層
TEC 發表于 2022-4-15 11:48
你最好把你的設計要達到的目標講一講,你放到主函數也未必能解決你的問題,設計上有空間的話,單獨用一個 ...

設計目的就是實現一個可以調節頻率、幅度的波形發生器,使用PCF8591芯片,STC89C52,頻率越高越好。我現在做的最高只有20HZ,單片機的話應該沒有時間改了
回復

使用道具 舉報

ID:123289 發表于 2022-4-18 14:37 | 顯示全部樓層
DA有無中斷信號(查DA手冊)
有:DA用中斷做,下達開始轉換后,立即退出。轉去執行下個數據的輸出準備工作(準備好輸出數據)。
       中斷響應后,立即將(準備好的輸出數據)送DA,重復上述過程。
無:查手冊給出DA轉換時間TS,下達開始轉換后,立即執行下個數據的輸出準備工作(準備好輸出數據)并統計準備工作用了多少時間,如果不足TS,用延時去補。達到TS時間時,立即立即將(準備好的輸出數據)送DA,重復上述過程。
不懂匯編的人,做這種對時序要求嚴的程序,吃虧許多。

回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产精品小视频在线观看 | 国产欧美视频一区 | 91中文字幕| 亚洲成人一二区 | 亚洲va欧美va天堂v国产综合 | 好姑娘影视在线观看高清 | 亚洲欧美中文日韩在线v日本 | www.久久艹 | 亚洲精品一区二区三区在线 | 操人视频在线观看 | 国产三级电影网站 | 欧美自拍日韩 | 久久精品99 | 视频一区二区在线观看 | 中文字幕免费中文 | 天天曰天天干 | 亚洲一区二区三区免费视频 | 欧美激情精品久久久久久 | 成人激情视频网 | av大片 | 欧美高清视频一区 | 天堂色区 | 日韩av成人 | 久久久免费| 国产午夜精品一区二区三区嫩草 | 日韩不卡三区 | 秋霞影院一区二区 | 天天碰日日操 | 久久精品二区亚洲w码 | 精品久久九 | 国产免费播放视频 | 91久久国产精品 | 国产99视频精品免费视频7 | 亚洲国产精品一区二区三区 | 成人教育av | 精品日韩一区二区 | 国产乱码精品1区2区3区 | 中文字幕亚洲视频 | 91精品国产综合久久国产大片 | 免费在线观看成人 | 久久久999免费视频 999久久久久久久久6666 |