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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4749|回復: 20
收起左側

大神們求助,我是小白,出現問題如下

[復制鏈接]
ID:221124 發表于 2017-7-20 16:53 | 顯示全部樓層 |閱讀模式
#include <reg52.h>
#include <intrins.h>             
#define uchar unsigned char
#define uint  unsigned int
#define ADC_FLAG      0X10
#define M     40

/*****************************************
功能定義
*****************************************/
sbit lockA                =        P3^2;       //
sbit lockB          =        P3^3;       //

sbit Key_0                =        P2^0;       //Key_0
sbit Key_1                =        P2^1;       //Key_1
sbit Key_2                =        P2^2;       //Key_2
sbit Key_3                =        P2^3;       //Key_3

uchar PWM = 230;
uchar channel=0;                              //ADC采樣第一通道
uint  CurrentA;             //設定A輸出電流
uint  CurrentB;             //設定B輸出電流
uint  OUT_voltage;                      //輸出電壓                
uint  OUT_Current;          //輸出總電流
uchar KEY_VALUE = 5;
uchar X=1;
uchar Y=1;
uchar site  = 12;
float SUM1, SUM2, SUM3 , I3;
uchar T1 = 0;
uint  protect_i ;

xdata uint U1,I1,I2;
xdata float PI = 3.5;
xdata uint I1_VALUE[M] , I2_VALUE[M] , U1_VALUE[M] ;

//data 加強抗干擾能力
data bit  Charge = 0;
data bit  ADC_ready=0;                   //ADC完畢
data bit  flag1 = 0;
data bit  flag2 = 0;
data bit  k=0;
data bit  Release = 0;
data bit  protect = 0;            //過流保護

//函數說明: 延時程序
void delay(uchar t)
{
        uint j;
        uchar i;
        for(i=0;i<t;i++)
                for(j=0;j<1000;j++);
}

//1602液晶
sbit RS = P2^4;               
sbit RW = P2^5;
sbit E  = P2^6;

//短延時
void delay5ms()   
{
    uchar i,v,k;
    for(i=1;i>0;i--)
        for(v=168;v>0;v--)
            for(k=22;k>0;k--);
}

//寫指令
void lcd_Write_com(uchar com)         
{
        RS=0;                        //定義指令寄存器
        RW=0;                                    //寫允許
        P0=com;                                              //寫指令
        delay5ms();        E=1;                  //片選端上拉
        delay5ms();        E=0;                  //下降沿鎖存
}

//寫數據
void lcd_write_date(uchar date)       
{
        RS=1;                                           //定義數據寄存器
        RW=0;                                           //寫允許
        P0=date;                                 //寫數據
        delay5ms();        E=1; //片選端上拉
        delay5ms();        E=0; //下降沿鎖存
}

//顯示程序
void dis_lcd1602(uchar x,uchar y,uchar dat)
{
        uchar add;
        if(y==1)         add=(0x80+x);
        if(y==2)         add=(0xc0+x);
        lcd_Write_com(add);                //寫指令
        lcd_write_date(dat);        //寫數據
}  

//液晶初始化
void lcd1602_init()
{
        lcd_Write_com(0x38);        //設置8位格式,2行,5*7
        lcd_Write_com(0x01);        //清屏
        lcd_Write_com(0x0C);        //整體顯示,關光標,不閃爍
        lcd_Write_com(0x06);        //設定輸入方式,增量不移位
        lcd_Write_com(0x80);        //初始坐標
}

//液晶顯示漢字程序
void hz_lcdDis(uchar x,uchar y,uchar *p) //漢字顯示
{
   uchar i=0,temp;
   if(x)temp = 0x40;   else temp = 0;
   for(i=y;*p!='\0';i++,p++)
   {
                lcd_Write_com(i|0x80+temp);
                lcd_write_date(*p);
                delay5ms();                         
   }
}

//液晶顯示數字程序
void  num_lcdDis(uchar X,uchar Y,uint num,uchar n)       
{
        uint i=0,temp,hang;   
        n +=1;
           if(X)hang = 0x40;else hang = 0;
           for(i=(n-1);i>0;i--)
    {           
                  lcd_Write_com((i+Y-1)|0x80+hang);          //從個位開始顯示
                  temp = num%10+0x30;
                  lcd_write_date(temp);       
                 delay5ms();
                  num/=10;                                         
        }       
}

//函數說明: 平均濾波函數
#define N 50
uint Filter(uint adc_data)
{
        uint value=0;
        uchar count,count_ADC;
        for(count=0;count<N;count++)
        {
                for(count_ADC=0;count_ADC<3;count_ADC++)
                {
                        while(!ADC_ready){}
                        ADC_ready=0;
                }
                value+=adc_data;          
        }
        return (value);
}

