pic笔记-16f877a-11-3x3矩阵键盘
PIC16F877A矩阵键盘的用法

PIC16F877A矩阵键盘的用法Post By:2010-9-27 13:39:00/*********************************************************************** ********Platform: PIC1687AProject : 实验16:矩阵式按键Clock F : 外部4MSoftware: PICCAuthor : 竹林清风comments:学习使用矩阵式按键的用法本例功能是按一下相应键,数码管显示相应的值0-9;不带连发,不带组合,希望有兴趣的人帮忙完成并共享UP键按键计数proteus仿真通过;************************************************************************ *******/#include <pic.h>#include <pic1687x.h>#include"delay.h"#include"key.h"unsigned char led_7[]={0x3f,0x06,0x5b,0x4F,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//数码管显示值unsigned char key_temp;void main(void){unsigned char ID=0;TRISB=0X00;//所有B0端口输出PORTB=0XFF;TRISD=0X0F;//初始化键盘接口PORTD=0XFF;//置输出为高电平while(1){delay_nms(5);key_temp = read_keyboard(); // 调用键盘接口函数读键盘 if (key_temp != No_key){ // 有按键按下switch(key_temp){case 1:PORTB=led_7[1];break;case 2:PORTB=led_7[2];break;case 3:PORTB=led_7[3];break;case 4:PORTB=led_7[4];break;case 5:PORTB=led_7[5];break;case 6:PORTB=led_7[6];break;case 7:PORTB=led_7[7];break;case 8:PORTB=led_7[8];break;case 9:PORTB=led_7[9];break;case K3_2:PORTB=led_7[0];break;case 13:if(++ID>=10){ID=0;}PORTB=led_7[ID];break;}}}}下面为延时函数:文件delay.cvoid delay_1us(void) //1us {asm("nop");}void delay_nus(unsigned int n) //N us延时函数{unsigned int i=0;for (i=0;i<n;i++)delay_1us();}void delay_1ms(void) //1ms延时函数{unsigned int i;for (i=0;i<1140;i++);}void delay_nms(unsigned int n) //N ms延时函数{unsigned int i=0;for (i=0;i<n;i++)delay_1ms();}头文件:delay.hvoid delay_1us(void);void delay_nus(unsigned int n); //N us延时函数void delay_1ms(void); //1ms延时函数void delay_nms(unsigned int n); //N ms延时函数键盘key.h#define No_key 255#define K1_1 1#define K1_2 2#define K1_3 3#define k1_4 4#define K2_1 5#define K2_2 6#define K2_3 7#define K2_4 8#define K3_1 9#define K3_2 0#define K3_3 10#define K3_4 11#define K4_1 12#define K4_2 13#define K4_3 14#define K4_4 15#define Key_mask 0b00001111unsigned char read_keyboard(){static unsigned char key_state = 0, key_value, key_line;unsigned char key_return = No_key,i,key_time;switch (key_state){case 0:key_line = 0b00010000;for (i=1; i<=4; i++) // 扫描键盘{PORTD = ~key_line; // 输出行线电平PORTD = ~key_line; // 必须送2次!!!key_value = Key_mask & PORTD; // 读列电平if (key_value == Key_mask)key_line <<= 1; // 没有按键,继续扫描else{key_state++; // 有按键,停止扫描break; // 转消抖确认状态}}break;case 1:if (key_value == (Key_mask & PORTD)) // 再次读列电平, {switch (key_line | key_value) // 与状态0的相同,确认按键 { // 键盘编码,返回编码值case 0b00011110:key_return = K1_1; //"1"key_state++;break;case 0b00011101:key_return = K1_2; //"2"key_state++;break;case 0b00011011:key_return = K1_3; //"3"key_state++;break;case 0b00010111:key_return = k1_4; //"4" key_state++;break;case 0b00101110:key_return = K2_1; //"5" key_state++;break;case 0b00101101:key_return = K2_2; //"6" key_state++;break;case 0b00101011:key_return = K2_3; //"7" key_state++;break;case 0b00100111:key_return = K2_4; //"8" key_state++;break;case 0b01001110:key_return = K3_1; //"9" key_state++;break;case 0b01001101:key_return = K3_2; //"0" key_state++;break;case 0b01001011:key_return = K3_3; //"A"key_state++;break;case 0b01000111:key_return = K3_4; //"B"key_state++;break;case 0b10001110:key_return = K4_1; //"C"key_state++;break;case 0b10001101://key_return = K4_2; //"D"// key_state++;key_time=0;key_state=3;break;case 0b10001011:key_return = K4_3; //"E"key_state++;break;case 0b10000111:key_return = K4_4; //"F"key_state++;break;}// 转入等待按键释放状态}elsekey_state--; // 两次列电平不同返回状态0,(消抖处理)break;case 2: // 等待按键释放状态PORTD = 0b00000111; // 行线全部输出低电平 PORTD = 0b00000111; // 重复送一次if ( (Key_mask & PORTD) == Key_mask)key_state=0; // 列线全部为高电平返回状态0 break;case 3:PORTD = 0b00000111; // 行线全部输出低电平 PORTD = 0b00000111; // 重复送一次if ( (Key_mask & PORTD) == Key_mask){key_state=0; // 列线全部为高电平返回状态0 key_return = K4_2;}//break;else if( (Key_mask & PORTD)!=Key_mask) {if(++key_time>=100){key_state=4;key_time=0;key_return=20;}}break;case 4:PORTD = 0b00000111; // 行线全部输出低电平PORTD = 0b00000111; // 重复送一次if ( (Key_mask & PORTD) == Key_mask){key_state=0; // 列线全部为高电平返回状态0 //key_return = K4_2;}else if(++key_time>=20){key_time=0;key_return=20;}break;}return key_return;}此主题相关图片如下ju.jpg:。
PIC16F877A功能及其编程

