郭天祥的10天学会51单片机_第十节
要多练,多练C语言程序,练习C语言程序编程思路,可以把别人的程序改改,找些电路焊接调试
AD985可以产生方波,三角波,正弦波
低通滤波器是通过低频阻止高频,作用是滤除杂波
液晶显示单片机状态
运算放大器放大波形
积分器将方波积分成三角波
AD985里面有比较器可以将正弦波变成方波
AD985是5伏的,单片机是3伏的,两者之间要有个电压转换器
数码管不仅可以用锁存器来驱动,也可以用三极管来驱动
一个函数用来刷新秒,分,时
键盘调节用三个键:功能键(秒的光标在闪烁,此时可以调节时间,分和小时同理),功能键第一次按键调节秒,第二次调节分,第三次调节小时,第四次恢复(程序中可以用一个变量计数,这个变量是几就执行相应的程序);TX-1C型单片机实验板原理图中因为LCDEN和RS用了,就不用它们做键盘了,可以用S9,S13,S17,使用时将RD置0,只需检测P3.0,P3.1和CSDA,键盘上最右列的三个,检测这三个键哪个键为低电平,就能知道哪个键被按下,这里把矩阵键盘(P3.0,P3.1和CSDA)当独立键盘使用
编程时,先让液晶显示,再利用定时器定时显示时间,先显示秒,再显示分和十,再做键盘调节,先做一个键调节,然后做其它键调节
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit dula=P2^6;
sbit wela=P2^7;
sbit rs=P3^5;
sbit lcden=P3^4;
sbit s1=P3^0;//键盘的三个功能键
sbit s2=P3^1;
sbit s3=P3^2;//对应于CSDA
sbit rd=P3^7;//将RD置0,检测P3.0,P3.1和CSDA的状态是否为低电平
uchar count,s1num;
char miao,shi,fen;
uchar code table[]=" 2007-7-30 MON";//加上空格为向右移动再显示
uchar code table1[]=" 00:00:00";
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void write_com(uchar com)
{
rs=0;
lcden=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_date(uchar date)
{
rs=1;
lcden=0;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init()
{
uchar num;
dula=0;//开始要关断数码管
wela=0;
lcden=0;
// fen=59;
// miao=53;
// shi=23;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
for(num=0;num<15;num++)
{
write_date(table[num]);
delay(5);
}
write_com(0x80+0x40);
for(num=0;num<12;num++)
{
write_date(table1[num]);
delay(5);
}
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
void write_sfm(uchar add,uchar date)//写时或分或秒(2位数),add 是位置,date是数值
{
uchar shi,ge;
shi=date/10;//因为数码管一位一位显示,时,分,秒都是两位数,要分开
ge=date%10;
write_com(0x80+0x40+add);
write_date(0x30+shi);//见字符手册的PDF的P11,例如6是30+6
write_date(0x30+ge);
}
void keyscan()
{
rd=0;
if(s1==0)
{
delay(5);//消抖
if(s1==0)//第一个功能键的作用,让秒钟停止闪烁
{
s1num++;
while(!s1);//键盘松手才开始执行功能键的下列程序
if(s1num==1)
{
TR0=0;
write_com(0x80+0x40+10);//光标的地址,因为写一下光标就跳到后一位,为了让光标在秒那要重写下光标的地址
write_com(0x0f);//光标闪烁
}
}
if(s1num==2)//第一个功能键的第二次按下,改变分
{
write_com(0x80+0x40+7);
}
if(s1num==3)//第一个功能键的第三次按下,改变小时
{
write_com(0x80+0x40+4);
}
if(s1num==4)//光标不再闪烁,计数器继续工作
{
s1num=0;
write_com(0x0c);
TR0=1;
}
}
if(s1num!=0)//第一个键按下之后,第二个和第三个键才好使,如果把对第二个和第三个键进行控制的程序放在第一个if(s1==0)语句里面,只有当第一个键按下的瞬间第二个或第三个键也被按下,才能执行第二个或第三个键的程序,所以应该在第一个if(s1==0)语句并列的位置写程序对第二个和第三个键进行控制
{
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!s2);//等待松手,如果不等待松手单片机就会在键盘按下的时
间里程序执行很多次
if(s1num==1)//当s1num==1,表示第一个键秒钟闪烁,即另两个键的按下可以用s1num的值来判断
{
miao++;
if(miao==60)
miao=0;
write_sfm(10,miao);//改变秒的数值后显示,第一个参数不能写成0x10,写成0x10就会出错
write_com(0x80+0x40+10);//光标指到秒的位置,从左往右数,数到秒的十位处
}
if(s1num==2)
{
fen++;
if(fen==60)
fen=0;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)
{
shi++;
if(shi==24)
shi=0;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}
}
if(s3==0)
{
delay(5);
if(s3==0)
{
while(!s3);
if(s1num==1)
{
/* if(miao==0)
{
miao=59;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}*/
miao--;
if(miao==-1)
miao=59;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)
{
fen--;
if(fen==-1)
fen=59;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)
{
shi--;
if(shi==-1)
shi=23;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}
}
}
}
void main()
{
init();
while(1)
{
keyscan();
}
// while(1);
}
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
if(count==18)//因为是12MHZ,所以不是count=20(对应11.0592MHZ)
{
count=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
}
write_sfm(4,shi);
}
write_sfm(7,fen);
}
write_sfm(10,miao);//到一秒只要秒不到60秒进位就改变显示,因为 table1[]=" 00:00:00";
//对于秒的位置是十,即前面空了十个空格,所以第一个参数是10,该句和第一个if是并列的关系
}
}
星期可以用switch case语句
我的程序:
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit dula=P2^6;
sbit wela=P2^7;
sbit rs=P3^5;
sbit lcden=P3^4;
sbit rd=P3^7;
sbit s1=P3^1;
sbit s2=P3^2;
sbit s3=P3^3;
uchar code table[]=" 2012-12-31 MON";
uchar code table1[]=" 23:59:50";
uchar code table2[]="MONTUEWEDTHRFRISATSUN";
uchar count,s1num,flag;
char shi,fen,miao,xq,day,month;
int year;
void delay(uint z)
{
uchar x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void write_com(uchar com)
{
rs=0;
lcden=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_date(uchar date)
{
rs=1;
lcden=0;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init()
{
uchar num;
shi=23;
fen=59;
miao=50;
xq=0;
day=31;
month=12;
year=2012;
dula=0;
wela=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
for(num=0;num<15;num++)
{
write_date(table[num]);
delay(5);
}
write_com(0x80+0x40);
for(num=0;num<12;num++)
{
write_date(table1[num]);
delay(5);
}
TMOD=0x01;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
void write_sfm(uchar add,uchar date)
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+0x40+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
void displayxq(uchar num)
{
uchar kk;
write_com(0x80+12);//星期的位置是从左数第十二位
for(kk=0;kk<3;kk++)
{
write_date(table2[num+kk]);
}
}
void write_xq(char date)//date是0到6,0到6对应星期一到星期日
{
uchar num;
date++;
if(date==7)
date=0;
switch(date)
{
case 0:num=0;
break;
case 1:num=3;
break;
case 2:num=6;
break;
case 3:num=9;
break;
case 4:num=12;
break;
case 5:num=15;
break;
case 6:num=18;
break;
}
displayxq(num);
}
void write_y(uchar add,int date)//这里date是2012,要用合适的类型定义
{
uchar qian,bai,shi,ge;
qian=date/1000;
bai=date%1000/100;
shi=date%100/10;
ge=date%10;
write_com(0x80+add);
write_date(0x30+qian);
write_date(0x30+bai);
write_date(0x30+shi);
write_date(0x30+ge);
}
void write_md(uchar add,uchar date)
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
void write_rq(char date)
{
date++;
if((year%4==0 && year%100!=0) || year%400==0)
flag=1;
if(month==1 || month==3 || month==5 || month==7 || month==8 || month==10)
{
if(date==32)
{
date=1;
}
month++;
}
if(month==2)
{
if(flag==1)
{
if(date==30)
{
date=1;
}
}
if(flag==0)
{
if(date==29)
{
date=1;
}
}
flag=0;
month++;
}
if(month==4 || month==6 || month==9 || month==11 )
{
if(date==31)
{
date=1;
}
month++;
}
if(month==12)
{
if(date==32)
{
date=1;
month=1;
}
year++;
if(year==10000)
year=0;
}
write_md(9,date);
write_md(6,month);
write_y(1,year);
}
void keyscan()
{
uchar num;
rd=0;
if(s1==0)
{
delay(5);
if(s1==0)
{
s1num++;
while(!s1);
if(s1num==1)
{
TR0=0;
write_com(0x80+0x40+10);
write_com(0x0f);
}
if(s1num==2)
{
write_com(0x80+0x40+7);
}
if(s1num==3)
{
write_com(0x80+0x40+4);
}
if(s1num==4)
{
write_com(0x80+12);
}
if(s1num==5)
{
write_com(0x80+9);
}
if(s1num==6)
{
write_com(0x80+6);
}
if(s1num==7)
{
write_com(0x80+1);
}
if(s1num==8)
{
s1num=0;
write_com(0x0c);
TR0=1;
}
}
}
if(s1num!=0)
{
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!s2);
if(s1num==1)
{
miao++;
if(miao==60)
miao=0;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)
{
fen++;
if(fen==60)
fen=0;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)
{
shi++;
if(shi==24)
shi=0;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
if(s1num==4)
{
xq++;
if(xq==7)
xq=0;
switch(xq)
{
case 0:num=0;
break;
case 1:num=3;
break;
case 2:num=6;
break;
case 3:num=9;
break;
case 4:num=12;
break;
case 5:num=15;
break;
case 6:num=18;
break;
}
displayxq(num);
write_com(0x80+12);
}
if(s1num==5)
{
day++;
if((year%4==0 && year%100!=0) || year%400==0)
flag=1;
if(month==1 || month==3 || month==5 || month==7 || month==8 || month==10)
{
if(day==32)
{
day=1;
}
}
if(month==2)
{
if(flag==1)
{
if(day==30)
{
day=1;
}
}
if(flag==0)
{
if(day==29)
{
day=1;
}
}
flag=0;
}
if(month==4 || month==6 || month==9 || month==11 )
{
if(day==31)
{
day=1;
}
}
if(month==12)
{
if(day==32)
{
day=1;
}
}
write_md(9,day);
write_com(0x80+9);
}
if(s1num==6)
{
month++;
if(month==13)
month=1;
write_md(6,month);
write_com(0x80+6);
}
if(s1num==7)
{
year++;
if(year==10000)
year=0;
write_y(1,year);
write_com(0x80+1);
}
}
}
if(s3==0)
{
delay(5);
if(s3==0)
{
while(!s3);
if(s1num==1)
{
miao--;
if(miao==-1)
miao=59;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)
{
fen--;
if(fen==-1)
fen=59;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)
{
shi--;
if(shi==-1)
shi=23;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
if(s1num==4)
{
xq--;
if(xq==-1)
xq=6;
switch(xq)
{
case 0:num=0;
break;
case 1:num=3;
break;
case 2:num=6;
break;
case 3:num=9;
break;
case 4:num=12;
break;
case 5:num=15;
break;
case 6:num=18;
break;
}
displayxq(num);
write_com(0x80+12);
}
if(s1num==5)
{
day--;
if((year%4==0 && year%100!=0) || year%400==0)
flag=1;
if(month==1 || month==3 || month==5 || month==7 || month==8 || month==10)
{
if(day==0)
{
day=31;
}
}
if(month==2)
{
if(flag==1)
{
if(day==0)
{
day=29;
}
}
if(flag==0)
{
if(day==0)
{
day=28;
}
}
flag=0;
}
if(month==4 || month==6 || month==9 || month==11 )
{
if(day==0)
{
day=30;
}
}
if(month==12)
{
if(day==0)
{
day=31;
}
}
write_md(9,day);
write_com(0x80+9);
}
if(s1num==6)
{
month--;
if(month==0)
month=12;
write_md(6,month);
write_com(0x80+6);
}
if(s1num==7)
{
year--;
if(year==0)
year=9999;
write_y(1,year);
write_com(0x80+1);
}
}
}
}
}
void main()
{
init();
while(1)
{
keyscan();
}
}
void timer0() interrupt 1
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
count++;
if(count==20)
{
count=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
}
write_sfm(4,shi);
write_xq(xq);//星期++的判断和显示都放到子函数里,和放到此中断函数
里效果相同
write_rq(day);//日期++的判断和显示都放到子函数里,和放到此中断函数里效果相同
}
write_sfm(7,fen);
}
write_sfm(10,miao);
}
}
郭天祥的10天学会51单片机_第十节相关推荐
- 郭天祥的10天学会51单片机_第十三节
AD软件: AD软件可以编译C语言和VHDL语言等:AD软件的工具栏上面可以输入网络地址进行浏览网页:AD软件可以布差分信号,即可以两条线可以一起布 按住Shift键和左键可以向左移动,按住Shift ...
- 郭天祥的10天学会51单片机_第七节
串行通信:从D0位一位一位发发到D7位 十个位为一帧如:0101000100,表示一个字符 起始位低电平有效,停止位高电平有效,单片机是异步通信 宽带网线是八根线,组成两队差分信号,分别是TXD1(发 ...
- 郭天祥的10天学会51单片机_第三节
单片机管脚,P3口有两个功能,上电默认情况下就使用P3口的普通IO口,当对单片机内部的某些寄存器设置时就启用P3口的第二个功能 P3^4和 P3^5可以作为计时器或定时器使用,给这两个口输入方波,进行 ...
- 10.4.4 51单片机控制系统8个LED“跑马灯”实验
10.4.4 51单片机控制系统8个LED"跑马灯"实验 仿真+代码 方法一 利用数组 #include"reg52.h"#define u8 unsigned ...
- 单片机c语言编程30倒计时,急求51单片机倒计时三十秒程序
急求51单片机倒计时三十秒程序 关注:117 答案:2 手机版 解决时间 2021-01-31 06:56 提问者青春统帅 2021-01-30 16:36 第二位同志请补充一下注释 谢谢 最佳答 ...
- [51单片机] 从业将近十年!手把手教你单片机程序框架(连载)(转载)
这个是转载的 http://bbs.21ic.com/icview-691804-1-1.html [51单片机] 从业将近十年!手把手教你单片机程序框架(连载) 大家好,我叫吴坚鸿,从事单片机项目开 ...
- 51单片机(三十)—— 矩阵键盘计算器
在<51单片机(二十九)-- 矩阵键盘输入实验>中,我们对矩阵键盘的原理及使用方法进行了介绍.在本文中,我们采用矩阵键盘设计一个计算器,实现简单的计算器功能. 这个实验的代码的主函数如下所 ...
- 51单片机(二十五)—— 独立按键控制LED
在51单片机的前面的文章中,我们主要讲述了单片机IO口的输出功能的应用,如LED控制.数码管控制等.这篇文章我们来讲解如何用单片机的IO口读取按键的状态,并根据按键的状态来控制LED.关于51单片机按 ...
- 51单片机学习笔记(郭天祥版)(1)——单片机基础和点亮LED灯
关于单片机型号的介绍: STC89C52RC40C-PDIP 0721CV4336..... STC:STC公司 89:89系列 C:COMS 52(还有51,54,55,58,516,):2表示存储 ...
- 红外测距模块 51单片机_[51单片机] HC-SR04超声波测距仪
1.HC-SR04超声波模块工作原理 (1)采用IO口触发测距,给至少10us高电平脉冲: (2)模块自动发送八个40khz方波,并自主检测是否有电波返回: (3)当有信号返回时,通过IO口输出一个高 ...
最新文章
- 一起谈.NET技术,.NET 打包入门
- Apache安装及jboss部署说明文档
- OpenCV 玩九宫格数独(二):knn 数字识别
- C#与数据库访问技术总结(十七)
- win7 mysql msi_windows下的Mysql安装与基本使用(msi)
- 广州交警发布科目三电子路考操作要点
- Linux中的MAN命令
- rabbitmq进阶一
- (124)FPGA面试题-ZYNQ的PS和PL端怎么交互的?
- 吃了一辈子土豆,原来这么多吃法还治病,真要好好学学!
- 为什么吃红薯容易放屁
- lua循环,减少不必要的循环
- 从load加载数据类型是struct说起
- aauto的listview(类似于C#的datagrid) 支持文件拖拽获取名单
- 网站服务器检测工具,服务器网络监测工具
- win7 修复计算机 黑屏,Win7系统崩溃不用重做!Win7无法进入桌面黑屏
- ArcGis-学习笔记1-地图矢量化
- 在网页中加入“加载中提示”的方法
- C语言银行排队系统仿真
- CentOS系统下文件夹目录结构及其作用