//函數說明: 按鍵程序
//開關按鍵
void Key_0_()
{
        if(Charge==0) {        lockA=0;lockB=0; hz_lcdDis(0,8,"K");num_lcdDis(0,11,X,2);num_lcdDis(0,14,Y,2);} //0有效
        else          { lockA=1;lockB=1; hz_lcdDis(0,8,"G");num_lcdDis(0,11,X,2);num_lcdDis(0,14,Y,2);} //1有效
        Charge=~Charge;
}

//函數說明:按鍵程序
//調整光標位置
void Key_1_()
{
        lockA=1;
        lockB=1;
        flag1  = 1;
        flag2  = 1;
        hz_lcdDis(0,8,"G");
        if(k) { site = 14;  hz_lcdDis(0,14," _");num_lcdDis(0,11,X,2); }
        else  { site = 12;  hz_lcdDis(0,11," _");num_lcdDis(0,14,Y,2); }
        k =~k;
}
         
//函數說明: 按鍵程序
//
void Key_2_()
{
        Charge = 0;
        lockA=1;
        lockB=1;
        hz_lcdDis(0,8,"G");
        if((site == 12)&&(X < 255))            { ++X;         num_lcdDis(0,11,X,2);}
        else if((site==14)&&(Y < 255))         { ++Y;         num_lcdDis(0,14,Y,2);}
}

//函數說明: 按鍵程序
//任意比例設定-
void Key_3_()
{
        flag1  = 1;
        flag2  = 1;
        Charge = 0;
        lockA=1;
        lockB=1;
        hz_lcdDis(0,8,"G");
        if((site == 12)&&(X > 0 ))            { --X;         num_lcdDis(0,11,X,2);}
        else if((site==14)&&(Y > 0))          { --Y;         num_lcdDis(0,14,Y,2);}
}

//按鍵掃描
void key_scan()
{
        uchar temp;
        temp = P2&0x0F;
        if(temp != 0x0F)
        {
                delay(10);
                temp = P2&0x0F;
                if(temp!= 0x0F)
                {
                        Release = 1;
                        switch(temp)
                        {
                                case 0x0E: KEY_VALUE = 0;        break;        //20
                                case 0x0D: KEY_VALUE = 1;        break;        //21
                                case 0x0B: KEY_VALUE = 2; break;        //22
                                case 0x07: KEY_VALUE = 3;        break;        //23
                                default:   KEY_VALUE = 4; break;
                        }
                }
        }
        else Release = 0;
               
        if( Release ==0 )
        {
                switch( KEY_VALUE )
                {
                        case 0: Key_0_(); KEY_VALUE = 4; break;
                        case 1: Key_1_(); KEY_VALUE = 4; break;
                        case 2: Key_2_(); KEY_VALUE = 4; break;
                        case 3: Key_3_(); KEY_VALUE = 4; break;
                        default:          break;
                }
        }
}

//函數說明: PWM初始化
void init_pwm()
{
  CCON = 0;
        CL = 0;
        CH = 0;
        CMOD = 0X08;          //0X08:43KHZ // 0X02,22KHZ // 0X0A,10KHZ //
        CCAPM1        =0x42;        //8位PWM輸出,無中斷
        CCAP1L         =CCAP1H = 230;//初始化pwm輸出的占空比  上電默認2A 電流值對應電壓值進行換算即可
        CR=1;
}

//函數說明: 中斷 始化函數
void InitADC()
{
        P1M1=0x27;          //0x00100111
        P1M0=0x00;
        P1ASF=0X27;                      //選擇ADC通道0125
        ADC_RES=0;
        ADC_CONTR=0X88;                   //1110 0000           E8 開電源,最高速
        EA=1;
        EADC=1;
}

void DISPLAY(void)
{
        if(T1 < M)
                        {
                                I1_VALUE[T1] = I1;
                                SUM1 += I1_VALUE[T1];
                               
                                I2_VALUE[T1] = I2;
                                SUM2 += I2_VALUE[T1];
                               
                                U1_VALUE[T1] = U1;
                                SUM3 += U1_VALUE[T1];
                               
                                T1++;
                                if( T1 >= M)
                                {
                                        T1 = 0 ;
                                        SUM1 /= M;
                                        SUM2 /= M;
                                        SUM3 /= M;
                                       
                                        if(SUM1 > 2) SUM1 += 1;       
                                        if(SUM2 > 2) SUM2 += 1;       

                                       
                                        num_lcdDis(1,11,(uint)(SUM3)/10,2);
                                        num_lcdDis(1,14,(uint)SUM3%10,1);       

                                        num_lcdDis(0,3,(uint)SUM1/100,1);
                                        num_lcdDis(0,5,(uint)SUM1%100,2);
                                        num_lcdDis(1,3,(uint)SUM2/100,1);
                                        num_lcdDis(1,5,(uint)SUM2%100,2);
                               
                                        SUM1 = 0;
                                        SUM2 = 0;
                                        SUM3 = 0;
                                }       
                        }
}

