数字电压表课程设计书.docx
《数字电压表课程设计书.docx》由会员分享,可在线阅读,更多相关《数字电压表课程设计书.docx(32页珍藏版)》请在冰豆网上搜索。
![数字电压表课程设计书.docx](https://file1.bdocx.com/fileroot1/2023-7/15/1384e231-e7a1-4b80-8b45-d15f7d0990f7/1384e231-e7a1-4b80-8b45-d15f7d0990f71.gif)
数字电压表课程设计书
单片机课程设计
姓名王嘉波
学号1206062135
年级专业自动化
所在院系电气工程与自动化学院
指导教师关健生
提交日期2015年1月11日
《单片机原理及应用》课程设计任务书
学年学期:
2014-2015第1学期
专业班级:
12级自动化1班
指导教师:
关键生
设计时间:
第17周
学时周数:
每班/周
一、设计目的
课程设计是单片机课程教学的最后一个环节,是对学生进行全面的系统的训练,让学生把学过的比较零碎的知识系统化,真正的能够把学过的知识落到实处,能够开发简单的系统,也进一步激发了学生再深一步学习的热情,进一步掌握和利用C语言进行单片机程序设计的能力,熟练掌握键盘、显示、A/D输入输出,I2C总线,温度传感器等知识点。
二、设计任务及要求
本课程设计的题目设计内容自选,学生可以根据平时的观察,了解单片机实验的应用系统,弄清其结构和功能,结合单片机课程及其相关的知识,充分发挥自身的想象力和创造力,自行选定设计项目,但总体应达到以下要求:
1、用89C51CPU,12M时钟,常规的上电和手动复位电路
2、包括3×4矩阵键盘
3、LCD显示显示器及接口
4、一路蜂鸣器输出
5.至少有2路输入信号,可以是模拟量或数字量
三、设计时间进度安排
时间
内容
周一
一、布置设计内容和要求
1、实习内容介绍、实习安排、实习纪律、注意事项
2、根据所选题的要求,进行总体设计,确定程序总体框架
周二、三
(2天)
二、系统设计
1)利用单片机实验箱,进行AD微调,AD微调的结果在LCD上显示,
2)在LCD上有上下限值,通过矩阵键盘来设置。
3)若AD微调的值超过上限或是下限则蜂鸣器发出声音。
周四
(1天)
三、系统调试
1)矩阵键盘加防抖程序测试
2)AD两路输入分别调试最大值和最小值,观察系统的变化
3)蜂鸣器要在上下限超出时分别发出不同的声音。
周五
(1天)
四、测试完整程序与报告上交
1、要求功能完整,结果符合设计要求,并进行程序验收。
(答辩)
2、完成实习报告的编写,并打印上交报告。
四、报告书写格式
1、课程设计任务书
2、设计项目简介
A/D转换
A/D转换
3、电路原理图
1、STC89C51功能简图
2、蜂鸣器
矩阵键盘
LCD
AD-DA转化
实体液晶屏电路图
4、系统功能描述
系统可以通过AD-DA模块进行采样,通过液晶屏显示出来,并对采样的数据与之前设定的上下限做比较,且如果采样的两路值的任何一路大于或小于设定的上限或下限,蜂鸣器会发出报警的声音。
5、程序框图
LCD初始化:
检查LCD状态:
写指令到LCD:
写数据到LCD:
键盘扫描:
判断键盘是否有键按下
AD转换值比较:
I2C启动:
I2C终止:
I2C接收:
I2C发送:
六、程序清单:
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
#define_Nop()_nop_()
voidKeyScan();
voidDispaly(uchark);
sbitP13=P1^3;//键盘
sbitP12=P1^2;
sbitP11=P1^1;
sbitrs=P2^6;//lcd
sbitrw=P2^5;
sbitE=P2^7;
sbitscl=P2^1;//i2c
sbitsda=P2^0;
sbitbee=P2^3;
bitack;/*应答标志位*/
uchari2c_Buffer[4];//数据缓冲
uintVoltage[]={'0','0','0','0'};
uchartable[]={"U1:
."};
uchartable2[]={"U2:
."};
ucharLCD_table[]={"U3:
.V"};
ucharLCD_table1[]={"U4:
.V"};
ucharkey,temp,kmax,kmin,kmax1,kmin1,kk,t,y=0;
voiddelay(uintms)
{
uinti,j;
for(j=0;jfor(i=0;i<120;i++);
}
voiddelayus(uintus)
{
uinti,j;
for(j=0;jfor(i=0;i<12;i++);
}
bitLCD_Busy_Check()//忙指令
{
bitResult;
rs=0;
rw=1;
E=1;
delayus(4);
Result=(bit)(P0&0x80);
E=0;
returnResult;
}
voidwrite_command(ucharcommand)//写命令
{
while(LCD_Busy_Check());
rs=0;
rw=0;
P0=command;
E=1;
E=0;
}
voidwrite_data(uchardata0)//写数据
{
while(LCD_Busy_Check());
rs=1;
rw=0;
P0=data0;
E=1;
E=0;
}
voidLCD_Set_Position(ucharpos)//放置位置
{
write_command(pos|0x80);
}
voidLCD_Display_A_Line(ucharLine_Addr,uchars[])
{
uchari;
LCD_Set_Position(Line_Addr);
for(i=0;i<16;i++)
write_data(s[i]);
}
voidLCD_Set_Position1(ucharpos)
{
write_command(pos|0xc0);
}
voidLCD_Display_A_Line1(ucharLine_Addr,uchars[])
{
uchari;
LCD_Set_Position1(Line_Addr);
for(i=0;i<16;i++)
write_data(s[i]);
}
voidi2c_start()//起始
{
sda=1;/*发送起始条件的数据信号*/
_Nop();
scl=1;
_Nop();/*起始条件建立时间大于4.7us,延时*/
_Nop();
_Nop();
_Nop();
_Nop();
sda=0;/*发送起始信号*/
_Nop();/*起始条件锁定时间大于4μs*/
_Nop();
_Nop();
_Nop();
_Nop();
scl=0;/*钳住I2C总线,准备发送或接收数据*/
_Nop();
_Nop();
}
voidi2c_stop()//终止
{
sda=0;/*发送结束条件的数据信号*/
_Nop();/*发送结束条件的时钟信号*/
scl=1;/*结束条件建立时间大于4μs*/
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
sda=1;/*发送I2C总线结束信号*/
_Nop();
_Nop();
_Nop();
_Nop();
}
voidi2c_ack(bita)//应答
{
if(a==0)sda=0;/*在此发出应答或非应答信号*/
elsesda=1;
_Nop();
_Nop();
_Nop();
scl=1;
_Nop();
_Nop();/*时钟低电平周期大于4μs*/
_Nop();
_Nop();
_Nop();
scl=0;/*清时钟线,钳住I2C总线以便继续接收*/
_Nop();
_Nop();
}
voidi2c_write(ucharc)//写数据
{
unsignedcharBitCnt;
for(BitCnt=0;BitCnt<8;BitCnt++)/*要传送的数据长度为8位*/
{
if((c<elsesda=0;
_Nop();
scl=1;/*置时钟线为高,通知被控器开始接收数据位*/
_Nop();
_Nop();/*保证时钟高电平周期大于4μs*/
_Nop();
_Nop();
_Nop();
scl=0;
}
_Nop();
_Nop();
sda=1;/*8位发送完后释放数据线,准备接收应答位*/
_Nop();
_Nop();
scl=1;
_Nop();
_Nop();
_Nop();
if(sda==1)ack=0;
elseack=1;/*判断是否接收到应答信号*/
scl=0;
_Nop();
_Nop();
}
uchari2c_read()//读数据
{
ucharretc,BitCnt;
retc=0;
sda=1;/*置数据线为输入方式*/
for(BitCnt=0;BitCnt<8;BitCnt++)
{
_Nop();
scl=0;/*置时钟线为低,准备接收数据位*/
_Nop();
_Nop();/*时钟低电平周期大于4.7μs*/
_Nop();
_Nop();
_Nop();
scl=1;/*置时钟线为高使数据线上数据有效*/
_Nop();
_Nop();
retc=retc<<1;
if(sda==1)retc=retc+1;/*读数据位,接收的数据位放入retc中*/
_Nop();
_Nop();
}
scl=0;
_Nop();
_Nop();
return(retc);
}
voidADC_PCF8591(ucharCtrlByte)//连续读入4路通道ad转换存入i2c_Buffer
{
uchari,j;
i2c_start();
i2c_write(0x90);//写
if(ack==0)return;
i2c_write(CtrlByte);
if(ack==0)return;
i2c_start();
i2c_write(0x91);//读
if(ack==0)return;
i2c_read();//空读数据
i2c_ack(j);
for(i=0;i<4;i++)
{
i2c_Buffer[i++]=i2c_read();
i2c_ack(j);
}
i2c_stop();
}
voidConvert_To_Voltage(ucharval)
{
ucharTmp;
Voltage[2]=val/51+'0';
Tmp=val%51*10;
Voltage[1]=Tmp/51+'0';
Tmp=Tmp%51*10;
Voltage[0]=Tmp/51+'0';
}
voidcom_(ucharaa)//比较,蜂鸣
{
if(kmin>kmax)
{temp=kmin;kmin=kmax;kmax=temp;}
if(aa>kmax)
{
bee=!
bee;
delayus
(1);
}
if(aa{
bee=!
bee;
delayus(100);
}
}
voidmain()
{
uchari;
bee=1;
delay(15);//lcd初始化
write_command(0x38);//设置8位格式,2行,5x7
delay(5);
write_command(0x38);
delay(5);
write_command(0x38);
delay(5);
write_command(0x0e);
delay(5);
write_command(0x06);
delay(5);
//write_command(0x01);
//delay(5);
//write_command(0x08);
//delay(5);
for(i=0;i{
write_data(table[i]);
delay
(1);
}
write_command(0xc0+0x01);//换行
delay(5);
for(i=0;i{
write_data(table2[i]);
delay
(1);
}
while
(1)
{
while(kk!
=100)
KeyScan();
ADC_PCF8591(0x04);
Convert_To_Voltage(i2c_Buffer[0]);//第一个通道
com_(i2c_Buffer[0]);
LCD_table[3]=Voltage[2];
LCD_table[5]=Voltage[1];
LCD_table[6]=Voltage[0];
Convert_To_Voltage(i2c_Buffer[2]);//第二通道
com_(i2c_Buffer[2]);
LCD_table1[3]=Voltage[2];
LCD_table1[5]=Voltage[1];
LCD_table1[6]=Voltage[0];
LCD_Display_A_Line(0x08,LCD_table);
LCD_Display_A_Line1(0x08,LCD_table1);
}
}
voidKeyScan()//键盘扫描程序
{kk=0;
P1=0xFF;
P11=0;
{
delay
(1);
temp=P1;
temp&=0xF0;
if(temp!
=0xF0)
{
switch(temp)
{
case0xe0:
key=0;break;
case0xd0:
key=1;break;
case0xb0:
key=2;break;
case0x70:
key=3;break;
}
Dispaly(key);
}
}
P1=0xFF;
P12=0;
{
delay(10);
temp=P1;
temp&=0xF0;
if(temp!
=0xF0)
{
switch(temp)
{
case0xe0:
key=4;break;
case0xd0:
key=5;break;
case0xb0:
key=6;break;
case0x70:
key=7;break;
}
if(key==7)
kk=100;
Dispaly(key);
}
}
P1=0xFF;
P13=0;
{
delay(10);
temp=P1;
temp&=0xF0;
if(temp!
=0xF0)
{
switch(temp)
{
case0xe0:
key=8;break;
case0xd0:
key=9;break;
case0xb0:
key=10;break;
case0x70:
key=11;break;
}
Dispaly(key);
}
}
}
voidDispaly(uchark)
{
if(k==10)
{
write_command(0x80+0x04);
delay
(1);
y=2;
}
if(k==11)
{
write_command(0x80+0x06);
delay
(1);
y=3;
}
if(k==8)
{
write_command(0xc0+0x04);
delay
(1);
y=1;
}
{
if(k==9)
{
write_command(0xc0+0x06);
delay
(1);
y=4;
}
if(k<7)
{write_data(k+0x30);delay(200);
if(y==1)kmin=k*51;
if(y==2)kmax=k*51;
if(y==3)kmax1=k/10*51;
if(y==4)kmin1=k/10*51;
kmax=kmax+kmax1;
kmin=kmin+kmin1;
}
}
}
七、收获与体会:
通过为期一周的单片机课程设计,我从中学到了很多。
首先,通过该课程设计我们对单片机的应用有了进一步的了解,知道把课堂的理论知识结合起来,加以设计,就能初步将设计方案的大纲列出来。
其次,在起初开始设计的时候,有点无从入手,最后在关老师的循循善诱下逐渐开始尝试着入手。
一开始写键盘的程序就遇到了问题,经过无数次尝试后终得到解决了。
而在随后的其他程序编程中也是问题不断,通过对理论知识的学习和不断的尝试,最后也完成了本次”数字电压表”的设计。
最后,谈谈本次课设的感受:
虽然期间困难很多,但收获也不少,看似复杂的问题只要多加学习,多花时间钻研,总是会得到解决的;在设计中原理和各芯片的结构都非常重要,可以帮我们更好的理解它的工作原理,进而帮助我们更好地设计程序框图;本课程设计提高了我们的独立思考能力和实验实践操作能力,同时也让我们对单片机有了更多的兴趣。