找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2282|回复: 3
收起左侧

萌新提问:STC51单片机如何根据电池中电压的大小来控制LED亮暗的个数

[复制链接]
ID:811125 发表于 2020-8-9 15:54 | 显示全部楼层 |阅读模式
      我师傅给我布置了一个任务(如下),我自己编写了一段代码(如下),但是只能和一个给定的电压值进行比较,但是我不知道怎么样和多个给定的电压值进行,比较,有没有懂哥告诉我一下呀。        利用stc15w204S内部的比较器,设计一款3.7V电压比较器,用来判断电池电压,用4颗LED作为电量指示灯。
当电池电压大于3.3V显示1颗LED,
电压大于3.4V显示2颗LED,
电压大于3.5V显示3颗LED,
电压大于3.6V显示4颗LED;


#include        "STC15.h"
#define u8  uint8_t
#define u16 uint16_t
#define u32 uint32_t
typedef unsigned char    uint8_t;
typedef unsigned int     uint16_t;
typedef unsigned long    uint32_t;
sfr CMOCR1  =   0XE6;
sfr CMPCR2  =   0XE7;
#define CMPEN   0x80
#define CMPIE   0x40
#define PIE     0x20
#define NIE     0x10
#define PIS     0x08
#define CMPOE   0x02
#define CMPRES  0x01
#define INVCMPO 0x80
#define DLSFLT  0x40
#define LCDTY   0x3F

void cmp_int() interrupt 21

void main(void)
{
    unsigned int j=0;
          P4^6=0;
          CMOCR1=0;
          CMPCR2=0;
          PIS=0;
          NIS=0;
          CMPOE=0;
          INVCMPO=0;
          DISFLT=0;
          CMPCR2|=(DISFLT&0x10);
          PIE=1;
          CMPEN=1;
          EA=1;
          while(1)
                {
      if((CMPCR1&0x01)==0)
                        {
        P4^6=1;
      }
    }
}
回复

使用道具 举报

ID:213173 发表于 2020-8-9 20:59 | 显示全部楼层
最好用有内置ADC的芯片,例如15WS404AS。非得用STC15W204S那只能模拟ADC功能,把下面程序的串口发送部分改成LED显示即可。
/*------------------------------------------------------------------*/
/* --- STC MCU International Limited -------------------------------*/
/* --- STC 1T Series MCU RC Demo -----------------------------------*/
/* --- Mobile: (86)13922805190 -------------------------------------*/
/* --- Fax: 86-755-82944243 ----------------------------------------*/
/* --- Tel: 86-755-82948412 ----------------------------------------*/
/* If you want to use the program or the program referenced in the  */
/* article, please specify in which data and procedures from STC    */
/*------------------------------------------------------------------*/

/*

功能描述: 使用STC15F系列C版本做的RC测量电压的例子.

*/
#include "reg51.h"
/********宏定义*******/
#define MAIN_Fosc                22118400L        //定义主时钟
#define        uchar        unsigned char
#define uint        unsigned int
/********特殊功能寄存器*******/
sfr AUXR = 0x8e;    //Auxiliary register
sfr P3M1  = 0xB1;        //P3M1.N,P3M0.N         =00--->Standard,        01--->push-pull
sfr P3M0  = 0xB2;        //                                        =10--->pure input,        11--->open drain
/********端口定义*******/
sbit P_TXD1  = P3^1;        //定义模拟串口发送脚,打印信息用
sbit P_RC = P3^2;                //RC 检测端口
/********变量与子程序声明*******/
uchar        SampleCnt;                //发送结果的采样间隔计数
uchar        LineCnt;                //每行显示结果计数
bit                B_Over;                        //超量程标志
bit                B_ADC_OK;                //检测完成标志
uint        adc;                        //RC做的ADC值

void        RC_start(void);                //RC检测开始
void        Tx1Send(uchar dat);        //发送数据
void         InitTimer(void);        //初始化定时器
void        delay_ms(uchar ms);        //延时

///////////////////////////////////////////////////////////