void PI_calculate(void)
{
                        if(Charge == 1)              //Charge 模式下進行自動調整
                {
                        if((float)I1 > ((float)X/(float)Y)*I2 ) PI += 0.1 ;
                        else               PI -= 0.1 ;
                        CCAP1L         = CCAP1H = PWM;
                       
                        if((flag1 == 1)&&(flag2 == 1)) //進入比例模式 比例最大 2:0.5即4:1 最小0.5:2 即1:4
                        {
                                PWM = 255-(uint)((I3*X/(X+Y)-PI)*256/500+0.5); //255-(uint)((I3*X/(X+Y))*255/500+0.5); //電流值等于電壓值 I3*X/(X+Y)/100/5*255 1為調節量
                        }
                        else if((flag1==0)&&(flag2==0)&&(I3 < 200))     //2A切換點
                        {       
                                PWM = 230;                                    //切換到0.5A模式
                        }                             
                        else if((flag1==0)&&(flag2==0)&&(I3 > 200))
                        {       
                                PWM = 153;                               //切換到2A模式
                        }     
                }       
}

void Protect_recover(void)
{       
                if((protect == 1)&&(protect_i++>500))     //延時自恢復 大概半分鐘S
                {
                        lockA=0; lockB=0;  
                        protect_i = 0;
                        protect = 0;
                        hz_lcdDis(0,8,"K");
                }
}
//函數說明: 主函數
void main(void)
{
        lockA=1;
        lockB=1;
        lcd1602_init();
        hz_lcdDis(0,4,"Welcome!");
        init_pwm();
        InitADC();
        delay(250);       
        EA=1;                 //開總中斷
        lcd_Write_com(0x01);        //清屏
        hz_lcdDis(0,0,"CA= .  A S= X: Y ");
        hz_lcdDis(1,0,"CB= .  A U=  . V");
        while(1)              //主循環
        {               
                EA = 1;
                I1=Filter(CurrentA)/99;          //輸出實際電流 Filter()=0.02Ω*I*放大倍數*1023/5v*50=I*放大倍數*204.6,為了顯示放大100倍處理 =102.3
                I2=Filter(CurrentB)/100;          //輸出實際電流 Filter()=0.02Ω*I*放大倍數*1023/5v*50=I*放大倍數*204.6,為了顯示放大100倍處理 =102.3                      //總電流
                U1=Filter(OUT_voltage)/255;              //輸入電壓  1:3采樣電阻 ,Filter()*5V*4/(50*1023) 同時為了小數轉成uint時,需要進行*10,使真實位變小數位 =255.7;顯示數值濾波處理
               
                EA = 0;
                I3=I1+I2;   
                if(I3 > 450)                      //4.5A保護
                {        lockA=1; lockB=1; hz_lcdDis(0,8,"P");protect = 1;}
                Protect_recover();                //自恢復時間在半分鐘
                PI_calculate();
                DISPLAY();
                key_scan();
        }
}


//函數說明: ADC中斷
//實現功能:執行ADC采集并做電壓和電流的調整。
void ADC_interrupt()interrupt 5                  //ADC轉換完后ADC_FLAG由硬件自動置位,須由軟件清零
{                               
        uint ADC_value;                                            //ADC轉換結果        10位
        ADC_value=(ADC_RES<<2)+ADC_RESL;        //ADC_value=(ADC_RES<<2)+ADC_RESL;
        switch(channel)
        {
                case 0:        CurrentA=ADC_value;       
                                channel=1;                                       
                                break;
                case 1:        CurrentB=ADC_value;
                                channel=5;               
                                break;                               
                case 5:OUT_voltage=ADC_value;
                                channel=0;
                                break;                                       
                default:break;
        }
        ADC_CONTR&=!ADC_FLAG;                                 //清除 ADCflag
        ADC_CONTR=0xE8|channel;
        ADC_ready=1;               
}
compiling 2011.c...
2011.C(30): error C231: 'T1': redefinition
2011.C(30): error C231: 'T1': redefinition
2011.C(245): error C202: 'CCON': undefined identifier
2011.C(246): error C202: 'CL': undefined identifier
2011.C(247): error C202: 'CH': undefined identifier
2011.C(248): error C202: 'CMOD': undefined identifier
2011.C(249): error C202: 'CCAPM1': undefined identifier
2011.C(250): error C202: 'CCAP1L': undefined identifier
2011.C(251): error C202: 'CR': undefined identifier
2011.C(257): error C202: 'P1M1': undefined identifier
2011.C(258): error C202: 'P1M0': undefined identifier
2011.C(259): error C202: 'P1ASF': undefined identifier
2011.C(260): error C202: 'ADC_RES': undefined identifier
2011.C(261): error C202: 'ADC_CONTR': undefined identifier
2011.C(263): error C202: 'EADC': undefined identifier
2011.C(312): error C202: 'CCAP1L': undefined identifier
2011.C(377): error C202: 'ADC_RES': undefined identifier
2011.C(391): error C202: 'ADC_CONTR': undefined identifier
2011.C(392): error C202: 'ADC_CONTR': undefined identifier
2011.c - 19 Error(s), 0 Warning(s).
回復

