打印
[AVR单片机]

自制镍镉、镍氢、锂电池充电器,兼电压源、电流源,可...

[复制链接]
2139|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
whtwhtw|  楼主 | 2015-5-15 17:04 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 whtwhtw 于 2015-5-15 17:06 编辑

手头有一个18650电池,由于没有心仪的充电器,萌生了自己做一个的冲动,想起以前有人做过充电器,借鉴电路也做了一个

电路原理如上图,因为是作为验证机,所以只做了一路,洞洞板见下图

其中左上角的变压器是LM2577驱动的,芯片在洞洞板下面,输入5-12v,输出双12v;右上角是12864液晶屏;中间为ATMeg16单片机,片内8M晶振;单片机左边为4个按键,可以调节是充电模式或者电压源模式或者电流源模式。充电模式也可以选择镍镉电池,镍氢电池还是锂电池。充电器可以检测如果不是锂电池的话在锂电模式下不会充电。而且充电模式下可以检测电池内阻。实时显示电池电压和充电电流。
充电器是分段式充电方式,分别为上电脉冲式检测、恒流脉冲式、恒压模式、涓流模式,最后充电完成
恒压和恒流模式为我提供一种方便的电源,可以调节任意的电压(精度0.01v),下图为恒压模式
下图为恒流模式



相关帖子

沙发
JY-DX-JY| | 2015-5-15 20:58 | 只看该作者
顶一个。

使用特权

评论回复
板凳
whtwhtw|  楼主 | 2015-5-17 14:00 | 只看该作者
主程序
void main(void)
{
    init();
        
    ADC_Init();
    InitLCD();  //液晶初始化
    batty_init();
        
    OSTaskSuspend(1);
    OSTaskSuspend(2);               //挂起恒压和恒流程序,开启充电模式
   
    #asm("sei");  
while (1)
      {
      //调试用led灯
      //RunTask(Change_LED1,0); //RunTask(Change_LED2,1);
      
      RunTask(chongdian,0);        //充电程序
      
      RunTask(hengyayuan,1);       //恒压源程序
      
      RunTask(hengliuyuan,2);      //恒流源程序     初始化挂起,所以初始化后不运行恒压、恒流程序
      
      RunTask(ShowScreen1,3);      //显示基本数据
      
      RunTask(KEY_Data_Show,4);     //键盘处理函数
      }
}

使用特权

评论回复
地板
whtwhtw|  楼主 | 2015-5-17 14:01 | 只看该作者
调度器部分
#ifndef _OS_H
#define _OS_H

/****调度器开始**********************************************/
#define MAXTASKS 5
static unsigned int timers[MAXTASKS];
unsigned long int currdt;           //系统时钟
#define _SS static unsigned int _lc; switch(_lc){default:
#define _EE ;}; _lc=0; return 0xffff;
#define WaitX(tickets)  do {_lc=__LINE__+((__LINE__%65536)==0); return tickets ;} while(0); case __LINE__+((__LINE__%65536)==0):
#define RunTask(TaskName,TaskID) do { if (timers[TaskID]==0) timers[TaskID]=TaskName(); }  while(0);

#define CallSub(SubTaskName) do {_lc=__LINE__+((__LINE__%65536)==0); return 0; case __LINE__+((__LINE__%65536)==0):  currdt=SubTaskName(); if(currdt!=0xffff) return currdt;} while(0);
#define UpdateTimers() unsigned char i; for(i=MAXTASKS;i>0;i--){if((timers[i-1]!=0)&&(timers[i-1]!=0xffff)) timers[i-1]--;}

#define SEM unsigned int
//初始化信号量
#define InitSem(sem) sem=0;
//等待信号量
#define WaitSem(sem) do{ sem=1; WaitX(0); if (sem>0) return 1;} while(0);
//等待信号量或定时器溢出, 定时器tickets 最大为0xFFFE
#define WaitSemX(sem,tickets)  do { sem=tickets+1; WaitX(0); if(sem>1){ sem--;  return 1;} } while(0);
//发送信号量
#define SendSem(sem)  do {sem=0;} while(0);

//任务的挂起与恢复
#define OSTaskSuspend(Prio)  timers[Prio]=0xffff
#define OSTaskResume(Prio)   timers[Prio]=0

//取系统时钟
unsigned long int getsystick(void)
{
    return  currdt;
}
//设置系统时钟
void setsystick(unsigned long int systick)
{
    currdt=systick;
}

/*****调度器结束*******************************************************/
#endif

使用特权

评论回复
5
whtwhtw|  楼主 | 2015-5-17 14:03 | 只看该作者
系统时钟
//定时器中断,产生SYSTICK时钟,10ms;
interrupt [TIM0_COMP] void timer0_comp_isr(void)
{
            // OCV0置0                                                            
       UpdateTimers();
       currdt++;        //系统时钟
       TIFR|=0x02;
}

使用特权

评论回复
6
whtwhtw|  楼主 | 2015-5-20 07:34 | 只看该作者
本帖最后由 whtwhtw 于 2015-5-22 10:08 编辑

..............

使用特权

评论回复
7
whtwhtw|  楼主 | 2015-5-28 19:14 | 只看该作者
怎么结贴啊,老显示未结贴。。。

使用特权

评论回复
8
pallee| | 2015-5-28 22:45 | 只看该作者
楼主无敌~赞一个

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

72

主题

2501

帖子

35

粉丝