痞酷網_PIGOO

 找回密碼
 立即註冊
!!! [系統偵測到廣告阻擋軟體] !!!

如果您覺得痞酷網對您有些許幫助,或者您認同痞酷網的理想,

那麼希望您將痞酷網設定為白名單.

並請在上論壇的時候,動動您的手指,用行動支持我們.

謝謝!
查看: 8478|回復: 39

新玩具 數位控制電源雛型電路(野人獻曝)

  [複製鏈接]
發表於 2013-6-13 20:46:59 | 顯示全部樓層 |閱讀模式
本帖最後由 antlu 於 2013-6-14 01:54 AM 編輯

最近除了忙家務之外,就是想要完成 電源供應器, 使用 LM317 作一個 15V 1A的電路,電路比較特殊的是使用 MCU來控制,由於功力有限所以使用兩個 獨立的 MCU 來作,STC15F204EA 有 A/D功能用來當作 顯示(電表) STC89C52RC 就當作傳統的 D/A 控制,控制8BIT 電流設定與 8BIT電壓設定, LM324 作為電流檢出 電壓 電流控制 D/A電壓放大
使用4個VR
1. D/A電壓轉換輸出
2. D/A電流轉換輸出
3. A/D 電壓顯示調整
4. 電流檢出比例調整

這期間遇到的問題有 STC15F204EA 的顯示不正常,原來是 4BIT 顯示的參數設定錯誤.
還有移植舊有程式時 接腳設定忘了改,無法顯示!! 以及漏了焊接幾條線...

程式的技巧純粹"土法煉鋼" 毫無技巧可言!! 還好 MCU記憶體很大都很夠用!!
先前本來打算使用 PWM來控制 D/A 後來發現除非使用 有 PWM 的MCU否則 程式很難搞!! 於是決定使用傳統的 D/A轉換,之所以捨棄手頭的 74LS373而上網購買 74HC573的原因是,使用 OK線連接用 74LS373 和 74HC573 相比有如 天堂地獄!! 於是一口氣買了30個(一個才5元)...感謝雄爸給的電流感應器,目前還沒使用,等下一版改進之後再使用!!

數值電源01.JPG

數值電源02.JPG

數值電源03.JPG

數值電源04.JPG

數值電源05.JPG

數值電源06.JPG

目前只把電壓輸出調整完成,電流方面的調校還需進一步的進行!!

控制部分使用 8952
/*20130612 利用 74hc573 2組以 P1為DATA PORT P2^0 電壓,P2^1 電流 輸出栓鎖 R-2R 產生的 D/A 輸出給 OPA 來控制 LM317的參考電壓 V I 可電電阻把 D/A值作衰減給OPA 經過 電晶體的導通使得LM317動作.  
1.        定時執行 顯示動作
2.        定時執行 按鍵掃描動作
3.        顯示位置以及增加減少動作
                    */
#include<reg52.h>
#include<stdio.h>
#include <intrins.h>
#include <delay.h>
#include <i2c.h>
#define DataPort P0//P0.0~P0.7 1602 LCM
#define DAPort  P1//P1.0~P1.7 74573 8bit
#define  _Nop()  _nop_()        //空指令
#define RS_CLR RS=0// LCM 控制
#define RS_SET RS=1
#define RW_CLR RW=0
#define RW_SET RW=1
#define EN_CLR EN=0
#define EN_SET EN=1
#define V_SET LTH1=1 //設定電壓數值
#define V_CLR LTH1=0 //
#define I_SET LTH0=1  //設定電流數值
#define I_CLR LTH0=1 //
sbit LTH0 = P2^0;//74hc573 latch bit
sbit LTH1 = P2^1;//74hc573 latch bit
sbit RS = P2^7;//LCM指令Lo/資料Hi
sbit RW = P2^6;//READ Hi/WRITELo
sbit EN = P2^5;//ENABLE Hi>>Lo



sbit STRP = P3^2;//控制輸出電壓的打開/關斷
sbit VoI = P3^3;//選擇電壓或是電流 VoI_flag=1 volt,0 current
sbit Inc = P3^4;//inc V/I set
sbit Dec= P3^5;//dec V/I set
sbit Lsft= P3^6;//Left shift
sbit Rsft = P3^7;//Right shift
bit Startflag;//start 1/ stop 0
bit VoI_flag;//volt 1 /current 0
bit Ts_flag;// down count second no use
bit TimeFlag;      //T0 counter
char DisplayWord[16];//LCM display buffer
unsigned char  counter; //T0counter
unsigned char Tcounter;//T1 counter no use
unsigned char Idata;//current setting data send to DAPort then I_SET & I_CLR
unsigned char Vdata;//volt setting data send to DAPort  then V_SET & V_CLR
unsigned char Idigt;// LCM 3bit   0.00 ~ 1.00 000~100
unsigned char Vdigt;//LCM V 3bit   00.0~15.0 000~150
float I_factor,V_factor;//factor for  D/A Port  no use
void DelayMs(unsigned char);
void DelayUs2x(unsigned char);
void Init_Timer0(void);//initial timer0
void LCD_Write_String(char x,char y, char *s);
void LCD_Write_Char(char x,char y,char Data);
void LCD_Clear(void);




/*------------      LCM control routine-------*/
bit LCD_Check_Busy(void) //busy check
{
DataPort= 0xFF;
RS_CLR; //
RW_SET; //
EN_CLR; //***special**** from LO  to HI **************
_nop_();
EN_SET; //***special**** from LO  to HI **************
return (bit)(DataPort & 0x80);//check bit7 =0 write data
}


/*void LCD_Write_Com(char com) //
{
while(LCD_Check_Busy()); //busy then wait 1=while loop still;
RS_CLR; //
RW_CLR; //
EN_SET; //
DataPort= com; //
_nop_();
EN_CLR;//
}*/