使用道具 舉報

ID:144941 發表于 2017-7-20 17:16 | 顯示全部樓層
T1與寄存器重復定義了,還有些寄存器沒有定義,看看引用頭文件是否正確
回復

使用道具 舉報

ID:221124 發表于 2017-7-20 17:39 | 顯示全部樓層
whble 發表于 2017-7-20 17:16
T1與寄存器重復定義了,還有些寄存器沒有定義,看看引用頭文件是否正確

如何改
回復

使用道具 舉報

ID:144941 發表于 2017-7-20 17:57 | 顯示全部樓層
2011.C(245): error C202: 'CCON': undefined identifier
2011.C(246): error C202: 'CL': undefined identifier
2011.C(247): error C202: 'CH': undefined identifier
2011.C(248): error C202: 'CMOD': undefined identifier
2011.C(249): error C202: 'CCAPM1': undefined identifier
2011.C(250): error C202: 'CCAP1L': undefined identifier
2011.C(251): error C202: 'CR': undefined identifier
2011.C(257): error C202: 'P1M1': undefined identifier
2011.C(258): error C202: 'P1M0': undefined identifier
2011.C(259): error C202: 'P1ASF': undefined identifier
2011.C(260): error C202: 'ADC_RES': undefined identifier
2011.C(261): error C202: 'ADC_CONTR': undefined identifier
2011.C(263): error C202: 'EADC': undefined identifier
2011.C(312): error C202: 'CCAP1L': undefined identifier
2011.C(377): error C202: 'ADC_RES': undefined identifier
2011.C(391): error C202: 'ADC_CONTR': undefined identifier
2011.C(392): error C202: 'ADC_CONTR': undefined identifier

上面這些要定義,沒有定義不能使用

2011.C(30): error C231: 'T1': redefinition
2011.C(30): error C231: 'T1': redefinition與#include <reg52.h>里面一個寄存器定義重復 換個比如A1什么的
回復

使用道具 舉報

ID:213173 發表于 2017-7-20 18:13 | 顯示全部樓層
全部錯誤都是相應寄存器沒有定義,或者說是頭文件用錯。#include <STC15F2K60S2.H>
1個警告是:void dis_lcd1602(uchar x,uchar y,uchar dat) 沒有引用
回復

使用道具 舉報

ID:221156 發表于 2017-7-20 18:34 | 顯示全部樓層
頭文件未引用,重新檢查一下。
回復

使用道具 舉報

ID:221124 發表于 2017-7-22 17:28 | 顯示全部樓層
改完之后出現這樣的問題如何弄   求助啊
Build target 'Target 1'
linking...
BL51 BANKED LINKER/LOCATER V6.22 - SN: Eval Version
COPYRIGHT KEIL ELEKTRONIK GmbH 1987 - 2009
"STARTUP.obj",
"6.obj"
TO "6"
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
    SEGMENT: ?PR?_DIS_LCD1602?6
******************************************************************************
* RESTRICTED VERSION WITH 0800H BYTE CODE SIZE LIMIT; USED: 08DBH BYTE (110%) *
******************************************************************************
Program Size: data=74.7 xdata=250 code=3502
LINK/LOCATE RUN COMPLETE.  1 WARNING(S),  0 ERROR(S)
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
    SEGMENT: ?PR?_DIS_LCD1602?6
*** FATAL ERROR L250: CODE SIZE LIMIT IN RESTRICTED VERSION EXCEEDED
    MODULE:  D:\KEIL4\C51\LIB\C51S.LIB (-----)
    LIMIT:   0800H BYTES
Target not created
回復

使用道具 舉報

ID:221124 發表于 2017-7-22 17:37 | 顯示全部樓層
whble 發表于 2017-7-20 17:57
2011.C(245): error C202: 'CCON': undefined identifier
2011.C(246): error C202: 'CL': undefined iden ...

改完變成這樣了,問題如下,求助啊,急
Build target 'Target 1'
linking...
BL51 BANKED LINKER/LOCATER V6.22 - SN: Eval Version
COPYRIGHT KEIL ELEKTRONIK GmbH 1987 - 2009
"STARTUP.obj",
"6.obj"
TO "6"
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
    SEGMENT: ?PR?_DIS_LCD1602?6