4.1.1 端口A
因此,在使用RA口时,除了要设置TRISA外,有 时相关寄存器也要设置。
注意:在上电复位时,与AN有关的端口的默认 设置是作为模拟端口,即ADCON1(见4.6)中默认 值为0b00xx0000,这个值的设置结果是除RA4外的所 有的RA引脚都作为模拟输入。
信的时钟线; RC7/RX/DT:IO引脚、异步串行通信的接收、同步串行通
信的数据线。
4.1.4 端口D
端口D有8个引脚,它除了作为普通IO口外, 还能作为并行从动口使用。
4.1.5 端口E 端口E只有3个引脚,它们都可以作为AD转换
的模拟电压输入口,功能如下:
RE0/RD/AN5:IO引脚、并行从动口的读控制、 模拟电压输入通道AN5;
➢ 中断的特点:可返回性。中断处理结束后必须能 回到原先的程序,并且能继续运行原先的程序,
这就需要在中断时能进行现场保护与恢复。
中断的执行过程
➢ 中断发生:程序执行到某行,突然事件(能够产 生中断的事件)发生,产生中断。
➢ 断点保护:CPU自动将中断时刻即将要执行的下 一条指令的地址压入堆栈。
➢ 中断响应:CPU自动将PC强制设为0X0004,且GIE =0。执行中断服务程序(自动完成现场保护与恢 复,手动清中断标志位)。
将被调试系统占用,因此在调试时此二个引脚暂 不能使用。
3、8个引脚具有内部弱上拉使能控制 由OPTION_REG寄存器的第7位RBPU控制,如果弱 上拉使能,作为输入的RB口在端口悬空时将被上拉 到高电平。以RB0为例,如下图所示:
4、RB0/INT具有外部中断功能。
5、RB的的高4位还具有电平变化中断功能
ADIE
proteus教学实验系统(单片机e型)实验指导

目录(版本 1.03)第1章PROTEUS教学实验系统(单片机E型)简介及使用说明 (1)1.1 系统简介 (1)1.2 实验系统的硬件布局 (4)1.3 实验系统原理图 (5)1.4 实验板硬件图 (16)1.5 USB下载方式说明 (23)第2章硬件实验目录 (27)实验一I /O口输出实验—LED流水灯实验 (27)实验二I/O口输入/输出实验—模拟开关灯 (29)实验三8255并行I/O扩展实验 (31)实验四无译码的七段数码管显示实验 (33)实验五BCD译码的多位数码管扫描显示实验 (36)实验六独立式键盘实验 (38)实验七计数器实验 (40)实验八定时器实验 (42)实验九单个外部中断实验 (44)实验十中断嵌套实验 (46)实验十一矩阵键盘扫描实验 (49)实验十二串行端口并行输出扩充实验 (51)实验十三串行端口并行输入扩充实验 (53)实验十四单片机与PC之间串行通信实验 (55)实验十五双单片机通信实验 (58)实验十六I2C总线——AT24CXX存储器读写 (60)实验十七温度传感器DS18B20实验 (64)实验十八实时时钟DS1302实验 (66)实验十九A/D转换实验 (68)实验二十D/A转换实验 (70)实验二十一1602液晶显示的控制(44780) (72)实验二十二12864液晶显示的控制(KS0108) (74)实验二十三直流电机控制实验 (76)实验二十四步进电机控制实验 (78)实验二十五16X16阵列LED显示 (81)实验二十六直流电机测速实验 (83)实验二十七串行AD—TLC549实验 (85)实验二十八串行DA—TLC5615实验 (87)实验二十九继电器控制实验 (89)实验三十LCD 1602 IO方式驱动 (92)第3章软件仿真实验目录 (96)实验一可控硅驱动 (96)实验二光耦应用实验 (98)实验三单片机播放音乐实验 (100)实验四SD卡读写实验 (104)第1章PROTEUS教学实验系统(单片机E型)简介及使用说明1.1 系统简介【硬件特点】PROTEUS教学实验系统(单片机E型)是我公司陆续推出的PROTEUS教学实验系统第三版。
PIC16f877中文资料1