void LCD_Write_Com(char com) // 4bit
{
while(LCD_Check_Busy()); //busy then wait 1=while loop still;
RS_CLR; //
RW_CLR; //
EN_SET; //
DataPort= com; //
_nop_();
EN_CLR;//
com<<=4;
EN_SET; //
_nop_();
DataPort= com; //
EN_CLR;//
}



/*
void LCD_Write_Data(char Data)
{
while(LCD_Check_Busy());
RS_SET;
RW_CLR;
EN_SET;
DataPort= Data;
_nop_();
EN_CLR;
}
*/
void LCD_Write_Data(char Data) //4bit
{
while(LCD_Check_Busy());
RS_SET;
RW_CLR;
EN_SET;
DataPort= Data;
_nop_();
EN_CLR;
Data<<=4;
  EN_SET;
DataPort= Data;
_nop_();
EN_CLR;
}

void LCD_Clear(void)
{
LCD_Write_Com(0x01);
DelayMs(5);
}

void LCD_Write_String(char x,char y, char *s)
{   
if (y == 0)
       {   
         LCD_Write_Com(0x80 + x);   
       }
else
       {     
       LCD_Write_Com(0xC0 + x);      
       }      
while (*s)
       {   
LCD_Write_Data( *s);
s ++;   
       }
}


void LCD_Write_Char(char x, char y, char Data)
{   
if (y == 0)
       {   
       LCD_Write_Com(0x80 + x);
       }   
else
       {   
       LCD_Write_Com(0xC0 + x);   
       }      
LCD_Write_Data( Data);
}

void LCD_Write_FChar(unsigned char x,unsigned char y)
{     //write cursor flash
if (y == 0)
        {     
        LCD_Write_Com(0x80 + x);     
        }   
else
        {     
        LCD_Write_Com(0xC0 + x);     
        }
LCD_Write_Com(0x0f);       
}

void LCD_Init(void)
{
   LCD_Write_Com(0x28);//38>>28  for 4bit
   DelayMs(5);
   LCD_Write_Com(0x28); //38>>28 for 4bit  data  2 line 5x7 character.
   DelayMs(5);
   LCD_Write_Com(0x28); //38>>28
   DelayMs(5);
   LCD_Write_Com(0x28);
   LCD_Write_Com(0x08);    /*no display*/
   LCD_Write_Com(0x01);    /*clean screen*/
   LCD_Write_Com(0x06);    /*cursor control*/
   DelayMs(5);
   LCD_Write_Com(0x0C);    /*display on cursor set*/
   }

void DelayUs2x(unsigned char t)
   {  
     while(t--);
   }
void DelayMs(unsigned char t)
{
      while(t--);
   {
     DelayUs2x(245);//from245>>45
         DelayUs2x(245);
   }
}

//--------------------------------------------------------------------------------------------
void Init_Timer0(void)
{
TMOD |= 0x01;      //mode 1,16bit timer "|"can "OR"operation                    
TH0= (65536-2000)/256; //   0x0D8 2ms if 12Mcristal
TL0= (65536-2000)%256;// 0x0F0
EA=1;         
ET0=1;         
TR0=1;         
}

//--------------------------------------------------------------------------------------------
void Timer0_isr(void) interrupt 1
{
TH0= (65536-2000)/256; //   0x0D8 2ms if 12Mcristal
TL0= (65536-2000)%256;// 0x0F0
    counter++;//counter is Global variable.
    if(counter>170)          //140ms update 1 time
     {      
      TimeFlag=1;            //
          counter=0;
        }//if(counter>70)

    //WDT_CONTR = 0x3d;//watch dog no use
}



void Display_pros(void)
    {
       // if(Dflag) DisplayWord[0]='+';
           // else DisplayWord[0]='-';
        DisplayWord[1]='A';
        DisplayWord[2]='n';
        DisplayWord[3]='t';
        DisplayWord[4]='l';
        DisplayWord[5]= 'u';
        DisplayWord[6]= ' ';
        DisplayWord[7]= 'P';
        DisplayWord[8]= 'S';
    //    else DisplayWord[8]= 'P';//????
                DisplayWord[9]= ' ';
        DisplayWord[10]= 'O';
                        if(Startflag) DisplayWord[11]='N',DisplayWord[12]= ' ';
      else DisplayWord[11]= 'F', DisplayWord[12]= 'F';;

        DisplayWord[13]= ' ';
        DisplayWord[14]= ' ';
        DisplayWord[15]= ' ';
       LCD_Write_String(0,0, DisplayWord);
  
        DisplayWord[0]=' ';
        DisplayWord[1]='V';
        DisplayWord[2]='=';
        DisplayWord[3]= Vdata/100+'0';
        DisplayWord[4]= Vdata /10%10+'0';
        DisplayWord[5]= '.';
        DisplayWord[6]= Vdata %10%10+'0';
        DisplayWord[7]= 'V';
        DisplayWord[8]= ' ';
        DisplayWord[9]= 'I';
        DisplayWord[10]= '=';
        DisplayWord[11]= Idata/100+'0';
        DisplayWord[12]= '.';
        DisplayWord[13]= Idata /10%10+'0';
        DisplayWord[14]= Idata %10%10+'0';
        DisplayWord[15]='A';
    LCD_Write_String(0,1, DisplayWord);//??????
if(VoI_flag)
{         

   if(Vdigt==2) LCD_Write_FChar(3,1);
         else if(Vdigt==1) LCD_Write_FChar(4,1);
         else LCD_Write_FChar(6,1);

}
  else
        {
   if(Idigt==2) LCD_Write_FChar(11,1);
         else if(Idigt==1) LCD_Write_FChar(13,1);
         else LCD_Write_FChar(14,1);
   
        }  
}


