关于51单片机若干的问题,急。。。。。

作者&投稿:直光 (若有异议请与网页底部的电邮联系)
51单片机的问题急急急急急急!!!!!!!!!~

0003H外部中断0
000BH定时/计数器0中断
0013H外部中断1
001BH定时/计数器1中断
0023H串口中断
2.题目:A=11H,R0=33H,B=44H,(11H)=22H,(22H)=66H,(33H)=44H
A=33H
B=55H
(40H)=44H
(11H)=66H
(33H)=66H
(题目没看错的话)

看什么传感器了,数字式的传感器可以连接IO口,根据通讯格式读取,设置的话可以通过串口或者按键设置

//实际晶振为11.0592MHz
//为方便计算,假设为12MHz
#include<reg52.h> //包含52单片机头文件
#define uchar unsigned char //宏定义
#define uint unsigned int //红定义
//#include<24c02.h>
sbit dula=P2^6; //定义锁存器锁存端
sbit wela=P2^7;
sbit rs=P3^5; //定义1602液晶RS端
sbit lcden=P3^4; //定义1602液晶LCDEN端
sbit s1=P3^0; //定义按键——功能键
sbit s2=P3^1; //定义按键——增大键
sbit s3=P3^2; //定义按键——减小键
//sbit s4=P3^6; //闹钟查看器
sbit rd=P3^7;
sbit beep=P2^3; //蜂鸣器
sbit dscs=P1^4;
sbit dsas=P1^5;
sbit dsrw=P1^6;
sbit dsds=P1^7;
sbit dsirq=P3^3;
bit flag1,flag_ri; //定义两个位变量
uchar count,s1num,flag,t0_num; //其他变量定义
char miao,fen,shi,day,month,year,week,amiao,afen,ashi;
uchar code table[]=" 20 - - "; //定义初始上电时液晶默认显示状态
//uchar code table1[]=" : : ";
void write_ds(uchar,uchar); //函数声明
uchar read_ds(uchar);
void set_time();

void delay(uint z) //延时函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}

void di() //蜂鸣器报警声音
{
beep=0;
delay(100);
beep=1;
}

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 write_sfm(uchar add,uchar date) //写时分秒函数
{
uchar shi,ge;
shi=date/10; //分解一个2位数的十位和个位
ge=date%10;
write_com(0x80+0x40+add); //设置显示位置
write_date(0x30+shi); //送去液晶显示十位
write_date(0x30+ge); //送去液晶显示个位
}

void write_nyr(uchar add,uchar date) //写年月日函数
{
uchar shi,ge;
shi=date/10; //分解一个2位数的十位和个位
ge=date%10;
write_com(0x80+add); //设置显示位置
write_date(0x30+shi); //送去液晶显示十位
write_date(0x30+ge); //送去液晶显示个位
}
void write_week(char we)
{ //写液晶星期显示函数
write_com(0x80+12);
switch(we)
{
case 1: write_date('M');
delay(5);
write_date('O');
delay(5);
write_date('N');
break;
case 2: write_date('T');
delay(5);
write_date('U');
delay(5);
write_date('E');
break;
case 3: write_date('W');
delay(5);
write_date('E');
delay(5);
write_date('D');
break;
case 4: write_date('T');
delay(5);
write_date('H');
delay(5);
write_date('U');
break;
case 5: write_date('F');
delay(5);
write_date('R');
delay(5);
write_date('I');
break;
case 6: write_date('S');
delay(5);
write_date('A');
delay(5);
write_date('T');
break;
case 7: write_date('S');
delay(5);
write_date('U');
delay(5);
write_date('N');
break;
}
}

void init() //初始化函数
{
uchar num;
rd=0; //软件将矩阵按键第四列一端置低用以分解出独立按键
dula=0; //关闭两锁存器锁存端,防止操作液晶时数码管出现乱码
wela=0;
lcden=0;
fen=0; //初始化分钟变量值
miao=0;
shi=0;
day=1;
month=1;
year=12;
week=1;
count=0;
s1num=0;
// init_24c02();
//一下几行在首次设置DS12C887时使用,以后不必在写入
// write_ds(0x0A,0x20); //打开振荡器
// write_ds(0x0B,0x26); //设置24小时模式,数据二进制格式 ,开启闹铃中断
set_time(); //设置上电默认时间

write_com(0x38); //初始化1602液晶
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80); //设置显示初始坐标
for(num=0;num<15;num++) //显示年月日星期
{
write_date(table[num]);
delay(5);
}
/* for(num=0;num<12;num++)
{
write_date(table1[num]);
delay(5);
}
*/
write_com(0x80+0x40+6); //写出时间显示部分的两个冒号
write_date(':');
delay(5);
write_com(0x80+0x40+9);
write_date(':');
delay(5);
// miao=read_add(1);
// fen=read_add(2);
// shi=read_add(3);
write_sfm(10,miao);
write_sfm(7,fen);
write_sfm(4,shi);
write_nyr(9,day);
write_nyr(6,month);
write_nyr(3,year);
write_week(week);

