{感謝原作者提供}
//STC多用下載器
//單片機用STC15W208AS,頻率為22.1M,注意單片機只有時鐘0及2
//功能有串口自動斷電下載,4路輸入電壓檢測(最大值25V),輸
//出5v及3.3V的檢測,輸出電流檢測,外接輸入電壓檢測,及單片機的電壓檢測。
//串口監控下載,如連續為0X7F的值,就說明要斷電重啟下載數據,
//串口斷電控制方式,每0.1s變一次波特率,如收到是7F的值,
//就停止變波特率,判斷是否是連接7F,如是就斷電重啟。
//4輸入的最大值為25v,電流最大值為2a
//開關的作用,短按為換頁,長按為輸出電源控制開關。
22.png (91.75 KB, 下載次數: 92)
下載附件
2018-1-25 17:26 上傳
11.png (116.54 KB, 下載次數: 97)
下載附件
2018-1-25 17:26 上傳
5.jpg (38.13 KB, 下載次數: 93)
下載附件
2018-1-25 17:18 上傳
6.jpg (39.65 KB, 下載次數: 94)
下載附件
2018-1-25 17:18 上傳
7.jpg (44.29 KB, 下載次數: 81)
下載附件
2018-1-25 17:18 上傳
8.jpg (46.28 KB, 下載次數: 87)
下載附件
2018-1-25 17:18 上傳
3.jpg (39.28 KB, 下載次數: 104)
下載附件
2018-1-25 17:18 上傳
4.jpg (38.82 KB, 下載次數: 76)
下載附件
2018-1-25 17:18 上傳
1.jpg (45.32 KB, 下載次數: 71)
下載附件
2018-1-25 17:18 上傳
2.jpg (53.76 KB, 下載次數: 94)
下載附件
2018-1-25 17:18 上傳
9.jpg (36.35 KB, 下載次數: 86)
下載附件
2018-1-25 17:18 上傳
10.jpg (46.3 KB, 下載次數: 84)
下載附件
2018-1-25 17:18 上傳
11.jpg (44.22 KB, 下載次數: 89)
下載附件
2018-1-25 17:18 上傳
33.jpg (55.88 KB, 下載次數: 70)
下載附件
2018-1-25 17:23 上傳
單片機源程序如下:
- #include <STC15W408AS.h>
- #include <intrins.h>
- #include <oled.h>
- unsigned char oldkey,keyval,jisu,rxdatvol,RSjisu,onjisu,RETjisu,kkkkjisu;
- unsigned int keyjixu;
- bit readtimekong,disppagebit,powonkong,time02s,RSPOWonkong,kkkk,time01kong;
- unsigned char STCADbit[9];
- unsigned int STCADvol[9],voldat[9];
- unsigned char tetete;
- sbit KEY1=P5^5;
- sbit LEDout=P5^4;
- sbit POWkong=P3^7;
- void delay(unsigned int t) //長延時程序,延時t毫秒,STC 1T單片機11.0592M晶振I值為648,22.1I值為1298,12MI值為705。
- {
- unsigned int i;
- while(t--)
- {
- for(i=705;i>0;i--);
- }
- }
- void delay1() //
- {
- unsigned int i;
- for(i=340;i>0;i--);
-
- }
- //以下為AD檢測
- void ADCINT()
- {
- P1M1=0xff;//AD高阻
- P1ASF=0xff;//設置 P1為AD口,根據實際設置。
- ADC_RES=0;//ad清0
- // AUXR1=0x04;//設置數據方式,低8位+高2位方式,易于運算。
- CLK_DIV=0X20;//由于408AS與204E不同,需寫成這。
- }
- unsigned int ADCwrite(unsigned char ch)
- { //由于所檢測的電壓不用快,所以采用查詢或延時法,沒用中斷法。 ch值從0-7,對應為P10-P17
- unsigned int x;
- ADC_CONTR=0x88+ch;//設置啟動 ,用慢速采集
- //查詢法。查詢是否完成AD,由于是單片機內的,如出錯單片機也出錯,所以沒做跳開處理。
- while ( !(ADC_CONTR & 0x10) );//等待A/D轉換結束(ADC_FLAG==0)
- ADC_CONTR &= 0xE7; //11100111,置ADC_FLAG=0清除結束標記, 置ADC_START=0關閉A/D 轉換
- //delay(1);//延時法。由于設置及晶振的原因,大約為20US完成過程。這里延時1MS
- x=ADC_RES*256+ADC_RESL;
- return x;
- }
- void nowtempAD()
- {//采用采集10次取平均值,整個采集時間在20MS,防止交流干擾。 每0.2S運行一次
- //0為3.3V,1為輸入1,2為輸入2,3為輸入3,4為輸入4,5為+5V,6為外接IN,7為電流,8為計算出來的單片機電壓CPU。
- unsigned char x,xx;
- unsigned int k=0;
- unsigned long y;
- bit ll=0;
- for(x=0;x<9;x++)
- {
- STCADvol[x]=0;
- }
-
-
- for(x=0;x<10;x++)//采集10次。
- {
- P1ASF=0x00;
- STCADvol[0]=ADCwrite(0)+STCADvol[0];//1.25V基準
- delay1();
- P1ASF=0xff;
- for(xx=0;xx<8;xx++)
- {
- STCADvol[xx+1]=ADCwrite(xx)+STCADvol[xx+1];
- }
- }
- //以下為計算
- for(x=0;x<9;x++)
- {
- STCADvol[x]=STCADvol[x]/10;
- if(STCADvol[x]>1000)
- {
- STCADbit[x]=1;
- }
- else
- {
- STCADbit[x]=0;
- }
- }
- //0為3.3V,1為輸入1,2為輸入2,3為輸入3,4為輸入4,5為+5V,6為外接IN,7為電流,8為計算出來的單片機電壓CPU。
- //以下的125等值是用于修改的。如電壓與實測不同,需修改這個值。
- y=(long)1024*125/STCADvol[0];//STCADvol[0]為基準
- voldat[8]=y;//8為計算出來的單片機電壓CPU。
- y=(long)STCADvol[1]*124/STCADvol[0];
- voldat[0]=y;////0為3.3V,
- y=(long)STCADvol[2]*685/STCADvol[0];
- voldat[1]=y;//1為輸入1,
- y=(long)STCADvol[3]*703/STCADvol[0];
- voldat[2]=y;//2為輸入2,
- y=(long)STCADvol[4]*706/STCADvol[0];
- voldat[3]=y;//3為輸入3,
- y=(long)STCADvol[5]*702.5/STCADvol[0];
- voldat[4]=y;//4為輸入4,
- y=(long)STCADvol[6]*248/STCADvol[0];
- voldat[5]=y;//5為+5V,
- y=(long)STCADvol[7]*53/STCADvol[0];
- voldat[6]=y;//6為外接IN,
- y=(long)STCADvol[8]*59/STCADvol[0];
- voldat[7]=y;//7為電流,
- }
- void disp0(bit all)
- {
- if(all==1)
- {
- OLED_Clear();
-
- OLED_ShowCHinese(4,0,0);
- OLED_ShowCHinese(20,0,1);
- OLED_ShowCHinese(36,0,2);
- OLED_ShowChar(52,0,13);
- OLED_ShowChar(60,0,14);
- OLED_ShowChar(68,0,15);
- OLED_ShowCHinese(76,0,3);
- OLED_ShowCHinese(92,0,4);
- OLED_ShowCHinese(108,0,5);
-
- //+5V:5.05V
- OLED_ShowChar(0,2,18);
- OLED_ShowChar(12,2,5);
- OLED_ShowChar(24,2,19);
- OLED_ShowChar(32,2,10);
- OLED_ShowChar(72,2,19);
- //3.3V:3.30V
- OLED_ShowChar(0,4,3);
- OLED_ShowChar(8,4,20);
- OLED_ShowChar(16,4,3);
- OLED_ShowChar(24,4,19);
- OLED_ShowChar(32,4,10);
- OLED_ShowChar(72,4,19);
- //電流:0.50A
- OLED_ShowCHinese(0,6,6);
- OLED_ShowCHinese(16,6,8);
- OLED_ShowChar(32,6,10);
- OLED_ShowChar(72,6,21);
- //IN:12.5V
- OLED_ShowChar8x6(98,2,17);
- OLED_ShowChar8x6(104,2,18);
- OLED_ShowChar8x6(110,2,16);
- OLED_ShowChar(119,3,19);
- //CPU:5.05V
- OLED_ShowChar8x6(95,5,19);
- OLED_ShowChar8x6(101,5,20);
- OLED_ShowChar8x6(107,5,21);
- OLED_ShowChar8x6(113,5,16);
- OLED_ShowChar(119,6,19);
- }
- //0為3.3V,1為輸入1,2為輸入2,3為輸入3,4為輸入4,5為+5V,6為外接IN,7為電流,8為計算出來的單片機電壓CPU。
- //+5V值
- if(STCADbit[6]==1)
- {//OL
- OLED_ShowChar(40,2,22);
- OLED_ShowChar(48,2,23);
- OLED_ShowChar(56,2,11);
- OLED_ShowChar(64,2,11);
- }
- else
- {
- OLED_ShowChar(40,2,voldat[5]/100);
- OLED_ShowChar(48,2,20);
- OLED_ShowChar(56,2,voldat[5]%100/10);
- OLED_ShowChar(64,2,voldat[5]%10);
- }
- //3.3V值
- if(STCADbit[1]==1)
- {
- OLED_ShowChar(40,4,22);
- OLED_ShowChar(48,4,23);
- OLED_ShowChar(56,4,11);
- OLED_ShowChar(64,4,11);
- }
- else
- {
- OLED_ShowChar(40,4,voldat[0]/100);
- OLED_ShowChar(48,4,20);
- OLED_ShowChar(56,4,voldat[0]%100/10);
- OLED_ShowChar(64,4,voldat[0]%10);
- }
- //電流值
- if(STCADbit[8]==1)
- {
- OLED_ShowChar(40,6,22);
- OLED_ShowChar(48,6,23);
- OLED_ShowChar(56,6,11);
- OLED_ShowChar(64,6,11);
- }
- else
- {
- OLED_ShowChar(40,6,voldat[7]/100);
- OLED_ShowChar(48,6,20);
- OLED_ShowChar(56,6,voldat[7]%100/10);
- OLED_ShowChar(64,6,voldat[7]%10);
- }
- //IN值
- if(STCADbit[7]==1)
- {
- OLED_ShowChar(88,3,22);
- OLED_ShowChar(96,3,23);
- OLED_ShowChar(104,3,11);
- OLED_ShowChar(111,3,11);
- }
- else
- {
- OLED_ShowChar(88,3,voldat[6]/100);
- OLED_ShowChar(96,3,voldat[6]%100/10);
- OLED_ShowChar(104,3,20);
- OLED_ShowChar(111,3,voldat[5]%10);
- }
- //CPU值
- OLED_ShowChar(88,6,voldat[8]/100);
- OLED_ShowChar(96,6,20);
- OLED_ShowChar(103,6,voldat[8]%100/10);
- OLED_ShowChar(111,6,voldat[8]%10);
-
-
- }
- void disp1(bit all)
- {
- if(all==1)
- {
- OLED_Clear();
-
- //電壓1:12.55V
-
- OLED_ShowCHinese(0,0,6);
- OLED_ShowCHinese(16,0,7);
- OLED_ShowChar(32,0,1);
- OLED_ShowChar(40,0,10);
- OLED_ShowChar(68,0,20);
- OLED_ShowChar(92,0,19);
- //電壓2:12.55V
- OLED_ShowCHinese(0,2,6);
- OLED_ShowCHinese(16,2,7);
- OLED_ShowChar(32,2,2);
- OLED_ShowChar(40,2,10);
- OLED_ShowChar(68,2,20);
- OLED_ShowChar(92,2,19);
- //電壓3:12.55V
- OLED_ShowCHinese(0,4,6);
- OLED_ShowCHinese(16,4,7);
- OLED_ShowChar(32,4,3);
- OLED_ShowChar(40,4,10);
- OLED_ShowChar(68,4,20);
- OLED_ShowChar(92,4,19);
- //電壓4:12.55V
- OLED_ShowCHinese(0,6,6);
- OLED_ShowCHinese(16,6,7);
- OLED_ShowChar(32,6,4);
- OLED_ShowChar(40,6,10);
- OLED_ShowChar(68,6,20);
- OLED_ShowChar(92,6,19);
- }
- //0為3.3V,1為輸入1,2為輸入2,3為輸入3,4為輸入4,5為+5V,6為外接IN,7為電流,8為計算出來的單片機電壓CPU。
- //電壓1值
- if(STCADbit[2]==1)
- {
- OLED_ShowChar(52,0,22);
- OLED_ShowChar(60,0,23);
- OLED_ShowChar(76,0,11);
- OLED_ShowChar(84,0,11);
- }
- else
- {
- OLED_ShowChar(52,0,voldat[1]/1000);
- OLED_ShowChar(60,0,voldat[1]%1000/100);
- OLED_ShowChar(76,0,voldat[1]%100/10);
- OLED_ShowChar(84,0,voldat[1]%10);
- }
- //電壓2值
- if(STCADbit[3]==1)
- {
- OLED_ShowChar(52,2,22);
- OLED_ShowChar(60,2,23);
- OLED_ShowChar(76,2,11);
- OLED_ShowChar(84,2,11);
- }
- else
- {
- OLED_ShowChar(52,2,voldat[2]/1000);
- OLED_ShowChar(60,2,voldat[2]%1000/100);
- OLED_ShowChar(76,2,voldat[2]%100/10);
- OLED_ShowChar(84,2,voldat[2]%10);
- }
- //電壓3值
- if(STCADbit[4]==1)
- {
- OLED_ShowChar(52,4,22);
- OLED_ShowChar(60,4,23);
- OLED_ShowChar(76,4,11);
- OLED_ShowChar(84,4,11);
- }
- else
- {
- OLED_ShowChar(52,4,voldat[3]/1000);
- OLED_ShowChar(60,4,voldat[3]%1000/100);
- OLED_ShowChar(76,4,voldat[3]%100/10);
- OLED_ShowChar(84,4,voldat[3]%10);
- }
- //電壓4值
- if(STCADbit[5]==1)
- {
- OLED_ShowChar(52,6,22);
- OLED_ShowChar(60,6,23);
- OLED_ShowChar(76,6,11);
- OLED_ShowChar(84,6,11);
- }
- else
- {
- OLED_ShowChar(52,6,voldat[4]/1000);
- OLED_ShowChar(60,6,voldat[4]%1000/100);
- OLED_ShowChar(76,6,voldat[4]%100/10);
- OLED_ShowChar(84,6,voldat[4]%10);
- }
- }
- //***********************鍵盤掃描子程序。******************
- //*********************************************************
- unsigned char keyboard()//鍵盤掃描
- {
- unsigned char keyboardj;
- keyboardj=0;
- if(KEY1==0)
- {
- delay(10);
- if(KEY1==0)
- {
- keyboardj=1;
- }
- }
-
- return keyboardj;
- }
- //************鍵盤控制子程序***************
- //
- //
- //******************************************
- void keykong()//主要功能是
- {
- unsigned char keyyy;
- keyyy=keyboard();
-
- if (keyyy!=oldkey)
- {
- if(keyyy==0)//
- {
- if(keyjixu>0)
- {
- if(keyjixu<80)
- {
- if(oldkey==1)
- {
- keyval=1;
- }
- }
- else
- {
- //keyval=11;
- keyjixu=0;
- }
- }
- else
- {
- keyval=0;
- keyjixu=0;
- }
- }
-
- }
- oldkey=keyyy;
- if(keyyy==1)//
- {
- keyjixu++;
- if(keyjixu==80)keyval=11;
- }
- //鍵盤處理完成。
- //以下為功能子程序
- if(keyval==1)
- {
- keyval=0;//這步必須的,清鍵值。
- keyjixu=0;//清計數值,這兩步是必要的。
- //短按翻頁
- if(disppagebit==1)
- {
- disppagebit=0;
- disp0(1);
- }
- else
- {
- disppagebit=1;
- disp1(1);
- }
-
-
- }
- if(keyval==11)
- {//
- keyval=0;//這步必須的,清鍵值。
- //keyjixu=0;//清計數值,這兩步是必要的。
- //長按開關電源
- if(powonkong==0)
- {
- powonkong=1;//開總電源
- POWkong=0;//電源控制
- }
- else
- {
- powonkong=0;//開總電源
- POWkong=1;//電源控制
- }
- }
- }
- void Timer0Init(void) //2毫秒@22.1184MHz
- {
- AUXR |= 0x80; //定時器時鐘1T模式
- TMOD &= 0xF0; //設置定時器模式
- TMOD |= 0x01; //設置定時器模式
- TL0 = 0x33; //設置定時初值
- TH0 = 0x53; //設置定時初值
- TF0 = 0; //清除TF0標志
- TR0 = 1; //定時器0開始計時
- ET0=1; //啟動T定中斷
-
- //IT1=1;//置中斷1為脈沖低電平觸發。
- //EX1=1;//開中斷1
-
- EA=1; //啟動總中斷
- }
- /*void rs1_232tx(unsigned char txdata)
- {
- SBUF=txdata;//把數據傳給串口寄存器SBUF。
- while(!TI);//檢測是否發完。
- TI=0;//重置初值。
- }*/
- void UartInit(void) //19200bps@22.1184MHz
- {
- SCON = 0x50; //8位數據,可變波特率
- AUXR |= 0x01; //串口1選擇定時器2為波特率發生器
- AUXR |= 0x04; //定時器2時鐘為Fosc,即1T
- T2L = 0xE0; //設定定時初值
- T2H = 0xFE; //設定定時初值
- AUXR |= 0x10; //啟動定時器2
-
- ES=1;//開中斷
- }
- void UartInit1()//這個是變化的串口參數
- {
- ES=0;//關串口中斷
- RETjisu=0;
- onjisu=0;
- rxdatvol=0;
- //OLED_ShowChar(0,0,RSjisu);
- //rs1_232tx(RSjisu);
- switch(RSjisu)
- {
- case 0:
- T2L = 0x00; //設定定時初值//1200bps@22.1184MHz
- T2H = 0xEE; //設定定時初值
- break;
- case 1:
- T2L = 0x00; //設定定時初值//2400bps@22.1184MHz
- T2H = 0xF7; //設定定時初值
- break;
- case 2:
- T2L = 0x80; //設定定時初值//4800bps@22.1184MHz
- T2H = 0xFB; //設定定時初值
- break;
- case 3:
- T2L = 0xC0; //設定定時初值//9600bps@22.1184MHz
- T2H = 0xFD; //設定定時初值
- break;
- case 4:
- T2L = 0x80; //設定定時初值//14400bps@22.1184MHz
- T2H = 0xFE; //設定定時初值
- break;
- case 5:
- T2L = 0xE0; //設定定時初值//19200bps@22.1184MHz
- T2H = 0xFE; //設定定時初值
- break;
- case 6:
- T2L = 0x40; //設定定時初值//28800bps@22.1184MHz
- T2H = 0xFF; //設定定時初值
- break;
- case 7:
- T2L = 0x70; //設定定時初值//38400bps@22.1184MHz
- T2H = 0xFF; //設定定時初值
- break;
- case 8:
- T2L = 0xA0; //設定定時初值//57600bps@22.1184MHz
- T2H = 0xFF; //設定定時初值
- break;
- case 9:
- T2L = 0xD0; //設定定時初值//115200bps@22.1184MHz
- T2H = 0xFF; //設定定時初值
- break;
- }
- RSjisu++;
- if(RSjisu>9)RSjisu=0;
- delay(20);
- ES=1;//開中斷
- }
- void main()
- {
- P5M0=0x10;//P54推換
- Timer0Init();
- UartInit();
- OLED_Init();
- ADCINT();
- WDT_CONTR=0X3d;//開看門狗,由于是長時間工作,防止死機。2S內喂狗一次。
- AUXR1=0x40;//串口轉P3637
- disp0(1);
- disppagebit=0;
- powonkong=1;//開總電源
- POWkong=0;//電源控制
- while(1)
- {
- WDT_CONTR=0X3d;//開看門狗,由于是長時間工作,防止死機。2S內喂狗一次。
- keykong();
- if(readtimekong==1)
- {
- nowtempAD();
- if(disppagebit==0)
- {
- disp0(0);//刷新
-
- }
- else
- {
- disp1(0);
- }
- //if(powonkong==1)
- //{//當總控為開,LED亮,如串口收到0x7f,就閃
- if(time02s==1&&rxdatvol==0x7f)//當收到7F時,表示下載,閃,
- {
- LEDout=0;
- }
- else
- {
- LEDout=1;
- }
- // }
- //else
- //{
- // LEDout=0;
- // }
-
- if(RSPOWonkong==1)
- {//當收到重啟控制時,判斷當前是不是處于總電源開,如是開就啟動重啟
- if(powonkong==1)
- {//整個過程大約需1.5s
- RETjisu++;
- if(RETjisu==2)POWkong=1;//關電源控制
- if(RETjisu==4)POWkong=0;//開電源控制
- if(RETjisu==8)
- {
- RSPOWonkong=0;//清控制值
- RETjisu=0;
- onjisu=0;
- }
- }
-
-
- }
-
-
- readtimekong=0;
- }
- if(time01kong==1)
- {
- if(kkkk==1)
- {
- kkkkjisu++;
- if(kkkkjisu>3)
- {
- kkkk=0;
- kkkkjisu=0;
- }
- }
- else
- {
- UartInit1();
- }
- time01kong=0;
- }
-
- }
- }
- void tt0(void) interrupt 1
- {//2毫秒@22.1184MHz
- //200MS數據,
-
- TL0 = 0x33; //設置定時初值
- TH0 = 0x53; //設置定時初值
- jisu++;
- if(jisu==50)time01kong=1;
- if(jisu>=100) //0.2S
- {
- jisu=0;
- readtimekong=1;
- time01kong=1;
- time02s=~time02s;
- }
- }
- void comm1(void) interrupt 4
- { //串口1中斷 控接收協議:2B引導碼FF FE,開關值及左右轉值(加1為0x01,減10x02,短按0x04,長按0x08)。
- //注意清空RSzhuantai值,防止接收到非法數據不返回。
- if(RI)
- {
-
- RI=0; //rs1_232tx(SBUF);
- rxdatvol=SBUF;
- if(rxdatvol==0x7f)
- {
- kkkk=1;
- onjisu++;
- if(onjisu>20)
- {
- RSPOWonkong=1;//連接接收20次就重啟
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
0.png (47.99 KB, 下載次數: 88)
下載附件
2018-1-25 17:38 上傳
所有資料51hei提供下載(原理圖+pcb+源碼):
DIY帶電壓電流表的多功能STC免冷啟動自動下載器.zip
(593.47 KB, 下載次數: 306)
2018-1-25 17:32 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|