PIC16F877原理简介1.1 PIC16F877特性:PIC16F877是由Microchip公司所生产开发的新产品,属于PICmicro系列单片微机,具有Flash program程序内存功能,可以重复烧录程序,适合教学、开发新产品等用途;而其内建ICD(In Circuit Debug)功能,可以让使用者直接在单片机电路或产品上,进行如暂停微处理器执行、观看缓存器内容等,让使用者能快速地进行程序除错与开发。
如图1为PIC16F877的40根接脚图,PDIP是指一般最常见的DIP(Dual In Line Package)包装,而PIC单片机也有PLCC(Plastic Leaded Chip Carrier)与QFP(Quad Flat Package)两种形式的包装,依照不同的需求,寻找不同的包装形式。
如图所示,每根接脚都有其特定功能,例如Pin11与Pin32(VDD)为正电源接脚,Pin12与Pin31(VSS)为地线接脚;而有些接脚有两种甚至三种以上功能,例如Pin2(RA0/AN0)代表PORTA的第一支接脚,在系统重置(Reset)后,可自动成为模拟输入接脚,接收模拟讯号,也可经由程序规划为数字输出输入接脚。
图1. PDIP40引脚PIC16F877接脚说明图2. PDIP28和SOIC28引脚PIC16F877接脚图说明图3. PLCC44引脚PIC16F877脚位图说明图4. QFP44引脚PIC16F877引脚图说明PIC16F877属于闪控式(Flash)单片机,可以重复烧录,其ROM的容量总共是8K words,以2K为一个page,区分为4个pages;内部RAM总共有512个字节(00f~1FFh),以128个字节为一个Bank,共区分为4个Bank,如图5所示,每个Bank的前半段都有其特殊用途,分别连接到其特殊功能模块,例如I/O、CCP、Timer、USART、MSSP等。
PIC16f877中文资料

PIC16F877原理简介1.1 PIC16F877特性:PIC16F877是由Microchip公司所生产开发的新产品,属于PICmicro系列单片微机,具有Flash program程序内存功能,可以重复烧录程序,适合教学、开发新产品等用途;而其内建ICD(In Circuit Debug)功能,可以让使用者直接在单片机电路或产品上,进行如暂停微处理器执行、观看缓存器内容等,让使用者能快速地进行程序除错与开发。
如图1为PIC16F877的40根接脚图,PDIP是指一般最常见的DIP(Dual In Line Package)包装,而PIC单片机也有PLCC(Plastic Leaded Chip Carrier)与QFP(Quad Flat Package)两种形式的包装,依照不同的需求,寻找不同的包装形式。
如图所示,每根接脚都有其特定功能,例如Pin11与Pin32(VDD)为正电源接脚,Pin12与Pin31(VSS)为地线接脚;而有些接脚有两种甚至三种以上功能,例如Pin2(RA0/AN0)代表PORTA的第一支接脚,在系统重置(Reset)后,可自动成为模拟输入接脚,接收模拟讯号,也可经由程序规划为数字输出输入接脚。
图1. PDIP40引脚PIC16F877接脚说明图2. PDIP28和SOIC28引脚PIC16F877接脚图说明图3. PLCC44引脚PIC16F877脚位图说明图4. QFP44引脚PIC16F877引脚图说明PIC16F877属于闪控式(Flash)单片机,可以重复烧录,其ROM的容量总共是8K words,以2K为一个page,区分为4个pages;内部RAM总共有512个字节(00f~1FFh),以128个字节为一个Bank,共区分为4个Bank,如图5所示,每个Bank的前半段都有其特殊用途,分别连接到其特殊功能模块,例如I/O、CCP、Timer、USART、MSSP等。
第三章 PIC16F887功能及编程