******************************************************************************
* RESTRICTED VERSION WITH 0800H BYTE CODE SIZE LIMIT; USED: 08DBH BYTE (110%) *
******************************************************************************
Program Size: data=74.7 xdata=250 code=3502
LINK/LOCATE RUN COMPLETE.  1 WARNING(S),  0 ERROR(S)
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
    SEGMENT: ?PR?_DIS_LCD1602?6
*** FATAL ERROR L250: CODE SIZE LIMIT IN RESTRICTED VERSION EXCEEDED
    MODULE:  D:\KEIL4\C51\LIB\C51S.LIB (-----)
    LIMIT:   0800H BYTES
Target not created
回復

使用道具 舉報

ID:155507 發表于 2017-7-22 19:44 | 顯示全部樓層
你的軟件沒有破解,請按以下步驟破解
如何破解Keil
若不破解Keil,那么我們程序容量會被限制在2k內。若破解,代碼的容量將不被限制。
第一步:打開Keil編譯器
第二步:單擊【File】
第三步:單擊【License Management】
第四步:復制License Management界面中的CID號
第五步:打開注冊機
第六步:將剛復制的CID號粘貼到注冊機的CID號框中
第七步:點擊【Generate】將會生成激活碼
第八步:把生成的激活碼復制粘貼到KEIL的New License ID Code(LIC)里
第九步:然后點擊【Add Lic】
、  注冊完成之后,會在License Management界面中間的PK51的后面添加使用截止日期到2020,說明已經成功破解了。
注意:若破解的時候出現:
ERROR R206: NO REGISTRY ACCESS, ADMINISTRATION RIGHTS REQUIRED
【翻譯】錯誤R206:沒有注冊使用權,需要管理員權限。
解決方法:
用管理員的身份運行Keil這個編譯器,然后再按上述的方法操作一遍即可破解。


http://pan.baidu.com/s/1jIiNr8M
keil4自己下載吧,破解版
回復

使用道具 舉報

ID:213173 發表于 2017-7-22 19:47 | 顯示全部樓層
為你寫詩 發表于 2017-7-22 17:37
改完變成這樣了,問題如下,求助啊,急
Build target 'Target 1'
linking...

1.用#include "STC15F2K60S2.h"代替#include <reg52.h>
2.把下面STC15F2K60S2.H文件復制放到你的工程文件里以便調用
3.注釋掉void dis_lcd1602(uchar x,uchar y,uchar dat)程序中沒有引用
已經驗證過了,這3件事做好編譯就能通過。
STC15F2K60S2.zip (2.33 KB, 下載次數: 11)


回復

使用道具 舉報

ID:220342 發表于 2017-7-23 11:41 | 顯示全部樓層
T1這個和單片機的寄存器名稱重復了,還有其它的CCON、\CH沒作定義就用了,當然會報錯
回復

使用道具 舉報

ID:220342 發表于 2017-7-23 11:42 | 顯示全部樓層
你試下將所用T1改為其他名稱,例如A試下
回復

使用道具 舉報

ID:213173 發表于 2017-7-27 21:33 | 顯示全部樓層
在程序中用//或/**/注釋掉某段語句的性質和刪除是一樣的,不同的是可以非常方便的恢復。
/*
void dis_lcd1602(uchar x,uchar y,uchar dat)
{
        uchar add;
        if(y==1)         add=(0x80+x);
        if(y==2)         add=(0xc0+x);
        lcd_Write_com(add);                //寫指令
        lcd_write_date(dat);        //寫數據
}  */
回復

使用道具 舉報

ID:222959 發表于 2017-7-28 11:13 | 顯示全部樓層
可以先檢查一下頭文件
回復

使用道具 舉報

ID:105206 發表于 2017-7-28 13:59 | 顯示全部樓層
老兄,我改了頭文件,編譯沒問題的,
Build target 'Target 1'
compiling main.c...
linking...
Program Size: data=51.7 xdata=250 code=3428
".\Objects\test" - 0 Error(s), 0 Warning(s).
Build Time Elapsed:  00:00:00
回復

使用道具 舉報

ID:105206 發表于 2017-7-28 14:01 | 顯示全部樓層
這是你的文件

#include <STC12C5A60S2.H>
#include <intrins.h>            
#define uchar unsigned char
#define uint  unsigned int
#define ADC_FLAG      0X10
#define M     40

/*****************************************
功能定義
*****************************************/
sbit lockA                =        P3^2;       //
sbit lockB          =        P3^3;       //

sbit Key_0                =        P2^0;       //Key_0
sbit Key_1                =        P2^1;       //Key_1
sbit Key_2                =        P2^2;       //Key_2
sbit Key_3                =        P2^3;       //Key_3

