A50 - Design of solar charging street lamp based on 51 microcontroller

Task

This article takes the design of solar street lamps as an example, and introduces the basic principles and components of solar street lamps based on the advantages and development background of solar street lamps. According to the program demonstration of solar panels, batteries, controller chips and other components. It is finally determined that photovoltaic power generation is used to provide electric energy support from solar panels and batteries, and under the action of the controller, the time display module and the LED driver module are controlled. Through the debugging and testing of solar street lights, the final solar street lights have the characteristics of high safety, easy maintenance, no pollution and automation.

Physical map

insert image description here

Principle design

insert image description here
insert image description here
insert image description here
insert image description here

Charge and discharge module

The device uses solar power to charge the battery module through trickle current. The battery module is used for power output. The physical simulation of this system uses a lithium battery with a 3.7V output. Because the system requires a 5V voltage, a booster module is used to convert the 3.7V output from the battery into 5V. The system supplies power. Figure 4-3 shows the power output circuit of the system, and Figure 4-4 shows the circuit diagram of the boost module used this time.
insert image description here

source code

/*******************************************************************************

\* 文件名称:基于51单片机的太阳能充电路灯设计

\* 实验目的:1.

\* 2.

\* 程序说明:定制可联系Q:2772272579;@: itworkstation@ hotmail.com

\* 日期版本:本项目已分享全部代码,熟悉使用单片机的可做参考代码。可定制。

*******************************************************************************/
#include<reg52.h>
#include<intrins.h>
/*******************************定义全局变量********************************/
unsigned char data1;  //AD转换值
long Value;           //光照强度值
unsigned int baojing=300;  //开灯阀值
/******************引脚定义********************/
sbit bADcs=P1^3;//ADC0832 引脚定义
sbit bADcl=P1^4;
sbit bADda=P1^5;
sbit  key1 = P3^7;//加键
sbit  key2 = P3^6;//减键
sbit  led = P1^6; //LED灯控制引脚
/*******************************函数声明********************************/
unsigned char IntToString(unsigned char *str, int dat);	 	//数字转字符串函数
extern void InitLcd1602();	//液晶初始化函数
extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str); //液晶显示字符串函数
/*******************延时函数*******************/
void Delay_Ms (unsigned int a)
{
    
    
	unsigned int i;
	while( a-- != 0)
	{
    
    
		for(i = 0; i < 600; i++);
	}
}
 /**********模数转换,光照检测子程序****************/ 
long kssj()   //开始收集
 {
    
    
   unsigned char i;

     bADcs = 0;//当ADC0832未工作时其CS输入端应为高电平,此时芯片禁用.
	 bADcl=0;
	 bADda=1;
	 bADcl=1;
	 bADcl=0;//i down
	 bADda=1;
	 bADcl=1;
	 bADcl=0;	//   2 down
	 bADda=0;
	 bADcl=1;
	 bADcl=0;	//   3 down
	 bADda=1;
	 bADcl=1;
	 bADcl=0;	//   4 down
	 for(i=8;i>0;i--)
	 	{
    
    
		
	 	data1<<=1;
	 	bADcl=0;
		bADcl=1;
		if(bADda==1) data1|=0x01;
		   	bADda=1;
	 	}
		 bADcs=1;
	  if(data1!=128)
	  {
    
    
	    Value=500-data1*1.96;	//ADC转换器的分辨率是255,转换成500要乘以1.96 得出A。   然后由于电路中光照越强A越小,所以再让500-A。
	
	  }	      	   
	   return Value;
 }
 /*****************按键扫描子程序*******************************/