void OP(bit K)//output control
{
  if (K)// data op =set
   {
DAPort=Vdata;// volt & current data sent to i/o and latch
V_SET;
V_CLR;
DAPort=Idata;
I_SET;
I_CLR;
    }
else //data output=0
  {
DAPort=0x00;// reset volt & current data sent to i/o and latch
V_SET;
V_CLR;
DAPort=0x00;
I_SET;
I_CLR;
}

}
void Check_STRP(void) //check start/stop key press
{
if(!STRP)//key press
   DelayMs(5);
     if(!STRP)
              {
          while(!STRP);              
              Startflag=!Startflag; // change state

                     }
  }


void Check_VOI(void)//V/I select key press
{
  if(!VoI) //key pressed
      DelayMs(5);
          if(!VoI)
            {
          while(!VoI);
             {
              VoI_flag=~ VoI_flag;
             }//Volt or Current will flash
                 }
}

void Check_LR(void)// check L/R shift key be pressed
{
  if(!Lsft)
      DelayMs(5);
          if(!Lsft)
            {
          while(!Lsft);//Key depress
           if(VoI_flag)   
{
              Vdigt++;
       if(Vdigt>2) Vdigt=0;
    }
  else
   {
    Idigt++;
     if(Idigt>2) Idigt=0;
    }
}
if(!Rsft)
          DelayMs(5);
   if(!Rsft)
            {
          while(!Rsft);//Key depress
           if(VoI_flag)   
{
              Vdigt--;
       if(Vdigt==255) Vdigt=2;
    }
  else
   {
    Idigt--;
     if(Idigt>255) Idigt=2;
    }
}

}

void Check_inc(void) //inc/dec key press check
{
  if(!Inc) //+ key press
      DelayMs(5);
          if(!Inc)
            {
          while(!Inc);//Key + depress
           if(VoI_flag)  //volt   
{
if(Vdigt==0) Vdata=Vdata++;
if(Vdigt==1) Vdata=Vdata+10;
if(Vdigt==2) Vdata=Vdata+100;
if(Vdata>250) Vdata=250;            
    }
  else
   {
if(Idigt==0) Idata=Idata++;
if(Idigt==1) Idata=Idata+10;
if(Idigt==2) Idata=Idata+100;
if(Idata>210) Idata=210;
     }
}

  if(!Dec) //- key press
      DelayMs(5);
          if(!Dec)
            {
          while(!Dec);//Key - depress
           if(VoI_flag)  //volt   
{
if(Vdigt==0) Vdata=Vdata--;
if(Vdigt==1) Vdata=Vdata-10;
if(Vdigt==2) Vdata=Vdata-100;
if(Vdata>250) Vdata=0;            
    }
  else
   {
if(Idigt==0) Idata=Idata--;
if(Idigt==1) Idata=Idata-10;
if(Idigt==2) Idata=Idata-100;
if(Idata>210) Idata=0;
     }
}
}




void main(void)
{
Init_Timer0();//initial timer0

LCD_Init();// LCM initial
LCD_Clear();//LCM clear
OP(0);//initial output
while(1)
{
if(TimeFlag==1)//140ms update
  {
  TimeFlag=0;
      Display_pros();//display data
  }
if(Startflag)
   {
    OP(1); //out put on
   }
         else
         {
                 OP(0); //output set volt & current to 0
          }


        DelayMs(100);
  Check_STRP();//on/off key process
  Check_VOI();//V/I key process
  Check_LR();// shift L/R process
  Check_inc();//+/- process
}      
}//finish


顯示部分使用 STC15F204EA 它只負責顯示而已
//#include<STC15F204EA.h>
/*  ????????? 20130611  no internal timer just delay for A/D read to avoid data chang fast use 10times average for nc power  */
#include <reg52.h>
#include<intrins.h>
sfr ADC_CONTR   =   0xBC;   //0000,0000 A/Dת»»¿ØÖƼĴæÆ÷
sfr ADC_RES     =   0xBD;   //0000,0000 A/Dת»»½á¹û¸ß8λ
sfr ADC_RESL    =   0xBE;   //0000,0000 A/Dת»»½á¹ûµÍ2λ
sfr P1M0        =   0x92;   //0000,0000 Ë¿Ú1ģʽ¼Ä´æÆ÷0
sfr P1M1        =   0x91;   //0000,0000 Ë¿Ú1ģʽ¼Ä´æÆ÷1
sfr P1ASF       =   0x9D;   //0000,0000 Ë¿Ú1Ä£Ä⹦ÄÜÅäÖüĴæÆ÷

sbit RS = P3^7;   //©w…óºÝ¤f
sbit RW = P3^6;
sbit EN = P3^5;
char displayword[16];
#define RS_CLR RS=0
#define RS_SET RS=1
#define RW_CLR RW=0
#define RW_SET RW=1
#define EN_CLR EN=0
#define EN_SET EN=1
#define DataPort P2 //STC15F204EA P1 A/D P2 LCM P3^7--RS  P3^6--W/R P3^5--E
//unsigned char d[5];
unsigned int R,L,M,N,Q,I;//unsigned int R,M,N;//­Y©w…ó¦¨uchar«´N¥u¯àF¥Ü2.5V¥H¤Uªº‡Û­È
signed int SV,AV;//´«ºâ«áªº³]©w•Å«×sv=100/V ´«ºâ«áªº¼ö°¸•Å«×av=100/V