TMOD=0x01; //设置定时器0工作模式1
TH0=(65536-50000)/256; //定时器装初值
TL0=(65536-50000)%256;
EA=1; //开总中断
ET0=1; //开定时器0中断
TR0=1; //启动定时器0
}

void keyscan() //按键扫描函数
{
// rd=0; //前面已定义
if(s1==0)
{
delay(5);
if(s1==0) //确认功能键被按下
{ s1num++; //功能键按下次数记录
while(!s1); //释放确认
di(); //每当有按键释放蜂鸣器发出滴声
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+9);
}
if(s1num==5) //第五次按下光标闪烁定位到月份位置
{
write_com(0x80+6);
}
if(s1num==6) //第六次按下光标闪烁定位到年份位置
{
write_com(0x80+3);
}
if(s1num==7) //第七次按下光标闪烁定位到年份位置
{
write_com(0x80+12);
}

if(s1num==8) //第八次按下
{
s1num=0; //记录按键数清0
write_com(0x0c); //取消光标闪烁
TR0=1; //启动定时器使时钟走
}
flag=0;
write_ds(0,miao);
write_ds(2,fen);
write_ds(4,shi);
write_ds(6,week);
write_ds(7,day);
write_ds(8,month);
write_ds(9,year);
// break;
}

}
if(s1num!=0) //只有功能键被按下后,增大和减小键才有效
{
if(s2==0)
{
delay(5);
if(s2==0) //增大键确认被按下
{
while(!s2); //按键释放
di(); //每当有按键释放蜂鸣器发出滴声

if(s1num==1) //若功能键第一次按下
{
miao++; //则调整秒加1
if(miao==60) //若满60后将清0
miao=0;
write_sfm(10,miao); //每调节一次送液晶显示一下
write_com(0x80+0x40+10); //显示位置重新回到调节处
// write_add(1,miao); //数据改变立即存入24C02

}
if(s1num==2) //若功能键第二次按下
{
fen++; //则调整分钟加1
if(fen==60) //若满60后将清0
fen=0;
write_sfm(7,fen); //每调节一次送液晶显示一下
write_com(0x80+0x40+7); //显示位置重新回到调节处
// write_add(2,fen);
}
if(s1num==3) //若功能键第三次按下
{
shi++; //则调整小时加1
if(shi==24) //若满24后将清0
shi=0;
write_sfm(4,shi);//每调节一次送液晶显示一下
write_com(0x80+0x40+4); //显示位置重新回到调节处
// write_add(3,shi); //数据改变立即存入24C02
}
if(s1num==4) //若功能键第四次按下
{
day++; //则调整日期加1
if(day==32) //若满31后将清0
day=1;
write_nyr(9,day);//每调节一次送液晶显示一下
write_com(0x80+9); //显示位置重新回到调节处
// write_add(9,day); //数据改变立即存入24C02
}
if(s1num==5) //若功能键第五次按下
{
month++; //则调整月份加1
if(month==13) //若满12后将清0
month=1;
write_nyr(6,month);//每调节一次送液晶显示一下
write_com(0x80+6); //显示位置重新回到调节处
// write_add(6,month); //数据改变立即存入24C02
}
if(s1num==6) //若功能键第六次按下
{
year++; //则调整年份加1
if(year==33) //若满32后将返回初始年份
year=12;
write_nyr(3,year);//每调节一次送液晶显示一下
write_com(0x80+3); //显示位置重新回到调节处
// write_add(3,year); //数据改变立即存入24C02
}
if(s1num==7) //若功能键第七次按下
{
week++; //则调整年份加1
if(week==8) //若满32后将返回初始年份
week=1;
write_week(week);//每调节一次送液晶显示一下
write_com(0x80+12); //显示位置重新回到调节处
// write_add(week); //数据改变立即存入24C02
}

}
}
if(s3==0)
{
delay(5);
if(s3==0) //确认减小按键按下
{
while(!s3); //按键释放
di(); //每当有按键释放蜂鸣器发出滴声
if(s1num==1) //若功能键第一次按下
{

miao--; //则调整秒减1
if(miao==-1) //若减到负数则将其重新设置为59
miao=59;
write_sfm(10,miao); //每调节一次送液晶显示一下
write_com(0x80+0x40+10); //显示位置重新回到调节处
// write_add(1,miao); //数据改变立即存入24C02
}
if(s1num==2) //若功能键第二次按下
{
fen--; //则调整分钟减1
if(fen==-1) //若减到负数则将其重新设置为59
fen=59;
write_sfm(7,fen); //每调节一次送液晶显示一下
write_com(0x80+0x40+7); //显示位置重新回到调节处
// write_add(2,fen); //数据改变立即存入24C02
}
if(s1num==3) //若功能键第三次按下
{
shi--; //则调整小时减1
if(shi==-1) //若减到负数则将其重新设置为23
shi=23;
write_sfm(4,shi); //每调节一次送液晶显示一下
write_com(0x80+0x40+4); //显示位置重新回到调节处
// write_add(3,shi); //数据改变立即存入24C02
}
if(s1num==4) //若功能键第四次按下
{
day--; //则调整日期减1
if(day==0) //若减到0则将其重新设置为31
day=31;
write_nyr(9,day); //每调节一次送液晶显示一下
write_com(0x80+9); //显示位置重新回到调节处
// write_add(9,day); //数据改变立即存入24C02
}
if(s1num==5) //若功能键第五次按下
{
month--; //则调整月份减1
if(month==0) //若减到0则将其重新设置为12
month=12;
write_nyr(6,month); //每调节一次送液晶显示一下
write_com(0x80+6); //显示位置重新回到调节处
// write_add(6,month); //数据改变立即存入24C02
}
if(s1num==6) //若功能键第六次按下
{
year--; //则调整月份减1
if(year==11) //若减到初始值则将其重新设置为32
year=32;
write_nyr(3,year); //每调节一次送液晶显示一下
write_com(0x80+3); //显示位置重新回到调节处
// write_add(3,year); //数据改变立即存入24C02
}
if(s1num==7) //若功能键第七次按下
{
week--; //则调整月份减1
if(week==0) //若减到初始值则将其重新设置为32
week=7;
write_week(week); //每调节一次送液晶显示一下
write_com(0x80+12); //显示位置重新回到调节处
// write_add(week); //数据改变立即存入24C02
}

}
}
}
}