void Key_set_scan()
{
    
        
   unsigned char buff[5];//设置值 	
	if(key1==0)	  //加键按下
	{
    
    
	   Delay_Ms(10);    //延时消抖
		if(key1==0)
		{
    
      
		  // while(!key1);
		   baojing++;		//开灯阀值加1
		   if(baojing>=500) baojing = 500;	//最大为500
		    buff[0] = baojing/100+0x30;		//获取开灯阀值百位,并转换为字符
            buff[1] = baojing%100/10+0x30;	//十位
            buff[2] = baojing%10+0x30;		//个位
            buff[3] = '\0';				    //结束符
            LcdShowStr(4, 1,buff);			//液晶显示开灯阀值		  
		}
	}	
	if(key2==0)	   //减键按下
	{
    
    
	   Delay_Ms(10); //延时消抖
		if(key2==0)
		{
    
      
		  // while(!key2);
		   baojing--;	  //开灯阀值减1
		   if(baojing<=0) baojing = 0;	//最小为0
		     buff[0] = baojing/100+0x30;  	//百位
            buff[1] = baojing%100/10+0x30;	//十位
            buff[2] = baojing%10+0x30;		//个位
            buff[3] = '\0';					//结束符
            LcdShowStr(4, 1,buff);			//液晶显示开灯阀值		  
		}
	}		 
}
/*------------------------------------------------
                    系统主程序
------------------------------------------------*/
void main()
{
    
    
  unsigned char str_yw[12];//光照强度显示缓存
  InitLcd1602();     //初始化液晶
  LcdShowStr(0, 0,"Light:   Lx");	//显示初始界面	光照单位勒克斯(lux或lx)
  LcdShowStr(0, 1,"Set:300Lx");	   //显示初始界面
  while(1)
 {
    
    
   
   Key_set_scan(); //按键扫描 
   kssj();  //模数转换,采集检测光照强度
   str_yw[0] = Value/100+0x30;	  //获取光照值百位,并转换为字符
   str_yw[1] = Value%100/10+0x30; //十位
   str_yw[2] = Value%10+0x30;	  //个位
   str_yw[3] = '\0';			  //结束符
   LcdShowStr(6, 0,str_yw);    //显示检测到的光照强度

   if(Value<=baojing) //光照值小于开灯阀值
	led = 0 ;	     //LED灯亮
   else
    led = 1;	     //LED灯灭 
   Delay_Ms(10);//延时防止刷新太快
 }
}
/* 整型数转换为字符串,str-字符串指针,dat-待转换数,返回值-字符串长度 */
unsigned char IntToString(unsigned char *str, int dat)
{
    
    
    signed char i = 0;
    unsigned char len = 0;
    unsigned char buf[6];
    
    if (dat < 0)  //如果为负数,首先
	
    {
    
    
        dat = -dat;
        *str++ = '-';
        len++;
    }
    do {
    
              //先转换为低位在前的十进制数组
        buf[i++] = dat % 10;
        dat /= 10;
    } while (dat > 0);
    len += i;     //i最后的值就是有效字符的个数
    while (i-- > 0)   //将数组值转换为ASCII码反向拷贝到接收指针上
    {
    
    
        *str++ = buf[i] + '0';
    }

    *str = '\0';  //添加字符串结束符
    
    return len;   //返回字符串长度
}

LCD1602 Liquid Crystal Driver

#include <reg52.h>

#define LCD1602_DB  P0
sbit LCD1602_RS = P1^0;
sbit LCD1602_RW = P1^1;
sbit LCD1602_E  = P1^2;

/* 等待液晶准备好 */
void LcdWaitReady()
{
    
    
    unsigned char sta;
    
    LCD1602_DB = 0xFF;
    LCD1602_RS = 0;
    LCD1602_RW = 1;
    do {
    
    
        LCD1602_E = 1;
        sta = LCD1602_DB; //读取状态字
        LCD1602_E = 0;
    } while (sta & 0x80); //bit7等于1表示液晶正忙,重复检测直到其等于0为止
}
/* 向LCD1602液晶写入一字节命令,cmd-待写入命令值 */
void LcdWriteCmd(unsigned char cmd)
{
    
    
    LcdWaitReady();
    LCD1602_RS = 0;
    LCD1602_RW = 0;
    LCD1602_DB = cmd;
    LCD1602_E  = 1;
    LCD1602_E  = 0;
}
/* 向LCD1602液晶写入一字节数据,dat-待写入数据值 */
void LcdWriteDat(unsigned char dat)
{
    
    
    LcdWaitReady();
    LCD1602_RS = 1;
    LCD1602_RW = 0;
    LCD1602_DB = dat;
    LCD1602_E  = 1;
    LCD1602_E  = 0;
}
/* 设置显示RAM起始地址,亦即光标位置,(x,y)-对应屏幕上的字符坐标 */
void LcdSetCursor(unsigned char x, unsigned char y)
{
    
    
    unsigned char addr;
    
    if (y == 0)  //由输入的屏幕坐标计算显示RAM的地址
        addr = 0x00 + x;  //第一行字符地址从0x00起始
    else
        addr = 0x40 + x;  //第二行字符地址从0x40起始
    LcdWriteCmd(addr | 0x80);  //设置RAM地址
}
/* 在液晶上显示字符串,(x,y)-对应屏幕上的起始坐标,str-字符串指针 */
void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str)
{
    
    
    LcdSetCursor(x, y);   //设置起始地址
    while (*str != '\0')  //连续写入字符串数据,直到检测到结束符
    {
    
    
        LcdWriteDat(*str++);
    }
}
/* 初始化1602液晶 */
void InitLcd1602()
{
    
    
    LcdWriteCmd(0x38);  //16*2显示,5*7点阵,8位数据接口
    LcdWriteCmd(0x0C);  //显示器开,光标关闭
    LcdWriteCmd(0x06);  //文字不动,地址自动+1
    LcdWriteCmd(0x01);  //清屏
}

Guess you like

Origin blog.csdn.net/qq_20467929/article/details/126118435