找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 819|回复: 6
打印 上一主题 下一主题
收起左侧

求助stc8051U 定时器t0不工作,pwm也没工作

[复制链接]
跳转到指定楼层
楼主
/*根据电池容量的mAh,可以计算电池的持续放电时间的电流数去确定电池的容量。
以下用了一个STC12C5608AD去做检测电池放电400mA的时间,再以公式400mA*时间=mAh
*/
#include "stc8051U.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define ADCTIM  (*(unsigned char volatile xdata *)0xfea8)
#define VREFH_ADDR CHIPID7
#define VREFL_ADDR CHIPID8
uint BGV;                                       //内部1.19V参考信号源值存放在idata中




typedef unsigned char BYTE;
uchar time1,time2,time3,pwm1;
uint fen=0,ad1=138,ad0;
sbit LED = P3^6;  //背光脚H亮
sbit rw = P2^5;
sbit  rs = P2^6;  //
sbit  en = P2^7;  //
sbit cs1 = P3^2;
sbit cs2 = P3^3;
sbit rst = P3^4;
sbit SPK = P3^5;  //蜂鸣器
sbit POW = P3^7;  //PWM
void InitADC();
uint GetADCResult(BYTE ch);
void Delayus(uint us);
void Delay(uchar  ms);
void lcdstate();
void write_command(uchar  command);
void   write_data(uchar  datas);
void   lcdinit();
void clearScreen();
void init();
void Timer0Init(void);
void dyADC();
void hz_display16(unsigned char pag, unsigned char col, unsigned char code *hzk);
unsigned char code    SZ[][16]=
{/*--  文字:  0  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0xF0,0x08,0x08,0x18,0xE0,0x00,0x00,0x00,0x0F,0x10,0x20,0x10,0x0F,0x00,

/*--  文字:  1  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x10,0x00,0x00,0x00,

/*--  文字:  2  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x30,0x08,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x18,0x14,0x13,0x10,0x08,0x00,

/*--  文字:  3  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0x10,0x08,0x88,0x78,0x00,0x00,0x00,0x00,0x10,0x20,0x20,0x11,0x0E,0x00,

/*--  文字:  4  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x03,0x02,0x02,0x02,0x1F,0x02,0x00,

/*--  文字:  5  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0x70,0x48,0xC8,0x88,0x00,0x00,0x00,0x10,0x10,0x20,0x10,0x0F,0x00,0x00,

/*--  文字:  6  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0xE0,0x90,0x88,0x80,0x00,0x00,0x00,0x07,0x18,0x20,0x20,0x19,0x06,0x00,

/*--  文字:  7  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x10,0x08,0x08,0x88,0x78,0x00,0x00,0x00,0x00,0x00,0x18,0x07,0x00,0x00,0x00,

/*--  文字:  8  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0x78,0x88,0x88,0x78,0x00,0x00,0x00,0x0C,0x12,0x21,0x21,0x1E,0x00,0x00,

/*--  文字:  9  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x60,0x98,0x08,0x08,0xF8,0xC0,0x00,0x00,0x00,0x21,0x12,0x09,0x07,0x00,0x00,

/*--  文字:  :  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0xC,0xC,0x00,0x00,0x00,0x00,0x00,
/*--  文字:  B  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,
/*--  文字:  a  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,
/*--  文字:  t  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,

/*--  文字:  T  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,

/*--  文字:  i  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,

/*--  文字:  m  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,

/*--  文字:  e  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,
/*--  文字:  V  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,

/*--  文字:  A  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,

/*--  文字:  h  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,
/*--  文字:  一  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x00,0x0,0x0,0x0,0x0,0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00,
/*--  文字: .  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x0,0x0,0x00,0x00,0x00,0x00,0x00,0x00,0xC,0x0,0x00,0x00,0x00,0x00,0x00,
};
/*----------------------------
读取ADC结果
----------------------------*/
uint GetADCResult(BYTE channel)
{
    ADC_RES = 0;
    ADC_RESL = 0;

  ADC_CONTR = (ADC_CONTR & 0xF0) | 0x40 | channel;    //启动 AD 转换
    _nop_();                        //等待4个NOP
    _nop_();
    _nop_();
    _nop_();
    while (!(ADC_CONTR & 0x20));                //查询ADC完成标志
    ADC_CONTR &= ~0x20;
        return (((int)ADC_RES << 8) | ADC_RESL);        //adc_data*4的意思是左移两位,4 = 2的2次方。
                                    //然后左移后加上adc_low的值,这个值应该是adc转换的低两位。  



}

/*----------------------------
初始化ADC
----------------------------*/
void InitADC()
{
    P_SW2 |= 0x80;                   //扩展 RAM 区特殊功能寄存器(XFR)访问控制寄存器
    ADCTIM = 0x3f;                              //ADC时序控制寄存器3f=00111111
    P_SW2 &= 0x7f;

    ADCCFG = 0x2f;                              //设置ADC时钟为系统时钟/2/16
    ADC_CONTR = 0x80;                           //使能ADC模块,并选择第15通道 8f=10001111                       //ADC上电并延时
}
void    lcdstate()  //读状态指令
{
uchar  lcd=0x00; /*设置初值为0,全部为低,方便后面的判忙*/
rs=0; /*根据时序图拉低,选择写指令*/
rw=1; /*根据时序图拉低,选择写模式*/
do
{
en=1; /*使能,使液晶输出信号,检查是否忙*/
_nop_();_nop_();_nop_();_nop_();/*延时4US*/
lcd=P0; /*把P0口的状态值读回来给lcd*/
en=0; /*使能端跳变*/;
}while(lcd&0x80); /*结果的高位保留,如果高位DB7为一,则表示忙*/
}
void Delayus(uint us)                //@12.000MHz
{
   while(--us)
   {
                _nop_();
                _nop_();
                _nop_();
                _nop_();
   }
}

void delay(uchar  ms)
{ uchar   i;
   uchar   j;
  for(i=0;i<100;i++)
   for(j=0;j<ms;j++);
}
void   write_command(uchar   command)
{
lcdstate();
  rs=0;                                //RS=0;为往MCU进行指令操作
  rw=0;                                //RW=0;为往MCU写入操作
  en=0;
  _nop_();_nop_();_nop_();_nop_();/*延时4US*/
  en=1;
  _nop_();_nop_();_nop_();_nop_();/*延时4US*/
  P0=command;
  _nop_();_nop_();_nop_();_nop_();/*延时4US*/
  en=0;
}
void   write_data(uchar   datas)
{  
   lcdstate();
   rs=1;
   rw=0;  
   en=0;
   _nop_();_nop_();_nop_();_nop_();/*延时4US*/
   en=1;
   _nop_();_nop_();_nop_();_nop_();/*延时4US*/
   P0=datas;
   _nop_();_nop_();_nop_();_nop_();/*延时4US*/
   en=0;
}
void   lcdinit()
{
    delay(100);                                         //
    cs1=1;
        cs2=1;
        delay(100);        
        lcdstate();                                 //
        write_command(0x3e);                 //
        write_command(0xb8+0);                         //
        write_command(0xc0+0);                 //
        write_command(0x40+0);                 //
        write_command(0x3f);                 
}
void clearScreen(  )
{   uchar i,j;
    lcdstate();
    cs1=1;
        cs2=1;
        write_command(0x3f);                        //设置显示开
        write_command(0xb8);                    //Y        设置第0页;
        write_command(0x40);                         //        设置第0列
   for(i=0;i<8;i++)
   {
     write_command(0xb8+i);
     for(j=0;j<64;j++)
     {
           //write_command(0x40+j);
       write_data(0x00);

     }
   }
}

void Timer0Init(void)                //2毫秒@12.000MHz
{
        AUXR &= 0x7F;                //定时器时钟12T模式
        TMOD &= 0xF0;                //设置定时器模式
        TMOD |= 0x01;                //设置定时器模式
        TL0 = 0x30;                //设置定时初值
        TH0 = 0xF8;                //设置定时初值
        TF0 = 0;                //清除TF0标志
        TR0 = 0;                //定时器0开始计时
}


void Timer1Init(void)                //5毫秒@12.000MHz
{
        AUXR &= 0xBF;                //定时器时钟12T模式
        TMOD &= 0x0F;                //设置定时器模式
        TMOD |= 0x10;                //设置定时器模式
        TL1 = 0x78;                //设置定时初值
        TH1 = 0xEC;                //设置定时初值
        TF1 = 0;                //清除TF1标志
        TR1 = 1;                //定时器1开始计时
}
void hz_display8(unsigned char pag, unsigned char col, unsigned char  zi)
{
        uchar j=0;
        uchar i=0;
        for(j=0;j<2;j++)                          //这里写四页
        {
                write_command(0xb8+pag+j);          //page在这里就是从page表示的这页开始写起。
                write_command(0x40+col);          //从列为col表示的列开始
                for(i=0;i<8;i++)                           //这里写32列
                write_data(SZ[zi][8*j+i]);        //J为页,I,为第J行第I个数
        }
}
void dyADC()
{
int res,ad1;
int xes;
GetADCResult(15);
GetADCResult(15);
res=GetADCResult(15);//读内部基准ADC, 读15通道
GetADCResult(0);
GetADCResult(0);
xes=GetADCResult(0);//读p1.1外部电压ADC
ad1=(int)((long)xes* BGV / res);  //计算p5.5外部电压, vcc为1.19V,
ad0=ad1/10;

}
void main()
{      
   bit q1=0,q2=0,q3=0;
    uchar k1;
    ulong ww=1667;
    P_SW2 = 0X80; //使能访问 XFR,没有冲突不用关闭
    CKCON = 0x00; //设置外部数据总线速度为最快
    WTST = 0x00;
    P0M0 = 0x00;       //00上拉准双向口/10浮空输入         
    P0M1 = 0x00;       //11开漏输出/01推挽输出
    P1M0 = 0x00;
    P1M1 = 0x01;    //设置P1.0为ADC
    P2M0 = 0x00;
    P2M1 = 0x00;
    P3M0 = 0x00;       //00上拉准双向口/10浮空输入         
    P3M1 = 0x00;       //11开漏输出/01推挽输出
    P4M0 = 0x00;
    P4M1 = 0x00;
    P5M0 = 0x00;
    P5M1 = 0x00;
BGV = (VREFH_ADDR << 8) + VREFL_ADDR; //从 CHIPID 中读取内部参考电压值
        POW=0;
        SPK=0;
      lcdinit();
       clearScreen();
        InitADC();
        Timer0Init();
        Timer1Init();
        TR0 = 1;                        //timer0 start running
    ET0 = 1;                        //enable timer0 interrupt
   // TR1 = 1;                        //timer1 start running
   // ET1 = 1;                        //enable timer1 interrupt
    EA = 1;                         //open global interrupt switch

        for(k1=255;k1>0;k1--)
           {
                   SPK=~SPK;
                Delayus(k1);
           }   
           SPK=0;

    cs1=1;
    cs2=0;
hz_display8(0,0,11); //Batt:
hz_display8(0,8,12);
hz_display8(0,16,13);
hz_display8(0,24,13);
hz_display8(0,32,10);
hz_display8(6,0,14);  //time:
hz_display8(6,8,15);
hz_display8(6,16,16);
hz_display8(6,24,17);
hz_display8(6,32,10);





          while(1)
   {


   if(EA==1)
     {
                 cs1=1;
            cs2=0;
            hz_display8(6,40,(time3%100/10));  //时
            hz_display8(6,48,(time3%10/1));
            hz_display8(6,56,10);  //:
                  cs1=0;
            cs2=1;
            hz_display8(6,0,(time2%100/10));  //分
            hz_display8(6,8,(time2%10/1));
            hz_display8(6,16,10);  //:
            hz_display8(6,24,(time1%100/10));  //秒
            hz_display8(6,32,(time1%10/1));
      }




          if(q1==0&time1==2)
            {
              dyADC();
              cs1=1;
              cs2=0;
                   hz_display8(0,40,(ad0/100));
                   hz_display8(0,48,22);
                   hz_display8(0,56,(ad0%100/10));
              cs1=0;
              cs2=1;
                   hz_display8(0,0,(ad0%10));
                   hz_display8(0,8,18);  //v

               q1=1;                              

                                   for(k1=0;k1<255;k1++)
                                     {
                                         SPK=~SPK;
                                         Delayus(150);
                                      }
                                   Delay(100);
                                    for(k1=0;k1<255;k1++)
                                      {
                                          SPK=~SPK;
                                          Delayus(150);
                                      }
                    SPK=0;
                    CCON = 0;                       //PCA控制寄存器CCON
                                                                //PCA timer stop running
                                                               //Clear CF flag
                                                                //Clear all module interrupt flag
                     CL = 0;                         //PCA的16位计数器 — 低8位CL和高8位CH
                     CH = 0;
                     CMOD = 0x08;                    //工作模式寄存器CMOD
                                                                //Disable PCA timer overflow interrupt
                     CCAP1H = CCAP1L = 0xFF;         //模块0的捕捉/比较寄存器用来控制输出的占?比
                     CCAPM1 = 0x42;                  //PCA比较/捕获寄存器CCAPMn (n=0,1,2,3) PCA interrupt
                     PCA_PWM1 = 0x40;         
                     CCON |= CR;                         //PCA计数器阵列, 运行控制位
                      TR1 = 1;
                      ET1 = 1;
                }  
          dyADC();
           cs1=0;
           cs2=1;
           hz_display8(0,16,(ad0/100));
           hz_display8(0,24,22);  
           hz_display8(0,32,(ad0%100/10));
           hz_display8(0,40,(ad0%10));
           hz_display8(0,48,18);  //v


            if(fen>=1)LED=0;
            if(ad0<=286)q3=1;
                            while(q3==1)
                               {
                                 for(k1=0;k1<100;k1++)
                                    {
                                        SPK=~SPK;
                                        Delayus(110);
                                     }
                                       SPK=0;                        
                                       LED=~LED;
                                       CCAP1H = CCAP1L = 0xFF;
                                       POW=0;
                                       EA=0;
                                       Delay(500);
                                                                                                          dyADC();
                                     //  ad0=GetADCResult(0);
                                                       cs1=0;
                                        cs2=1;
                                                            hz_display8(0,16,(ad0%1000/100));
                                                            hz_display8(0,24,10);  
                                                            hz_display8(0,16,(ad0%100/10));
                                                            hz_display8(0,16,(ad0%10/1));
                                                            hz_display8(0,24,18);  //v
                                                         
                                                if(!q2)
                                                  {      
                                                   ww*=fen;
                                                   ww*=4;
                                                         cs1=1;
                                                   cs2=2;
                                                   hz_display8(6,0,21);  //-------
                                                                   hz_display8(6,8,21);
                                                                                                hz_display8(6,16,21);
                                                                                                hz_display8(6,24,21);
                                                                                                hz_display8(6,32,21);
                                                                                                hz_display8(6,40,21);
                                                                                                hz_display8(6,48,21);
                                                                                                hz_display8(6,56,21);
                                                                                          cs1=0;
                                                                                     cs2=1;
                                                                                          hz_display8(6,0,(ww%100000000/10000000));
                                                                           hz_display8(6,8,(ww%10000000/1000000));
                                                                           hz_display8(6,16,(ww%1000000/100000));
                                                                           hz_display8(6,24,(ww%100000/10000));
                                                                           hz_display8(6,32,(ww%10000/1000));
                                                                           hz_display8(6,40,16);  //mah
                                                                           hz_display8(6,48,19);
                                                                           hz_display8(6,56,20);
                                                                  Delay(1000);
                                                                  q2=1;
                                                      }
                          }


    }


}
void tm0_isr() interrupt 1 using 1
{
  static uchar i1,i2;
        TL0 = 0x30;                //设置定时初值
        TH0 = 0xF8;                //设置定时初值
        i1++;
  if(i1>=50)
  {
    i1=0;
    i2++;
    if(i2>=10)
            {
             i2=0;
             time1++;
            if(time1>=60)
                   {
                     time1=0;
                     time2++;
                     fen++;
     if(time2>=60)
             {
               time2=0;
                   time3++;
                   if(time3>=24)time3=0;
             }
                    }
                    }
  }
  // ad0=GetADCResult(0);      
}

void tm1_isr() interrupt 3 using 1
{
        TL1 = 0x78;                //设置定时初值
        TH1 = 0xEC;                //设置定时初值

        if(ad0>=428)CCAP1H = CCAP1L = 142;    //模块0的捕捉/比较寄存器用来控制输出的占?比
        if(ad0<=427&&ad0>424)CCAP1H = CCAP1L = 142;
        if(ad0<=424&&ad0>420)CCAP1H = CCAP1L = 141;
        if(ad0<=420&&ad0>416)CCAP1H = CCAP1L = 140;
        if(ad0<=416&&ad0>412)CCAP1H = CCAP1L = 139;
        if(ad0<=412&&ad0>408)CCAP1H = CCAP1L = 138;
        if(ad0<=408&&ad0>404)CCAP1H = CCAP1L = 137;
        if(ad0<=404&&ad0>400)CCAP1H = CCAP1L = 136;
        if(ad0<=400&&ad0>396)CCAP1H = CCAP1L = 135;
        if(ad0<=396&&ad0>392)CCAP1H = CCAP1L = 134;
        if(ad0<=392&&ad0>388)CCAP1H = CCAP1L = 132;//
        if(ad0<=388&&ad0>384)CCAP1H = CCAP1L = 131;
        if(ad0<=384&&ad0>380)CCAP1H = CCAP1L = 129;
        if(ad0<=380&&ad0>376)CCAP1H = CCAP1L = 128;
        if(ad0<=376&&ad0>372)CCAP1H = CCAP1L = 127;
        if(ad0<=372&&ad0>368)CCAP1H = CCAP1L = 126;//
        if(ad0<=368&&ad0>364)CCAP1H = CCAP1L = 125;
        if(ad0<=364&&ad0>360)CCAP1H = CCAP1L = 123;
        if(ad0<=360&&ad0>356)CCAP1H = CCAP1L = 122;
        if(ad0<=356&&ad0>352)CCAP1H = CCAP1L = 120;
        if(ad0<=352&&ad0>348)CCAP1H = CCAP1L = 119;
        if(ad0<=348&&ad0>344)CCAP1H = CCAP1L = 117;
        if(ad0<=344&&ad0>340)CCAP1H = CCAP1L = 116;
        if(ad0<=340&&ad0>336)CCAP1H = CCAP1L = 114;
        if(ad0<=336&&ad0>332)CCAP1H = CCAP1L = 113;
        if(ad0<=332&&ad0>328)CCAP1H = CCAP1L = 111;
        if(ad0<=328&&ad0>324)CCAP1H = CCAP1L = 109;
        if(ad0<=324&&ad0>320)CCAP1H = CCAP1L = 108;
        if(ad0<=320&&ad0>316)CCAP1H = CCAP1L = 106;
        if(ad0<=316&&ad0>312)CCAP1H = CCAP1L = 105;
        if(ad0<=312&&ad0>308)CCAP1H = CCAP1L = 103;
        if(ad0<=304&&ad0>300)CCAP1H = CCAP1L = 100;
        if(ad0<=300&&ad0>296)CCAP1H = CCAP1L = 98;
        if(ad0<=296&&ad0>292)CCAP1H = CCAP1L = 97;
        if(ad0<=292&&ad0>288)CCAP1H = CCAP1L = 94;
        if(ad0<=288&&ad0>284)CCAP1H = CCAP1L = 91;
        if(ad0<=284)CCAP1H = CCAP1L = 0xFF;

        //CCAPM0 = 0x42;*/
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:161164 发表于 2025-1-26 16:05 | 只看该作者
LCD有没有显示?
回复

使用道具 举报

板凳
ID:322197 发表于 2025-1-27 20:55 | 只看该作者
/*根据电池容量的mAh,可以计算电池的持续放电时间的电流数去确定电池的容量。
以下用了stc8051U去做检测电池放电400mA的时间,再以公式400mA*时间=mAh
*/
#include "stc8051U.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define ADCTIM  (*(unsigned char volatile xdata *)0xfea8)
#define VREFH_ADDR CHIPID7
#define VREFL_ADDR CHIPID8
uint BGV;                                       //内部1.19V参考信号源值存放在idata中




typedef unsigned char BYTE;
uchar time1,time2,time3,pwm1;
uint fen=0,ad1=138,ad0;
sbit LED1 = P1^7;
sbit LED = P3^6;  //背光脚H亮
sbit rw = P2^5;
sbit  rs = P2^6;  //
sbit  en = P2^7;  //
sbit cs1 = P3^2;
sbit cs2 = P3^3;
sbit rst = P3^4;
sbit SPK = P3^5;  //蜂鸣器
sbit POW = P3^7;  //PWM
void InitADC();
uint GetADCResult(BYTE ch);
void Delayus(uint us);
void Delay(uchar  ms);
void lcdstate();
void write_command(uchar  command);
void   write_data(uchar  datas);
void   lcdinit();
void clearScreen();
void init();
void Timer0Init(void);
void Timer1Init(void);
void dyADC();
void hz_display16(unsigned char pag, unsigned char col, unsigned char code *hzk);
unsigned char code    SZ[][16]=
{/*--  文字:  0  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0xF0,0x08,0x08,0x18,0xE0,0x00,0x00,0x00,0x0F,0x10,0x20,0x10,0x0F,0x00,

/*--  文字:  1  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x10,0x00,0x00,0x00,

/*--  文字:  2  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x30,0x08,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x18,0x14,0x13,0x10,0x08,0x00,

/*--  文字:  3  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0x10,0x08,0x88,0x78,0x00,0x00,0x00,0x00,0x10,0x20,0x20,0x11,0x0E,0x00,

/*--  文字:  4  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x03,0x02,0x02,0x02,0x1F,0x02,0x00,

/*--  文字:  5  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0x70,0x48,0xC8,0x88,0x00,0x00,0x00,0x10,0x10,0x20,0x10,0x0F,0x00,0x00,

/*--  文字:  6  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0xE0,0x90,0x88,0x80,0x00,0x00,0x00,0x07,0x18,0x20,0x20,0x19,0x06,0x00,

/*--  文字:  7  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x10,0x08,0x08,0x88,0x78,0x00,0x00,0x00,0x00,0x00,0x18,0x07,0x00,0x00,0x00,

/*--  文字:  8  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0x78,0x88,0x88,0x78,0x00,0x00,0x00,0x0C,0x12,0x21,0x21,0x1E,0x00,0x00,

/*--  文字:  9  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x60,0x98,0x08,0x08,0xF8,0xC0,0x00,0x00,0x00,0x21,0x12,0x09,0x07,0x00,0x00,

/*--  文字:  :  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0xC,0xC,0x00,0x00,0x00,0x00,0x00,
/*--  文字:  B  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,
/*--  文字:  a  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,
/*--  文字:  t  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,

/*--  文字:  T  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,

/*--  文字:  i  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,

/*--  文字:  m  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,

/*--  文字:  e  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,
/*--  文字:  V  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,

/*--  文字:  A  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,

/*--  文字:  h  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,
/*--  文字:  一  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x00,0x0,0x0,0x0,0x0,0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00,
/*--  文字: .  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x0,0x0,0x00,0x00,0x00,0x00,0x00,0x00,0xC,0x0,0x00,0x00,0x00,0x00,0x00,
};
/*----------------------------
读取ADC结果
----------------------------*/
uint GetADCResult(BYTE channel)
{
    ADC_RES = 0;
    ADC_RESL = 0;

  ADC_CONTR = (ADC_CONTR & 0xF0) | 0x40 | channel;    //启动 AD 转换
    _nop_();                        //等待4个NOP
    _nop_();
    _nop_();
    _nop_();
    while (!(ADC_CONTR & 0x20));                //查询ADC完成标志
    ADC_CONTR &= ~0x20;
        return (((int)ADC_RES << 8) | ADC_RESL);        //adc_data*4的意思是左移两位,4 = 2的2次方。
                                    //然后左移后加上adc_low的值,这个值应该是adc转换的低两位。  



}

/*----------------------------
初始化ADC
----------------------------*/
void InitADC()
{
    P_SW2 |= 0x80;                   //扩展 RAM 区特殊功能寄存器(XFR)访问控制寄存器
    ADCTIM = 0x3f;                              //ADC时序控制寄存器3f=00111111
    P_SW2 &= 0x7f;

    ADCCFG = 0x2f;                              //设置ADC时钟为系统时钟/2/16
    ADC_CONTR = 0x80;                           //使能ADC模块,并选择第15通道 8f=10001111                       //ADC上电并延时
}
void    lcdstate()  //读状态指令
{
uchar  lcd=0x00; /*设置初值为0,全部为低,方便后面的判忙*/
rs=0; /*根据时序图拉低,选择写指令*/
rw=1; /*根据时序图拉低,选择写模式*/
do
{
en=1; /*使能,使液晶输出信号,检查是否忙*/
_nop_();_nop_();_nop_();_nop_();/*延时4US*/
lcd=P0; /*把P0口的状态值读回来给lcd*/
en=0; /*使能端跳变*/;
}while(lcd&0x80); /*结果的高位保留,如果高位DB7为一,则表示忙*/
}
void Delayus(uint us)                //@12.000MHz
{
   while(--us)
   {
                _nop_();
                _nop_();
                _nop_();
                _nop_();
   }
}

void delay(uchar  ms)
{ uchar   i;
   uchar   j;
  for(i=0;i<100;i++)
   for(j=0;j<ms;j++);
}
void   write_command(uchar   command)
{
lcdstate();
  rs=0;                                //RS=0;为往MCU进行指令操作
  rw=0;                                //RW=0;为往MCU写入操作
  en=0;
  _nop_();_nop_();_nop_();_nop_();/*延时4US*/
  en=1;
  _nop_();_nop_();_nop_();_nop_();/*延时4US*/
  P0=command;
  _nop_();_nop_();_nop_();_nop_();/*延时4US*/
  en=0;
}
void   write_data(uchar   datas)
{  
   lcdstate();
   rs=1;
   rw=0;  
   en=0;
   _nop_();_nop_();_nop_();_nop_();/*延时4US*/
   en=1;
   _nop_();_nop_();_nop_();_nop_();/*延时4US*/
   P0=datas;
   _nop_();_nop_();_nop_();_nop_();/*延时4US*/
   en=0;
}
void   lcdinit()
{
    delay(100);                                         //
    cs1=1;
        cs2=1;
        delay(100);        
        lcdstate();                                 //
        write_command(0x3e);                 //
        write_command(0xb8+0);                         //
        write_command(0xc0+0);                 //
        write_command(0x40+0);                 //
        write_command(0x3f);                 
}
void clearScreen(  )
{   uchar i,j;
    lcdstate();
    cs1=1;
        cs2=1;
        write_command(0x3f);                        //设置显示开
        write_command(0xb8);                    //Y        设置第0页;
        write_command(0x40);                         //        设置第0列
   for(i=0;i<8;i++)
   {
     write_command(0xb8+i);
     for(j=0;j<64;j++)
     {
           //write_command(0x40+j);
       write_data(0x00);

     }
   }
}

void Timer0Init(void)                //2毫秒@12.000MHz   时间
{
        AUXR &= 0x7F;                //定时器时钟12T模式
        TMOD &= 0xF0;                //设置定时器模式
        TMOD |= 0x01;                //设置定时器模式
        TL0 = 0x30;                //设置定时初值
        TH0 = 0xF8;                //设置定时初值
        TF0 = 0;                //清除TF0标志
        TR0 = 0;                //定时器0开始计时
}


void Timer1Init(void)                //5毫秒@12.000MHz
{
        AUXR &= 0xBF;                //定时器时钟12T模式
        TMOD &= 0x0F;                //设置定时器模式
        TMOD |= 0x10;                //设置定时器模式
        TL0 = 0xB0;                                //设置定时初始值
        TH0 = 0x3C;                        //设置定时初值
        TF1 = 0;                //清除TF1标志
        TR1 = 0;                //定时器1开始计时
}
void hz_display8(unsigned char pag, unsigned char col, unsigned char  zi)
{
        uchar j=0;
        uchar i=0;
        for(j=0;j<2;j++)                          //这里写四页
        {
                write_command(0xb8+pag+j);          //page在这里就是从page表示的这页开始写起。
                write_command(0x40+col);          //从列为col表示的列开始
                for(i=0;i<8;i++)                           //这里写32列
                write_data(SZ[zi][8*j+i]);        //J为页,I,为第J行第I个数
        }
}
void dyADC()
{
int res,ad1;
int xes;
GetADCResult(15);
GetADCResult(15);
res=GetADCResult(15);//读内部基准ADC, 读15通道
GetADCResult(0);
GetADCResult(0);
xes=GetADCResult(0);//读p1.1外部电压ADC
ad1=(int)((long)xes* BGV / res);  //计算p1.1外部电压, vcc为1.19V,
ad0=ad1/10;

}
void main()
{      
   bit q1=0,q2=0,q3=0;
  //  uchar k1;
    ulong ww=1667;
    P_SW2 = 0X80; //使能访问 XFR,没有冲突不用关闭
    CKCON = 0x00; //设置外部数据总线速度为最快
    WTST = 0x00;
    P0M0 = 0x00;       //00上拉准双向口/10浮空输入         
    P0M1 = 0x00;       //11开漏输出/01推挽输出
    P1M0 = 0x00;
    P1M1 = 0x01;    //设置P1.0为ADC
    P2M0 = 0x00;
    P2M1 = 0x00;
    P3M0 = 0x00;       //00上拉准双向口/10浮空输入         
    P3M1 = 0x00;       //11开漏输出/01推挽输出
    P4M0 = 0x00;
    P4M1 = 0x00;
    P5M0 = 0x00;
    P5M1 = 0x00;
BGV = (VREFH_ADDR << 8) + VREFL_ADDR; //从 CHIPID 中读取内部参考电压值
        POW=1;
        LED1=1;
        SPK=0;
      lcdinit();
       clearScreen();
        InitADC();
        Timer0Init();
        Timer1Init();
        TR0 = 1;                        //timer0  时间
    ET0 = 1;                        // 时间
   // TR1 = 1;                        //timer1 start running
   // ET1 = 1;                        //enable timer1 interrupt
    EA = 1;                         //open global interrupt switch


    cs1=1;
    cs2=0;
hz_display8(0,0,11); //Batt:
hz_display8(0,8,12);
hz_display8(0,16,13);
hz_display8(0,24,13);
hz_display8(0,32,10);
hz_display8(6,0,14);  //time:
hz_display8(6,8,15);
hz_display8(6,16,16);
hz_display8(6,24,17);
hz_display8(6,32,10);
while(1)
{




          while(1)
   {


   if(EA==1)
     {
                 cs1=1;
            cs2=0;
            hz_display8(6,40,(time3%100/10));  //时
            hz_display8(6,48,(time3%10/1));
            hz_display8(6,56,10);  //:
                  cs1=0;
            cs2=1;
            hz_display8(6,0,(time2%100/10));  //分
            hz_display8(6,8,(time2%10/1));
            hz_display8(6,16,10);  //:
            hz_display8(6,24,(time1%100/10));  //秒
            hz_display8(6,32,(time1%10/1));
      }




          if(q1==0&time1==2)  //q1=0 time1=2  才执行括号里的程序
            {
              dyADC();
              cs1=1;
              cs2=0;
                   hz_display8(0,40,(ad0/100));
                   hz_display8(0,48,22);
                   hz_display8(0,56,(ad0%100/10));
              cs1=0;
              cs2=1;
                   hz_display8(0,0,(ad0%10));
                   hz_display8(0,8,18);  //v

               q1=1;                              


                    CCON = 0;                       //PCA控制寄存器CCON
                     CMOD = 0x08;                    //工作模式寄存器CMOD
                     CL = 0;                         //PCA的16位计数器 — 低8位CL和高8位CH
                     CH = 0;
                    CCAPM1 = 0x42;                  //PCA比较/捕获寄存器CCAPMn (n=0,1,2,3) PCA interrupt
                    PCA_PWM1 = 0x40;                                                        //Disable PCA timer overflow interrupt
                     CCAP1H = CCAP1L = 0x01;         //模块0的捕捉/比较寄存器用来控制输出的占?比
                       CCON |= CR;                         //PCA计数器阵列, 运行控制位
                    // while(1);
                                                                                 TR1 = 1;      // 时间
                      ET1 = 1;
                }  
          dyADC();
                                        //ad0=GetADCResult(0);                       
           cs1=0;
           cs2=1;
           hz_display8(0,16,(ad0/100));
           hz_display8(0,24,22);  
           hz_display8(0,32,(ad0%100/10));
           hz_display8(0,40,(ad0%10));
           hz_display8(0,48,18);  //v


            if(fen>=1)LED=0;
            if(ad0<=286)q3=1;
                            while(q3==1)
                               {

                                       LED=~LED;
                                      // CCAP1H = CCAP1L = 0x00;
                                       POW=0;
                                       EA=0;
                                       Delay(500);
                                                                                Delay(500);
                                                                                Delay(500);
                                                                    Delay(500);
                                                                                Delay(500);
                                                                                Delay(500);                                      
                                                                                 Delay(500);
                                                                                Delay(500);
                                                                                Delay(500);
                                                                                dyADC();
                                     //  ad0=GetADCResult(0);
                                                       cs1=0;
                                     cs2=1;
                                                            hz_display8(0,16,(ad0/100));
                                                            hz_display8(0,24,22);  
                                                            hz_display8(0,32,(ad0%100/10));
                                                            hz_display8(0,40,(ad0%10));
                                                            hz_display8(0,48,18);  //v
                                                         
                                                if(!q2)
                                                  {      
                                                   ww*=fen;
                                                   ww*=4;
                                                         cs1=1;
                                                   cs2=2;
                                                hz_display8(6,0,21);  //-------
                                                            hz_display8(6,8,21);
                                                                                                hz_display8(6,16,21);
                                                                                                hz_display8(6,24,21);
                                                                                                hz_display8(6,32,21);
                                                                                                hz_display8(6,40,21);
                                                                                                hz_display8(6,48,21);
                                                                                                hz_display8(6,56,21);
                                                                                          cs1=0;
                                                                                    cs2=1;
                                                                                             hz_display8(6,0,(ww%100000000/10000000));
                                                                           hz_display8(6,8,(ww%10000000/1000000));
                                                                           hz_display8(6,16,(ww%1000000/100000));
                                                                           hz_display8(6,24,(ww%100000/10000));
                                                                           hz_display8(6,32,(ww%10000/1000));
                                                                           hz_display8(6,40,16);  //mah
                                                                           hz_display8(6,48,19);
                                                                           hz_display8(6,56,20);
                                                                  Delay(1000);
                                                                  q2=1;
                                               
                                                      }
                          }


    }
        }

}
void tm0_isr() interrupt 1 using 1
{
  static uchar i1,i2;
        TL0 = 0x30;                //设置定时初值  2ms
        TH0 = 0xF8;                //设置定时初值
        i1++;
  if(i1>=50)
  {
    i1=0;
    i2++;
    if(i2>=10)
            {
             i2=0;
             time1++;
            if(time1>=60)
                   {
                     time1=0;
                     time2++;
                     fen++;
     if(time2>=60)
             {
               time2=0;
                   time3++;
                   if(time3>=24)time3=0;
             }
                    }
                    }
  }
//dyADC();
//ad0=GetADCResult(0);       
}

void tm1_isr() interrupt 3 using 1
{
        TL0 = 0xB0;                                //设置定时初始值
        TH0 = 0x3C;                       //设置定时初值
//dyADC();
        if(ad0>=428)CCAP1H = CCAP1L = 142;    //模块0的捕捉/比较寄存器用来控制输出的占?比
        if(ad0<=427&&ad0>424)CCAP1H = CCAP1L = 142;
        if(ad0<=424&&ad0>420)CCAP1H = CCAP1L = 141;
        if(ad0<=420&&ad0>416)CCAP1H = CCAP1L = 140;
        if(ad0<=416&&ad0>412)CCAP1H = CCAP1L = 139;
        if(ad0<=412&&ad0>408)CCAP1H = CCAP1L = 138;
        if(ad0<=408&&ad0>404)CCAP1H = CCAP1L = 137;
        if(ad0<=404&&ad0>400)CCAP1H = CCAP1L = 136;
        if(ad0<=400&&ad0>396)CCAP1H = CCAP1L = 135;
        if(ad0<=396&&ad0>392)CCAP1H = CCAP1L = 134;
        if(ad0<=392&&ad0>388)CCAP1H = CCAP1L = 132;//
        if(ad0<=388&&ad0>384)CCAP1H = CCAP1L = 131;
        if(ad0<=384&&ad0>380)CCAP1H = CCAP1L = 129;
        if(ad0<=380&&ad0>376)CCAP1H = CCAP1L = 128;
        if(ad0<=376&&ad0>372)CCAP1H = CCAP1L = 127;
        if(ad0<=372&&ad0>368)CCAP1H = CCAP1L = 126;//
        if(ad0<=368&&ad0>364)CCAP1H = CCAP1L = 125;
        if(ad0<=364&&ad0>360)CCAP1H = CCAP1L = 123;
        if(ad0<=360&&ad0>356)CCAP1H = CCAP1L = 122;
        if(ad0<=356&&ad0>352)CCAP1H = CCAP1L = 120;
        if(ad0<=352&&ad0>348)CCAP1H = CCAP1L = 119;
        if(ad0<=348&&ad0>344)CCAP1H = CCAP1L = 117;
        if(ad0<=344&&ad0>340)CCAP1H = CCAP1L = 116;
        if(ad0<=340&&ad0>336)CCAP1H = CCAP1L = 114;
        if(ad0<=336&&ad0>332)CCAP1H = CCAP1L = 113;
        if(ad0<=332&&ad0>328)CCAP1H = CCAP1L = 111;
        if(ad0<=328&&ad0>324)CCAP1H = CCAP1L = 109;
        if(ad0<=324&&ad0>320)CCAP1H = CCAP1L = 108;
        if(ad0<=320&&ad0>316)CCAP1H = CCAP1L = 106;
        if(ad0<=316&&ad0>312)CCAP1H = CCAP1L = 105;
        if(ad0<=312&&ad0>308)CCAP1H = CCAP1L = 103;
        if(ad0<=304&&ad0>300)CCAP1H = CCAP1L = 100;
        if(ad0<=300&&ad0>296)CCAP1H = CCAP1L = 98;
        if(ad0<=296&&ad0>292)CCAP1H = CCAP1L = 97;
        if(ad0<=292&&ad0>288)CCAP1H = CCAP1L = 94;
        if(ad0<=288&&ad0>284)CCAP1H = CCAP1L = 91;
        if(ad0<=284)CCAP1H = CCAP1L = 0xFF;


}







51hei图片_20250127204632.jpg (45.27 KB, 下载次数: 0)

51hei图片_20250127204632.jpg

51hei图片_20250127204656.jpg (75.54 KB, 下载次数: 0)

51hei图片_20250127204656.jpg
回复

使用道具 举报

地板
ID:322197 发表于 2025-1-27 20:59 | 只看该作者
运行时间和检测电压都正常,就是PMW不正常无输出,把ADC关掉PMW有输出
回复

使用道具 举报

5#
ID:1136941 发表于 2025-1-28 11:09 | 只看该作者
mhb7231 发表于 2025-1-27 20:59
运行时间和检测电压都正常,就是PMW不正常无输出,把ADC关掉PMW有输出

这里的TL0,TH0改为TL1,TH1试试

2345截图20250128105954.png (14.06 KB, 下载次数: 0)

2345截图20250128105954.png
回复

使用道具 举报

6#
ID:1136941 发表于 2025-1-28 11:27 | 只看该作者
mhb7231 发表于 2025-1-27 20:59
运行时间和检测电压都正常,就是PMW不正常无输出,把ADC关掉PMW有输出

还有这里的初始化,TL0,TH0改为TL1,TH1

2345截图20250128112237.png (12.13 KB, 下载次数: 0)

2345截图20250128112237.png
回复

使用道具 举报

7#
ID:322197 发表于 2025-1-30 02:35 | 只看该作者
TL0,TH0改为TL1,TH1,还是不行,
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表