0:计时
01-1:4
… 1111-1:16
1X-1:16
福州大学电气工程与自动化学院
• TMR0是个8位计数/定时器,有可编程预分频率 器,可对外部脉冲计数或对内部指令脉冲计数的 功能。
• 当对外部脉冲计数时,符合一定要求的外部脉冲 送到RA4/T0CKI,且OPTION_REG(<T0CS>)要 置1,且该口(RA4)要设置为输入。
• TMR0寄存器的地址在01H、101H。 • TMR0有溢出中断功能。
中断 信接收 信发送 行通信 模块 溢出 溢出 使能 中断 中断 中断 中断 中断 中断
使能 使能 使能 使能 使能 使能
福州大学电气工程与自动化学院
bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
- ADIF RCIF TXTF SSPIF CCP1IF TMR2IF TMR1IF - AD转换 串行通 串行通 同步串 CCP1 TMR2 TMR1
• 恢复被保护的相关寄存器 • 程序执行到”RETFIE”时后入先出的原则,从堆栈
中弹出地址给PC,GIE=1,程序返回到中断前 要执行的程序,程序恢复中断前程序的运行状 态。
福州大学电气工程与自动化学院
PIC16F887有17个中断源,每个中断源都有自 己的使能控制位(IE)和中断标志位(IF)。包括:
• 假设当前TRM1H、TMR1L=0x01FF,则在读取TMR1时 就可能发生错误:
• 如先读低字节,得到0xFF,假设此时发生进位,则再读 高字节时得到0x02,总的结果是0x2FF,显然是错误的。
• 如先读高字节,得到0x01,假设此时发生进位,则再读低 字节得到0x00,总的结果是0x100,也是错误的。
PIC16F877A开发学习板用户手册
KEY_LED 实验步骤: 短接跳线 J23 将 hex 文件下载到单片机中 实验现象:按下 GPIO 键,松开后,led 点亮;按下 INT 健,松开后,led 灭 KEY_ZTJ 10、 矩阵键盘实验 KEY_JZH 实验步骤: 短接跳线 J50 的 LED_ON 和中间脚 将 hex 文件下载到单片机中 实验现象:按下按键,数码管显示键值 11、 定时器/计数器 T0 实验 T0_DSQ 实验步骤: 短接跳线 J23 将 hex 文件下载到单片机中 实验现象:下载代码,运行程序,LED 闪烁 T0_JS_1 实验步骤: 短接跳线 J50 的 LED_ON 和中间脚
断电后数据保持,上电后,从断电时的值开始加(写入 24C02 的数据为 1 递加到 99,LCD1602 从 24C02 中读数据之后显示)
AT24C02 实验步骤: 短接跳线 J18 上面两个引脚和 J22 上面两个引脚 将 hex 文件下载到单片机中 将 1602 液晶屏插入 1602 接口 如果此时没有显示则按复位键便可正常显示 实验现象:1602 第一行显示数值,数值从 1 加到 99, 断电后数据保持,上电后,从断电时的值开始加 17、 模数转换 AD 实验 AD_1
将 hex 文件下载到单片机中 实验现象:LED 灯依次点亮 2、 数码管实验 SMG 实验步骤: 短接跳线 J50 的 LED_ON 和中间脚 将 hex 文件下载到单片机中 实验现象:8 个数码管依次显示 0~7 SMG_JT 实验步骤: 短接跳线 J50 的 LED_ON 和中间脚 将 hex 文件下载到单片机中 实验现象:数码管静态显示一个数字 74HC595_SMG 实验步骤: 短接跳线 J50 的 LED_ON 和中间脚 将 hex 文件下载到单片机中 实验现象:8 位数码管显示 0-7 3、 蜂鸣器实验 BUZZER 实验步骤: 短接跳线 J6
第四章PIC16F877A功能及其编程
for (k=246;k>0;k--) NOP();
}
以后此程序略,可参见附录:公用子程序。
返回目录
4.3 定时/计数器TMR0 TMR0是个8位计数/定时器
自带可编程预分频器,可对外部脉冲计数或对内部 指令脉冲计数(1:1~1:256)
这就需要在中断时能进行现场保护与恢复。
中断的执行过程
➢ 中断发生:程序执行到某行,突然事件(能够产 生中断的事件)发生,产生中断。
➢ 断点保护:CPU自动将中断时刻即将要执行的下 一条指令的地址压入堆栈。
➢ 中断响应:CPU自动将PC强制设为0X0004,且GIE =0。执行中断服务程序(自动完成现场保护与恢 复,手动清中断标志位)。
RA3=1; NOP(); RA4=0;
4.1.1 端口A
因此,在使用RA口时,除了要设置TRISA外,有 时相关寄存器也要设置。
注意:在上电复位时,与AN有关的端口的默认 设置是作为模拟端口,即ADCON1(见4.6)中默认 值为0b00xx0000,这个值的设置结果是除RA4外的所 有的RA引脚都作为模拟输入。
➢ 一条写IO引脚的指令如RB3=1,实际上是在指令的 开头读入整个B端口,并在指令周期的末尾时刻把 1写入RB端口3的输出锁存器。 如果立即对同一端口操作,如x=PORTB,在指令 周期的开始处,由于前一指令产生在IO口的电平 尚未稳定,读入的可能是引脚的前一个状态而不 是新状态值。
因此连续对同一端口的操作时,最好用一个NOP 指令或者其他不访问该I/O 端口的指令隔开。
RD 并行口
中断 标志
AD转换 中断
pic16f877a程序
实验二程序清单:(1)编写程序使8个LED实现双跳灯显示//===========led程序===========#include <pic.h>//===========变量定义==========void delay(int z);//===========主程序============main(){TRISD=0x00;while(1){PORTD=0x03;delay(200);PORTD=0x0c;delay(200);PORTD=0x30;delay(200);PORTD=0xc0;delay(200);}}void delay(int z){int x,y;for(x=z;x>0;x--)for(y=120;y>0;y--);}(2)编写程序实现8个LED灯高四位和低四位交替点亮//===========led程序===========#include <pic.h>//===========变量定义==========void delay(int z);//===========主程序============main(){TRISD=0x00;while(1){PORTD=0xf0;delay(500);PORTD=0x0f;delay(500);}}void delay(int z){int x,y;for(x=z;x>0;x--)for(y=120;y>0;y--);}(3)编写程序使第一次按下按键时单双星闪(1、3、5、7个 LED灯与2、4、6、8个LED交替点亮),第二次按下按钮时高四位的LED和低四位的LED交替点亮,这两种显示方式依次循环#include <pic.h>//===========变量定义==========void delay(int z);void KEYSCAN();#define shuru RB0unsigned int i,j;//===========主程序============ main(){TRISD=0x00;TRISB=0X01;//设置RB0为输入i=0;PORTD=0XFF;while(1){KEYSCAN();if(i%2==1){PORTD=0xaa;delay(500);PORTD=0x55;delay(500);}if(i%2==0){PORTD=0xf0;delay(500);PORTD=0x0f;delay(500);}}}void delay(int z){int x,y;for(x=z;x>0;x--)for(y=120;y>0;y--);}void KEYSCAN(){while(1){if(shuru==1)break;} /*等待有键按下*/delay(10); /*软件延时*/if(shuru==1)i++; /* 如果仍有键按下,则调用键服务子程序*/}实验三程序清单:(1)4*4键盘扫描#include<pic.h> //包含单片机内部资源预定义const charLEDCODE[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7c,0x 39,0x5e,0x79,0x71};int result;void delay(); //delay函数申明void init(); //I/O口初始化函数申明void scan(); //按键扫描程序申明void display(int x); //显示函数申明//---------------------------------------------------//主程序void main(){while(1) //循环工作{init(); //调用初始化子程序scan(); //调用按键扫描子程序display(result); //调用结果显示子程序}}//---------------------------------------------------//初始化函数void init(){TRISD=0X0f; //设置C口高4位为输入,低4位为输出TRISC=0X00; //设置D口为输出PORTC=0X00;PORTD=0X00; //先清除所有显示}//按键扫描程序void scan(){PORTD=0XEF; //C3输出低电平,其他三位输出高电平asm("nop"); //插入一定延时,确保电平稳定result=PORTD; //读回C口高4位结果result=result&0x0f; //清除低4位if(result!=0x0f) //判断高4位是否为全1(全1代表没按键按下)?{result=result|0xE0; //否,加上低4位0x07,做为按键扫描的结果return;}PORTD=0XDF; //C3输出低电平,其他三位输出高电平asm("nop"); //插入一定延时,确保电平稳定result=PORTD; //读回C口高4位结果result=result&0x0f; //清除低4位if(result!=0x0f) //判断高4位是否为全1(全1代表没按键按下)?{result=result|0xD0; //否,加上低4位0x07,做为按键扫描的结果return;}PORTD=0XBF; //C3输出低电平,其他三位输出高电平asm("nop"); //插入一定延时,确保电平稳定result=PORTD; //读回C口高4位结果result=result&0x0f; //清除低4位if(result!=0x0f) //判断高4位是否为全1(全1代表没按键按下)?{result=result|0xB0; //否,加上低4位0x07,做为按键扫描的结果return;}PORTD=0X7F; //C3输出低电平,其他三位输出高电平asm("nop"); //插入一定延时,确保电平稳定result=PORTD; //读回C口高4位结果result=result&0x0f; //清除低4位if(result!=0x0f) //判断高4位是否为全1(全1代表没按键按下)?{result=result|0x70; //否,加上低4位0x07,做为按键扫描的结果return;}}//显示程序void display(int x){switch(result){case 0xee:PORTC= LEDCODE[0];delay();break; case 0xed:PORTC= LEDCODE[1];delay();break; case 0xeb:PORTC= LEDCODE[2];delay();break; case 0xe7:PORTC= LEDCODE[3];delay();break;case 0xde:PORTC= LEDCODE[4];delay();break;case 0xdd:PORTC= LEDCODE[5];delay();break; case 0xdb:PORTC= LEDCODE[6];delay();break; case 0xd7:PORTC= LEDCODE[7];delay();break;case 0xBE:PORTC= LEDCODE[8];delay();break;case 0xbd:PORTC= LEDCODE[9];delay();break; case 0xBb:PORTC= LEDCODE[10];delay();break; case 0xb7:PORTC= LEDCODE[11];delay();break; case 0x7E:PORTC= LEDCODE[12];delay();break; case 0x7d:PORTC= LEDCODE[13];delay();break; case 0x7b:PORTC= LEDCODE[14];delay();break;case 0x77:PORTC= LEDCODE[15];delay();break;}}//延时程序void delay() //延时程序{int i; //定义整形变量for(i=0x100;i--;); //延时}(2)数码管显示#include<pic.h> //包含单片机内部资源预定义// __CONFIG(0x1832);//芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡void delay(); //delay函数申明void init(); //I/O口初始化函数申明char TABLE[]={0,1,2,3,4}; //定义常数0-5的数据表格const charLEDCODE1[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00};//共阴码void main(){init(); //调用初始化函数while(1) //死循环,让数码管持续{PORTC=0X01; //点亮第1位数码管PORTD=~LEDCODE1[TABLE[0]]; //D口输出数据表格第1个数据0 delay();PORTD=0xFF; //延时一定时间,保证数码管亮度PORTC= 0x02;PORTD=~LEDCODE1[TABLE[1]]; //显示数据1delay();PORTD=0xFF;PORTC= 0x04;PORTD=~LEDCODE1[TABLE[2]]; //显示数据2delay();PORTD=0xFF;PORTC= 0x08;PORTD=~LEDCODE1[TABLE[3]]; //显示数据3delay();PORTD=0xFF;}}void init() //I/O口初始化函数{TRISC=0X00; //设置A0输出,其他输入TRISD=0X00; //设置D口输出PORTC=0x00;PORTD=0x00; //先熄灭所有显示}void delay() //延时程序{int i; //定义整形变量for(i=0xF000;i--;); //延时 //0x400for(i=0xff;i--;);}void display(){int i ;unsigned char DISPBIT;DISPBIT=0x01;for (i=0;i<=3;i++){PORTC=DISPBIT; //点亮第1位数码管PORTD=~LEDCODE1[TABLE[i]]; //D口输出数据表格第1个数据0 delay();PORTD=0xFF;DISPBIT=DISPBIT<<1;}}实验四程序清单:(1)方波发生器#include<pic.h>sbit P1_0=P1^0;void timer0(void){P1_0=!P1_0;TH0=-(1000/256); /*计数初值重装*/TL0=-(1000%256);}void main(void){TMOD=0x01; /*T0工作在定时器方式1*/P1_0=0;TH0=-(1000/256); /*预置计数初值*/TL0=-(1000%256);EA=1; /*CPU开中断*/ET0=1; /*T0开中断*/TR0=1; /*启动T0*/do{}while(1);}(2)程序说明:P1口输出,低电平有效#include<pic.h>#define uchar unsigned char //定义无符号字符#define uint unsigned int //定义无符号整数void Delayms(uint x){ //定义延时函数uint i,j;for(i=x;i>0;i--)for(j=110;j>0;j--);}void main(){uint i;uchar temp;while(1){temp=0x01; //8个流水灯逐个闪动for(i=0;i<8;i++){P1=~temp;Delayms(300);temp<<=1;}temp=0x80; //8个流水灯反向逐个闪动for(i=0;i<8;i++){P1=~temp;Delayms(300);temp>>=1;}temp=0xfe; //8个流水灯依次全部点亮for(i=0;i<8;i++){P1=temp;Delayms(300);temp<<=1;}temp=0x7f; //8个流水灯依次反向全部点亮for(i=0;i<8;i++){P1=temp;Delayms(300);temp>>=1;}}}实验六程序清单:(1) U1发送部分程序清单#include<pic.h>unsigned tran[10]={0,2,4,6,8,1,3,5,7,9};unsigned char k,x;int i=0;const chartable[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xD8,0x80,0x90,0x88,0x83,0x c6,0xa1,0x86,0x8c,0x7f,0xbf,0x89,0xff};void sciint(){SPBRG=0x19;TXSTA=0x04;RCSTA=0x80;TRISC6=1;TRISC7=1;TRISB=0x00;}void delay(){for(i=0x1FFF;i>0;i--) {;}}void display(){for(k=0;k<10;k++) { x=tran[k];PORTB=table[x];delay();}}main(){sciint();di();TXEN=1;CREN=1;for(k=0;k<10;k++){ TXREG=k;while(1){if(TXIF==1)break;}while(1){if(RCIF==1)break;}RCREG=RCREG;}display();while(1){;}}(2) U2接收部分程序清单#include<pic.h>unsigned rece[10];unsigned char k,x;int i=0;const chartable[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xD8,0x80,0x90,0x88,0x83,0x c6,0xa1,0x86,0x8c,0x7f,0xbf,0x89,0xff};void sciint(){SPBRG=0x19;TXSTA=0x04;RCSTA=0x80;TRISC6=1;TRISC7=1;TRISB=0x00;}void delay(){for(i=0x1FFF;i>0;i--){;}}void display(){for(k=0;k<10;k++) { x=rece[k];PORTB=table[x]; delay();}}main(){sciint();di();CREN=1;TXEN=1;for(k=0;k<10;k++){ while(1){if(RCIF==1)break;}rece[k]=RCREG; TXREG=rece[k];while(1){if(TXIF==1)break;}}display();while(1){;}}实验七程序清单:(1)单路显示#include<pic.h>unsigned int i;unsigned int a,b,c;static inttable[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xD8,0x80,0x90,0x88,0x83,0x c6,0xa1,0x86,0x8c,0x7f,0xbf,0x89,0xff};void initial() //初始化{TRISB=0x00; //定义为输出PORTB=0x13; //数码管全灭TRISC=0x00;PORTC=0x13;a=0;b=0;c=0;}void ADC() //A/D转换初始化{ADCON0=0x41; //0100 0001 选择转换时钟8Tosc,选择A/D通道为RA0,//打开A/D转换器。
基于单片机的电子密码锁实验报告
基于单片机的电子密码锁实验报告题目:基于16F877的电子密码锁班级:班内序号:实验组号:学生姓名:指导教师:基于16F877的电子密码锁实验摘要在日常的生活和工作中, 住宅与部门的安全防范、单位的文件档案、财务报表以及一些个人资料的储存多以加锁的方法来解决。
假设使用传统的机械式钥匙开锁,人们常需携带多把钥匙, 使用极不方便, 且钥匙丢失后安全性即大打折扣。
具有防盗报警等功能的电子密码锁代替密码量少、安全性差的机械式密码锁已是必定趋势。
随着科学技术的不断进展,人们对日常生活中的安全保险器件的要求越来越高。
为满足人们对锁的使用要求,增加其安全性,用密码代替钥匙的密码锁应运而生。
密码锁具有安全性高、成本低、功耗低、易操作、记住密码即可开锁等优点。
目前使用的电子密码锁大部分是基于单片机技术,以单片机为要紧器件,其编码器与解码器的生成为软件方式。
本系统由16F877单片机系统〔要紧是16F877单片机最小系统〕、4×4矩阵键盘、LCD1602显示和报警系统等组成,具有设置、修改四位用户密码、输入提示音、密码错误报警等功能〔本设计由单片机操纵LCD显示,密码正确显示password ok!密码错误显示wrong,please reset!用户reset后进行重新输入。
由单片机操纵矩阵键盘含有0-9数字键和A-F功能键。
按F键,那么进行密码重置功能〕。
本系统成本低廉,功能有用。
〔宋体五号〕A b s t r a c tIn daily life and work, the department of housing and security, unit documents, financial statements and some personal information to save more in order to lock the ways to solve. If use the traditional mechanical key to open the lock, people often need to carry multiple keys, use very convenient, and the key missing after security is compromised. With anti-theft alarm function such as electronic combination lock instead of password quantity is little, security, poor mechanical combination lock is inevitable trend. With the continuous development of science and technology, people in daily life the demand is higher and higher safety insurance device. To meet the requirements of people on the use of the lock, increase its safety, use the password instead of the key combination lock arises at the historicmoment. Combination lock with high safety, low cost, low power consumption, easy operation, remember password lock, etc.Currently use electronic combination lock is mostly based on single chip microcomputer technology, single chip microcomputer as the main device, the encoder and decoder for software.This system consists of 16 f877 microcontroller system (mainly minimum 16 f877 microcontroller system), 4 * 4 matrix keyboard, LCD1602 display and alarm system, etc, and has set up four, modify user password, password, input prompt error alarm functions (this design by the single chip microcomputer control LCD display, the password correctly display the password ok! Wrong password shows wrong, both please reset! The user to enter again after reset. By single-chip microcomputer control matrix keyboard contains 0-9 number keys and A - F function keys. Press the F key, then carries on the password reset function). This system is low cost, function and practical.WM function to control its turn. And this is so called navigating aptitudinally .关键字单片机——microcontroller 芯片——CMOS chip16F877一、PIC16F877系列单片机简介PIC16F87X ( 含873P874P876P877) 是美国微芯(Microchip) 公司推出的高性能单片机,除具有单片机的通用资源外,该系列单片机还采纳哈佛总线结构、二级指令流水线取指方式、精简指令集(RISC)和内部具有E2 PROM 数据储备器及FLASH 结构的程序储备器、仅35 条单字节单周期指令、在系统串行编程技术和在线调试技术。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
******************************************************************************/
#include <pic.h>
//调用头文件
__CONFIG(0x3F32);
//芯片配置字
typedef unsigned char uchar; //用 uchar 替代关键字 unsigned char typedef unsigned int uint; //用 uint 替代关键字 unsigned int
(一)编写程序
/******************************************************************************
程序名:3x3 矩阵键盘
晶振:外部晶振 4MHz,1 机器周期=1us
描述:3x3 矩阵键盘
作者:张周伟
完成日期:2013 年 06 月 26 号
void init(void);
//子函数声明,初始化
void delayms(uint t); //延时子函数声明,无返回值,需要输入一个 16 位无符号变量值
void key_scan();
void LED_DISPLAY();
uchar LED_DIS[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};//共阳段码表 uchar key_val; void main (void) {
一、3x3 矩阵键盘
作者:张周伟
日期:2013-06-26
QQ:18758153306
旺旺:zzwasd
淘宝:
博客地址:
关于文章中的疑问在本文后留言即可,请勿联系 QQ。 建议或意见请发 e-mail:crudeoil@ 转载请注明出处并保证文章完整性,未经作者许可不得用于商业用途,包括但不限于拷贝、 附赠等形式。
(二)电路和效果
电路左半部分与基本电路相同。 按下 1~9 个按键,在数码管上显示对应的按键值。 为了仿真的便利,共阳数码管的位选直接接了反向器,实际制作电路时应换成 pnp 三极 管以降低成本。
(三)版本
v1.0SB=0X07; //行线设为输入
if((key_temp=PORTB & 0X07)!=0X07){key_val=(key_y_num & 0x38);}//保
存列值
key_y_num>>=1; //扫描下一列 } key_val=key_val | key_x_num; //保存行值 } switch(key_val) { case 0x36: key_val=0x01; break; case 0x2e: key_val=0x02; break; case 0x1e: key_val=0x03; break; case 0x35: key_val=0x04; break; case 0x2d: key_val=0x05; break; case 0x1d: key_val=0x06; break; case 0x33: key_val=0x07; break; case 0x2b: key_val=0x08; break; case 0x1b: key_val=0x09; break; } } } /******显示子函数*****/ void LED_DISPLAY() { PORTA=0Xfe; PORTD=LED_DIS[key_val]; //显示 } /*本例要求 1.了解 3x3 矩阵键盘*/
init(); while(1)
{ key_scan(); LED_DISPLAY();
} }
/******延时子函数**4Mhz 晶振时最小约 1ms,最大 65s******/
void delayms(uint t)
{
uint temp;
//定义变量 temp,和 main 中的 temp 都属于局部变量,两者没有联系
//行线设为输入
if((key_x_num=PORTB & 0X07)!=0x07)
{
delayms(10);
//消抖
if((key_x_num=PORTB & 0X07)!=0X07)
{
for(i=0;i<3;i++) //键扫描
{
TRISB=0X00;
PORTB=key_y_num |0x07;
while(t--)
{
temp=58;
while(temp--); //延时一段时间
}
}
/******初始化子函数*****/
void init(void)
{
TRISA=0XFE; //RA0 设为输出控制数码管
PORTA=0XFF; //全关(共阳)
TRISD=0x00; //PORTD 作为段选
PORTD=0XFF;
//关闭
}
/******键盘扫描子函数*****/
void key_scan()
{
uchar key_y_num=0xDF,key_x_num,key_temp,i;
RBPU=0;
//PB 口使能拉高
TRISB=0X00;
//设为输出
PORTB=0X07;
//键盘行线上拉
TRISB=0X07;