哈哈 有个1602显示的 不过程序太长 贴不上 给你个数码管的吧 不行再联系
1302.c
#includeDS1302.h
#includekey.h
uchar bit_ser[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
uchar seven_seg[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
/***********************时间显示*****************/
void timer0_init(void) //T0初始化函数,用于时间的动态显示
{
TMOD = 0x21;
TL0 = (65536-5000) % 256;
TH0 = (65536-5000) / 256;
EA = 1;
ET0 = 1;
TR0 = 1;
}
void timer0_isr(void) interrupt 1 //T0中断处理函数
{
char flag; //flag用于表示调整时闪烁的亮或灭
TR0 = 0;
TL0 = (65536-5000) % 256;
TH0 = (65536-5000) / 256;
TR0 = 1;
flag = x / 100 * 0xff; //设置闪烁标志,如果x大于100则flag为0xff,小于100则为0x00
x++;
if(x 200)
x = 0;
switch(i)
{
case 0:
P2 = bit_ser[0];
if(setflag == 3) //根据setflag的值判断当前位是否需要闪烁
P0 = flag | seven_seg[dis_buffer[0]];
else
P0 = seven_seg[dis_buffer[0]];
break;
case 1:
P2 = bit_ser[1];
if(setflag == 3)
P0 =flag | seven_seg[dis_buffer[1]];
else
P0 =seven_seg[dis_buffer[1]];
break;
case 2:
P2 = bit_ser[2];
if(setflag == 2)
P0 =flag | seven_seg[dis_buffer[2]];
else
P0 =seven_seg[dis_buffer[2]];
break;
case 3:
P2 = bit_ser[3];
if(setflag == 2)
P0 =flag | seven_seg[dis_buffer[3]];
else
P0 =seven_seg[dis_buffer[3]];
break;
case 4:
P2 = bit_ser[4];
if(setflag == 1)
P0 =flag | seven_seg[dis_buffer[4]];
else
P0 =seven_seg[dis_buffer[4]];
break;
case 5:
P2 = bit_ser[5];
if(setflag == 1)
P0 =flag | seven_seg[dis_buffer[5]];
else
P0 =seven_seg[dis_buffer[5]];
break;
}
i++;
if(i = 6)
{
i = 0;
if(j == 10)
{
j = 0;
if(setflag == 0)
DS1302_GetTime(Time); //如果setflag是0,就从1302中读出时间,因为setflag不是0时,说明处于调整状态,不需要读时间
dis_buffer[5] = Time.Second % 10; //把当前时间放入显示缓冲区
dis_buffer[4] = Time.Second / 10;
dis_buffer[3] = Time.Minute % 10;
dis_buffer[2] = Time.Minute / 10;
dis_buffer[1] = Time.Hour % 10;
dis_buffer[0] = Time.Hour / 10;
}
j++;
}
}
void main()
{
Initial_DS1302(Time);
timer0_init();
while(1)
{
set_down();
timer_down();
up_down();
down_down();
beepflag_down();
if(setflag == 0 Time.Hour == romhour Time.Minute == romminute Beepflag == 1) //判断蜂鸣器是否要响
Beep = !Beep;
}
}
//key.c
#includereg51.h
#define uchar unsigned char
#define uint unsigned int
uchar i = 0,j = 0,x = 0,setflag,flag_set,flag_timer; //setflag用来表示调整的位置,flag_set和flag_timer分别表示当前处于调整状态还是定时状态
SYSTEMTIME Time={0,20,15,3,30,6,10}; //系统时间的初始值2010年6月30日星期三,15时20分0秒
char dis_buffer[6]; //存放显示数据的缓冲区
sbit Beep_flag = P3^2; //蜂鸣器的接口
sbit key_timer = P3^4; //定时按钮
sbit key_set = P3^5; //调整按钮
sbit key_up = P3^6; //增加按钮
sbit key_down = P3^7; //减小按钮
char romhour,romminute,romsec; //分别存放定时的时,分,秒
bit Beepflag; //标记闹钟是否开启
//延时函数
void delays(uchar x)
{
while(x) x--;
}
//设置键的处理函数
void set()
{
setflag ++;
flag_set = 1;
if(setflag = 4)
{
setflag = 0;
flag_set = 0;
Initial_DS1302(Time);
}
}
//定时间的处理函数
void timer()
{
setflag ++;
flag_timer = 1;
if(setflag == 1)
{
Time.Hour = romhour;
Time.Minute = romminute;
Time.Second = romsec;
}
else if(setflag = 4)
{
setflag = 0;
flag_timer = 0;
romhour = Time.Hour;
romminute = Time.Minute;
romsec = Time.Second;
}
}
//增加键的处理函数
void up()
{
switch(setflag)
{
case 0:
break;
case 1:
Time.Second ++;
if(Time.Second = 60)
Time.Second = 0;
break;
case 2:
Time.Minute ++;
if(Time.Minute = 60)
Time.Minute = 0;
break;
case 3:
Time.Hour ++;
if(Time.Hour = 24)
Time.Hour = 0;
break;
}
}
//减小键的处理函数
void down()
{
switch(setflag)
{
case 0:
break;
case 1:
Time.Second --;
if(Time.Second 0)
Time.Second = 59;
break;
case 2:
Time.Minute --;
if(Time.Minute 0)
Time.Minute = 59;
break;
case 3:
Time.Hour --;
if(Time.Hour 0)
Time.Hour = 23;
break;
}
}
//设置键的扫描函数
void set_down()
{
if(key_set == 0 flag_timer == 0)
{
delays(100);
if(key_set == 0)
{
set();
}
while(!key_set);
}
}
//定时键的扫描函数
void timer_down()
{
if(key_timer == 0 flag_set == 0)
{
delays(100);
if(key_timer == 0)
{
timer();
}
while(!key_timer);
}
}
//增加键的扫描函数
void up_down()
{
if(key_up == 0 setflag != 0)
{
delays(100);
if(key_up == 0)
{
up();
while(!key_up);
}
}
}
//减少键的处理函数
void down_down()
{
if(key_down == 0 setflag != 0)
{
delays(100);
if(key_down == 0)
{
down();
while(!key_down);
}
}
}
//定时开关的扫描处理函数
void beepflag_down()
{
if(Beep_flag == 0)
{
delays(100);
{
Beepflag = !Beepflag;
while(!Beep_flag);
}
}
}
//ds1302.h
#ifndef _REAL_TIMER_DS1302
#define _REAL_TIMER_DS1302
#include REG51.h
sbit DS1302_CLK = P1^1; //实时时钟时钟线引脚
sbit DS1302_IO = P1^2; //实时时钟数据线引脚
sbit DS1302_RST = P1^3; //实时时钟复位线引脚
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
sbit Beep = P2^7;
typedef struct __SYSTEMTIME__
{ char Second;
char Minute;
char Hour;
char Week;
char Day;
char Month;
char Year;
}SYSTEMTIME; //定义的时间类型
#define AM(X) X
#define PM(X) (X+12) // 转成24小时制
#define DS1302_SECOND 0x80 //秒寄存器
#define DS1302_MINUTE 0x82 //分寄存器
#define DS1302_HOUR 0x84
#define DS1302_WEEK 0x8A
#define DS1302_DAY 0x86
#define DS1302_MONTH 0x88
#define DS1302_YEAR 0x8C
#define DS1302_RAM(X) (0xC0+(X)*2) //用于计算 DS1302_RAM 地址的宏
void DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数)
{ unsigned char i;
ACC = d;
for(i=8; i0; i--)
{ DS1302_IO = ACC0; //相当于汇编中的 RRC
DS1302_CLK = 1;
DS1302_CLK = 0; //发一个高跳变到低的脉冲
ACC = ACC 1;
}
}
unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数)
{ unsigned char i;
for(i=8; i0; i--)
{ ACC = ACC 1; //相当于汇编中的 RRC
ACC7 = DS1302_IO;
DS1302_CLK = 1;
DS1302_CLK = 0; //发一个高跳变到低的脉冲
}
return(ACC);
}
void Write1302(unsigned char ucAddr, unsigned char ucDa)//ucAddr: DS1302地址, ucData: 要写的数据
{ DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr); // 地址,命令
DS1302InputByte(ucDa); // 写1Byte数据
DS1302_CLK = 1;
DS1302_RST = 0; //RST 0-1-0,CLK 0-1
}
unsigned char Read1302(unsigned char ucAddr) //读取DS1302某地址的数据
{ unsigned char ucData;
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1; //enable
DS1302InputByte(ucAddr|0x01); // 地址,命令
ucData = DS1302OutputByte(); // 读1Byte数据
DS1302_CLK = 1; //RST 0-1-0,CLK 0-1
DS1302_RST = 0;
return(ucData);
}
void DS1302_SetProtect(bit flag) //是否写保护
{ if(flag)
Write1302(0x8E,0x80); //WP=1,不能写入
else
Write1302(0x8E,0x00);//WP=0,可以写入
}
void DS1302_SetTime(unsigned char Address, unsigned char Value) // 设置时间函数
{ DS1302_SetProtect(0);
Write1302(Address, ((Value/10)4 | (Value%10))); //高4位为十位,低4位为个位
DS1302_SetProtect(1);
}
//获取时间函数,从DS1302内读取时间然后存入Time内
void DS1302_GetTime(SYSTEMTIME *Time)
{ unsigned char ReadValue;
ReadValue = Read1302(DS1302_SECOND);
Time-Second = ((ReadValue0x70)4)*10 + (ReadValue0x0F);//转换成10进制的秒
ReadValue = Read1302(DS1302_MINUTE);
Time-Minute = ((ReadValue0x70)4)*10 + (ReadValue0x0F);
ReadValue = Read1302(DS1302_HOUR);
Time-Hour = ((ReadValue0x70)4)*10 + (ReadValue0x0F);
ReadValue = Read1302(DS1302_DAY);
Time-Day = ((ReadValue0x70)4)*10 + (ReadValue0x0F);
ReadValue = Read1302(DS1302_WEEK);
Time-Week = ((ReadValue0x70)4)*10 + (ReadValue0x0F);
ReadValue = Read1302(DS1302_MONTH);
Time-Month = ((ReadValue0x70)4)*10 + (ReadValue0x0F);
ReadValue = Read1302(DS1302_YEAR);
Time-Year = ((ReadValue0x70)4)*10 + (ReadValue0x0F);
}
//利用STime初始化DS1302
void Initial_DS1302(SYSTEMTIME STime)
{ unsigned char Second=Read1302(DS1302_SECOND);
if(Second0x80) DS1302_SetTime(DS1302_SECOND,0); //如果第七为1(表明没有启动), 则启动时钟
DS1302_SetTime(DS1302_SECOND,STime.Second); //设定起始时间
DS1302_SetTime(DS1302_MINUTE,STime.Minute);
DS1302_SetTime(DS1302_HOUR,STime.Hour);
DS1302_SetTime(DS1302_DAY,STime.Day);
DS1302_SetTime(DS1302_MONTH,STime.Month);
DS1302_SetTime(DS1302_YEAR,STime.Year);
DS1302_SetTime(DS1302_WEEK,STime.Week);
}
#endif
//采集并返回
unsigned int Adc0832(unsigned char channel)
{
uchar i=0;
uchar j;
uint dat=0;
uchar ndat=0;
if(channel==0)channel=2;
if(channel==1)channel=3;
ADDI=1;
_nop_();
_nop_();
ADCS=0;//拉低CS端
_nop_();
_nop_();
ADCLK=1;//拉高CLK端
_nop_();
_nop_();
ADCLK=0;//拉低CLK端,形成下降沿1
_nop_();
_nop_();
ADCLK=1;//拉高CLK端
ADDI=channel0x1;
_nop_();
_nop_();
ADCLK=0;//拉低CLK端,形成下降沿2
_nop_();
_nop_();
ADCLK=1;//拉高CLK端
ADDI=(channel1)0x1;
_nop_();
_nop_();
ADCLK=0;//拉低CLK端,形成下降沿3
ADDI=1;//控制命令结束
_nop_();
_nop_();
dat=0;
for(i=0;i8;i++)
{
dat|=ADDO;//收数据
ADCLK=1;
_nop_();
_nop_();
ADCLK=0;//形成一次时钟脉冲
_nop_();
_nop_();
dat=1;
if(i==7)dat|=ADDO;
}
for(i=0;i8;i++)
{
j=0;
j=j|ADDO;//收数据
ADCLK=1;
_nop_();
_nop_();
ADCLK=0;//形成一次时钟脉冲
_nop_();
_nop_();
j=j7;
ndat=ndat|j;
if(i7)ndat=1;
}
ADCS=1;//拉低CS端
ADCLK=0;//拉低CLK端
ADDO=1;//拉高数据端,回到初始状态
dat=8;
dat|=ndat;
return(dat); //return ad data
}int main(void)
{
while(1)
P3=Adc0832(0);
}
1.单片机控制的60s倒计时
这个太简单了,不用什么提示吧?硬件上只要单片机最小系统加上数码管两个,程序上只要设置好定时器就行.
2.
基于单片机的电子钟设计
这个要复杂一点.大概要单片机+数码管+实时时钟芯片如DS系列(ds1302加要电池)+存储芯片如24C02,当然驱动数码管的如译码器或锁存器也要有.
实在说你第一个设计网上能找到现成的,第二个设计网上也能找到现成的,不过要你自己使用keil、proteus软件综合调试仿真,这两个内容都有,自己动手百度一下吧,不要太依赖别人.毕竟这样才能提高一下你自己.
我有个比你要复杂点的,去年编写的.功能:时间,花样,速度可调,并且可通过上位机控制!你要的话我可以给你程序的一半!因为我觉得你问问题的态度不好! 反省一下把!
把你的邮箱留下
一、毕业设计题目及要求 (2个) 1、基于单片机控制的电动机Y-△启动的设计 要求:1)控制器为单片机,电动机为三相异步电动机;2)启动时间为3秒;3)由按键设置电动机Y-△运行、停止。 2、基于单片机控制的可调直流稳压电源的设计 要求:1)控制器为单片机,电压输出范围为0-10V,电压精度为0.1V;2)通过数码管显示电压值;3)由按键设置电压值。 二、毕业设计用到的主要软件(及功能) 毕业设计用到的主要软件(及功能):Keil 51(源程序编译),Proteus(电路仿真),AutoCAD(绘图), Visio(绘流程图), Protel 99SE(原理图电路设计,PCB板制作) 三、单片机方面毕业设计要求 1、学会编写程序(用C语言或汇编语言),用Keil 51软件对源程序进行编译。 2、学会用Proteus电路仿真软件对所设计的硬件电路进行仿真。 3、在写毕业论文时,学会用Word、AutoCAD, Visio,Protel 99SE等软件对程序流程图、电路原理图等进行绘制。 相关答案 ↓位朋友,以51单片机为例。51现在很多都是用仿真器来进行在线调试的,而每个公司的仿真器都会有自带的编程软件,当然,跟keil是差不了多少的。 步骤大体如下: 1.新建,进行程序的编写 2.连上仿真器或烧写器,这一步有可能要对仿真器或烧写器进行设置,具体可看它们的使用说明 3.对程序进行编译,这一步会自动检测你的程序有没错,如果有错,是不能进入下一步的.如果你用的是仿真器,这一步编译成功后就可以直接运行进行在线调试了。 4.如果用的是烧写器,那就进行烧写 各个软件和调试方法会有些不同,但大体就是这样,一些调试工具的说明书也有很详细的说明。 学参数测量技术涉及范围广,特别是微电压、微电流、高电压以及待测信号强弱相差极大的情况下,既要保证弱信号的测量精度又要兼顾强信号的测量范围,在技术上有一定的难度。传统的低成本仪表在测量电压、电阻时都采用手动选择档位的方法来转换量程。在使用中,当忘记转换档位时,会造成仪表测量精度下降或损坏。 现代电子测量对系统的精度要求越来越高且智能化程度也越来越高。全量程无档自动量程转换电压表和电阻表是在保证测量精度不下降的前提条件下省去手动转换量程的工作,得到了广泛应用。 本文介绍了一种基于AT89S52 单片机 的智能多用表。该表能在单片机的控制下完成直流电压、电阻和直流电流的测量。测量电流部分采用了简单的I/V转换电路完成测试;测量电压部分结合模拟开关CD4051和运算放大器OP07构成程控放大器,实现了自动量程转换;测量电阻部分也由模拟开关CD4051和运算放大器OP07相结合,在单片机控制下完成了自动量程转换。电流、电压和电阻的最终测量信号都在单片机的控制下由12位A/D转换器TLC2543进行采集,采集的信号经单片机数据处理后通过LCD(12864)显示出来,测量结果还可以由带有串行EEPROM的CPU存储器和监控器的X25045进行多个数据保存。 关键词:TLC2543 自动量程转换 程控增益放大器 电压 电阻 电流 目录 摘要1 Abstract 2 第一章 绪论 5 1. 1 概述 5 1. 2 智能仪器/仪表国内外发展概况 5 1. 3 课题研究目的及意义 6 第二章 系统结构及功能介绍 8 2. 1 系统功能和性能指标 8 2. 1. 1 仪表功能 8 2. 1. 2 性能指标 8 2. 1. 3 本机特色 8 2. 1. 4 系统使用说明 9 2. 2 系统工作原理概述 9 第三章 方案设计与论证 11 3. 1 量程选择的设计与论证 11
手边有一些你需要的关于单片机的论文设计资料 需要的话加QQ 晚上7点以后隐身在线,直接加就行,说明要的资料名字就好。嘿嘿 楼主 要是觉的好的话 可别忘了给分哦。
单片机课程设计怎么写的介绍就聊到这里吧,感谢您花时间阅读,谢谢。
本文标签:单片机课程设计怎么写