标题:
stc12c5a60s2单片机锂电池放电装置源码参考(实测可用无电路图)
[打印本页]
作者:
小丁one
时间:
2018-7-7 22:03
标题:
stc12c5a60s2单片机锂电池放电装置源码参考(实测可用无电路图)
如题所示,附件压缩包有oled屏幕程序以及菜单的例程
单片机源程序如下:
//////////////////////////////////////////////////////////////////////////////////
// @文 件 名 : main.c
// @版 本 号 : v1.0
// @功能描述 : 放电器主函数
// @author :Mr.Z
// @QQ :
// @说明 :
// ----------------------------------------------------------------
// GND 电源地
// VCC 接5V或3.3v电源
// D0 P3^5(SCL)
// D1 P3^7(SDA)
// RES 接P12
// DC 接P13
// CS 接P14
// ----------------------------------------------------------------
// @注意 :版权所有,如用作任何商业用途,须和本人联系
//******************************************************************************/
#include "REG51.h"
#include "oled.h"
//#include "bmp.h"
#include <intrins.h>
#include "51_UART_RECEIVE.h"
//#include <math.h>
#define Dot_Size 2 // ??????
//#define uint unsigned int
//#define uchar unsigned char
#define U8 unsigned char
#define U16 unsigned int
#define uchar unsigned char
#define uint unsigned int
float Voltage1=4.2;
float Voltage2;
float ad0,ad1;
char String[5];
int time,key;
char temp,menu,t,sbuf0;
char pwm=0x40;
char pwm1;
extern char uart_receive_number;
//sbit ad1=P1^0;
//sbit ad2=P1^1; //
sbit int1=P1^2;
sbit int2=P1^3;
sbit int3=P1^4;
sbit int4=P1^5;
sbit LF=P3^4;
sbit L1=P3^2;
sbit F1=P0^5;
sbit F2=P0^7;
void hanshutiaodong(menu);
void keyscan();
/********************************************************************
初始化设置
*********************************************************************/
sfr ADC_CONTR = 0xBC; //ADC 控制寄存器
sfr ADC_RES = 0xBD; //ADC 转换结果寄存器
sfr ADC_LOW2 = 0xBE; //ADC 低2位结果寄存器
sfr P1ASF = 0x9D; //Pl口模拟功能控制寄存器
/********************************************************************
/********************************************************************
延时函数
*********************************************************************/
void Delay(U16 n)
{
U16 x;
while (n--)
{
x = 5000;
while (x--);
}
}
void delay(void)
{
unsigned char i,j;
for(i = 0; i < 255; i++)
{
for(j = 0; j < 200; j++);
}
}
void delaykey(uchar z)
{
uchar x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void delaydianya(uchar zzz)
{
uchar xxx,yyy;
for(xxx=zzz;xxx>0;xxx--)
for(yyy=110;yyy>0;yyy--)
keyscan();
}
/********************************************************************
ADC 数据转换函数
*********************************************************************/
#define ADC_POWER 0x80 //ADC 电源控制位
#define ADC_FLAG 0x10 //ADC 转换结束标志位
#define ADC_START 0x08 //ADC 开始转换控制位
#define ADC_SPEEDLL 0x00 //420 个时钟周期转换一次
#define ADC_SPEEDL 0x20 //280 个时钟周期转换一次
#define ADC_SPEEDH 0x40 //140 个时钟周期转换一次
#define ADC_SPEEDHH 0x60 //70 个时钟周期转换一次
/********************************************************************
ADC 初始化
*********************************************************************/
void InitADC()
{
P1ASF = 0x05; //设置P1口为开漏模式,使用AD功能(0000 0101)
ADC_RES = 0; //AD数据寄存器清空
ADC_CONTR = ADC_POWER | ADC_SPEEDLL; //打开AD电源,转换周期420
Delay(2); //延时
}
/*********************************************************************
中断初始化
**********************************************************************/
void initzhongduan()
{
time=0;
temp=0xfe;
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
/********************************************************************
ADC 数据转换函数
*********************************************************************/
U8 GetADCResult(U8 ch)
{
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;//开始转换
_nop_(); //延时一个机器周期
_nop_(); //延时一个机器周期
_nop_(); //延时一个机器周期
_nop_(); //延时一个机器周期
while (!(ADC_CONTR & ADC_FLAG));//等待转换结束
ADC_CONTR &= ~ADC_FLAG; //关闭AD转换
return ADC_RES; //返回数据
}
/********************************************************************
初始化定义函数
*********************************************************************/
sfr CCON = 0xD8; //PCA控制寄存器
sfr CMOD = 0xD9; //PCA模式寄存器
sfr CCAPM0 = 0xDA; //PCA模块0模式寄存器 //模块0对应P1.3/CEX0/PCA0/PWM0(STC12C5A60S2系列)
sfr CCAPM1 = 0xDB; //PCA模块1模式寄存器 //模块1对应P1.4/CEX1/PCA1/PWM1(STC12C5A60S2系列)
sfr CL = 0xE9; //PCA 定时寄存器 低位
sfr CH = 0xF9; //PCA 定时寄存器 高位
sfr CCAP0L = 0xEA; //PCA模块0的 捕获寄存器 低位
sfr CCAP0H = 0xFA; //PCA模块0的 捕获寄存器 高位
sfr CCAP1L = 0xEB; //PCA模块1的 捕获寄存器 低位
sfr CCAP1H = 0xFB; //PCA模块1的 捕获寄存器 高位
sfr PCA_PWM0 = 0xF2; //PCA PWM 模式辅助寄存器0
sfr PCA_PWM1 = 0xF3; //PCA PWM 模式辅助寄存器1
sbit CF = 0xDF; //PCA计数溢出标志位
sbit CR = 0xDE; //PCA计数器 运行控制位
sbit CCF1 = 0xD9; //PCA模块1中断标志
sbit CCF0 = 0xD8; //PCA模块0中断标志
//* CCAPOH = CCAPOL = 0XC0; //模块0输出 占空因数为25%
//* CCAPOH = CCAPOL = 0X80; //模块0输出 占空因数为50%
//* CCAPOH = CCAPOL = 0X40; //模块0输出 占空因数为75%
/********************************************************************
PWN时钟函数
*********************************************************************/
void PWM_clock(U8 clock)
{
CMOD |= (clock<<1);
CL = 0x00; //定时寄存器低位
CH = 0x00; //定时寄存器高位
}
/********************************************************************
PWM输出函数函数
*********************************************************************/
void PWM_start(a)
{
/********************设置PWM信号输出值*******************************/
//n=m=0x40;
//CCAPM0 = 0X42;
a=0x00;
CCAPM1 =a;
//CCAP0H = CCAP0L = 0X40; //模块0输出 占空因数为75%
CCAP1H = CCAP1L = 0X40; //模块1输出 占空因数为75%
CR=1; //PCA计数器开始计数
}
/********************************************************************
定时器函数
*********************************************************************/
void PCA_Intrrpt(void) interrupt 7
{
if(CCF0) CCF0=0;
if(CCF1) CCF1=0; //软件清零
if(CF) CF=0; //软件清零
}
void yichu()
{
TMOD|=0x02; /* timer 0 mode 2: 8-Bit reload */
TH0=0xff;
TR0=1;
PWM_clock(2); // PCA/PWM时钟源为 定时器0的溢出
}
void PWM(U8 m,U8 n)
{
CCAP0L =m;
CCAP0H =m;
CCAP1L = n;
CCAP1H = n;
}
/*------------------*浮点型转字符串*------------------*/
char Float_To_String(float Float_Num)
// Dot_Size??????????
// ???????
{
//char String[5];
char Num_Length=0;
int Temp_i=0;
char *Point_p=String; //????????
char *Point_s=String;
char Negative_Flag=0;
long Predot_Num;
long Afterdot_Num;
float Afterdot_Float;
if(Float_Num<0)
{
Negative_Flag=1;
Float_Num=0-Float_Num;
}
Predot_Num=(long)Float_Num; //????????????
Afterdot_Float=Float_Num-Predot_Num; //???????????
for(Temp_i=Dot_Size;Temp_i>0;Temp_i--)
{
Afterdot_Float=Afterdot_Float*10;
}
Afterdot_Num=(long)Afterdot_Float;
Temp_i=Dot_Size;
while(Afterdot_Num>0|Temp_i>0)
{
Temp_i--;
String[Num_Length++]=Afterdot_Num%10+'0';
Afterdot_Num=Afterdot_Num/10;
}
String[Num_Length++]='.';
if(Predot_Num==0) //???????0???
String[Num_Length++]='0';
while(Predot_Num>0)
{
String[Num_Length++]=Predot_Num%10+'0';
Predot_Num=Predot_Num/10;
}
if(Negative_Flag==1)
String[Num_Length++]='-';
String[Num_Length]='\0'; //?????????
Point_p=String+Num_Length-1; //?P?????????????
for(;Point_p-Point_s>0;Point_p--,Point_s++) //???????????
{
*Point_s^=*Point_p;
*Point_p^=*Point_s;
*Point_s^=*Point_p;
}
return(String);
}
/*********************************************************
AD键盘扫描函数
*********************************************************/
void keyscan()
{
ad1=GetADCResult(2);
key=ad1;
if(key<250)
{
delaykey(5);
key=ad1;
if(key<=250)
{
switch(key)
{
case 0: //确认键
{
switch(menu) //不同的页数,菜单不同的作用选择
{
case 1://第一页
{
switch(t)
{
case 3:
{
hanshutiaodong(3);
break;
}
case 6:
{
hanshutiaodong(4);
break;
}
}
}
case 2://第二页
{
switch(t)
{
case 3:
{
hanshutiaodong(5);
break;
}
}
break;
}
case 3://第三页
{
break;
}
case 4://第四页
{
break;
}
}
while(key<=250)//松开按键扫
{
ad1=GetADCResult(2);
key=ad1;
}
break;
}
case 127: //加↑
{
switch(menu)
{
case 1:
{
OLED_ShowString(6,t," ",16);
t+=3;
menu=(t+3)/6;
if(t>=7)
{
hanshutiaodong(menu);
t=t%6;
}
OLED_ShowString(6,t,"&",16);
while(key<=250)//松开按键扫
{
ad1=GetADCResult(2);
key=ad1;
}
break;
}
case 2:
{
OLED_ShowString(6,t," ",16);
if(t>=7)
{
t=0;
}
t+=3;
if(t>=6)
{
t=6;
}
OLED_ShowString(6,t,"&",16);
while(key<=250)//松开按键扫
{
ad1=GetADCResult(2);
key=ad1;
}
break;
}
case 4: //电压设定的加减值
{
Voltage1+=0.05;
Float_To_String(Voltage1); //电压的设定值
OLED_ShowString(80,3,String,16);
while(key<=250)//松开按键扫
{
ad1=GetADCResult(2);
key=ad1;
}
break;
}
case 5:
{
pwm+=5;
OLED_ShowNum(40,6,pwm1,16);//变量显示
while(key<=250)//松开按键扫
{
ad1=GetADCResult(2);
key=ad1;
}
break;
}
case 6:
{
break;
}
case 7:
{
break;
}
}
break;
}
case 170: //减↓
{
switch(menu)
{
case 1:
{
OLED_ShowString(6,t," ",16);
t-=3;
if(t<=3)
{
t=3;
}
OLED_ShowString(6,t,"&",16);
while(key<=250)//松开按键扫
{
ad1=GetADCResult(2);
key=ad1;
}
break;
}
case 2:
{
OLED_ShowString(6,t," ",16);
t-=3;
if(t<3)
{
t=6;
menu=1;
hanshutiaodong(menu);
}
OLED_ShowString(6,t,"&",16);
while(key<=250)//松开按键扫
{
ad1=GetADCResult(2);
key=ad1;
}
break;
}
case 4: //电压设定的加减值
{
Voltage1-=0.05;
Float_To_String(Voltage1); //电压的设定值
OLED_ShowString(80,3,String,16);
while(key<=250)//松开按键扫
{
ad1=GetADCResult(2);
key=ad1;
}
break;
}
case 5:
{
pwm-=5;
OLED_ShowNum(40,6,pwm1,16);//变量显示
while(key<=250)//松开按键扫
{
ad1=GetADCResult(2);
key=ad1;
}
break;
}
}
break;
}
case 191: //返回首页
{
t=3;
hanshutiaodong(1);
while(key>=250)//松开按键扫
{
key=ad1;
}
break;
}
case 192: //返回首页
{
TR1 = 0; //关闭定时器1
ES = 0; //关闭串口中断
t=3;
hanshutiaodong(1);
while(key<=250)//松开按键扫
{
ad1=GetADCResult(2);
key=ad1;
}
break;
}
}
}
}
}
/**************************************************************************
OLED函数
***************************************************************************/
void oled(void)
{
menu=0;
OLED_Init(); //初始化OLED
OLED_Clear();
OLED_ShowCHinese(0,0,0);//
OLED_ShowCHinese(18,0,1);//
OLED_ShowCHinese(36,0,2);//
OLED_ShowCHinese(54,0,3);//
OLED_ShowCHinese(72,0,4);//
OLED_ShowCHinese(91,0,5);//科
OLED_ShowCHinese(108,0,6);//技
OLED_ShowString(6,3,"Ver3.0 XD-One",16);
OLED_ShowString(6,6,"TRRANS FORCE",16);
delay_ms(1000);
}
int oledxuanxiang1(void)
{
menu=1;
OLED_Init(); //初始化OLED
OLED_Clear();
OLED_ShowCHinese(6,0,13);//模式选择
OLED_ShowCHinese(38,0,14);//
OLED_ShowCHinese(70,0,11);//
OLED_ShowCHinese(102,0,12);//
OLED_ShowString(6,t,"&",16);
OLED_ShowCHinese(26,3,15);//蓝牙模式
OLED_ShowCHinese(44,3,16);//
OLED_ShowCHinese(62,3,13);//
OLED_ShowCHinese(80,3,14);//
OLED_ShowCHinese(26,6,17);//放电模式
OLED_ShowCHinese(44,6,18);//
OLED_ShowCHinese(62,6,13);//
OLED_ShowCHinese(80,6,14);//
while(1)
{
keyscan();
}
}
void oledxuanxiang2(void)
{
menu=2;
OLED_Init(); //初始化OLED
OLED_Clear();
OLED_ShowCHinese(6,0,13);//模式选择
OLED_ShowCHinese(38,0,14);//
OLED_ShowCHinese(70,0,11);//
OLED_ShowCHinese(102,0,12);//
OLED_ShowString(6,3,"&",16);
OLED_ShowString(26,3,"PWM",16);
OLED_ShowCHinese(56,3,13);//模
OLED_ShowCHinese(80,3,14);//式
OLED_ShowCHinese(26,6,39);//数字时钟
OLED_ShowCHinese(44,6,40);//
OLED_ShowCHinese(62,6,41);//
OLED_ShowCHinese(80,6,42);//
}
void oled_lanya(void)
{
menu=3;
OLED_Init(); //初始化OLED
OLED_Clear();
OLED_ShowCHinese(6,0,15);//蓝牙模式
OLED_ShowCHinese(38,0,16);//
OLED_ShowCHinese(70,0,13);//
OLED_ShowCHinese(102,0,14);//
OLED_ShowCHinese(45,3,15);//蓝牙
OLED_ShowCHinese(65,3,16);//
OLED_ShowCHinese(28,6,24);//未连接
OLED_ShowCHinese(53,6,22);//
OLED_ShowCHinese(78,6,23);//
while(1)
{
keyscan();
receive();
if(uart_receive_number)
{
//OLED_ShowNum(20,3,sbuf0,16);//变量显示
switch(sbuf0)
{
case 1:
{
L1=0;
OLED_ShowCHinese(45,3,46);//照明
OLED_ShowCHinese(65,3,47);//
OLED_ShowCHinese(28,6,21);//已打开
OLED_ShowCHinese(53,6,50);//
OLED_ShowCHinese(78,6,43);//
break;
}
case 2:
{
L1=1;
OLED_ShowCHinese(45,3,46);//照明
OLED_ShowCHinese(65,3,47);//
OLED_ShowCHinese(28,6,21);//已关闭
OLED_ShowCHinese(53,6,44);//
OLED_ShowCHinese(78,6,50);//
break;
}
/*case 3:
{
OLED_Clear();
OLED_ShowCHinese(6,0,15);//蓝牙模式
OLED_ShowCHinese(38,0,16);//
OLED_ShowCHinese(70,0,13);//
OLED_ShowCHinese(102,0,14);//
OLED_ShowCHinese(45,3,15);//蓝牙
OLED_ShowCHinese(65,3,16);//
OLED_ShowCHinese(28,6,21);//已连接
OLED_ShowCHinese(53,6,22);//
OLED_ShowCHinese(78,6,23);//
L1=0;
L2=0;
break;
}*/
}
//delaydianya(200);
}
}
}
int oled_fangdian(void)
{
menu=4;
OLED_Init(); //初始化OLED
OLED_Clear();
OLED_ShowCHinese(6,0,17);//放电模式
OLED_ShowCHinese(38,0,18);//
OLED_ShowCHinese(70,0,13);//
OLED_ShowCHinese(102,0,14);//
OLED_ShowCHinese(0,3,37);//设定电压
OLED_ShowCHinese(18,3,38);//
OLED_ShowCHinese(36,3,18);//
OLED_ShowCHinese(54,3,36);//
OLED_ShowString(72,3,":",16);
OLED_ShowString(115,3,"V",16);
Float_To_String(Voltage1); //电压的设定值
OLED_ShowString(80,3,String,16);
OLED_ShowCHinese(0,6,34);//实际电压
OLED_ShowCHinese(18,6,35);//
OLED_ShowCHinese(36,6,18);//
OLED_ShowCHinese(54,6,36);//
OLED_ShowString(72,6,":",16);
OLED_ShowString(115,6,"V",16);
while(1)
{
ad0=GetADCResult(0); //ad采集
Voltage2=ad0*2/256*5;
Float_To_String(Voltage2); //浮点型转字符型
OLED_ShowString(80,6,String,16);//字符型变量显示
//keyscan();
if(Voltage2>=Voltage1)
{
LF=0;
delaydianya(500);
}
else
{
LF=1;
delaydianya(500);
}
delaydianya(50);
}
}
void oled_PWM(void)
{
pwm1=pwm/256*100;
menu=5;
OLED_Init(); //初始化OLED
OLED_Clear();
OLED_ShowString(26,0,"PWM",16);
OLED_ShowCHinese(56,0,15);//模
OLED_ShowCHinese(80,0,16);//式
OLED_ShowCHinese(26,3,28);//占空比: %
OLED_ShowCHinese(44,3,29);//
OLED_ShowCHinese(62,3,30);//
OLED_ShowString(100,3,"%",16);
while(1)
{
keyscan();
}
}
void oled_shizhong(void)
{
menu=6;
OLED_Init(); //初始化OLED
OLED_Clear();
OLED_ShowCHinese(6,0,15);//模式选择
OLED_ShowCHinese(38,0,16);
OLED_ShowCHinese(70,0,13);
OLED_ShowCHinese(102,0,14);
OLED_ShowString(26,3,"PWM",16);
OLED_ShowCHinese(56,3,15);//模
OLED_ShowCHinese(80,3,16);//式
OLED_ShowCHinese(26,6,41);//放电模式
OLED_ShowCHinese(44,6,42);
OLED_ShowCHinese(62,6,43);
OLED_ShowCHinese(80,6,44);
}
void hanshutiaodong(menu)
{
switch(menu)
{
case 0:
oled();
break;
case 1:
oledxuanxiang1();
break;
case 2:
oledxuanxiang2();
break;
case 3:
oled_lanya();
break;
case 4:
oled_fangdian();
break;
case 5:
oled_PWM();
break;
case 6:
oled_shizhong();
break;
case 7:
break;
case 8:
break;
case 9:
break;
case 10:
break;
}
}
/********************************************************************
主函数
*********************************************************************/
void main()
{
L1=0;
LF=0;
InitADC();
t=3;
oled();
oledxuanxiang1();
//oledxuanxiang2();
//oled_lanya();
//oled_fangdian();
//PWM_start();
}
复制代码
所有资料51hei提供下载:
放电.zip
(180.13 KB, 下载次数: 16)
2018-7-7 22:03 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
51hei团团
时间:
2018-7-8 00:04
这个无电路图真的无法用,楼主能简单的介绍一下电路连接吗?
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1