uchar PWM = 230;
uchar channel=0;                              //ADC采樣第一通道
uint  CurrentA;             //設定A輸出電流
uint  CurrentB;             //設定B輸出電流
uint  OUT_voltage;                      //輸出電壓                 
uint  OUT_Current;          //輸出總電流
uchar KEY_VALUE = 5;
uchar X=1;
uchar Y=1;
uchar site  = 12;
float SUM1, SUM2, SUM3 , I3;
uchar T1 = 0;
uint  protect_i ;

xdata uint U1,I1,I2;
xdata float PI = 3.5;
xdata uint I1_VALUE[M] , I2_VALUE[M] , U1_VALUE[M] ;

//data 加強抗干擾能力
data bit  Charge = 0;
data bit  ADC_ready=0;                   //ADC完畢
data bit  flag1 = 0;
data bit  flag2 = 0;
data bit  k=0;
data bit  Release = 0;
data bit  protect = 0;            //過流保護

//函數說明: 延時程序
void delay(uchar t)
{
        uint j;
        uchar i;
        for(i=0;i<t;i++)
                for(j=0;j<1000;j++);
}

//1602液晶
sbit RS = P2^4;               
sbit RW = P2^5;
sbit E  = P2^6;

//短延時
void delay5ms()   
{
    uchar i,v,k;
    for(i=1;i>0;i--)
        for(v=168;v>0;v--)
            for(k=22;k>0;k--);
}

//寫指令
void lcd_Write_com(uchar com)         
{
        RS=0;                        //定義指令寄存器
        RW=0;                                    //寫允許
        P0=com;                                              //寫指令
        delay5ms();        E=1;                  //片選端上拉
        delay5ms();        E=0;                  //下降沿鎖存
}

//寫數據
void lcd_write_date(uchar date)        
{
        RS=1;                                           //定義數據寄存器
        RW=0;                                           //寫允許
        P0=date;                                 //寫數據
        delay5ms();        E=1; //片選端上拉
        delay5ms();        E=0; //下降沿鎖存
}

//顯示程序
//void dis_lcd1602(uchar x,uchar y,uchar dat)
//{
//        uchar add;
//        if(y==1)         add=(0x80+x);
//        if(y==2)         add=(0xc0+x);
//        lcd_Write_com(add);                //寫指令
//        lcd_write_date(dat);        //寫數據
//}  

//液晶初始化
void lcd1602_init()
{
        lcd_Write_com(0x38);        //設置8位格式,2行,5*7
        lcd_Write_com(0x01);        //清屏
        lcd_Write_com(0x0C);        //整體顯示,關光標,不閃爍
        lcd_Write_com(0x06);        //設定輸入方式,增量不移位
        lcd_Write_com(0x80);        //初始坐標
}

//液晶顯示漢字程序
void hz_lcdDis(uchar x,uchar y,uchar *p) //漢字顯示
{
   uchar i=0,temp;
   if(x)temp = 0x40;   else temp = 0;
   for(i=y;*p!='\0';i++,p++)
   {
                lcd_Write_com(i|0x80+temp);
                lcd_write_date(*p);
                delay5ms();                          
   }
}

//液晶顯示數字程序
void  num_lcdDis(uchar X,uchar Y,uint num,uchar n)        
{
        uint i=0,temp,hang;   
        n +=1;
           if(X)hang = 0x40;else hang = 0;
           for(i=(n-1);i>0;i--)
    {           
                  lcd_Write_com((i+Y-1)|0x80+hang);          //從個位開始顯示
                  temp = num%10+0x30;
                  lcd_write_date(temp);        
                 delay5ms();
                  num/=10;                                         
        }        
}

//函數說明: 平均濾波函數
#define N 50
uint Filter(uint adc_data)
{
        uint value=0;
        uchar count,count_ADC;
        for(count=0;count<N;count++)
        {
                for(count_ADC=0;count_ADC<3;count_ADC++)
                {
                        while(!ADC_ready){}
                        ADC_ready=0;
                }
                value+=adc_data;         
        }
        return (value);
}

//函數說明: 按鍵程序
//開關按鍵
void Key_0_()
{
        if(Charge==0)
                {        
                        lockA=0;lockB=0;
                        hz_lcdDis(0,8,"K");
                        num_lcdDis(0,11,X,2);
                        num_lcdDis(0,14,Y,2);
                } //0有效
        else
        {
                        lockA=1;lockB=1; hz_lcdDis(0,8,"G");
                        num_lcdDis(0,11,X,2);num_lcdDis(0,14,Y,2);
                } //1有效
        Charge=~Charge;
}

