C51单片机课程设计报告Word文档格式.docx
- 文档编号:5670146
- 上传时间:2023-05-05
- 格式:DOCX
- 页数:30
- 大小:1.29MB
C51单片机课程设计报告Word文档格式.docx
《C51单片机课程设计报告Word文档格式.docx》由会员分享,可在线阅读,更多相关《C51单片机课程设计报告Word文档格式.docx(30页珍藏版)》请在冰点文库上搜索。
(8)KEIL软件
(9)MCS-51单片机官方烧写程序软件STC_ISP_V488.exe
三、设计任务和要求
1.通过单片机的I/O口直接控制8盏LED小灯,实现7种彩灯灯光效果(左移、右移、中间向两边展开、两边向中间合拢等,不含全部点亮,全部熄灭);
2.用按键来切换控制器的灯光模式,能显示当前的运行模式号;
3.彩灯效果的移动速度基于AD输入量的大小(控制器通过PCF8591对0~5V信号进行采样,根据模拟信号的大小而改变彩灯移动速度);
彩灯控制器还要显示当前模拟输入信号的大小(数码管显示);
4.彩灯效果中的延时采用定时中断实现。
按键、数码管直接用C51的I/O驱动
扩展:
可以通过串口通讯芯片595来控制彩灯效果的切换,将AD采样结果显示的数码管上。
四、需求分析
根据本次课程设计题目分析及其题目简化,需要做的是通过电位器来控制8盏彩灯的扫描显示速度,并且显示此时AD芯片的采样值,并且通过一个按键来切换不同的彩灯的7种显示模式。
于是乎,可以将系统分为两个部分:
其一,模拟采样部分;
其二,彩灯显示部分。
最后得到以下的设计方案:
通过一个电位器来得到一个可以改变的模拟值;
采用PCF8591采样电位器所产生的模拟值,并将其转化为数字信号;
MCU通过I2C总线读取PCF8951内部ROM中所缓存的数值;
编写数码管显示函数,通过单片机的I/O口驱动数码管显示PCF8591所采样的值。
(数码管高四位显示PCF8591所采样的数值,低四位显示当前PCF8591所采取的精确电压值,精确到小数点后三位);
编写LED彩灯的显示,利用定时器0来控制每一盏小灯的显示延迟时间,利用定时器1和pcf8591所采样的数字信号来共同确定LED彩灯的扫描速度,即通过调节电位器可以改变LED灯的扫描速度(通过MCU的I/O驱动74HC595芯片实现串口转并口来驱动8个LED小彩灯的显示);
采用外部中断0来切换LED彩灯的显示模式。
五、硬件电路图设计及描述
注:
电路图原图另有PDF文件
1、数码管显示电路设计
课程设计中所用的数码管为共阴极数码管,当给其引脚加入高电平时,数码管中对应的那一段就亮。
下图为外部显示图,其内部结构如下:
共阴极数码管内部结构
2、LED显示电路设计
本次课程设计中要用发光二极管显示状态。
由下图知发光二极管阳极经过电阻接高电平,当其阴极为低电平时,二极管就发光显示所处状态。
通过串口转并口芯片74HC595的并口输出来改变LED灯的显示状态。
3、AD转换电路设计
此次课程设计的AD转换芯片采用的是PCF8591芯片,芯片的9、10管脚是I2C串口协议传输引脚,其与MCU的P2^0、P2^1接口连接。
A0、A1、A2为地址线,此处接地,地址为I2C传输数据的地址为000。
四路模拟输入接口为AIN0、AIN1、AIN2、AIN3,此处只选择一路模拟输入-------AIN0。
模拟输入信号通过一个电位器的改变而提供。
4、时钟电路设计
时钟电路对单片机是不可缺的,单片机的每个功能都要以时钟电路为基础工作。
单片机内部自带一个时钟电路,外部接入定时控制元件即可构成一个稳定的自激振荡器。
其中机器周期共有12个振荡脉冲周期,因此,机器周期是时钟周期的12倍。
本课程设计中时钟电路中使用的晶体是12MHz,则时钟周期为(1/12)us,机器周期为1us。
实验图如下:
5、外部中断信号电路设计
外部中断信号的是由一个简单的不带锁的按键开关提供的一个脉冲信号。
六、软件设计思想及流程
(1)使用单片机资源的情况:
设计时使用单片机资源的情况如下:
AT89S51单片机的P0、P1口作为数码管数据线接口,其中,P0口接是段选,P1接位选,P2^0、P2^1接AD转换芯片PCF8591的I2C串口接口,P3^4、P3^5、P3^6口接74HC595的串口输入接口,P3^2外接外部中断按键。
单片机定时器0、定时器1均匀方式1来控制定时器运行。
(2)软件系统的各个模块功能:
本设计的软件系统主要采用以下基本模块来实现:
主程序、中断服务程序、串口传输程序。
主程序用于对于各个程序模块的运行及控制,以及各个模式程序的初始化。
特别是定时中断的初始值。
在主程序中还主要的对pcf8591进行了操作,采样,量化,显示。
有三个中断服务程序,分别是定时器0中断、定时器1中断、外部中断,通过外部中断来实现各个LED灯的显示模式的切换。
定时器中断0用于控制LED灯的显示延时。
定时器1用于操作LED灯的不同模式的显示。
串口传输程序只要有两种串口传输函数,分别I2C串口传输函数和595串口转并口的串口传输函数。
在串口函数里面详细的对串口进行了操作,里面有I2C串口的初始化,终止,数据传输,应答,595串口的传输。
(3)设计的软件流程框图:
(4)软件调试过程
使用keil软件在做写程序之前选择createHEXFi:
表示生成可烧写进单片机的HEX文件。
在编写程序结束之后点击编译,生成HEX文件。
再生成HEX文件之后打开STC单片机官方烧写软件进行程序烧写:
选择单片机型号;
选择生成的HEX文件;
选择单片机连接的COM口;
选择传输的波特率;
断电烧写。
七、实验效果
在完成烧写程序完成之后单片机即可正常执行程序。
执行效果如下:
电位器1即模拟信号的输入,通过旋转电位器1可改变数码管的显示电位器1的采样值,与调节LED的扫描显示速度。
通过按键2可改变LED灯的显示模式。
不同的实验效果图还有如下:
八、源程序代码
/************main.c***************/
#include<
reg52.h>
#include<
I2C.H>
intrins.H>
#definePCF85910x90//PCF8591地址
unsignedcharLED[9]={0x01,0x01,0x01,0x01,0x7F,0x81,0x81,0x01,0xAA};
//LED的显示模式
unsignedcharLED_kind=1,a=0x80,b=0x01;
unsignedintj,mun;
//此表为LED的字模,共阴数码管0-9-
unsignedcharcodeDisp_Tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f
0x6f};
unsignedlongxdataLedOut[8];
unsignedintD[3],n=1;
/********************DAC变换,转化函数*********************/
bitDACconversion(unsignedcharsla,unsignedcharc,unsignedcharVal)
{
Start_I2c();
//启动总线
SendByte(sla);
//发送器件地址
if(ack==0)return(0);
SendByte(c);
//发送控制字节
SendByte(Val);
//发送DAC的数值
Stop_I2c();
//结束总线
return
(1);
}
/***********************ADC发送字节[命令]数据函数***************************/
bitISendByte(unsignedcharsla,unsignedcharc)
//发送数据
/**************************ADC读字节数据函数**********************/
unsignedcharIRcvByte(unsignedcharsla)
{unsignedcharc;
SendByte(sla+1);
//发送器件地址+1使写入地址为0x91为读地址10010001
c=RcvByte();
//读取数据0
Ack_I2c
(1);
//发送非就答位
return(c);
//****************************************************/
main()
{chari;
TMOD=0x11;
//设置计数模式为方式2
TH0=(65536-500)/256;
TL0=(65536-500)%256;
TH1=(65536-50)/256;
TL1=(65536-50)%256;
IE=0x8B;
//开定时器0、定时器1
TR0=1;
TR1=1;
IT0=1;
while
(1)
{
ISendByte(PCF8591,0x40);
//使用通道0进行采样
D[0]=IRcvByte(PCF8591);
//从pcf8591读取模数转换的数值
D[1]=D[0]*5/0.255;
//将模数转换的数值转换成电压值
D[2]=D[0]*2/25.5;
//用于控制LED的速度
/***********将AD的值送到LED数码管显示*************/
LedOut[0]=Disp_Tab[D[0]%10000/1000];
LedOut[1]=Disp_Tab[D[0]%1000/100];
LedOut[2]=Disp_Tab[D[0]%100/10];
LedOut[3]=Disp_Tab[D[0]%10];
/***********转换后的电压值送到LED数码管显示************/
LedOut[4]=Disp_Tab[D[1]%10000/1000]|0x80;
LedOut[5]=Disp_Tab[D[1]%1000/100];
LedOut[6]=Disp_Tab[D[1]%100/10];
LedOut[7]=Disp_Tab[D[1]%10];
for(i=0;
i<
8;
i++)
{P0=LedOut[i];
//段选择
switch(i)//使用switch位选择
case0:
P1=0xFE;
break;
case1:
P1=0xFD;
case2:
P1=0xFB;
case3:
P1=0xF7;
case4:
P1=0xEF;
case5:
P1=0xDF;
case6:
P1=0xBF;
case7:
P1=0x7F;
}
//for(j=0;
j<
90;
j++){;
}//扫描间隔时间
n=1;
while(n);
P1=0xFF;
//清除余辉相映
}
voidTimer0(void)interrupt1//3定时器1的中断号1定时器0的中断号0外部中断12外部中断24串口中断
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
n=0;
voidTimer2(void)interrupt0
if(LED_kind<
=7)
LED_kind++;
else
LED_kind=1;
}
voidTimer1(void)interrupt3//3定时器1的中断号1定时器0的中断号0外部中断12外部中断24串口中断
unsignedcharc=1,d=0;
j++;
TH1=(65536-40000)/256;
TL1=(65536-40000)%256;
if(j>
D[2])
switch(LED_kind)
{
case1:
HC595SendData(~(LED[0]++));
case2:
LED[1]=_cror_(LED[1],1);
mun=~LED[1];
HC595SendData(mun);
case3:
LED[2]=_crol_(LED[2],1);
mun=~LED[2];
HC595SendData(mun);
break;
case4:
{
mun=~LED[3];
if(LED[3]<
=0x80)
{
LED[3]=LED[3]<
<
1;
LED[3]=LED[3]|0x01;
}
else
LED[3]=0x01;
}
break;
HC595SendData(LED[4]);
LED[4]=LED[4]>
>
if(LED[4]==0)
{
HC595SendData(LED[4]);
LED[4]=0x7F;
}
}
break;
if(a!
=0)
{
d=a^LED[7];
HC595SendData(~d);
a=a>
LED[7]=LED[7]<
}
else
{
a=0x80;
LED[7]=0x01;
d=a|LED[7];
}
}break;
LED[8]=~LED[8];
HC595SendData(LED[8]);
}
j=0;
/***************************I2C.c************************/
intrins.h>
#defineucharunsignedchar
#defineuintunsignedint
#defineNOP()_nop_()/*定义空指令*/
#define_Nop()_nop_()/*定义空指令*/
sbitSCL=P2^1;
//I2C时钟
sbitSDA=P2^0;
//I2C数据
bitack;
/*应答标志位*/
sbitMOSIO=P3^4;
//HC595数据线
sbitR_CLK=P3^5;
//输出时钟
sbitS_CLK=P3^6;
//输入时钟
/*******************************************************************
起动总线函数
函数原型:
voidStart_I2c();
功能:
启动I2C总线,即发送I2C起始条件.
********************************************************************/
voidStart_I2c()
SDA=1;
/*发送起始条件的数据信号*/
_Nop();
SCL=1;
/*起始条件建立时间大于4.7us,延时*/
SDA=0;
/*发送起始信号*/
/*起始条件锁定时间大于4μs*/
SCL=0;
/*钳住I2C总线,准备发送或接收数据*/
结束总线函数
voidStop_I2c();
结束I2C总线,即发送I2C结束条件.
voidStop_I2c()
/*发送结束条件的数据信号*/
/*发送结束条件的时钟信号*/
/*结束条件建立时间大于4μs*/
/*发送I2C总线结束信号*/
字节数据发送函数
voidSendByte(UCHARc);
将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
此状态位进行操作.(不应答或非应答都使ack=0)
发送数据正常,ack=1;
ack=0表示被控器无应答或损坏。
voidSendByte(unsignedcharc)
unsignedcharBitCnt;
for(BitCnt=0;
BitCnt<
BitCnt++)/*要传送的数据长度为8位*/
if((c<
BitCnt)&
0x80)SDA=1;
/*判断发送位*/
elseSDA=0;
/*置时钟线为高,通知被控器开始接收数据位*/
/*保证时钟高电平周期大于4μs*/
/*8位发送完后释放数据线,准备接收应答位*/
if(SDA==1)ack=0;
elseack=1;
/*判断是否接收到应答信号*/
字节数据接收函数
UC
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C51 单片机 课程设计 报告
![提示](https://static.bingdoc.com/images/bang_tan.gif)