signed int Difv;
/*------------------------------------------------
uS©µƒº¨ç‡Û¡A§t¦³‰r¤Jƒò‡Û unsigned char t¡AÆÓªð¦^­È
unsigned char O©w…óÆӲņA¦r²Å@q¡A¨ä­Èªº­S„ÏO
0~255 „±¨½¨Ï¥Î´¹®12M¡AºëÚÌ©µƒºˆ[¨Ï¥Î…¹ˆC,¤j­P©µƒº
ƒc«×¦p¤U T=tx2+5 uS
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{   
while(--t);
}
/*------------------------------------------------
mS©µƒº¨ç‡Û¡A§t¦³‰r¤Jƒò‡Û unsigned char t¡AÆÓªð¦^­È
unsigned char O©w…óÆӲņA¦r²Å@q¡A¨ä­Èªº­S„ÏO
0~255 „±¨½¨Ï¥Î´¹®12M¡AºëÚÌ©µƒºˆ[¨Ï¥Î…¹ˆC
------------------------------------------------*/
void DelayMs(unsigned char t)
{
     
while(t--)
{
     //¤j­P©µƒº1mS
   DelayUs2x(245);
         DelayUs2x(245);
}
}


/*------------------------------------------------
              §P¦£¨ç‡Û
------------------------------------------------*/
bit LCD_Check_Busy(void)
{
DataPort= 0xFF;
RS_CLR;
RW_SET;
EN_CLR;
_nop_();
EN_SET;
return (bit)(DataPort & 0x80);
}

void LCD_Write_Com(char com) //©R¥O¼g¤J 4bit
{  
while(LCD_Check_Busy()); //¦£ƒhµ¥«Ý 1=while loop still;
RS_CLR; //«ü¥O¥\¯à
RW_CLR; //¼g¤J
EN_SET; //¤U­°½t ¥ÑHIÅܦ¨LO
DataPort= com; // «ü¥O³]©w
_nop_();
EN_CLR;//
com<<=4;
EN_SET; //¤U­°½t ¥ÑHIÅܦ¨LO
_nop_();
DataPort= com; // «ü¥O³]©w
EN_CLR;//
DelayMs(1);
}

void LCD_Write_Data(char Data) //¸ê®Æ¼g¤J4bit
{
while(LCD_Check_Busy()); //¦£ƒhµ¥«Ý
RS_SET; // ¸ê®Æ³B²z
RW_CLR;// ¼gªº°Ê§@
EN_SET; // ±Ò°Ê¤U½tIJµo
DataPort= Data; //¿é¤J»Ý­n¼g¤Jªº¸ê®Æ
_nop_();//©µ«á¤@­Ó®É¡
EN_CLR;//
Data<<=4;
  EN_SET; // ±Ò°Ê¤U½tIJµo
DataPort= Data; //¿é¤J»Ý­n¼g¤Jªº¸ê®Æ
_nop_();//©µ«á¤@­Ó®É¡
EN_CLR;//
DelayMs(1);//µ¹ 1T MCU ¨Ï¥Î
}



/*------------------------------------------------
                ²M«Ì¨ç‡Û
------------------------------------------------*/
void LCD_Clear(void)
{
LCD_Write_Com(0x01);
DelayMs(5);
}
/*------------------------------------------------
              ‡À¤J¦r²Å¦ê¨ç‡Û
------------------------------------------------*/
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
{     
if (y == 0)
        {     
         LCD_Write_Com(0x80 + x);     
        }
else
        {     
        LCD_Write_Com(0xC0 + x);     
        }        
while (*s)
        {     
LCD_Write_Data( *s);     
s ++;     
        }
}
/*------------------------------------------------
              ‡À¤J¦r²Å¨ç‡Û
------------------------------------------------*/
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
{     
if (y == 0)
        {     
        LCD_Write_Com(0x80 + x);     
        }   
else
        {     
        LCD_Write_Com(0xC0 + x);     
        }        
LCD_Write_Data( Data);  
}
/*------------------------------------------------
              ªì©l¤Æ¨ç‡Û
------------------------------------------------*/
void LCD_Init(void)
{
   LCD_Write_Com(0x28);    /*F¥Ü¼Ò4bit„¦¸m*/
   DelayMs(5);
   LCD_Write_Com(0x28);
   DelayMs(5);
   LCD_Write_Com(0x28);
   DelayMs(5);
   LCD_Write_Com(0x28);  
   LCD_Write_Com(0x08);    /*F¥Ü‹×„¸*/
   LCD_Write_Com(0x01);    /*F¥Ü²M«Ì*/
   LCD_Write_Com(0x06);    /*F¥Ü¥ú‡á²¾ƒð„¦¸m*/
   DelayMs(5);
   LCD_Write_Com(0x0C);    /*F¥Ü…{¤Î¥ú‡á„¦¸m*/
   }