//函數說明:按鍵程序
//調整光標位置
void Key_1_()
{
        lockA=1;
        lockB=1;
        flag1  = 1;
        flag2  = 1;
        hz_lcdDis(0,8,"G");
        if(k) { site = 14;  hz_lcdDis(0,14," _");num_lcdDis(0,11,X,2); }
        else  { site = 12;  hz_lcdDis(0,11," _");num_lcdDis(0,14,Y,2); }
        k =~k;
}
         
//函數說明: 按鍵程序
//
void Key_2_()
{
        Charge = 0;
        lockA=1;
        lockB=1;
        hz_lcdDis(0,8,"G");
        if((site == 12)&&(X < 255))            { ++X;         num_lcdDis(0,11,X,2);}
        else if((site==14)&&(Y < 255))         { ++Y;         num_lcdDis(0,14,Y,2);}
}

//函數說明: 按鍵程序
//任意比例設定-
void Key_3_()
{
        flag1  = 1;
        flag2  = 1;
        Charge = 0;
        lockA=1;
        lockB=1;
        hz_lcdDis(0,8,"G");
        if((site == 12)&&(X > 0 ))            { --X;         num_lcdDis(0,11,X,2);}
        else if((site==14)&&(Y > 0))          { --Y;         num_lcdDis(0,14,Y,2);}
}

//按鍵掃描
void key_scan()
{
        uchar temp;
        temp = P2&0x0F;
        if(temp != 0x0F)
        {
                delay(10);
                temp = P2&0x0F;
                if(temp!= 0x0F)
                {
                        Release = 1;
                        switch(temp)
                        {
                                case 0x0E: KEY_VALUE = 0;        break;        //20
                                case 0x0D: KEY_VALUE = 1;        break;        //21
                                case 0x0B: KEY_VALUE = 2; break;        //22
                                case 0x07: KEY_VALUE = 3;        break;        //23
                                default:   KEY_VALUE = 4; break;
                        }
                }
        }
        else Release = 0;
               
        if( Release ==0 )
        {
                switch( KEY_VALUE )
                {
                        case 0: Key_0_(); KEY_VALUE = 4; break;
                        case 1: Key_1_(); KEY_VALUE = 4; break;
                        case 2: Key_2_(); KEY_VALUE = 4; break;
                        case 3: Key_3_(); KEY_VALUE = 4; break;
                        default:          break;
                }
        }
}

//函數說明: PWM初始化
void init_pwm()
{
  CCON = 0;
        CL = 0;
        CH = 0;
        CMOD = 0X08;          //0X08:43KHZ // 0X02,22KHZ // 0X0A,10KHZ //
        CCAPM1        =0x42;        //8位PWM輸出,無中斷
        CCAP1L         =CCAP1H = 230;//初始化pwm輸出的占空比  上電默認2A 電流值對應電壓值進行換算即可
        CR=1;
}

//函數說明: 中斷 始化函數
void InitADC()
{
        P1M1=0x27;          //0x00100111
        P1M0=0x00;
        P1ASF=0X27;                      //選擇ADC通道0125
        ADC_RES=0;
        ADC_CONTR=0X88;                   //1110 0000           E8 開電源,最高速
        EA=1;
        EADC=1;
}

void DISPLAY(void)
{
    if(T1 < M)
        {
                        I1_VALUE[T1] = I1;
                        SUM1 += I1_VALUE[T1];
                       
                        I2_VALUE[T1] = I2;
                        SUM2 += I2_VALUE[T1];
                       
                        U1_VALUE[T1] = U1;
                        SUM3 += U1_VALUE[T1];
                       
                        T1++;
                        if( T1 >= M)
                        {
                                        T1 = 0 ;
                                        SUM1 /= M;
                                        SUM2 /= M;
                                        SUM3 /= M;
                                       
                                        if(SUM1 > 2) SUM1 += 1;        
                                        if(SUM2 > 2) SUM2 += 1;        

                                       
                                        num_lcdDis(1,11,(uint)(SUM3)/10,2);
                                        num_lcdDis(1,14,(uint)SUM3%10,1);        

                                        num_lcdDis(0,3,(uint)SUM1/100,1);
                                        num_lcdDis(0,5,(uint)SUM1%100,2);
                                        num_lcdDis(1,3,(uint)SUM2/100,1);
                                        num_lcdDis(1,5,(uint)SUM2%100,2);
                       
                                        SUM1 = 0;
                                        SUM2 = 0;
                                        SUM3 = 0;
                        }        
        }
}

