以下是部分程序,需要完整程序请下载附件
制作出来的实物图如下:
单片机源程序如下:
//**************************************************************
//【本程序使用STC12C5A60S2单片机和12M晶振,外挂DS1302和DS18B20】
//【本程序集成时间显示,温度显示,ADC电压显示,8位PWM输出功能】
//**************************************************************
//【对于学习单片机的新手来说,此程序看一下然后慢慢理解】
//【对于老手来说可以路过】
//**************************************************************
//【程序中使用经典写法保证DS1302走时稳定和DS18B20显示精度】
//【程序中也使用一些非经典写法,使ADC非查询方式也非中断方式】
//【保证ADC采样速度的同时也保证稳定性(在相应的ADC端口要接30PF
//左右的电容保证采样稳定性)】
//【本程序可以ADC和PWM单独使用,也可以ADC控制PWM做相应输出】
//【ADC采样引脚:P1.0,PWM输出P1.3】
//****************************************************************
//【LCD1602的数据线】
//****************************************************************
// RS=P2^6; //模式位,低电平输入指令,高电平输入数据
// RW=P2^5; //读写位,低电平读,高电平写
// E =P2^7; //LCD12864使能位,低电平无效,高电平使能
//****************************************************************
//【DS1302的数据线】
//****************************************************************
// CLK=P3^6; //DS1302的时钟信号线
// IO =P3^4; //DS1302的数据端口线
// RST=P3^5; //DS1302的片选信号线
//***************************************************************
//【程序编写于2022年5月17日深夜】
//***************************************************************
#include<STC12C5A60S2.h> //载入单片机头文件
#include<intrins.h> //载入编程规则文件
#include<lcd1602cl.h> //载入LCD1602文件
#include<ds1302cl.h> //载入DS1302文件
#include<ds18b20cl.h> //载入DS18B20文件
unsigned int result,ge,shifen,baifen;
unsigned char seg[10]={'0','1','2','3','4','5','6','7','8','9'};//要显示字符
bit flag1 =0;
bit flag2 =0;
bit flag3 =0;
//****************************************************************
//【显示界面子程序】
//****************************************************************
//void Displayqt(void)
//{
// LCDTestWord(0,0x80);
// LCDSendWord("LOVE LIFE! ");
// }
void DisplayHour(void) //往LCD上填写小时数据
{
hour=ReadDs1302(0x85); //读小时数据
LCDTestWord(0,0x80); //在80位置显示小时数据
LCDTestWord(1,(hour/16)+0x30);
LCDTestWord(1,hour%16+0x30);
LCDTestWord(0,0x82); //在82位置显示":"
LCDTestWord(1,(0x3a));
}
void DisplayMin(void) //往LCD上填写分钟数据
{
min=ReadDs1302(0x83); //读分钟数据
LCDTestWord(0,0x83); //在83位置显示分钟数据
LCDTestWord(1,(min/16)+0x30);
LCDTestWord(1,min%16+0x30);
LCDTestWord(0,0x85); //在85位置显示":"
LCDTestWord(1,0x3a);
}
void DisplaySec(void) //往LCD上填写秒钟数据
{
unsigned char i=0;
unsigned int a=0,b=0,c=0;
sec=ReadDs1302(0x81); //读秒钟数据
LCDTestWord(0,0x86); //在86位置显示秒数据
LCDTestWord(1,(sec/16)+0x30);
LCDTestWord(1,sec%16+0x30);
LCDTestWord(0,0x88); //写三个空格,把空的部分占掉以免乱码
LCDSendWord(" ");
}
void DisplayTemp(void) //往LCD上填写温度数据
{
unsigned int i; //定义i
unsigned char a,b,c; //定义a,b,c
LCDTestWord(0,0x8b); //从8b位置开始写入
TempChange();
i=GetTemp(); //i等于读出来的温度值
a=i/100; //温度十位
LCDTestWord(1,a+0x30);
b=i/10-a*10; //温度个位
LCDTestWord(1,b+0x30);
LCDTestWord(1,0x2e); //写入小数点
c=i-a*100-b*10; //温度小数位
LCDTestWord(1,c+0x30);
LCDSendWord("C"); //写入字母"C"
}
void Displayvoltage(void) //往LCD上填写电压数据
{ //ADC转换结果
unsigned int temp;
temp=ADC_RES;
result=temp*0.01953125*1000;
ge=result/1000; //个位结果
shifen=result%1000/100; //十分位结果
baifen=result%100/10; //百分位结果
ADC_CONTR = 0xc8; //开启转换
LCDTestWord(0,0xC0); //从80位置开始显示
LCDSendWord(" ");
LCDTestWord(0,0xC8); //从86位置开始显示
LCDSendWord("A"); //写入字母"A"
LCDSendWord("D"); //写入字母"D"
DelayMs(20);
LCDTestWord(1,0x3a);
LCDTestWord(1,seg[ge]);
LCDTestWord(1,0x2e);
LCDTestWord(1,seg[shifen]);
LCDTestWord(1,seg[baifen]);
LCDSendWord("V"); //写入字母"V"
}
//****************************************************************
//【显示指定内容程序】
//****************************************************************
void Displayxs(void)
{
DisplayHour(); //显示小时数据
DisplayMin(); //显示分钟数据
DisplaySec(); //显示秒钟数据
DisplayTemp(); //显示温度数据
Displayvoltage(); //显示ADC采样电压值
}
//****************************************************************
//【延时部分子程序】
//****************************************************************
void DelayMs(unsigned int a) //延时 1MS/次
{
unsigned char i;
while(--a!=0)
{
for(i=0;i<125;i++)
;
}
}
void Delay(unsigned char num)
{
unsigned char i;
_nop_();
while(num--)
i=num;
;
}
此程序已完美验证,注意本程序使用12M晶振,22.1184M晶振容易导致DS18B20不显示温度,那个延时太难调了.
Keil5代码下载:
LCD1602ADCPWM.rar
(47.96 KB, 下载次数: 414)
|