/*******************************************************************
¨ç‡Û¦W¡GADCªì©l¤Æ¤Î8¦ìA/D‹H„ã¨ç‡Û
ªð¦^­È¡G8¦ìªºADC‡ÛÕu
…C  ªG¡GŒÝ¥X«ü©wADC±µ¤fªºA/D‹H„ã­È¡A¦}ªð¦^‡Û­È
„  ª`¡GÓì¥Î¤_STC12C2052AD¨t¦C„ˤùÉó¡]¥²…§¨Ï¥ÎSTC12C2052AD.h‰³¤å¥ó¡^
*******************************************************************/
unsigned char Read (unsigned char CHA)
         {
     unsigned char AD_FIN=0; //¦s‰ÉA/D‹H„ã‡á§Ó;­Y¦b¨ç‡Û¥~©w…󦹍@qƒh¤£¯à±o¨ì„²Œ¢@¤Æªº¼Ò‰ÞqªºF¥Ü
/******¥H¤UƒoADCªì©l¤Æµ{§Ç****************************/
    CHA &= 0x07;            //‰uˆáADCªº8ƒª±µ¤f¤¤ªº¤@ƒª¡]0000 0111 ²M0°ª5¦ì¡^
    ADC_CONTR = 0x60;  //ADC‹H„㪺³t«×¡]0XX0 0000 ¨ä¤¤XX±±¨î³t«×¡Aˆ[®ÚÕu‡ÛÕu¤â•ä„¦¸m¡^
    _nop_();
    ADC_CONTR |= CHA;       //‰uˆáA/D…å«e³q¹D
    _nop_();
    ADC_CONTR |= 0x80;      //„QƒðA/D†z•½
    DelayMs(1);            //¨Ï‰r¤J†z‰Í†c¨ì‹®©w¡]1ms§Y¥i?
/******¥H¤UƒoADCƒù¦æµ{§Ç****************************/
    ADC_CONTR |= 0x08;      //„QƒðA/D‹H„ã¡]0000 1000 ¥OADCS = 1¡^
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    while (AD_FIN ==0){     //µ¥«ÝA/D‹H„ã…C§ô
    AD_FIN = (ADC_CONTR & 0x10); //0001 0000„ò†IA/D‹H„ã…C§ô§_
    }
    ADC_CONTR &= 0xE7;      //1111 0111 ²MADC_FLAG¦ì, ‹×„¸A/D‹H„ã,
//return (ADC_DATA);          //ªð¦^A/D‹H„ã…CªG¡]8¦ì¡^
  return(ADC_RES);
}



unsigned int Mavg(unsigned char an)
// read 10 times data and average
// an for analog input no.
{
        unsigned char at;
        unsigned int M;
        M=0;
        for (at=0;at<10;at++)
  {
                M=Read(an)+M;//analog 3 input
                DelayMs(250);
        }
        M=M/10;
        return M;
}
/******************************************************************
F¥Ü¨ç‡Û‹H„ã¨ç‡Û¡G
M=¼Ò‰Þqªö‡Þ­È¡AN=°ò­ã†z‰Í•½ªö‡Þ­È¡]¥»¨Òƒo2.5V¡^¡AR=¼Ò‰Þq‰r¤J­È¡]«ÝF¥Ü­È¡^
N=256*2.5/Vcc¡F@§Î¦Z±oVcc=256*2.5/N¡F ¥N¤JM=256*R/Vcc¡F±o¨ìM=R*N/2.5¡F@§Î¦Z±oR=M*2.5/N
1ƒo‰r¤JºÝ¤À‰Í¤ñ¡C
******************************************************************/
void transfer(void){
       

L= Mavg(0);//Read(0); // read volt analog
I= Mavg(1);//read (1) read current analog
N=Read(2);//P1.2¤f2.5V°ò­ã†z‰Í•½ªö‡Þ¡]‹H„ã¡^
Q=(L*2.58/N)*100; //Q=display volt data
//R=((I*2.58)/(N))*10;//R=display current data 1V=.1A
R=((I*2.58)/(N))*100;//R=display current data 1V=1A ??10:1 ??
}


void display(void)
{
        displayword[0]=' ';
        // if(Kon) displayword[0]='1';
        displayword[1]='V';//Tab[IRcord[0]/16];
        displayword[2]='=';//Tab[IRcord[0]%16];
        displayword[3]= Q/100+'0';
        displayword[4]= (Q%100)/10+'0';
        displayword[5]= '.';
        displayword[6]=(Q%10)+'0';
        displayword[7]='V';
        displayword[8]= ' ';
        displayword[9]= 'I';
        displayword[10]='=';
        displayword[11]= R/100+'0';
        displayword[12]= '.';
        displayword[13]=(R%100)/10+'0';
        displayword[14]=R%10+'0';
        displayword[15]='A';
         LCD_Write_String(0,0, displayword);//Åã¥Ü¦b²Ä¤G¦æ       

/*        displayword[0]='S';
        displayword[1]='E';
        displayword[2]='T';
        displayword[3]=':';
        displayword[4]= Q/1000+'0';
        Q=Q%1000;
        displayword[5]=Q/100+'0';
         Q=Q%100;
        displayword[6]=Q/10+'0';
        displayword[7]=Q%10+'0';
        displayword[8]= ' ';
        displayword[9]= 'T';
        displayword[10]='C';
        displayword[11]=':';
        displayword[12]=R/1000+'0';
        R=R%1000;
        displayword[13]=R/100+'0';
   R=R%100;
        displayword[14]=R/10+'0';
        displayword[15]=R%10+'0';
    LCD_Write_String(0,1, displayword);//Åã¥Ü¦b²Ä¤G¦æ         
                */
}
  


void main(void)
{
P1M0 = 0xff; //P1.0/P1.1¡G1111 1111¡]°ªªý¡^//ª`•N¡G§ó§ïADC³q¹Dƒº…§¦Pƒº’â†Á‰ØªºIO±µ¤f­×§ïƒo°ªªý‰r¤J¡C
P1M1 = 0x00; //P1.0/P1.1¡G0000 0000
P1ASF=0xff;        //all analog in put mode
LCD_Init();
LCD_Clear();//²M«Ì
//Difv=0;
//SV=0;
//LCD_Write_String(0,0,"IRON Temp Contrl");

while (1)
{

  transfer();//do ADC & putto display
        DelayMs(250);
  display();
}
}

亂碼大家請包涵我也沒辦法!!

評分

7

查看全部評分

發表於 2013-6-13 23:37:58 | 顯示全部樓層
antlu大
亂碼會不會是簡體字你沒有先在外部作轉換呢,原始檔用word作字碼轉換看看
目前手上拿到一些STC的mcu,15F204EA還在想來試試換用c來寫
不懂的地方再向antlu你請問了
發表於 2013-6-13 23:55:06 | 顯示全部樓層
沒學過程式----對我來說像天書-----------------antlu大--你是自己寫的嗎
 樓主| 發表於 2013-6-14 00:57:53 | 顯示全部樓層