void write_ds(uchar add,uchar date)
{ //写12C887函数
dscs=0;
dsas=1;
dsds=1;
dsrw=1;
P0=add; //先写地址
dsas=0;
dsrw=0;
P0=date; //再写数据
dsrw=1;
dsas=1;
dscs=1;
}
uchar read_ds(uchar add)
{ //读12C887函数
uchar ds_date;
dsas=1;
dsds=1;
dsrw=1;
dscs=0;
P0=add; //先写地址
dsas=0;
dsds=0;
P0=0xff;
ds_date=P0; //再读数据
dsds=1;
dsas=1;
dscs=1;
return ds_date;
}

void set_time()
{ //首次上电初始化时间函数
write_ds(0,0);
write_ds(1,0);
write_ds(2,0);
write_ds(3,0);
write_ds(4,0);
write_ds(5,0);
write_ds(6,0);
write_ds(7,0);
write_ds(8,0);
write_ds(9,0);
}

void main() //主函数
{
init(); //首先初始化各函数
while(1) //进入主程序大循环
{
keyscan(); //不停地检测按键是否被按下
if(flag==0&&flag1==0) //正常工作时进入这里
{
keyscan(); //按键扫描
year=read_ds(9); //读取12C887数据
month=read_ds(8);
day=read_ds(7);
week=read_ds(6);
shi=read_ds(4);
fen=read_ds(2);
miao=read_ds(0);
write_sfm(10,miao); //送液晶显示
write_sfm(7,fen);
write_sfm(4,shi);
write_week(week);
write_nyr(3,year);
write_nyr(6,month);
write_nyr(9,day);
}
}
// while(1);
}

void timer0() interrupt 1 //定时器0中断服务程序
{
TH0=(65536-50000)/256; //再次装定时器初值
TL0=(65536-50000)%256;
count++; //中断次数累加
if(count==20) //20次50毫秒为1秒
{
count=0;
miao++;
if(miao==60) //秒加到60则进位分钟
{
miao=0; //同时秒数清0
fen++;
if(fen==60) //分钟加到60则进位小时
{
fen=0; //同时分钟数清0
shi++;
if(shi==24) //小时加到24则进位日期
{
shi=0; //同时小时数清0
day++;
if(day==31) //日期加到31则进位月份
{
day=0; //同时日期数清0
month++;
if(month==12) //月份加到12则进位年份
{
month=0; //同时月份数清0
year++;
if(year==99) //年份加到32则将年份返回初始值
{
year=0;
}
write_nyr(3,year);
// write_add(3,year); //数据改变立即存入24C02
}
write_nyr(6,month);
// write_add(6,month); //数据改变立即存入24C02
}
write_nyr(9,day);
// write_add(9,day); //数据改变立即存入24C02
}
write_sfm(4,shi); //小时若变化则重新写入
// write_add(3,shi); //数据改变立即存入24C02
}
write_sfm(7,fen); //分钟若变化则重新写入
// write_add(2,fen); //数据改变立即存入24C02
}
write_sfm(10,miao); //秒若变化则重新写入
// write_add(1,miao); //数据改变立即存入24C02

}
}

