《单片机原理及应用》课程设计任务书1
系(部):电信系 专业:2012级电子信息工程
课题名称
数字式温湿度测量仪设计
设计内容及要求
(1)课题内容:
以单片机为核心,设计一个数字频率计,进行频率的自动测量,并用12864液晶屏的第一行显示“数字频率计”,第二行显示设计者的姓名和学号,第三行显示测量的频率值(单位:HZ)。
基本部分:测频范围为1HZ-50HZ。
发挥部分:扩大测频范围为1HZ-1MHZ。
(2)要求:完成该系统的硬件和软件的设计,在Proteus 软件上仿真通过,并提交一篇课程设计说明书。
设计工作量
1、汇编或C51 语言程序设计;
2、程序调试;
3、在Proteus 上进行仿真成功;
4、提交一份完整的课程设计说明书,包括设计原理、程序设计、程序
分析、仿真分析、调试过程,参考文献、设计
总结
初级经济法重点总结下载党员个人总结TXt高中句型全总结.doc高中句型全总结.doc理论力学知识点总结pdf
等。
进度安排
起止日期(或时间量)
设计内容(或预期目标)
备注
第一天
课题介绍,答疑,收集材料,C51介绍
第二天
设计方案论证,练习编写C51程序
第三天~第六天
程序设计
第六天~第八天
程序调试、仿真
第九天~第十天
系统测试并编写设计说明书
教研室
意见
年 月 日
系(部)主管领导意见
年 月 日
目录
摘要 5
1引言 5
2设计任务 5
2.1设计内容 5
2.2设计要求 6
2.3设计过程 6
3设计原理 6
3.1 Keil uVision3简介 6
3.2 Proteus简介 6
3.3数字频率计原理 6
4设计方案 7
4.1程序设计 7
4.2仿真设计 8
5.设计分析及结果 9
5.1程序分析 9
5.2仿真分析 9
6设计结论 10
6.1设计的问题及解决 10
6.2设计的心得与体会 10
7参考文献 11
摘要 本课程设计主要运用Keil uVision3软件的编程环境以及Proteus软件的仿真环境下设计一个数字频率计,通过软件Keil uVision4用C语言来编程从而从软件上来达到要求,进而通过软件ISIS 7 Professional的模拟仿真来检测效果,通过仿真上面的测频的范围来检测编程中的不足以及需要改进的地方,这种反馈有利于我们及时的纠错以及更快更好的实现我们所需要的效果。从而在真正的硬件显示效果的时候做好嫁衣。
1引言
随着经济与社会发展对智能化和信息化技术要求的不断提高,单片机作为智能控制的核心,逐渐渗透到社会生产和生活的各个方面。单片机芯片的使用量每年去年一数百亿计,广泛应用于仪器仪
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
、信息处理和通信设备、家用电器和汽车,以及精密制导武器等方方面面,似乎已经找不到不使用单片机的领域了。因此社会需要大量的学习和掌握了单片机应用技术的专门人才。
2设计任务
2.1设计内容
以单片机为核心,设计一个数字频率计,进行频率的自动测量,并用12864液晶屏的第一行显示“数字频率计”,第二行显示设计者的姓名和学号,第三行显示测量的频率值(单位:HZ)。
基本部分:测频范围为1HZ~50KHZ。
发挥部分:扩大频率范围为1HZ~1MHZ。
2.2设计要求
完成数字频率计系统的软件与硬件设计,在Proteus软件上仿真通过后,下载到实验板上验证。
2.3设计过程
(1)汇编或C51语言程序设计;
(2)程序调试;
(3)在Proteus上进行仿真并取得成功;
(4)提交一份完整的课程设计说明书,包括封面,中文摘要,目录,正文(正文主要包括:设计原理、程序设计、程序分析、仿真分析、调试过程、调试结果等部分),参考文献,设计总结等。
3设计原理
3.1 Keil uVision3简介
KeilSoftware公司推出的uVision3是一款可用于多种8051MCU的集成开发环境(IDE),该IDE同时也是PK51及其它开发套件的一个重要组件。除增加了源代码、功能导航器、模板编辑以及改进的搜索功能外,uVision3还提供了一个配置向导功能,加速了启动代码和配置文件的生成。此外其内置的仿真器可模拟目标MCU,包括指令集、片上外围设备及外部信号等。uVision3提供逻辑分析器,可监控基于MCUI/O引脚和外设状态变化下的程序变量。
uVision3提供对多种最新的8051类微处理器的支持,包括AnalogDevices的ADuC83x和ADuC84x,以及Infineon的XC866等。
3.2 Proteus简介
Proteus是世界上著名的EDA工具(仿真软件),从原理图布图、代码调试到单片机与外围电路协同仿真,一键切换到PCB设计,真正实现了从概念到产品的完整设计。是目前世界上唯一将电路仿真软件、PCB设计软件和虚拟模型仿真软件三合一的设计平台,其处理器模型支持8051、HC11、PIC10/12/16/18/24/30/DsPIC33、AVR、ARM、8086和MSP430等,2010年又增加了Cortex和DSP系列处理器,并持续增加其他系列处理器模型。在编译方面,它也支持IAR、Keil和MPLAB等多种编译器
3.3数字频率计原理
所谓频率,就是周期性信号在单位时间 (1s) 内变化的次数.若在一定时间间隔T内测得这个周期性信号的重复变化次数为N,则其频率可表示为 fx=N/T 。因此,可以将信号放大整形后由计数器累计单位时间内的信号个数,然后经译码、显示输出测量结果,这是所谓的测频法。可见数字频率计主要由放大整形电路、闸门电路、计数器电路、锁存器、时基电路、逻辑控制、译码显示电路几部分组成,
Ⅲ
从原理图可知,被测信号Vx经放大整形电路变成计数器所要求的脉冲信号Ⅰ,频率与被测信号的频率fx相同。时基电路提供标准时间基准信号Ⅱ,具有固定宽度T的方波时基信号II作为闸门的一个输入端,控制闸门的开放时间,被测信号I从闸门另一端输入,被测信号频率为fx,闸门宽度T,若在闸门时间内计数器计得的脉冲个数为N,则被测信号频率fx=N/THz。可见,闸门时间T决定量程,通过闸门时基选择开关选择,选择T大一些,测量准确度就高一些,T小一些,则测量准确度就低. 根据被测频率选择闸门时间来控制量程.在整个电路中,时基电路是关键,闸门信号脉冲宽度是否精确直接决定了测量结果是否精确.逻辑控制电路的作用有两个:一是产生锁存脉冲Ⅳ,使显示器上的数字稳定;二是产生清“0”脉冲Ⅴ,使计数器每次测量从零开始计数。
4设计方案
4.1程序设计
通过C语言在Keil uVision4软件中编程建立数字频率计.c文件,并生成HEX文件。主体程序框架展示如下:
#include
#include
#include
#include
#define LCD_databus P0
#define uint unsigned int
#define uchar unsigned char
sbit EN=P2^2;
sbit RS=P2^0;
sbit RW=P2^1;
sbit CS2=P2^3;
sbit CS1=P2^4;
sbit led=P1^0;
uchar count0;
uchar count1_freq;
uchar start_flag;
unsigned long a;
uchar Z,H,G,D,E,F,X;
unsigned char code time[][16]
uchar code HZ[][32]
void main(void)
{
}
void timer0() interrupt 1
{
}
4.2仿真设计
通过软件Proteus仿真,原理图由AT89C51、12864显示屏、上拉电阻RP1、指示灯、开关等器件组成,仿真原理图展示如下:
图1仿真原理图
5.设计分析及结果
5.1程序分析
总的程序展示:
#include
#include
#include
#include
#define LCD_databus P0
#define uint unsigned int
#define uchar unsigned char
sbit EN=P2^2;
sbit RS=P2^0;
sbit RW=P2^1;
sbit CS2=P2^3;
sbit CS1=P2^4;
sbit led=P1^0;
uchar count0;
uchar count1_freq;
uchar start_flag;
unsigned long a;
uchar H,Z,G,D,E,F,X;
unsigned char code time[][16]={
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,
0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,
0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,
0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,
0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,
0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,
0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,
0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,
0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,
0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,
0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
uchar code HZ[][32]={0x00,0x12,0x22,0x42,0x82,0x62,0x1E,0x00,0x00,0xFE,0x02,0x22,0xDA,0x06,0x00,0x00,
0x20,0x10,0x08,0x06,0x01,0x06,0x18,0x00,0x00,0xFF,0x08,0x10,0x08,0x07,0x00,0x00,
0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x20,0x40,0x80,0x00,0x00,
0x08,0x04,0x03,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x01,0x0E,0x00,
0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x40,0xA0,0x10,0x08,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0C,0x10,0x21,0x42,0xF0,0x00,
0x10,0x92,0x54,0x30,0xFF,0x50,0x94,0x32,0xD8,0x17,0x10,0x10,0xF0,0x18,0x10,0x00,
0x02,0x82,0x4E,0x33,0x22,0x52,0x8E,0x40,0x23,0x14,0x08,0x16,0x61,0xC0,0x40,0x00,
0x00,0x10,0x0C,0x24,0x24,0x24,0x25,0x26,0xA4,0x64,0x24,0x04,0x14,0x0C,0x00,0x00,
0x02,0x02,0x02,0x02,0x02,0x42,0x82,0x7F,0x02,0x02,0x02,0x02,0x02,0x03,0x02,0x00,
0x40,0x7C,0x40,0xFF,0x48,0x6C,0x4A,0xF2,0x12,0x1A,0xD6,0x12,0x12,0xFB,0x12,0x00,
0x08,0x87,0x40,0x2F,0x10,0x0F,0x80,0x8F,0x40,0x20,0x1F,0x20,0x40,0xCF,0x00,0x00,
0x00,0x14,0xA4,0x44,0x04,0x24,0xB5,0x6E,0x24,0x94,0x04,0x44,0xA6,0x14,0x00,0x00,
0x08,0x09,0x08,0x08,0x09,0x09,0x09,0xFF,0x09,0x09,0x0B,0x08,0x08,0x0D,0x08,0x00,
0x40,0x40,0x42,0xCC,0x00,0x40,0x40,0x40,0x40,0xFF,0x40,0x40,0x40,0x60,0x40,0x00,
0x00,0x00,0x00,0x7F,0x20,0x10,0x08,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00
};
void Read_busy()
{
P0=0x00;
RS=0;
RW=1;
EN=1;
while(P0 & 0x80);
EN=0;
}
void write_LCD_command(uchar value)
{
Read_busy();
RS=0;
RW=0;
LCD_databus=value;
EN=1;
_nop_();
_nop_();
EN=0;
}
void write_LCD_data(uchar value)
{
Read_busy();
RS=1;
RW=0;
LCD_databus=value;
EN=1;
_nop_();
_nop_();
EN=0;
}
void Set_page(uchar page)
{
page=0xb8|page;
write_LCD_command(page);
}
void Set_line(uchar startline)
{
startline=0xC0|startline;
write_LCD_command(startline);
}
void Set_column(uchar column)
{
column=column &0x3f;
column= 0x40|column;
write_LCD_command(column);
}
void SetOnOff(uchar onoff)
{
onoff=0x3e|onoff;
write_LCD_command(onoff);
}
void SelectScreen(uchar screen)
{
switch(screen)
{
case 0: CS1=0;CS2=0;break;
case 1: CS1=0;CS2=1;break;
case 2: CS1=1;CS2=0;break;
default:break;
}
}
void init_LCD()
{
SetOnOff(1);
SelectScreen(0);
Set_line(0);
}
void Display_ASCII(uchar screen,uchar page,uchar column,uchar a[][16],uchar h)
{
uchar i;
SelectScreen(screen);
Set_page(page);
Set_column(column*8);
for(i=0;i<8;i++)
{
write_LCD_data(*(a[h]+i));
}
Set_page(page+1);
Set_column(column*8);
for(i=0;i<8;i++)
{
write_LCD_data(*(a[h]+i+8));
}
}
void Display_HZ(uchar screen,uchar page,uchar column,uchar a[][32],uchar h)
{
uchar i;
SelectScreen(screen);
Set_page(page);
Set_column(column*16);
for(i=0;i<16;i++)
{
write_LCD_data(*(a[h]+i));
}
Set_page(page+1);
Set_column(column*16);
for(i=0;i<16;i++)
{
write_LCD_data(*(a[h]+16+i));
}
}
void disp()
{
Display_HZ(1,2,0,HZ,0);
Display_HZ(1,2,1,HZ,1);
Display_HZ(1,2,2,HZ,2);
Display_ASCII(1,2,6,time,2);
Display_ASCII(1,2,7,time,0);
Display_ASCII(2,2,0,time,1);
Display_ASCII(2,2,1,time,1);
Display_ASCII(2,2,2,time,0);
Display_ASCII(2,2,3,time,2);
Display_ASCII(2,2,4,time,6);
Display_ASCII(2,2,5,time,2);
Display_ASCII(2,2,6,time,3);
Display_ASCII(2,2,7,time,3);
}
void disp1()
{
Display_HZ(1,0,0,HZ,3);
Display_HZ(1,0,1,HZ,4);
Display_HZ(1,0,2,HZ,5);
Display_HZ(1,0,3,HZ,6);
Display_HZ(2,0,0,HZ,7);
Display_HZ(1,4,0,HZ,5);
Display_HZ(1,4,1,HZ,6);
Display_ASCII(2,4,6,time,10);
Display_ASCII(2,4,7,time,11);
}
void dingshiqi()
{
TMOD=0X51;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TH1=0;
TL1=0;
EA=1;
ET0=1;
ET1=1;
TR0=1;
TR1=0;
IT0=0;
EX0=1;
}
void main(void)
{
init_LCD();
dingshiqi();
disp();
disp1();
while(1)
{
H=a/1000000%10;
Z=a/100000%10;
G=a/10000%10;
D=a/1000%10;
E=a/100%10;
F=a/10%10;
X=a%10;
Display_ASCII(1,4,7,time,H);
Display_ASCII(2,4,0,time,Z);
Display_ASCII(2,4,1,time,G);
Display_ASCII(2,4,2,time,D);
Display_ASCII(2,4,3,time,E);
Display_ASCII(2,4,4,time,F);
Display_ASCII(2,4,5,time,X);
}
}
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
if(start_flag==1)
{ led=!led;
TR1=1;
count0++;
if(count0==21)
{ start_flag=0;
TR1=0;
TR0=0;
a= count1_freq*65536+TH1*256+TL1;
TH1=0;
TL1=0;
count1_freq=0;
TR1=1;
TR0=1;
EX0=1;
}
}
}
void timer1() interrupt 3
{
count1_freq++;
}
void counter0 () interrupt 0
{
EX0=0;
start_flag=1;
}
void counter1(void) interrupt 2
{
}
12864显示屏有128列,64行构成,即12864一行最多可以容纳8个汉字,16个字符,一列最多显示4个汉字,8个字符,通过用程序控制12864显示屏的行与列的显示从而达到控制12864显示屏的显示,在我这个程序当中,将12864显示屏分为左右两个半屏幕,即通过控制两个半屏来达到控制行的显示,将列分为8页,每行占两页,从而通过这样的分页来达到控制显示屏的列显示。通过开关的关与开来控制频率的测试,而指示灯则有指示的作用,当其在测量时,灯会不停的闪。
5.2仿真分析
仿真的分析则是通过仿真软件中的实物展示来定量定性的分析,并且通过其效果来反馈程序的问题。
图2仿真效果显示
通过上图可得出基本的部分的要求基本上达到了,测量的频率范围在1HZ~50KHZ,而上图所显示的最大范围显然已经达到了50KHZ,但出现了误差,如何消除误差到目前为止也不知道。
图3仿真效果显示
通过上图可得出发挥的部分的要求基本上达到了,测量的频率范围在1HZ~1MHZ,而上图所显示的最大范围显然已经达到了1MHZ,但出现了误差,如何消除误差到目前为止也不知道。
6设计结论
6.1设计的问题及解决
在这次单片机的课程设计的过程中首当其冲的问题就是对于C语言的不熟悉,虽说我们在大一的下学期就有学过C语言的课程,但当时本人就是怀着打酱油的心态在学习,所以导致现在产生了“书到用时方恨少”的怨夫情节,当然悔恨的泪水是在最开始的时候占据着我的大脑的,当我意识到我在做一些无济于事的情感纠结时我也就回到了自己的正规,我猛然间想到了一些可以安慰自己的思绪,那就是我寝室就有几位大神的,所以最终在我们寝室几位大神的指导下,自己才半推半就的勉强的完成了程序的书写,随后遇到的另一个问题就是如何将程序化为虚拟的一些元器件在软件上来展示给别人看,从而也达到通过看展示的效果来反馈程序的准确度的这样的一个良性循环,自己不懂怎么放元器件就自己上百度查阅资料,再不懂就自己问自己的室友了,但结果也是令人欣慰的,我的仿真作品顺利的达到要求了,只是美中不足的是出现了些许偏差,我我对于这些偏差采取的态度则是纵容,因为我觉得吧,这理想的要求总是和现实有偏差的,这是可允许的,可以原谅的。
6.2设计的心得与体会
通过这次单片机课程设计,我慢慢地,慢慢地了解到所谓单片机学习者,辛苦也,自己所学的单片机知识只是单片机的冰山一角,知识远远地还不够,需要自己夜以继日的去学习来弥补自己的不足,也正是这次单片机课程设计让我在清醒的认识到自己知识掌握的不足的同时也深刻的意识到自己人性中的灰暗点,对于同学需要急于解决的学术问题无能无力,这种状态让人很是难过,就如戊戌六君子那谁一样,加入把问题比拟成自己的敌人的话,我就可以引用他的话了,那就是当自己发现自己有心杀贼却无力回天的时候的那种黯然神伤的感觉,哎,哀伤之情溢于言表呀。,当然说是这样说,造成这样的局面的因还是自己种下的,因为天下就从来没有这种有果无因的事情,都因为自己的不努力,不认真学习,凡事无所谓,然后自己真的就无所谓了,对于这社会也就无所用了,所以自己还是得慢慢的改变的,说实话呢,谁也不想到时去做一个修理地球的人,所以自己得付出实践,与上进为友。另一个自己通过这次课程设计意识到的就是自己的习惯性的弱点就是自己不上进,意志力不强,总是想打退堂鼓,每当我遇到问题无法解决时,首当其冲的想法就是逃。有时自己也惊讶自己对于这种要动手的课程设计以及实习怎么会表现的如此不耐烦,而我明明在搞理论学习的时候确实狠积极的,夸张的说下,似乎还有种打破沙锅问到底的精神气在其中,或许是因为自己不远挂科吧,或许是自己惯性的要强在其中吧,自己也迷糊,自己也不甚了解。最深的体会在这次课程设计中体会到的是未来的路是得靠自己走出来的,这路是谁都无法来代替你走的。这也是大实话,在这次的课程设计当中,许多人有抱着靠别人的想法来想着顺利通过,包括我自己也是如此的,可我们也从未想过,当别人也自顾不暇时,他有时间顾及到你吗?且不说他忙,就算他闲的很,他就非得帮你吗?不帮你是应该的,帮你是交情,但切莫要把使这种交情来成为你偷懒的理由,不要认为理由当然的你得好朋友就得帮你解决一切,也不要因为你好朋友当他自己自顾不暇没有顾及到你而伤悲,得先检讨自己,如果自己有能力的话有何须劳烦自己的朋友呢,所以现在可以打酱油的资本是有朋友会帮你,可当自己到社会上以后又该如何立足呢,而自己又能有这样的好运气使自己旁边的人都愿意帮你吗?所以从现在开始得慢慢的改过来,自己解决问题,自己独立思考,不要去跟风了,得靠自己的能力,多学习,多学些对自己有用的东西来充实自己,这样自己才可以在社会上很好的立足。
7参考文献
【1】周航慈.单片机应用程序设计技术(修订版).北京:北京航天航空大学出版社,2002年
【2】周立功.增强型80C51单片机速成与实战.北京.北京航天航空大学出版社,2003年
【3】何立民.单片及应用技术选编(10).北京.北京航天航空大学出版社,2004年
【4】曹巧媛.单片机原理及应用(第二版).北京.电子工业出版社,2002年
【5】赖麒文.《8051单片机C语言开发环境实务与设计》.北京:科学出版社,2002年