legion 發表於 2013-6-13 11:37 PM static/image/common/back.gif
antlu大
亂碼會不會是簡體字你沒有先在外部作轉換呢,原始檔用word作字碼轉換看看
目前手上拿到一些STC的mcu ...

LEGION大:
   我試看看!! C對於計算超方便,但是對於時間掌控就會比較無力!! 我發現 1T的MCU用在 LCM的顯示幾乎都可以相容,只有40微秒的更新時間需要考慮,於是我用5豪秒來代替..
 樓主| 發表於 2013-6-14 00:59:21 | 顯示全部樓層
maxcar 發表於 2013-6-13 11:55 PM static/image/common/back.gif
沒學過程式----對我來說像天書-----------------antlu大--你是自己寫的嗎

MAXCAR大:
   我都是東抄一下西抄一下然後土法煉鋼,把舊的程式改一改...
發表於 2013-6-14 01:24:27 | 顯示全部樓層
那也利害----------
發表於 2013-6-14 07:00:09 | 顯示全部樓層
阿乾大您可以先用word開啟原本簡體的txt或C檔,然後再簡繁轉換,轉完後把文字複製下來,另開一個新的c檔貼上去,然後存檔覆蓋原始檔,這樣亂碼問題就解了。
我看到阿乾大您捨棄了sprintf,程式碼可以少掉很多空間。
另外,剛剛突然想到一個東西,可以節省51的接線,用74164來推資料去控制R-2R,串列進,並列出,應該也不錯用,51只要兩條線控制它就行了。
發表於 2013-6-14 13:37:37 | 顯示全部樓層
晴兒 發表於 2013-6-14 07:00 AM static/image/common/back.gif
阿乾大您可以先用word開啟原本簡體的txt或C檔,然後再簡繁轉換,轉完後把文字複製下來,另開一個新的c檔貼 ...
可以節省51的接線,用74164來推資料去控制R-2R,串列進,並列出

一般是用PWM啦...

除標準型號89c51外...STC應該幾乎都有提供 8-16bits 的PWM可以使用.....線性度應該還不錯...只要濾波+OP當buffer...

R-2R matching還有焊那些線也有點麻煩....IO的負載效應也是會影響精準度..


我光看那麼多顆IC...要手焊那麼多接線就很佩服............唉.....看看自己...實在好懶惰喔..好久沒動手了....應該好好學習一下了!!
 樓主| 發表於 2013-6-14 20:10:29 | 顯示全部樓層
晴兒 發表於 2013-6-14 07:00 AM static/image/common/back.gif
阿乾大您可以先用word開啟原本簡體的txt或C檔,然後再簡繁轉換,轉完後把文字複製下來,另開一個新的c檔貼 ...

晴兒大:
   許久不見!!  習慣使然!! 我沒用過 74164 到是用過 74595,不過只用1~2次還不太熟!! 74573很方便的是 程式好寫,又短! 焊接方面配合 R-2R 電阻排 接起來算是方便!!  記得以前公司的機器使用 CANON 對準機台, 機台從 幾萬美元機種進階到幾十萬美元,後來又推出百萬美元的機台,它的基本控制都有一些影子可循...應該也是習慣使然吧!!
 樓主| 發表於 2013-6-14 20:16:56 | 顯示全部樓層
imcrazy 發表於 2013-6-14 01:37 PM static/image/common/back.gif
一般是用PWM啦...

除標準型號89c51外...STC應該幾乎都有提供 8-16bits 的PWM可以使用.....線性度應該還 ...

imcrazy大:
   8051系列的 MCU 很多,記得 除了 宏晶外 華邦 等公司也都有出,而且同一家公司也出了許多型號!! 我是因為純好玩又要省費用,所以就選這兩個MCU 因為價錢都是 30元/顆,比起 電子材料店 一顆74HC573就要 30元真是便宜又好用,當然也懶得學習其他 MCU ,像是 ATMEL 公司也很多 MCU...
發表於 2013-6-14 20:49:59 | 顯示全部樓層
antlu 發表於 2013-6-14 08:16 PM static/image/common/back.gif
imcrazy大:
   8051系列的 MCU 很多,記得 除了 宏晶外 華邦 等公司也都有出,而且同一家公司也出了許多型 ...

oh....我的意思是.......真的要節省接腳.....

你用的那顆STC15F204EA應該有PWM可以拿來當D/A的功能用啦....

一般的51也是可以啦...只是用軟體模擬的PWM...MCU一直中斷處理太忙了....
 樓主| 發表於 2013-6-14 21:44:21 | 顯示全部樓層
legion 發表於 2013-6-13 11:37 PM static/image/common/back.gif
antlu大
亂碼會不會是簡體字你沒有先在外部作轉換呢,原始檔用word作字碼轉換看看
目前手上拿到一些STC的mcu ...

LEGION大:
  您太客氣了!! 微控的路上沒有你的指導怎麼會有我的玩具 PO出來呢!! 你是專業我是業餘!!
發表於 2013-6-14 21:47:42 | 顯示全部樓層
寫什毀看毋! 拍手加分就對了
 樓主| 發表於 2013-6-14 21:51:25 | 顯示全部樓層
數控電源20130614.png   

數控電源20130614.png
 樓主| 發表於 2013-6-14 21:54:08 | 顯示全部樓層
popcorn 發表於 2013-6-14 09:47 PM static/image/common/back.gif
寫什毀看毋! 拍手加分就對了

POPCORN大:
  就是玩具啦!!  LM317做的電源 用一些電路取代 "可變電阻" !!
 樓主| 發表於 2013-6-14 21:58:01 | 顯示全部樓層
