PIC课程设计报告.docx
《PIC课程设计报告.docx》由会员分享,可在线阅读,更多相关《PIC课程设计报告.docx(39页珍藏版)》请在冰点文库上搜索。
PIC课程设计报告
电子装置与系统设计
课程设计
学院:
班级:
学号:
姓名:
指导老师:
日期:
电子装置与系统设计课程设计任务书
任务一:
以下是PIC评估板上可用的资源列表,请阅读以下芯片的手册资料。
编号
元件
功能
备注
U9
max232
RS485
U12
at24C02
I2C存储器
U6
ds18b20
数字温度传感器
u3
pcf8563
时钟
1602
液晶模块
K1-K16
4*4键盘
任务二:
完成以下单元模块电路
1、双机RS232和RS485通讯,测试10m,50m不同距离时的通讯情况
2、键盘显示功能(计算器)
3、遥控日历查询
4、I2C存储器读写(计数器,并能断点存储)
5、温度测量并带报警(用键盘ps/2设置最高值)
任务三:
设计一个简单系统,每10S进行温度采集(结合电路与程序,分析指标),在液晶屏上显示当前温度和前一状态的温度,并将结果存入存储器,具备可将温度的存储结果与PC机通讯和数据发送功能,可以使用键盘设定温度高低限制值,达到限制值时报警。
任务二选择:
键盘显示功能(计算器)
相关资料:
一、PIC18F452芯片
引脚说明:
MCLR/VPP:
主清0或编程电压
VDD:
接电源
VSS:
接地
RA0-RA7:
双向I/O口
RB0-RB7:
数字I/O口
RC0-RC7:
数字I/O口
RD0-RD7:
数字I/O口
RE0-RE3:
数字I/O口
PIC18F452外设功能:
高灌/拉电流:
25mA/25mA;
3个外部中断引脚,定时器0模块:
具有8位可编程预分频器的8/16位定时器/计数器;
定时器1模块:
16位定时器/计数器;
定时器2模块:
具有8位周期寄存器的8位定时器/计数器(时基为脉宽调制);
定时器3模块:
16位定时器/计数器;
辅助振荡器时钟选项:
定时器1/定时器3;
2个捕捉/比较/PWM模块。
CCP引脚,可以配置为:
捕捉输入:
16位捕捉模块,最大分辨率是6.25ns(TCY/16);
16位比较模块,最大分辨率为100ns(TCY);
PWM输出:
最大PWM是1~10位。
最大PWM频率:
当8位分辨率为156kHz,10位分辨率为39kHz;
主同步串口(MSSP)模块;2种运作模式:
3线SPITM(支持所有4线SPI模式);I2CTM主从模式;
模拟功能:
兼容的10位模数转换模块带有:
快速采样率;可用转换睡眠;线形≤1LSB;可编程低电压检测(PLVD);支持中断低电压检测;可编程欠压复位(BOR);
微控制器的特殊功能:
可进行100000次擦写操作的闪存程序存储器(标准值);闪存/数据EEPROM的保存时间:
>40年,在软件控制下自行编程;
上电复位(POR),上电延时定时器(PWRT)和振荡器起振定时器(OST);
采用自身片上RC振荡器可靠工作的看门狗定时器(WDT),可编程代码保护;省电的休眠模式;可选振荡器选项包括:
碴倍锁相回路(初级振荡器);辅助振荡器(32kHz)时钟输入;
通过2个引脚进行5V单电源供电在线串行编程(ICSPTM);通过2个引脚进行在线调试
二、LCD1602液晶显示屏
字符型液晶显示模块是一种专门用于显示字母、数字、符号等点阵式LCD,目前常用16*1,16*2,20*2和40*2行等的模块。
一般1602字符型液晶显示器实物如图
1602LCD分为带背光和不带背光两种,基控制器大部分为HD44780,带背光的比不带背光的厚,是否带背光在应用中并无差别,两者尺寸差别如下图
`LCD1602主要技术参数:
显示容量:
16×2个字符
芯片工作电压:
4.5—5.5V
工作电流:
2.0mA(5.0V)
模块最佳工作电压:
5.0V
字符尺寸:
2.95×4.35(W×H)mm
引脚功能说明:
1602LCD采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明如表
编号
符号
引脚说明
编号
符号
引脚说明
1
VSS
电源地
9
D2
数据
2
VDD
电源正极
10
D3
数据
3
VL
液晶显示偏压
11
D4
数据
4
RS
数据/命令选择
12
D5
数据
5
R/W
读/写选择
13
D6
数据
6
E
使能信号
14
D7
数据
7
D0
数据
15
BLA
背光源正极
8
D1
数据
16
BLK
背光源负极
第1脚:
VSS为地电源。
第2脚:
VDD接5V正电源。
第3脚:
VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度。
第4脚:
RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。
第5脚:
R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。
当RS和R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平R/W为高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数据。
第6脚:
E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
第7~14脚:
D0~D7为8位双向数据线。
第15脚:
背光源正极。
第16脚:
背光源负极。
三、4×4键盘
矩阵键盘又称为行列式键盘,它是用4条I/O线作为行线,4条I/O线作为列线组成的键盘。
在行线和列线的每一个交叉点上,设置一个按键。
这样键盘中按键的个数是4×4个。
这种行列式键盘结构能够有效地提高单片机系统中I/O口的利用率。
按键排列
4×4矩阵键盘的编程方法:
1、先读取键盘的状态,得到按键的特征编码。
先从P1口的高四位输出低电平,低四位输出高电平,从P1口的低四位读取键盘状态。
再从P1口的低四位输出低电平,高四位输出高电平,从P1口的高四位读取键盘状态。
将两次读取结果组合起来就可以得到当前按键的特征编码。
使用上述方法我们得到16个键的特征编码。
举例说明如何得到按键的特征编码:
假设“1”键被按下,找其按键的特征编码。
从P1口的高四位输出低电平,即P1.4-P1.7为输出口。
低四位输出高电平,即P1.0-P1.3为输入口。
读P1口的低四位状态为“1101”,其值为“0DH”。
再从P1口的高四位输出高电平,即P1.4-P1.7为输入口。
低四位输出低电平,即P10-P13为输出口,读P1口的高四位状态为“1110”,其值为“E0H”。
将两次读出的P0口状态值进行逻辑或运算就得到其按键的特征编码为“EDH”。
用同样的方法可以得到其它15个按键的特征编码。
2、根据按键的特征编码,查表得到按键的顺序编码。
将用上述方法得到的16个按键的特征编码按图2按键排列的顺序排成一张特征编码与顺序编码的对应关系表,然后用当前读得的特征编码来查表,当表中有该特征编码时,它所在的位置就是对应的顺序编码。
程序代码:
#include
#defineuintunsignedint
#defineucharunsignedchar
#defineePORTBbits.RB3
#definerwPORTBbits.RB4
#definersPORTBbits.RB5
voiddisp_init(void);//液晶屏初始化
voiddisp(uintnum1,uinti);
voiddispc(uintnum1);
voiddisp1(uintnum1,uintnum2,uintnum3,uintnum4,uintnum5);
voidwrite_com(ucharcom);//写指令
voidwrite_data(uchardat);//写数据
unsignedintanjian(void);
unsignedintjisuan(uinta1,uinta2,uintfuhao);
voiddelay(uintz)
{
uintx,y;
for(x=110;x>0;x--)
for(y=z;y>0;y--);
}
romunsignedcharSEGCODE[]=
{
0x30,0x31,0x32,0x33,
0x34,0x35,0x36,0x37,
0x38,0x39,0x2B,0x2D,
0x2A,0x2F,0x3D,0x24,
};
romunsignedcharKEYCODE[]=
{
0xEE,0xDE,0xBE,0x7E,
0xED,0xDD,0xBD,0x7D,
0xEB,0xDB,0xBB,0x7B,
0xE7,0xD7,0xB7,0x77,
};
voidmain(void)
{
uinta=0,b=0,c,s=0;
uinttemp,fuhao;
uinti,j,ii=0,temp1=0,temp2=0;
disp_init();
loop:
while
(1)
{
for(i=0;i<6;i++)
{
temp=anjian();
if(temp!
=0x24)
{
disp(temp,i);temp1=temp-0x30;
if((temp!
=0x2B)&(temp!
=0x2D)&(temp!
=0x2A)&(temp!
=0x2F))
{
a=a*10+temp1;
}
else
{
fuhao=temp;
i=6;
}
ii++;
}
else
{
a=(a-temp1)/10;
i--;
disp(0x20,i);
i--;
ii--;
}
}
for(j=0;j<6;j++)
{
temp=anjian();
if(temp!
=0x24)
{
disp(temp,j+ii);temp2=temp-0x30;
if(temp!
=0x3D)
{
b=b*10+temp2;
}
else
{
j=6;
}
}
else
{b=(b-temp2)/10;
j--;
disp(0x20,j+ii);
j--;}
}
c=jisuan(a,b,fuhao);//c的值
dispc(c);
temp=anjian();//c的显示
if(temp=0x24)
{
a=0;
b=0;
ii=0;
disp_init();
gotoloop;
}
}
}
unsignedintjisuan(uinta1,uinta2,uintfuhao)
{
uintc;
switch(fuhao)
{
case0x2B:
c=a1+a2;
break;
case0x2D:
c=a1-a2;
break;
case0x2A:
c=a1*a2;
break;
case0x2F:
c=a1/a2;
break;
}
returnc;
}
unsignedintanjian(void)//按键扫描
{
unsignedchari;
unsignedcharKeyTemp;
TRISC=0xFF;
while
(1)
{
TRISC=0xF0;
LATC=0xF0;
if(0xF0!
=(PORTC&0xF0))
{
delay(50);
if(0xF0!
=(PORTC&0xF0))
{
KeyTemp=PORTC&0xF0;
TRISC=0x0F;
LATC=0x0F;
KeyTemp|=(PORTC&0x0F);
for(i=0;i{
if(KeyTemp==KEYCODE[i])
{
KeyTemp=i;
i=sizeof(KEYCODE)+1;
}
}
returnSEGCODE[KeyTemp];
}
//while(0x0F!
=(PORTC&0x0F));
}
}
}
voidwrite_com(ucharcom)//对液晶屏写指令
{
TRISB=0b000000000;//TRISB=0b00010000;
TRISD=0;
e=0;
rw=0;
rs=0;//写指令:
RS=L,RW=L,D0~D7=指令码,E=高脉冲
PORTD=com;//写指令到液晶
delay(5);
e=1;
delay(5);
e=0;
}
voidwrite_data(uchardat)//写数据
{
TRISD=0;
e=0;
rw=0;
rs=1;//写数据:
RS=H,RW=L,D0~D7=指令码,E=高脉冲
PORTD=dat;//写数据到液晶
delay(5);
e=1;
delay(5);
e=0;
}
voiddisp_init()
{
TRISD=0;//选择D端口为液晶屏数据的输入口
write_com(0x38);//液晶开显示
write_com(0x0c);//显示光标,光标闪烁
write_com(0x06);//读或写一个字符后地址指针加一,光标加一
write_com(0x01);//显示清屏:
1、数据指针清零;2、所有显示清零
write_com(0x80);//第一行首位
}
voiddisp(uintnum1,uinti)
{
write_com(0x80+i);//液晶第一行第i位数
write_data(num1);
delay
(1);
}
voiddispc(uintnum1)
{
uintc1,c2,c3,c4,c5;
c1=num1/10000;//ADC结果千位上的数字
c2=num1%10000/1000;//ADC结果百位上的数字
c3=num1%1000/100;//ADC结果十位上的数字
c4=num1%100/10;
c5=num1%10;
disp1(c1,c2,c3,c4,c5);
}
voiddisp1(uintnum1,uintnum2,uintnum3,uintnum4,uintnum5)
{
write_com(0x80+0x40);
write_data(num1+0x30);//液晶第二行第一位数
delay
(1);
write_com(0x80+0x41);
write_data(num2+0x30);//液晶第二行第二位数
delay
(1);
write_com(0x80+0x42);
write_data(num3+0x30);//液晶第二行第三位数
delay
(1);
write_com(0x80+0x43);
write_data(num4+0x30);//液晶第二行第四位数
delay
(1);
write_com(0x80+0x44);
write_data(num5+0x30);//液晶第二行第五位数
delay
(1);
}
任务三:
相关资料:
一、max232RS485
MAX232芯片是专门为电脑的RS-232标准串口设计的接口电路,使用+5v单电源供电。
内部结构基本可分三个部分:
第一部分是电荷泵电路。
由1、2、3、4、5、6脚和4只电容构成。
功能是产生+12v和-12v两个电源,提供给RS-232串口电平的需要。
第二部分是数据转换通道。
由7、8、9、10、11、12、13、14脚构成两个数据通道。
其中13脚(R1IN)、12脚(R1OUT)、11脚(T1IN)、14脚(T1OUT)为第一数据通道。
8脚(R2IN)、9脚(R2OUT)、10脚(T2IN)、7脚(T2OUT)为第二数据通道。
TTL/CMOS数据从T1IN、T2IN输入转换成RS-232数据从T1OUT、T2OUT送到电脑DP9插头;DP9插头的RS-232数据从R1IN、R2IN输入转换成TTL/CMOS数据后从R1OUT、R2OUT输出。
第三部分是供电。
15脚DNG、16脚VCC(+5v)。
下图为MAX232引脚图和接线图,带有转串口的电路。
二、ds18b20数字温度传感器
1.DS1820的特性
·单线接口:
仅需一根口线与MCU连接
·无需外围元件
·由总线提供电源
·测温范围为-55℃~75℃,精度为0.5℃
·九位温度读数
·A/D变换时间为200ms
·用户自设定温度报警上下限,其值是非易失性的
·报警搜索命令可识别哪片DS1820超温度限
2.DS1820引脚及功能(见图4)
ØGND:
地;
ØDQ:
数据输入/输出脚(单线接口,可作寄生供电);
ØVDD:
电源电压。
3.DS18B20内部结构
DS1820的内部结构如图5所示。
由图5可知,DS1820由三个主要数字器件组成:
①64bit闪速ROM;
②温度传感器;
③非易失性温度报警触发器TH和TL。
4.温度寄存器格式
5.DS18B20的使用方法
由于DS18B20采用的是1-Wire总线协议方式,即在一根数据线实现数据的双向传输,而对AT89S51单片机来说,硬件上并不支持单总线协议,因此,我们必须采用软件的方法来模拟单总线的协议时序来完成对DS18B20芯片的访问。
由于DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。
DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。
该协议定义了几种信号的时序:
初始化时序、读时序、写时序。
所有时序都是将主机作为主设备,单总线器件作为从设备。
而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。
数据和命令的传输都是低位在先。
DS18B20的复位时序
DS18B20的读时序
对于DS18B20的读时序分为读0时序和读1时序两个过程。
对于DS18B20的读时隙是从主机把单总线拉低之后,在15秒之内就得释放单总线,以让DS18B20把数据传输到单总线上。
DS18B20在完成一个读时序过程,至少需要60us才能完成。
DS18B20的写时序
对于DS18B20的写时序仍然分为写0时序和写1时序两个过程。
对于DS18B20写0时序和写1时序的要求不同,当要写0时序时,单总线要被拉低至少60us,保证DS18B20能够在15us到45us之间能够正确地采样IO总线上的“0”电平,当要写1时序时,单总线被拉低之后,在15us之内就得释放单总线。
程序代码:
//40MHZ,连在RA4脚上
#include
#include
//===================================================================
voidPIC18F_HIGH_ISR(void);//高优先级中断服务函数
voidPIC18F_LOW_ISR(void);//低优先级中断服务函数
#pragmacodehigh_vector_section=0x08
voidhigh_vector(void)
{
_asmgotoPIC18F_HIGH_ISR_endasm
}
#pragmacodelow_vector_section=0x18
voidlow_vector(void)
{
_asmgotoPIC18F_LOW_ISR_endasm
}
#pragmacode
//------------------------------------------------宏定义
#defineuintunsignedint
#defineucharunsignedchar
#definedsLATAbits.LATA4
#defineDQ1_dataPORTA&0x10
#defineePORTBbits.RB3//液晶屏e端接RB5
#definerwPORTBbits.RB4//液晶屏rw端接RB6
#definersPORTBbits.RB5//液晶屏rs端接RB7
#defineLEDSEG_CLATC
#defineKey_DataPORTBbits.RB1
#defineKey_CLKPORTBbits.RB0
romunsignedcharLEDSEGCODE[]=//0-9笔段代码
{
0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f,
};
//-------------------------------------------------------全局变量
uinttemp;
floatf_temp;//温度传感器转换结果保存在lednum
uchara1,a2,a3,a4,num;//a1--a4分别为液晶屏第二行第1、3、4、5位数
unsignedintvalue=0;
unsignedintvalue2=0;
unsignedintvalue3=0;
unsignedcharrecebuf;
ucharIntNum=0;//中断次数计数
ucharKeyV;//键值
unsignedcharBF=0;
unsignedchark;
unsignedcharflag;
unsignedchari=0;
unsignedcharflagok=0;
unsignedchardata[2];
unsignedintlednum=0,lednum0=0;
unsignedcharSndStr[]={"thetempretureis:
"};
//---------------------------------------------------------函数声明
voiddisp(ucharnum1,ucharnum2,ucharnum3);//液晶显示
voiddisp1(ucharnum11,ucharnum21);
voiddisp2(ucharnum11,ucharnum21,ucharnum31);
voiddisp3(uchar