工程测控课程设计 电子c082班 王柳 087774.docx
- 文档编号:27018464
- 上传时间:2023-06-25
- 格式:DOCX
- 页数:31
- 大小:89.28KB
工程测控课程设计 电子c082班 王柳 087774.docx
《工程测控课程设计 电子c082班 王柳 087774.docx》由会员分享,可在线阅读,更多相关《工程测控课程设计 电子c082班 王柳 087774.docx(31页珍藏版)》请在冰豆网上搜索。
工程测控课程设计电子c082班王柳087774
工程测控系统课程设计
使用51单片机设计软件钟、涡流称重计、光电转速计
一、实验目的:
1.掌握元器件及芯片的焊接与调试;
2.了解基于51单片机的软件钟、涡流称重计、光电转速计的工作原理;
3.熟悉掌握AT89C51系列单片微型计算机的工作原理、熟悉ADC0832的器件手册;
4.会用C语言编写时钟函数,复习用switch语句和do-while语句、for语句实现循环的方法;
5.会使用MEDWIN编译调试程序,并生成HEX,通过数据线下载到电路板上;
6.根据自己焊接的板子在程序中设置按键控制时钟的调整。
7.了解电涡流传感器用于称重的原理与方法、了解光电传感器的工作原理及其使用方法;
软件钟
二、算法原理:
所谓软件钟就是利用51单片机制作一个电子时钟。
其算法就是以单片机的时钟为基准,记录单片机时钟脉冲的数量,当数量足够多(如脉冲为每秒6Mhz,那么记录6M个脉冲所需时间即为1秒)就可以将显示部分的“秒”位加一。
加到60以后进位为“分”,”秒“位清零以后继续记录。
当“分”累加为60以后进位为”时“,”分“位清零以后继续记录,当”时“位为24以后,”时“位清零并继续记录。
三、硬件原理:
显示电路:
单片机外围电路(复位电路,时钟电路):
按键控制电路:
数码管驱动电路:
四、实现功能要求:
使用中需要对时钟进行调整。
在调整的时候需要一个按键来进入调整状态。
进入调整状态以后需要一个按键来向左移动调整位置,一个按键来向右移动调整位置,一个按键来增加所选位置的数值,一个按键来减小所选位置的数值。
调整完成以后还需要一个按键来退出调整位置,恢复时钟的计数运转。
以上所需按键可以根据需要合并。
在调整中另外一个需要注意的问题是如何显示目前所选定调整的位置(如秒的个位或者十位,分的个位或者十位等)。
可以采用是否显示数位右下的小数点或者所选需调整位是否闪烁来让操作者明确目前自己所选定的需要调整的数位。
五、设计内容:
(1)硬件焊接:
按照电路图焊接好各个元器件和芯片插座,注意焊接时焊点要尽量光滑,与管脚接触良好,元件的管脚弯曲处要尽量光滑,有需要区分正负极的元器件焊接时要注意不要焊反。
焊接完后将元件多余的管脚用尖嘴钳剪掉,以免形成短路。
(2)软件设计:
1.子程序设计:
A.单片机初始化程序
a)定时器T0中断服务程序
B.显示子程序
C.时钟运行计数子程序
D.时间数据送显示缓冲区子程序
E.设置时间子程序
F.时钟调整子程序
G.键值读入子程序
H.延时子程序
2.实验程序清单:
#pragmadboe
#include
#include
#include
#include
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
#defineulongunsignedlong
voiddisplay(void);
voidinitsiu(void);
voiddelay(void);
voidsztz(void);
voidjssz(void);
voidsetsz(void);
voidtzszw(ucharzj);
ucharinkey(void);
ucharsec,min,hour;
uchardisdat[6];
ucharcodetab[]={0x3f,0x6,0x5b,0x4f,0x66,0x6d,0x7d,0x7,0x7f,0x6f};
uintcount;
ucharset_state,xsd;
sbitzsd=P1^0;
main()
{
uchari;
for(i=0;i<2;i++)
{
disdat[i]=0;//将显示缓存清零
}
initsiu();//初始化单片机
set_state=0;
do
{
i=inkey();//设置时钟
if(i==0x70)
setsz();
jssz();
display();//显示
if((sec&0x01))//指示灯闪烁
zsd=1;
else
zsd=0;
}
while
(1);
}
voiddisplay(void)//六位数码管显示程序,disdat[]是要显示的内容(是0~9的数字),xsd是在那一位显示小数点
{
uchari,disa,disb,disc;
disb=0x00;//显示第n位
for(i=0;i<6;i++)//共显示6个数据
{
disa=disdat[i];//显示数据
if(disa<10)
{
P2=disb;
disc=tab[disa];//显示段码
if(set_state==0)//显示时钟
{
if((i==1)||(i==3))
disc=disc|0x80;//增加小数点显示
}
else//设置时显示
{
if(xsd==i)
disc=disc|0x80;//增加小数点显示
}
P0=disc;//送显示
delay();//延时
P0=0x0;
disb++;//下一个要显示的位置
}
}
P2=0xff;
}
voidsetsz(void)//设置时间
{
uchari,k;
set_state=1;//改变显示状态
xsd=0;//设置位置
TR0=0;//停止时钟运行
jssz();//将现在的结果放到数组disdat[]
do
{
display();//显示
i=inkey();//读键
switch(i)
{
case0x70:
//退出设置,1号键
k=0xff;
break;
case0xb0:
//改变设置位置,每按下一次右移一个,2号键
k=0;
xsd++;
if(xsd==6)
xsd=0;
break;
break;
case0xd0:
//加1,3号键
k=0;
tzszw(0);
break;
case0xe0:
//进入设置,减1,4号键
k=0;
tzszw
(1);
break;
default:
k=0;
break;
}
}
while(k!
=0xff);
set_state=0;//恢复显示时钟
TR0=1;//时钟运行
_nop_();
}
voidtzszw(ucharzj)
{
ucharj;
switch(xsd)
{
case0:
//时高位调整
if(zj==0)
{
disdat[0]++;
if(disdat[0]>2)
disdat[0]=0;
}
else
{
if(disdat[0]==0)
disdat[0]=2;
else
disdat[0]--;
}
hour=disdat[0]*10+disdat[1];
break;
case1:
//时低位调整
if(zj==0)
{
disdat[1]++;
if(disdat[1]>9)
disdat[1]=0;
}
else
{
if(disdat[0]!
=2&&disdat[1]==0)
disdat[1]=9;
//else
//disdat[1]--;
elseif(disdat[0]==2&&disdat[1]==0)
disdat[1]=3;
else
disdat[1]--;
}
if(disdat[0]==2&&disdat[1]>3)
disdat[1]=0;
hour=disdat[0]*10+disdat[1];
break;
case2:
//分高位调整
if(zj==0)
{
disdat[2]++;
if(disdat[2]>5)
disdat[2]=0;
}
else
{
if(disdat[2]==0)
disdat[2]=5;
else
disdat[2]--;
}
min=disdat[2]*10+disdat[3];
break;
case3:
//分低位调整
if(zj==0)
{
disdat[3]++;
if(disdat[3]>9)
disdat[3]=0;
}
else
{
if(disdat[3]==0)
disdat[3]=9;
else
disdat[3]--;
}
min=disdat[2]*10+disdat[3];
break;
case4:
//秒高位调整
if(zj==0)
{
disdat[4]++;
if(disdat[4]>5)
disdat[4]=0;
}
else
{
if(disdat[4]==0)
disdat[4]=5;
else
disdat[4]--;
}
sec=disdat[4]*10+disdat[5];
break;
case5:
//秒低位调整
if(zj==0)
{
disdat[5]++;
if(disdat[5]>9)
disdat[5]=0;
}
else
{
if(disdat[5]==0)
disdat[5]=9;
else
disdat[5]--;
}
sec=disdat[4]*10+disdat[5];
break;
default:
break;
}
}
voiddelay(void)//延时程序
{
uchari;
for(i=0;i<201;i++)
_nop_();
}
voidjssz(void)//将时钟分离送到显示缓存
{
disdat[0]=hour/10;
disdat[1]=hour%10;
disdat[2]=min/10;
disdat[3]=min%10;
disdat[4]=sec/10;
disdat[5]=sec%10;
}
voidsztz(void)//时钟运行计数,每秒运行一次
{
sec++;
if(sec==60)
{
sec=0;
min++;
if(min==60)
{
min=0;
hour++;
if(hour==24)
{
hour=0;
}
}
}
}
voidinitsiu(void)//初始化单片机
{
TMOD=0x11;//定时器1:
gate=0->TR1=1开始计数,C/T=0->对内部计数,模式1->16位计数
TH0=0X3C;
TL0=0XAF;
ET0=1;//打开定时器0中断
ET1=0;//关闭定时器1中断
TR0=1;//打开计数器0
TR1=0;//关闭计数器1
EA=1;//总中断允许
}
voidinttime0(void)interrupt1using1
{
TH0=0X3C;//50ms中断一次,20次为一秒,调整时间一次
TL0=0XAF;
count++;
if(count==20)
{
count=0;
sztz();
}
}
ucharinkey(void)
{
ucharjjj,keydat;
P2=0xff;//P2准备读入
keydat=P2;//读入键值
keydat=keydat&0xf0;//找出四个键的值
if(keydat!
=0xf0)//有键输入
{
_nop_();
_nop_();
jjj=P2;//再读,去抖动
jjj=jjj&0xf0;
if(jjj!
=keydat)
keydat=0xf0;
do
{
jjj=P2;
jjj=jjj&0xf0;
}//等待键松手
while(jjj!
=0xf0);
}
return(keydat);
}
六、测试结果分析:
本实验共设置了5个按钮,按键1设置小数点到达那位数码管的值,按键2控制小数点的位置,按键3按下后进入计时状态,到达23:
59:
59后数据清零为00:
00:
00,按键4按下后进入设置状态,按键5是复位按键。
七、遇到的问题与解决方法:
问题一:
如何编写时钟函数?
解决方法:
每60秒进一位,即一分钟;每60分钟进一位,即一小时;在函数体内用循环,在主函数中调用。
编写时注意当时高位为2时,时地位最高到3,且分高位和秒高位最高为5。
问题二:
如何设置时间?
解决方法:
改变现实状态,将现在的结果放到数组中去,读取按键,设置按键对时钟进行调整,编写SWITCH语句控制按键的选择。
问题三:
如何解决时间变化太快?
解决方法:
使用一个延时函数来缓冲每一秒变化时间。
八、实验总结:
通过本次实验,我对时钟函数的编写有了更深一步的掌握,复习了C语言的编程。
并且可以通过自己焊接的板子来调试时钟程序,对今后的学习与研究有了很大的帮助。
涡流称重计
二、算法原理
本项设计中用电位器的中间抽头所输出的电压模拟采集的重量数据,单片机经ADC0832的通道0输入该电压信号,并将其转换为数字信息送6位共阳8段LED显示。
ADC0832的芯片接口说明:
·CS_片选使能,低电平芯片使能。
·CH0模拟输入通道0,或作为IN+/-使用。
·CH1模拟输入通道1,或作为IN+/-使用。
·GND芯片参考0电位(地)。
·DI数据信号输入,选择通道控制。
·DO数据信号输出,转换数据输出。
·CLK芯片时钟输入。
·Vcc/REF电源输入及参考电压输入(复用)
当此2位数据为“1”、“0”时,只对CH0进行单通道转换。
当2位数据为“1”、“1”时,只对CH1进行单通道转换。
当2位数据为“0”、“0”时,将CH0作为正输入端IN+,CH1作为负输入端IN-进行输入。
当2位数据为“0”、“1”时,将CH0作为负输入端IN-,CH1作为正输入端IN+进行输入。
到第3个脉冲的下沉之后DI端的输入电平就失去输入作用,此后DO/DI端则开始利用数据输出DO进行转换数据的读取。
从第4个脉冲下沉开始由DO端输出转换数据最高位DATA7,随后每一个脉冲下沉DO端输出下一位数据。
直到第11个脉冲时发出最低位数据DATA0,一个字节的数据输出完成。
也正是从此位开始输出下一个相反字节的数据,即从第11个字节的下沉输出DATD0。
随后输出8位数据,到第19个脉冲时数据输出完成,也标志着一次A/D转换的结束。
最后将CS置高电平禁用芯片,直接将转换后的数据进行处理就可以了。
三、实现功能要求:
使用时用5V的电压来表示200g的重量,使用通道O来输入模拟量。
四、设计内容:
(1)硬件焊接:
根据ADC0832的接口说明焊接导线
(2)软件设计:
1.子程序设计:
A.单片机的初始化程序
B.显示子程序
C.3.0832的转换子程序
D.采样数据换算压力子程序
E.将压力值转换为十进制数,并将每位送入显示缓冲区子程序
2.实验程序清单:
#include
#include"intrins.h"
#defineuintunsignedint
#defineucharunsignedchar
//ADC0832的引脚
sbitADCS=P3^5;//ADC0832chipseclect
sbitADCLK=P3^4;//ADC0832clocksignal
sbitADDI=P3^3;//ADC0832kin
sbitADDO=P3^3;//ADC0832kout
uchardispbuf[6];
ucharcodetab[]={0x3f,0x6,0x5b,0x4f,0x66,0x6d,0x7d,0x7,0x7f,0x6f};
ucharcodetab1[]={0x79,0x3f,0x77};
uinttemp;
uchargetdata;//获取ADC转换回来的值
uchare=0;
voiddelay(void)//延时程序
{
uchari;
for(i=0;i<201;i++)
_nop_();
}
voiddisplay(void)//六位数码管显示程序,disdat[]是要显示的内容(是0~9的数字),xsd是在那一位显示小数点
{
uchari,disa,disb,disc;
disb=0x00;//显示第n位
for(i=0;i<6;i++)//共显示3个数据
{
if(e==0)
disa=dispbuf[i];//显示数据
else
disa=i-3;
if(disa<10&&e==0)
{
P2=disb;
disc=tab[disa];//显示段码
if(i==0||i==5)
disc=disc|0x80;//增加小数点显示
P0=disc;//送显示
delay();//延时
P0=0x0;
disb++;//下一个要显示的位置
}
else//(e==1)
{
P2=disb;
disc=tab1[disa];//显示段码
P0=disc;//送显示
delay();//延时
P0=0x0;
disb++;//下一个要显示的位置
}
}
P2=0xff;
}
unsignedintAdc0832(unsignedcharchannel)//AD转换,返回结果
{
uchari=0;
ucharj;
uintdat=0;
ucharndat=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=channel&0x1;
_nop_();
_nop_();
ADCLK=0;//拉低CLK端,形成下降沿2
_nop_();
_nop_();
ADCLK=1;//拉高CLK端
ADDI=(channel>>1)&0x1;
_nop_();
_nop_();
ADCLK=0;//拉低CLK端,形成下降沿3
ADDI=1;//控制命令结束
_nop_();
_nop_();
dat=0;
for(i=0;i<8;i++)
{
dat|=ADDO;//收数据
ADCLK=1;
_nop_();
_nop_();
ADCLK=0;//形成一次时钟脉冲
_nop_();
_nop_();
dat<<=1;
if(i==7)dat|=ADDO;
}
for(i=0;i<8;i++)
{
j=0;
j=j|ADDO;//收数据
ADCLK=1;
_nop_();
_nop_();
ADCLK=0;//形成一次时钟脉冲
_nop_();
_nop_();
j=j<<7;
ndat=ndat|j;
if(i<7)ndat>>=1;
}
ADCS=1;//拉低CS端
ADCLK=0;//拉低CLK端
ADDO=1;//拉高数据端,回到初始状态
dat<<=8;
dat|=ndat;
return(dat);//returnadk
}
voidmain(void)
{
//doublek;
unsignedintw;
while
(1)
{
getdata=Adc0832(0);
temp=getdata*1.0/255*500;//电压值转换,5V做为参考电压,分成256份。
dispbuf[2]=temp%10;//个位
dispbuf[1]=temp/10%10;//十位
dispbuf[0]=temp/100;//百位
w=temp*1.0/2.5;
if(w<=199)
{
e=0;
dispbuf[5]=w%10;//个位
dispbuf[4]=w/10%10;//十位
dispbuf[3]=w/100;//百位
}
else
{
e=1;
}
display();
}
}
五、测试结果分析:
此电路板实现的功能是从电位器中分出一部分电压,并将其进行A/D转换,将模拟量转换为数字量,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 工程测控课程设计 电子c082班 王柳 087774 工程 测控 课程设计 电子 c082