imcrazy 發表於 2013-6-14 08:49 PM static/image/common/back.gif
oh....我的意思是.......真的要節省接腳.....

你用的那顆STC15F204EA應該有PWM可以拿來當D/A的功能用啦. ...

imcrazy 大:
   因為我看資料有2個特性,1 貪快(不消化) 2. 十目一行,過目即忘(別人是 一目十行,過目不忘) 我沒找到 PWM功能...
發表於 2013-6-14 22:32:27 | 顯示全部樓層
antlu 發表於 2013-6-14 09:58 PM static/image/common/back.gif
imcrazy 大:
   因為我看資料有2個特性,1 貪快(不消化) 2. 十目一行,過目即忘(別人是 一目十行,過目不忘) ...

抱歉是我錯了   剛剛仔細找... 還真的被..."唬"....了...

我以前用STC 1T大多都有....

原本只大概看了一下....也沒仔細看內容.....Sorry...

唉....那個姚工還是死性不改....寫手冊真的不是普通的唬爛......軟體模擬的也好意思寫出來....那乾脆說這顆也有三個UART算了...兩個也是可以軟體模擬出來的..

STC.PNG
 樓主| 發表於 2013-6-14 23:11:47 | 顯示全部樓層
imcrazy 發表於 2013-6-14 10:32 PM static/image/common/back.gif
抱歉是我錯了   剛剛仔細找... 還真的被..."唬"....了...

我以前用STC 1T大多都有....

姚工說有應該就會有!! 只是可能用軟體來操作吧!! 我先把它定位在 數位電壓電流表也還很好用!! 因為 LCM 對我來說很便宜(回收場經常可以看到!) 15F204EA 30元/個 所以很划算,又不需要石英震盪...
發表於 2013-6-14 23:56:06 | 顯示全部樓層
antlu 發表於 2013-6-14 08:10 PM static/image/common/back.gif
晴兒大:
   許久不見!!  習慣使然!! 我沒用過 74164 到是用過 74595,不過只用1~2次還不太熟!! 74573很方 ...

嗯嗯!哈!習慣性順手比較重要。
573直接一個port丟資料出去,再栓鎖起來就行了。
至於說用164,同樣要控制電壓、電流,這樣就可以少掉將近12條線,但程式稍微難一些,變成要自己用指定一個I/O腳打clock,另外一支送data。
例如:

  1. sbit clk_0 = P0^1;   //定義埠
  2. sbit data_0 = P0^2;   //定義埠
  3. /*-------------------------
  4. 74164送電壓資料副程式
  5. -------------------------*/
  6. void volt_data_set(unsigned char data)
  7. {
  8.     char loop = 7;
  9.     while(loop>=0)
  10.    {
  11.        clk_0 = 1;
  12.        data_0 = data >>loop;
  13.       _nop_ ();    // delay
  14.       _nop_ ();
  15.       _nop_ ();
  16.       clk_0 = 0;
  17.       _nop_ ();    // delay
  18.       _nop_ ();
  19.       _nop_ ();
  20.      loop--;
  21.    }

  22. }
複製代碼
發表於 2013-6-15 00:01:01 | 顯示全部樓層
哈!我也只能拍手...加分!!!
原來這裡真多高手的..
 樓主| 發表於 2013-6-15 00:46:58 | 顯示全部樓層
本帖最後由 antlu 於 2013-6-15 01:00 AM 編輯
晴兒 發表於 2013-6-14 11:56 PM static/image/common/back.gif
嗯嗯!哈!習慣性順手比較重要。
573直接一個port丟資料出去,再栓鎖起來就行了。
至於說用164,同樣要控 ...