void main(void)
{        
        InitTimer();                //初始化定时器
        P3M1 |=  1 << 2;         //P3.2 开漏模式
        P3M0 |=  1 << 2;
        P_RC = 0;               //RC 检测端口

        while (1)
        {
                delay_ms(5);                //放电时间        
                B_ADC_OK = 0;                //清除ADC结束标志        
                B_Over = 0;                        //清除超量程标志
                RC_start();         //RC 检测开始
                while(!B_ADC_OK && !B_Over);        //等待ADC结束或超量程
                if(B_ADC_OK)                                        //检测完成标志为1
                {
                        if(++SampleCnt >= 100)        //1秒钟发一个结果给串口
                        {
                                SampleCnt = 0;
                                Tx1Send(adc / 10000 + '0');           //send to PC from the UART
                                Tx1Send(adc % 10000 / 1000 + '0');
                                Tx1Send(adc % 1000 / 100 + '0');
                                Tx1Send(adc % 100 / 10 + '0');
                                Tx1Send(adc % 10 + '0');
                                Tx1Send(' ');
                                Tx1Send(' ');
                                if(++LineCnt >= 10)                //10个结果后换行
                                {
                                        LineCnt = 0;
                                        Tx1Send(0x0d);   //send CR
                                        Tx1Send(0x0a);
                                }
                        }
                }
        }
}

/***************延时函数*****************/
void  delay_ms(uchar ms)
{
        uint i;
        do
        {
                i = MAIN_Fosc / 14000L;        //1T
                while(--i)        ;   //13T per loop
        }while(--ms);
}
/**************** Timer初始化函数 ************/
void InitTimer(void)
{
        TMOD = 0;                //16位自动重装
        TH0  = 0;                //
        TL0  = 0;                //
        TR0  = 0;                //关定时器0
        ET0  = 1;                //开定时器0中断
        EA   = 1;                //开总中断
}
/********************* INT0外部中断函数 *************************/
void INT0_int () interrupt 0                //
{
        if(INT0 && !B_Over)                //上升沿中断,无超时
        {
                TR0 = 0;            //关定时器0
                P_RC = 0;           //RC 检测端口置0
                adc = TH0;          //读定时寄存器高8位数据
                adc =(adc<<8)+TL0;        //高8位数据+低8位数据
                B_ADC_OK = 1;                //标志ADC结束
        }
}
/********************** Timer0中断函数************************/
void timer0 (void) interrupt 1
{
        TR0 = 0;        //超量程关闭
        B_Over = 1;        //标志超量程
}
/**************** RC启动函数 ******************************/
void RC_start()
{                                       //使用定时器0计时
        TH0 = 0;            //计数寄存器清0
        TL0 = 0;
        B_Over = 0;                        //超时标志清0
        P_RC = 1;           //RC 检测端口置1
        TR0 = 1;            //开启定时器
        IE0 = 0;                        //外部中断0请求标志清0
        EX0 = 1;                        //INT0 开外中断
        IT0 = 0;                        //INT0 上升/下降沿均可触发中断        
}
/********************** 模拟串口相关函数************************/

void BitTime(void)        //位时间函数
{
        uint i;
        i = ((MAIN_Fosc / 100) * 104) / 130000L - 1;                //根据主时钟来计算位时间
        while(--i);
}

//模拟串口发送
void Tx1Send(uchar dat)                //9600,N,8,1                发送一个字节
{
        uchar        i;
        EA = 0;
        P_TXD1 = 0;
        BitTime();
        for(i=0; i<8; i++)
        {
                if(dat & 1)
                        P_TXD1 = 1;
                else
                        P_TXD1 = 0;
                dat >>= 1;
                BitTime();
        }
        P_TXD1 = 1;
        EA = 1;
        BitTime();
        BitTime();
}
回复

使用道具 举报

ID:123289 发表于 2020-8-10 13:30 | 显示全部楼层
改行吧,不太适合学这个专业。
回复

使用道具 举报

ID:811125 发表于 2020-8-12 15:47 | 显示全部楼层
wulin 发表于 2020-8-9 20:59
最好用有内置ADC的芯片,例如15WS404AS。非得用STC15W204S那只能模拟ADC功能,把下面程序的串口发送部分改 ...

谢谢您!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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