这都是我调试好用过的程序,不知道硬件连接的是不是一样,希望对你有帮助。

QQ 2606454510

51单片机的问题
答:18B20不说其他东西(校验、温度限值、系列号配对),就说 温度的结果,18B20的温度精度可以设置 9位~12位,而其温度结果有2字节(16位),多余的位,使用 符号扩展 方式填充:如下列:其中 S表示符号(正负温度),D表示温度结果 9位精度:SSSS SSSS DDDD DDDD,分辨率为 0.5℃;也就是一个数值...

关于51单片机的问题
答:程序中可以有很多中断,主要看怎么合理分配资源。51中只有两个定时器,但也有其他中断啊,如2个外部中断。建议延时用定时器来做比较好,一是准确,二是不占用MCU资源。其实关键还是多写多做几个项目就知道了。

关于51单片机的问题,求教
答:既然是数据存储器,当然要用到读和写,即存储数据和取出数据,完成这两项任务,就要用到RD(读)和WR(写)。而且还要用到ALE(地址锁存),这都是必须的,不然数据总线和地址总线就没法分了,因为地址总线的低八位和数据总线是复用的。

51单片机的地址问题(位地址和字节地址)
答:1. 8051的内部RAM能作为用户RAM区的只有00~7FH,可以用直接寻址或寄存器间接寻址;80H~FFH是SFR,放了些特殊功能寄存器,只能用直接寻址;2. 位地址00~7FH和片内RAM字节地址00~7FH只是地址的称呼一样,代表的含义不同,位地址只能用位寻址;3. 具体的地址是只能通过指令来区分。其实楼主的理解还是...

关于51单片机IO口驱动能力的问题
答:51单片机IO口为集电极上拉输出方式,高电平输出电流等于上拉电阻的电流,这个电流比较小,低电平输出是内部晶体管吸收的电流,最大可以达到10mA,但是整个端口的总电流不能超过24mA。电平低于0.7V就是低电平,高于1.8V就是高电平。在这个之间不确定。

51单片机,简单问题
答:一般情况下我们都是以1作为高电平,0作为低电平,因为这样符合我们日常生活中的认识。但是芯片的高低电平有时候不是这样的,单片机是以1作为高电平(这时也是高电压),0作为低电平(低电压)。但是并不是所有的逻辑电平都是这样(1为高,0为低)的。比如RS-232C标准规定的逻辑电平与TTL数字电路(例如...

关于51单片机矩阵键盘的问题。
答:(1)P3口是准双向IO口(注意与双向IO口的区别),它 的硬件结构决定着,读取之前先写1,再读取,读取的结果才可能是正确的,你可以区域查查书。(2)4X4 矩阵键盘的8根线直接连在IO上,而独立按键有一根线固定是接地的,这就意味着必须采取扫面或者线反转的方法。比如其中一根行线赋0,相当于...

51单片机的问题急啊!!!请看下面这个程序!!!
答:a=0;bai=a/100;shi=a%100/10;ge=a%10;这个结构肯定有问题,当你a为300的时候岂不是不会执行bai=a/100;这条语句了吗?最主要的问题是你a++竟然在主程序里;这样当然没法显示了,你单片机运行速度那么快没等你t==20,a都不知道加够几千个300了,怎么会显示呢!这下明白了吗 ...

51单片机 的一点问题
答:根据汉字个数和刷频率设定地址线的刷新速度并把相应的数据送到数据线上去;至于滚动么无非就是改变地址线和数据线的对应关系;L的翻转和倒置:(1)存四个方向的四个字库,对按键计数,根据计数值选择相应的字库(2)口字四边显示的取舍 思路应该比较清楚,试着编一下,有问题可以再交流~...

51单片机code的问题(RAM和ROM)+50
答:补充一下。全局变量一般占用RAM区较高位,如从32H开始,根据编译器不同而不同。且所占用RAM一直占用。局部变量一般临时存放在REGISTER中,执行速度较快。且当子程序执行完毕,资源回收。上例是那个for循环就是用的局部变量,存放在寄存器中的,子程序执行完毕,寄存器可用作他用。希望能回答你的问题。