void PI_calculate(void)
{
        if(Charge == 1)              //Charge 模式下進行自動調整
        {
                if((float)I1 > ((float)X/(float)Y)*I2 ) PI += 0.1 ;
                else               PI -= 0.1 ;
                CCAP1L         = CCAP1H = PWM;
               
                if((flag1 == 1)&&(flag2 == 1)) //進入比例模式 比例最大 2:0.5即4:1 最小0.5:2 即1:4
                {
                                PWM = 255-(uint)((I3*X/(X+Y)-PI)*256/500+0.5); //255-(uint)((I3*X/(X+Y))*255/500+0.5); //電流值等于電壓值 I3*X/(X+Y)/100/5*255 1為調節量
                }
                else if((flag1==0)&&(flag2==0)&&(I3 < 200))     //2A切換點
                {        
                                PWM = 230;                                    //切換到0.5A模式
                }                             
                else if((flag1==0)&&(flag2==0)&&(I3 > 200))
                {        
                                PWM = 153;                               //切換到2A模式
                }     
        }        
}

void Protect_recover(void)
{        
                if((protect == 1)&&(protect_i++>500))     //延時自恢復 大概半分鐘S
                {
                        lockA=0; lockB=0;  
                        protect_i = 0;
                        protect = 0;
                        hz_lcdDis(0,8,"K");
                }
}
//函數說明: 主函數
void main(void)
{
        lockA=1;
        lockB=1;
        lcd1602_init();
        hz_lcdDis(0,4,"Welcome!");
        init_pwm();
        InitADC();
        delay(250);        
        EA=1;                 //開總中斷
        lcd_Write_com(0x01);        //清屏
        hz_lcdDis(0,0,"CA= .  A S= X: Y ");
        hz_lcdDis(1,0,"CB= .  A U=  . V");
        while(1)              //主循環
        {               
                EA = 1;
                I1=Filter(CurrentA)/99;          //輸出實際電流 Filter()=0.02Ω*I*放大倍數*1023/5v*50=I*放大倍數*204.6,為了顯示放大100倍處理 =102.3
                I2=Filter(CurrentB)/100;          //輸出實際電流 Filter()=0.02Ω*I*放大倍數*1023/5v*50=I*放大倍數*204.6,為了顯示放大100倍處理 =102.3                      //總電流
                U1=Filter(OUT_voltage)/255;              //輸入電壓  1:3采樣電阻 ,Filter()*5V*4/(50*1023) 同時為了小數轉成uint時,需要進行*10,使真實位變小數位 =255.7;顯示數值濾波處理
               
                EA = 0;
                I3=I1+I2;   
                if(I3 > 450)                      //4.5A保護
                {        lockA=1; lockB=1; hz_lcdDis(0,8,"P");protect = 1;}
                Protect_recover();                //自恢復時間在半分鐘
                PI_calculate();
                DISPLAY();
                key_scan();
        }
}


//函數說明: ADC中斷
//實現功能:執行ADC采集并做電壓和電流的調整。
void ADC_interrupt()interrupt 5                  //ADC轉換完后ADC_FLAG由硬件自動置位,須由軟件清零
{                                
        uint ADC_value;                                            //ADC轉換結果        10位
        ADC_value=(ADC_RES<<2)+ADC_RESL;        //ADC_value=(ADC_RES<<2)+ADC_RESL;
        switch(channel)
        {
                case 0:        CurrentA=ADC_value;        
                                channel=1;                                       
                                break;
                case 1:        CurrentB=ADC_value;
                                channel=5;               
                                break;                                
                case 5:OUT_voltage=ADC_value;
                                channel=0;
                                break;                                       
                default:break;
        }
        ADC_CONTR&=!ADC_FLAG;                                 //清除 ADCflag
        ADC_CONTR=0xE8|channel;
        ADC_ready=1;               
}
回復

使用道具 舉報

ID:493140 發表于 2019-5-12 12:05 | 顯示全部樓層
解決了沒有
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲国产电影 | 久久精品网 | 四虎影音 | 免费国产一区二区 | 国产成人精品综合 | 国产精品中文字幕在线观看 | 少妇特黄a一区二区三区88av | 中文字幕在线一区二区三区 | 激情影院久久 | 97在线播放 | 成人免费在线视频 | 亚洲 精品 综合 精品 自拍 | 久久精品—区二区三区 | 日韩亚洲视频 | 国产福利在线播放 | 国产一级片网站 | 午夜精品一区 | 久久精品久久久久久 | 毛片一级片 | 日韩中文字幕在线观看 | 久久精品亚洲精品国产欧美 | 99免费在线视频 | 黄色91在线 | 日本精品裸体写真集在线观看 | 亚洲男人的天堂网站 | 中文字幕一区二区三区在线观看 | 一区二区久久精品 | av黄色国产 | 永久免费在线观看 | 国产精品高潮呻吟 | 91久久久久久久久久久 | 成人高清视频在线观看 | 国产成人在线播放 | 久草精品视频 | av一区二区在线观看 | 久久久久国色av免费观看性色 | 华丽的挑战在线观看 | 成人在线中文字幕 | 欧美一二三四成人免费视频 | 亚洲福利一区二区 | 亚洲第一视频网 |