|
簡化 上次的數位控制電源使用 單一個 mcu STC15F204EA 使用 串列模式 74HC595取代 74HC573 可以由原先的 2條控制線+8條資料線 變成3條控制線 ,並採用 LEGION大的建議,使用 1A/D 取代6條按鍵控制線,仍然使用 8bit R-2R 模式....
最大問題是 A/D 讀取按鍵會有偶發的錯誤,請 大家幫忙修改 感謝!!
上方是電壓輸出 電流輸出 下方為 R-2R 輸出 最前方@ 表示輸出中...
/*有缺點 按鍵會有些誤動作 20130621 使用 2線控制6按鍵 A/D轉換 0 電壓 1 電流 2參考電壓 3 按鍵掃描 ,利用74595兩個形成 串列輸入並列 R2R 產生類比電壓值*/
#include<STC15F204EA.h>
#include<intrins.h>
sbit RS = P3^7; //LCM control
sbit RW = P3^6;
sbit EN = P3^5;
//----------------------------below----NEW---------
sbit SER = P3^4;// 74hc595 control
sbit Latch = P3^3;
sbit Clk = P3^2;
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
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
unsigned int KS;//key read 3 times data
bit Kinc;
bit Kdec;
bit Kls;
bit Krs;
bit VoI;
bit STRP;
bit Khold;
//-------------------up new------------------
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 int R,L,M,N,Q,I;//unsigned int R,M,N;//-Y?w…ó|¨uchar?′N¥uˉà?F¥ü2.5V¥H¤Uao??-è
//signed int SV,AV;//′?oa?áao3]?w???×sv=100/V ′?oa?áao??°????×av=100/V
signed int Difv;
unsigned int Mavg(unsigned char an);
void Send595(unsigned char Dat) ;
unsigned char Read (unsigned char CHA);
void DelayMs(unsigned char t);
void Send2byte(unsigned char Dat1,unsigned char Dat2);
//--------------------------------------------------------------------------------------------
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>150) //140ms update 1 time
{
TimeFlag=1; //
counter=0;
}//if(counter>70)
}
//convert 6 key to 1.on/off 2.VoI 3.inc 4.dec 5. < 6. >
// bit--on bit--inc bit--dec bit-off
void Keyscan(void)
{
KS=Read(3);//Read(3); //key scan read port3
if(KS>220) Khold=0;
if((KS<215)&&(!Khold))
{
Khold=1;
DelayMs(200);
KS=Mavg(3);
if((KS<215)&&(KS>208)) //1st key on/off press
Krs=1;
else if((KS<208)&&(KS>195))//2nd key VoI press
Kls=1;
else if((KS<195)&&(KS>175))//3rd key Inc press
Kdec=1;
else if((KS<175) &&(KS>150)) //4th key Dec press
Kinc=1;
else if((KS<150)&&(KS>100))//5th key "<" press
VoI=1;
else if(KS<100)// 6 th key ">" press
STRP=1;
}
else //key release
{ //
Khold=0;
}
}
//*******************待處理******************
void OP(bit K)//output control
{
if (K)// data op =set
{
Send2byte(Idata,Vdata);// volt & current data sent to i/o and latch
}
else //data output=0
{
// reset volt & current data sent to i/o and latch
Send2byte(0x00,0x00);
}
}
void Key_Pros (void)
{
{
if(STRP) {STRP=0;Startflag=!Startflag;}//ON/OFF
else if(VoI) {VoI=0;VoI_flag=~ VoI_flag;}// Volt or Current
else if (Kls) // shift left "<"
{
Kls=0;//-------------------------------------
if(VoI_flag)
{
Vdigt++;
if(Vdigt>2) Vdigt=0;
}
else
{
Idigt++;
if(Idigt>2) Idigt=0;
}
}
else if(Krs) //shift right ">"
{ Krs=0;//-----------------------------
if(VoI_flag)
{
Vdigt--;
if(Vdigt==255) Vdigt=2;
}
else
{
Idigt--;
if(Idigt>255) Idigt=2;
}
}
else if(Kinc)
{ Kinc=0;//------------------------
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;
}
}
else if(Kdec)
{ Kdec=0;//---------------------------
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 Send595(unsigned char Dat) //output data to D/A converter through the serial mode
{
unsigned char i;
for (i=0;i<8;i++)
{
Clk=0;
SER=Dat & 0x80;
_nop_();
Dat<<=1;
Clk=1;
_nop_();
}
Latch=0;
_nop_();
_nop_();
Latch=1;
_nop_();
_nop_();
}
void Send2byte(unsigned char Dat1,unsigned char Dat2)
{
Send595(Dat1);
Send595(Dat2);
}
/*------------------------------------------------
delay us
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{
while(--t);
}
/*------------------------------------------------
delay ms
------------------------------------------------*/
void DelayMs(unsigned char t)
{
while(t--)
{
DelayUs2x(245);
DelayUs2x(245);
}
}
/*------------------------------------------------
LCM driver
------------------------------------------------*/
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μ¥?Y 1=while loop still;
RS_CLR; //?ü¥O¥\ˉà
RW_CLR; //?g¤J
EN_SET; //¤U-°?t ¥?HI?ü|¨LO
DataPort= com; // ?ü¥O3]?w
_nop_();
EN_CLR;//
com<<=4;
EN_SET; //¤U-°?t ¥?HI?ü|¨LO
_nop_();
DataPort= com; // ?ü¥O3]?w
EN_CLR;//
DelayMs(1);
}
void LCD_Write_Data(char Data) //?ê???g¤J4bit
{
while(LCD_Check_Busy()); //|£?hμ¥?Y
RS_SET; // ?ê??3B2z
RW_CLR;// ?gao°ê§@
EN_SET; // ±ò°ê¤U?t?2μo
DataPort= Data; //?é¤J?Y-n?g¤Jao?ê??
_nop_();//?μ?á¤@-ó?é?
EN_CLR;//
Data<<=4;
EN_SET; // ±ò°ê¤U?t?2μo
DataPort= Data; //?é¤J?Y-n?g¤Jao?ê??
_nop_();//?μ?á¤@-ó?é?
EN_CLR;//
DelayMs(1);//μ1 1T MCU ¨?¥?
}
/*------------------------------------------------
2M?�??
------------------------------------------------*/
void LCD_Clear(void)
{
LCD_Write_Com(0x01);
DelayMs(5);
}
/*------------------------------------------------
?à¤J|r2?|ê¨???
------------------------------------------------*/
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|r2?¨???
------------------------------------------------*/
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);
}
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);
}
/*------------------------------------------------
initial LCM
------------------------------------------------*/
void LCD_Init(void)
{
LCD_Write_Com(0x28); /*4bit mode*/
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¥ü2M?ì*/
LCD_Write_Com(0x06); /*?F¥ü¥ú?á2??e?|?m*/
DelayMs(5);
LCD_Write_Com(0x0C); /*?F¥ü…{¤?¥ú?á?|?m*/
}
/*******************************************************************
analog input DATA read
*******************************************************************/
unsigned char Read (unsigned char CHA)
{
unsigned char AD_FIN=0; //|s‰éA/D?H???á§ó;-Y|b¨???¥~?w…ó|1?@q?h¤£ˉà±o¨ì?2?¢?@¤?ao?ò‰Tqao?F¥ü
/******¥H¤U?oADCaì?l¤?μ{§?****************************/
CHA &= 0x07; //‰u?áADCao8?a±μ¤f¤¤ao¤@?a?]0000 0111 2M0°a5|ì?^
ADC_CONTR = 0x60; //ADC?H??ao3t?×?]0XX0 0000 ¨?¤¤XX±±¨?3t?×?A?[?ú?u???u¤a???|?m?^
_nop_();
ADC_CONTR |= CHA; //‰u?áA/D…??e3q1D
_nop_();
ADC_CONTR |= 0x80; //?Q?eA/D?z??
DelayMs(1); //¨?‰r¤J?z‰í?c¨ì???w?]1ms§Y¥i?
/******¥H¤U?oADC?ù|?μ{§?****************************/
ADC_CONTR |= 0x08; //?Q?eA/D?H???]0000 1000 ¥OADCS = 1?^
_nop_();
_nop_();
_nop_();
_nop_();
while (AD_FIN ==0){ //μ¥?YA/D?H??…C§?
AD_FIN = (ADC_CONTR & 0x10); //0001 0000?ò?IA/D?H??…C§?§_
}
ADC_CONTR &= 0xE7; //1111 0111 2MADC_FLAG|ì, ?×??A/D?H??,
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<3;at++)
{
M=Read(an)+M;//analog 3 input
DelayMs(250);
}
M=M/3;
return M;
}
/******************************************************************
?F¥ü¨????H??¨????G
M=?ò‰Tqa??T-è?AN=°ò-??z‰í??a??T-è?]¥?¨ò?o2.5V?^?AR=?ò‰Tq‰r¤J-è?]?Y?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¤JoY¤à‰í¤??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‰í??a??T?]?H???^
Q=(L*2.50/N)*100; //Q=display volt data
R=((I*2.50)/(N))*100;//R=display current data 1V=1A ??10:1 ??
}
void Display_pros(void)
{
displayword[0]=' ';
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);//??¥ü|b2?¤G|?
if(Startflag) displayword[0]='@';
else 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 main(void)
{
P1M0 = 0xff; //P1.0/P1.1?G1111 1111?]°aay?^//a`?N?G§ó§?ADC3q1D?o…§|P?o’a?á‰?aoIO±μ¤f-ק??o°aay‰r¤J?C
P1M1 = 0x00; //P1.0/P1.1?G0000 0000
P1ASF=0xff; //all analog in put mode
Init_Timer0();//initial timer0
LCD_Init();
LCD_Clear();//2M?ì
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);
transfer();//do ADC & put to display
Keyscan();//read key press
Key_Pros ();// scan key and do something
}
}
|
|