单片机15人投票表决器
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
15
人
投
票
表
决
器
班级:
姓名:
学号:************
第一章概述
1.设计内容:
设计一个基于AT89C52系列单片机的15人投票表决器,利用按键来进行投票,通过1602进行票数的显示。
可以投反对票,赞同票,不投票默认为弃权。
2.设计目的:
本文设计的投票表决器,是基于单片机设计制作的电子式投票表决器。
比传统的手动统计票数更为方便直观,通过程序来进行控制,有效避免了暗箱操作。
制作的投票表决器小巧容易携带,特别方便。
3.设计原理:
该音乐盒主要由按键电路、复位电路、1602显示电路以及指示灯组成。
使用两排按键控制赞同票与反对票,一个指示灯用来表示正在计算。
待投票结束后按下统计按钮即可统计票数。
可以从1602上直观的读出赞同票,反对票,弃权票。
第二章硬件设计
1.设计框架:
音乐盒的系统结构以AT89C52单片机位控制核心,加上2排按键、1602显示电路、LED模块组成。
单片机负责接收按键的输入,根据输入控制1602显示票数,以LED显示单片机正在计算票数的状态。
系统组成框图如图2.1所示。
图2.1 系统组成框图
2.各元器件选择及功能介绍:
(1) AT89C52简介
AT89C52是一种带4K字节闪存可编程可擦除只读存储器(FPEROM—Flash Programmable and Erasable Read Only Memory)的低电压,高性能CMOS 8位微处理器,俗称单片机。
AT89C52是一种带4K字节闪存可编程可擦除只读存储器的单片机。
单片机的可擦除只读存储器可以反复擦除100次。
该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。
由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C52是一种高效微控制器,AT89C2051是它的一种精简版本。
AT89C52单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。
外形及引脚排列如图2.2所示
图2.2 AT89C51系列单片机
(2) 1602显示电路设计与原理
1602是字符型液晶,它是16*2的显示的。
工业字符型液晶,能够同时显示16x02即32个字符。
通过1602进行票数的显示。
(3)时钟振荡电路
AT89C52中有一个用于构成内部振荡器的高增益反相放大器,引脚XTAL1和XTAL2分别是该放大器的输入端和输出端。
这个放大器与作为反馈元件的片外石英晶体或者陶瓷谐振器一起构成自然振荡器。
外接石英晶体及电容C1、C2接在放大器的反馈回路中构成并联振荡电路。
对外接电容C1,C2虽然没有什么严格的要求,但电容容量的大小会轻微影响振荡频率的高低、振荡器工作的稳定性、起振的难易程序及温度稳定性。
如果使用石英晶体,我们推荐电容使用
30PF±10PF,而如果使用陶瓷振荡器建议选择40PF±10PF。
用户也可以采用外部时钟。
采用外部时钟的电路如图示。
这种情况下,外部时钟脉冲接到XTAL1端,即内部时钟发生器的输入端,XTAL2则悬空。
由于外部时钟信号是通过一个2分频触发器后作为内部时钟信号的,所以对外部时钟信号的占空比没有特殊要求,但最小高电平持续时间和最大的低电平持续时间应符合产品技术条件的要求。
振荡器电路图如下:
图2.3 单片机内部、外部振荡电路
3.设计原理图:
总体硬件电路实现功能如下,如图2.4所示
1)电路中用P0、部分P1口进行赞同票读取。
2)电路中用P2、部分P3口进行反对票读取。
3)P1.6作为统计票数的开关。
4)P1.7控制正在计算票数的显示灯。
5)电路为12MHZ晶振频率工作,起振电路中C1、C2均为30PF。
图2.4 硬件电路图
第三章软件设计
1.个程序段介绍:
使用中断来扫描统计票数的按键,更精确。
先对定时器进行初始化,选择定时器工作方式。
定时时间为没50000us进入一次中断。
再对1602液晶进行初始化,编写显示作者姓名学号的函数disp_myname();a 延时2s后将1602的指针指向第二行,将学号替换为投票表决器的英文‘voting machine’。
在while(1)的循环中一直等待P1.6口的按键,若按键未被按下,则在中断中继续统计票数,直到P1.6被按下,关闭定时器中断,使之后的投票无效化统计当前的赞同,反对,弃权票数,显示到1602中。
之后开启定时器中断等待下一次投票统计的到来。
主程序流程图3-5所示:
图 3-5主程序流程图
A.主程序代码:
#include <reg52.h>
unsigned int yes=0,no=0,qiquan=0,i=0,j=0;
unsigned int temp,succeed=0;
unsigned int y,com,date;
unsigned int ge,shi,bai,a=0;
char y1[8]={2,2,2,2,2,2,2,2},n1[8],y2[7]={2,2,2,2,2,2,2},n2[7];
sbit K1=P1^6; //开关
sbit K2=P1^7; //指示灯
//*****************赞同***************//
sbit D0=P0^0;
sbit D1=P0^1;
sbit D2=P0^2;
sbit D3=P0^3;
sbit D4=P0^4;
sbit D5=P0^5;
sbit D6=P0^6;
sbit D7=P0^7;
sbit DB1=P1^0;
sbit DB2=P1^1;
sbit DB3=P1^2;
sbit DB4=P1^3;
sbit DB5=P1^4;
sbit DB6=P1^5;
sbit rd=P3^7;
//*****************反对**************// sbit A0=P2^0;
sbit A1=P2^1;
sbit A2=P2^2;
sbit A3=P2^3;
sbit A4=P2^4;
sbit A5=P2^5;
sbit A6=P2^6;
sbit A7=P2^7;
sbit rx=P3^0;
sbit tx=P3^1;
sbit csda=P3^2;
sbit int1=P3^3;
sbit lcden=P3^4;
sbit rs=P3^5;
sbit wr=P3^6;
void delay(unsigned int y) //延时{
unsigned int a,b;
for(a=y;a>0;a--)
for(b=110;b>0;b--);
}
void write_com(unsigned int com) //写指令{
rs=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_date(unsigned int date) //写数据
{
rs=1;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
int change(unsigned int a) //把票数转为字符型{
switch(a)
{
case 0: a=0x30;break;
case 1: a=0x31;break;
case 2: a=0x32;break;
case 3: a=0x33;break;
case 4: a=0x34;break;
case 5: a=0x35;break;
case 6: a=0x36;break;
case 7: a=0x37;break;
case 8: a=0x38;break;
case 9: a=0x39;break;
}
return a;
}
/***********************************1602显示 **/ void xianshi(unsigned int d)
{
// init();
bai=d/100;
shi=(d-100*bai)/10;
ge=d%10;
bai=change(bai);
shi=change(shi);
ge=change(ge);
write_date(bai);
delay(5);
write_date(shi);
delay(5);
write_date(ge);
delay(5);
} //*********************************1602显示 */
void xianshi2() //********显示赞同**// {
write_date('y');
delay(5);
write_date('e');
delay(5);
write_date('s');
delay(5);
write_date(':');
delay(5);
}
void xianshi3() //*****显示反对****// {
write_date('n');
delay(5);
write_date('o');
delay(5);
write_date(':');
delay(5);
}
void xianshi4() //******显示弃权*****// {
write_date('a');
delay(5);
write_date('b');
delay(5);
write_date('s');
delay(5);
write_date('t');
delay(5);
write_date('e');
delay(5);
write_date('n');
delay(5);
write_date('t');
delay(5);
write_date('i');
delay(5);
write_date('o');
delay(5);
write_date('n');
delay(5);
write_date(':');
delay(5);
}
void panduan_yes() {
if(D0==0)
{
y1[0]=1;
n1[0]=0;
}
if(D1==0)
{
y1[1]=1;
n1[1]=0;
}
if(D2==0)
{
y1[2]=1;
n1[2]=0;
}
if(D3==0)
{
y1[3]=1;
n1[3]=0;
}
if(D4==0)
{
y1[4]=1;
n1[4]=0;
}
if(D5==0)
{
y1[5]=1;
n1[5]=0;
}
if(D6==0)
{
y1[6]=1;
n1[6]=0; }
if(D7==0) {
y1[7]=1;
n1[7]=0; }
if(DB1==0) {
y2[0]=1;
n2[0]=0; }
if(DB2==0) {
y2[1]=1;
n2[1]=0; }
if(DB3==0) {
y2[2]=1;
n2[2]=0; }
if(DB4==0) {
y2[3]=1;
n2[3]=0; }
if(DB5==0) {
y2[4]=1;
n2[4]=0; }
if(DB6==0) {
y2[5]=1;
n2[5]=0; }
if(rd==0) {
y2[6]=1;
n2[6]=0; }
}
void panduan_no() {
if(A0==0)
{
y1[0]=0;
n1[0]=1;
}
if(A1==0)
{
y1[1]=0;
n1[1]=1;
}
if(A2==0)
{
y1[2]=0;
n1[2]=1;
}
if(A3==0)
{
y1[3]=0;
n1[3]=1;
}
if(A4==0)
{
y1[4]=0;
n1[4]=1;
}
if(A5==0)
{
y1[5]=0;
n1[5]=1;
}
if(A6==0)
{
y1[6]=0;
n1[6]=1;
}
if(A7==0)
{
y1[7]=0;
n1[7]=1;
}
if(rx==0)
{
y2[0]=0;
n2[0]=1;
}
if(tx==0)
{
y2[1]=0;
n2[1]=1;
}
if(csda==0)
{
y2[2]=0;
n2[2]=1;
}
if(int1==0)
{
y2[3]=0;
n2[3]=1;
}
if(lcden==0)
{
y2[4]=0;
n2[4]=1;
}
if(rs==0)
{
y2[5]=0;
n2[5]=1;
}
if(wr==0)
{
y2[6]=0;
n2[6]=1;
}
}
void init() //1602初始化
{
lcden=0;
write_com(0x38);
write_com(0x0e);
write_com(0x01);
write_com(0x80); //为了移动效果
}
void tongji()
{
unsigned int i;
for(i=0;i<8;i++)
{
if(y1[i]==1)
yes++;
if(n1[i]==1)
no++;
if(y1[i]==2)
qiquan++;
}
for(i=0;i<7;i++)
{
if(y2[i]==1)
yes++;
if(n2[i]==1)
no++;
if(y2[i]==2)
qiquan++;
}
}
void restart()
{
unsigned int i;
P0=0xff;
P1=0xff;
P2=0xff;
P3=0xff;
for(i=0;i<8;i++)
{
y1[i]=2;
n1[i]=0;
}
for(i=0;i<7;i++)
{
y2[i]=2;
n2[i]=0;
}
yes=0;
no=0;
qiquan=0;
}
void disp_myname()
{
init(); //1602初始化
write_date('I');
delay(5);
write_date('`');
delay(5);
write_date('m');
delay(5);
write_date(' ');
delay(5);
write_date('C');
delay(5);
write_date('h');
delay(5);
write_date('e');
delay(5);
write_date('n');
delay(5);
write_date(' ');
delay(5);
write_date('Q');
delay(5);
write_date('u');
delay(5);
write_com(0x80+0x40); //写第二行,我的学号 write_date('2');
delay(5);
write_date('0');
delay(5);
write_date('1');
delay(5);
write_date('2');
delay(5);
write_date('0');
delay(5);
write_date('5');
delay(5);
write_date('1');
delay(5);
write_date('4');
delay(5);
write_date('0');
delay(5);
write_date('1');
delay(5);
write_date('3');
delay(5);
write_date('3');
restart();
}
void disp_mydesign()
{
// init(); //1602初始化
write_com(0x80+0x40); //写第二行,显示投票表决器的功能 write_date('V');
delay(5);
write_date('o');
delay(5);
write_date('t');
delay(5);
write_date('i');
delay(5);
write_date('n');
delay(5);
write_date('g');
delay(5);
write_date(' ');
delay(5);
write_date('m');
delay(5);
write_date('a');
delay(5);
write_date('c');
delay(5);
write_date('h');
delay(5);
write_date('i');
delay(5);
write_date('n');
delay(5);
write_date('e');
delay(5);
restart();
}
void main()
{
K2=0;
TMOD=0x01;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
EA=1;
ET0=1;
TR0=1;
disp_myname(); //显示作者姓名,学号
delay(2000); //2秒后显示本设计名称,投票表决器 disp_mydesign();
while(1)
{
while(K1==1);
EA=0;
K2=1; //计算指示灯
tongji();
init(); //1602初始化
xianshi2();
xianshi(yes);
write_date(' ');
delay(5);
xianshi3();
xianshi(no);
write_com(0x80+0x40);
xianshi4();
xianshi(qiquan);
while(K1==0);
EA=1;
restart();
K2=0;
}
}
void time() interrupt 1
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
panduan_yes();
panduan_no();
}
第四章仿真结果及其总结
1.仿真结果图:
(1)1602先显示作者姓名学号,2s后显示作品名称
(2)按下统计按键开始统计票数
(3)附上一张静态图片
2.总结:
通过这次课程设计,我学到了不少课本上没有的知识,也锻炼了自己的动手能力,将以前学过的零散的知识串到一起。
经过长时间的设计及调试,本系统基本能实现按下1键盘会使led灯跟着音乐闪动,扬声器播放对应的音符。
按下2键会使led灯产生相应花样。
但由于仿真系统原因,本设计音频效果不是很好。
不足之处有:1.音量不可调。
我的综合设计主要涉及硬件和软件两方面的内容,通过这些我的硬件和软件开发能力都获得了提高。
首先硬件方面,基本了解了电子产品的开发流程和所要做的工作。
使我对51系单片机的接口有了更深层次的理解,熟悉了一些单片机常用的外围电路引脚和连接方法,如LED数码管,按键等。
并且我学会了分析问题解决问题的能力,加深了对所学理论知识的理解和运用。
我的动手能力得到了很大的提高,创新意识得到了锻炼。