晴兒大:
   感恩喔!! 這樣可以省得我"老鼠抓龜"(無從著手)的困境!! 把他放在我的資料庫裏頭,好用!!

     while(loop>=0)
   {
       clk_0 = 1;
       data_0 = data >>loop;
      _nop_ ();    // delay....

    這指令我沒用過ㄟ...  高手!!
發表於 2013-6-15 01:01:07 | 顯示全部樓層
阿乾大:
您的電壓上升與下降好調嗎?

有沒設計成兩種方式,就是例如按低於0.5秒,就是正常每次+1或-1,高於0.5秒就快速+1與快速-1.
或者多花一點coco買Code Switch,調電壓就像用傳統的VR一樣.

您的8 bits ADC基本解析度為多少V?
15V/256 = 0.058V
0.058V x 256 = 14.84V

15/258 = 0.059V
0059V x 256 = 15.10

看您的電表顯示15.00V,而您的玩具也是15.0V,這樣與上面的算起來不符合.
另外也有看到顯示16.8V,難道您的電壓不是最高15V?
  
要不要預告一下下個玩具,方波與正弦波震盪器?
74HC573同樣用得到.

或者玩一下這個?
8051 Scope
http://www.youtube.com/watch?v=lTHY3qeiQtg
 樓主| 發表於 2013-6-15 01:33:59 | 顯示全部樓層
本帖最後由 antlu 於 2013-6-15 01:43 AM 編輯
scottwang 發表於 2013-6-15 01:01 AM static/image/common/back.gif
阿乾大:
您的電壓上升與下降好調嗎?


scottwang大:
    這次算是有點突破,我因為想到要按很久才可以到達要用的電壓或是電流,所以,用上下左右鍵來調整需要的數值.另外 I/V  選定調電壓或是電流  O/P 控制輸出,當輸出為ON時候 調整電壓會立即輸出,解析度我是以150=15.0V  100=1.00A 所以解析度不算高,以可變電阻配合OPA來簡化控制的複雜.我沒試過若是加上20V 25V會不會有效的控制輸出? 小修改要把2.5V 參考電壓用 TL431替代, 電流檢出的OP電路比較有問題,因為除非使用接地電阻取電位差,否則高電位檢出電流時候 OP的電源都要比輸入電壓還要高,或除非使用專門IC(我手上只有LM324).當然使用專用的電流感測模組也是一種方法,只是,電流檢出模組價格昂貴,2A小電流檢出也不多... 輸出電壓最低只能達到2V,假如加上負偏壓或許可以從0V開始!!

記得以前修設備後要校正轉速,有兩個VR 一個調整指示值 一個調整D/A值,我都是先把實際的轉速與顯示值相符合,再調整到設定的轉速目標值, 一開始有控制值15V 實際值16.x V 後來調整到輸出與實際相符,這就是 OPA 和VR的方便地方,缺點是會有漂移的可能...
發表於 2013-6-15 01:44:57 | 顯示全部樓層
antlu 發表於 2013-6-15 01:33 AM static/image/common/back.gif
scottwang大:
    這次算是有點突破,我因為想到要按很久才可以到達要用的電壓或是電流,所以,用上下左右鍵 ...

電流檢出可以買錳銅線. (Shunt Resistor)
http://www.liket.com.tw/mana_php/prod/file/5-4_ok.pdf

http://www.silvercrown.com.tw/ma ... Wire_ver1.0_cht.pdf

上面的是已做好的跳線式的.
另一種是買線來剪,依據所需的電阻計算長度來剪.

LM324好用啊,我這裡也有一些,都是很久以前的舊貨,以前的老闆送的,因為收攤了.

評分

1

查看全部評分

發表於 2013-6-15 09:21:59 | 顯示全部樓層
antlu 發表於 2013-6-15 12:46 AM static/image/common/back.gif
晴兒大:
   感恩喔!! 這樣可以省得我"老鼠抓龜"(無從著手)的困境!! 把他放在我的資料庫裏頭,好用!!

哈!阿乾大您過譽了。我還算新手,有時候邏輯實在很爛,不太會用技巧性的演算法,只會硬做。
這_nop_()指令,是空指令,CPU會閒置一個機械週期不做事,用來延時是還蠻不錯的。
但是使用這個指令必須要#include "intrins.h"。
發表於 2013-6-15 13:16:20 | 顯示全部樓層
antlu 發表於 2013-6-14 12:57 AM static/image/common/back.gif
LEGION大:
   我試看看!! C對於計算超方便,但是對於時間掌控就會比較無力!! 我發現 1T的MCU用在 LCM的顯 ...


其實antlu大你的作法是看了有點怪,但每個人用法不同,順手就好
即然用兩棵mcu的話,如果是自己作的話,會用一棵作輸入及顯示功能
另一棵則作A/D及和D/A的控制端,整合起來會比較方便一些
穩定度上也比較好控制的,不過每人作法不同,多試試也是不錯的
 樓主| 發表於 2013-6-15 21:05:59 | 顯示全部樓層
legion 發表於 2013-6-15 01:16 PM static/image/common/back.gif
其實antlu大你的作法是看了有點怪,但每個人用法不同,順手就好
即然用兩棵mcu的話,如果是自己作的話,會用 ...

LEGION大:
   其實我會這樣的選擇是有原因的!! 因為你可以看出這兩個 MCU一點關係都沒有(各自獨立),主要原因是我完全沒有 兩個MCU 互動的經驗與技巧,昨天有想到一個就是 把其中一個MCU的一個BIT輸出接到另一個MCU的一個 BIT作為輸入,比方說 STC15F204EA 輸出電壓超過的信號,來把 STC89C52的輸出 OFF 這樣或許就有一些互動...只是 15F204EA 也要有資料輸入的動作按鍵了!!
   不知到大家都如何處理這問題!!
發表於 2013-6-15 21:54:32 | 顯示全部樓層
阿乾師傅!!!...好久沒看到您的新玩具了!!!.....
這次真的完全看不懂了!!!.....
只能給您...拍拍手!!!
放煙火!!!
發表於 2013-6-15 22:01:43 | 顯示全部樓層
antlu 發表於 2013-6-15 09:05 PM static/image/common/back.gif
LEGION大:
   其實我會這樣的選擇是有原因的!! 因為你可以看出這兩個 MCU一點關係都沒有(各自獨立),主要 ...

基本上就看你要怎麼作成主從模式了,不過依你現有的模式也不可能全部重改
如果使用串列的模式,兩端都只要各有4個bit空出作,1個bit為request,1bit作接收,1bit作y/n
另1個bit作串列data,有點類似串列eeprom模式,簡易一點的就能作雙向溝通了
或是兩個mcu都使用rs232模式互連也是能用的,互相用TX和RX就能互通了,才用2個BIT而己
方法是有多種,就看那個方便順手了,
如同15F204有A/D輸入,用A/D的模式來判斷,光一個BIT就能解決那6個按鍵的輸入
現在剛在習慣C的一些寫法,在計算及字碼上是比組語簡單多了,不過在定址上反而麻煩了些
還沒上手,所以也沒辦法給比較合適建議
發表於 2013-6-15 22:43:40 | 顯示全部樓層
antlu 發表於 2013-6-15 09:05 PM static/image/common/back.gif
LEGION大:
   其實我會這樣的選擇是有原因的!! 因為你可以看出這兩個 MCU一點關係都沒有(各自獨立),主要 ...

短距離就用SPI或I2C...

長距離就用RS485把全部的阿花阿貓阿狗設備並接在一起...
您需要登錄後才可以回帖 登錄 | 立即註冊

本版積分規則

關閉

站長小叮嚀上一條 /1 下一條

禁閉室|手機版|連繫我們|痞酷網電子技術論壇

GMT+8, 2024-11-17 10:44 PM , Processed in 0.368754 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4 Licensed

© 2001-2023 Discuz! Team.