PIC16F877A功能及其编程
pic16f877a单片机课程设计收银机
pic16f877a单片机课程设计收银机一、概述单片机作为现代电子技术的重要组成部分,被广泛应用于各行各业。
在计算机课程设计中,使用单片机进行项目设计是非常常见且有挑战性的。
本课程设计将以pic16f877a单片机为核心,设计一个简单的收银机系统,旨在让学生通过实际操作,理解单片机系统的工作原理和应用场景。
二、需求分析1.功能需求:(1)收银台显示当前商品信息和总价;(2)能够扫描商品条码,并实时更新商品信息和总价;(3)能够输入商品数量,并实时更新总价;(4)能够完成结账功能,并打印小票。
2.性能需求:(1)界面友好,操作便捷;(2)扫描速度快,反应迅速;(3)稳定性高,能够长时间稳定运行。
三、系统设计1.硬件设计:(1)选用pic16f877a单片机作为核心处理器,具有丰富的外围接口和强大的计算能力;(2)外围设备包括LCD显示屏、扫描条码器、按键、打印机等。
2.软件设计:(1)运用C语言进行系统软件设计,编写驱动程序和控制程序;(2)设计界面交互逻辑,包括显示商品信息、扫描条码、输入数量、结账等功能;(3)设计打印小票的格式和内容。
四、系统实现1.硬件连接:(1)将pic16f877a单片机与外围设备连接,包括LCD显示屏、扫描条码器、按键、打印机等;(2)确保硬件连接稳定可靠,避免因硬件问题导致系统运行失败。
2.软件编程:(1)编写pic16f877a单片机的初始化程序,初始化外围设备;(2)编写显示、扫描、输入、结账等功能的控制程序;(3)编写打印小票的格式和内容。
3.系统调试:(1)逐步调试系统功能,确保各功能模块正常运行;(2)检测系统的稳定性和反应速度,进行必要的优化。
五、系统测试1.功能测试:(1)测试收银台显示功能是否正常;(2)测试扫描条码和输入数量功能是否正常;(3)测试结账和打印小票功能是否正常。
2.性能测试:(1)测试系统的稳定性,长时间运行是否正常;(2)测试扫描速度和界面反应速度是否满足需求。
PIC16F877A定时器的学习
PIC16F877A定时器的学习由于实时数据的仿真需要用到定时器产生数据,今天晚上完成PIC16F877A 产生正弦波形,并将波形数据发送到上位机!这是一个三角波的仿真程序,并通过串口发送到上位机#include #include #include#include “main.h”#include“t232.h”#include“lcd.h”#include“timer.h”//define global variablebank1 uchar flag =0 ;//利用flag 判断中断时间是否到了!bank1 char dat[6] ;bank2 char str[]=“shan dong qing gong ye xue yuan”;bank2 char str1[]=“Starting........”;bank2 char str2[]=“Capturing.......”;bank2 char str3[]=“Stop..........” ;//bank2 float test = 0;//bank2 float t1 ;bank2 uchar t1 =0 ;bank2 uchar t2=0 ;bank1 uchar state = READY ;//当前状态bank1 uchar frame[3] ;//帧缓冲bank1 uchar temp ;//ms 级延时程序void DelayMS(uint ms){ uint i; while(ms--){ for(i=0;i//10us 级延时程序void Delay10US(uint us){ uchar i; for(i=0;iwhile(1) {while((t1>=-20)&&(state==CAPTURE)){t1++ ;sprintf(dat,”(%d)”,t1) ;send_str(dat);if(t1==20)break ;}while((t1}tips:感谢大家的阅读,本文由我司收集整编。
pic16f877a编程实例
pic16f877a编程实例pic16f877a是一款常用的单片机,被广泛应用于嵌入式系统中。
它具有多种功能和强大的性能,可以实现各种应用需求。
本文将以pic16f877a编程实例为主题,介绍其基本特性和常见应用。
pic16f877a是一款8位单片机,采用哈佛架构,具有高性能和低功耗的特点。
它内置了8KB的程序存储器,368字节的数据存储器,以及35个I/O引脚,可以满足大多数嵌入式系统的需求。
我们来看一个简单的实例,通过pic16f877a控制LED灯的开关。
```c#include <pic16f877a.h>void main() {TRISB0 = 0; // 设置RB0为输出引脚while(1) {RB0 = 1; // 将RB0引脚电平设置为高,LED灯亮__delay_ms(1000); // 延时1秒RB0 = 0; // 将RB0引脚电平设置为低,LED灯灭__delay_ms(1000); // 延时1秒}}```在上面的程序中,我们首先将RB0引脚设置为输出引脚,然后进入一个无限循环。
在循环中,我们将RB0引脚电平设置为高,LED灯亮起,然后延时1秒;然后将RB0引脚电平设置为低,LED灯熄灭,再次延时1秒。
通过不断重复这个过程,我们可以实现LED灯的闪烁效果。
除了控制LED灯,pic16f877a还可以用来控制其他外设,如蜂鸣器、液晶显示屏等。
下面是一个使用pic16f877a控制蜂鸣器的实例。
```c#include <pic16f877a.h>void main() {TRISB0 = 0; // 设置RB0为输出引脚while(1) {RB0 = 1; // 将RB0引脚电平设置为高,蜂鸣器鸣叫__delay_ms(1000); // 延时1秒RB0 = 0; // 将RB0引脚电平设置为低,蜂鸣器停止鸣叫__delay_ms(1000); // 延时1秒}}```在上面的程序中,我们同样将RB0引脚设置为输出引脚,并进入一个无限循环。
基于PIC16F877A的超低频脉冲调制高频信号的实现
2009年7月第28卷 第7期研究与开发中国科技核心期刊基于PIC16F877A 的超低频脉冲调制高频信号的实现李 涛 张华锋(中国人民解放军92957部队 舟山 316000)摘 要:实现了一种用低频率或超低频率的窄脉冲对正弦波高频信号进行调制的方法。
该方法在PICC 语言平台上设计程序,控制PIC16F877A 单片机的PWM 功能产生超低频脉冲调制的高频脉冲信号;设计串联谐振电路高频滤波器对高频脉冲进行滤波,把高频脉冲变成纯度较高的高频正弦波;设计衰减器和功率放大器,控制信号幅度。
经过测试表明:该方法设计实现的超低频脉冲调制高频信号具有高准确度、高稳定度的优点,满足使用要求。
关键词:PIC16F877A ;脉冲调制;超低频;高频中图分类号:TN761.2 文献标识码:AR ealization of ultralow frequency pulse modulated high frequencysignal based on PIC16F877ALi Tao Zhang Huafeng(PLA Units :92957,Zhoushan 316000,China )Abstract :A kind of low or ultralow frequency narrow pulse modulated high frequency sine wave signal method is realized in this paper.This method programmes on PICC platform ,and controls PWM mode of PIC16F877A MCU to produce high frequency signal modulated by ultralow frequency pulse ,and designs high frequency filter with series 2wound syntonic electrocircuit to filter out impurity from high frequency pulse and change high frequency pulse to pure high frequency sine wave ,and designs attenuator and power amplifier to modulate amplitude.Experimental results show that ultralow frequency pulse modulated high frequency signal produced by this method is high 2exact and steady 2state and satisfies use requirements.K eyw ords :PIC16F877A ;PWM ;ultralow frequency ;high frequency 作者简介:李涛,博士,高级工程师,从事军事计量管理和计量测试工作。
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转换器。
PIC16F877A万年历程序
PIC16F877A万年历程序时间:2009-03-05 来源: 作者:Wujieflash 点击:1639 字体大小:【大中小】为了把KS0108系列的液晶吃透,特别制作了这款万年历,感觉效果还是不错的.希望大家分享我的喜悦,毕竟有了更多志同道合的朋友支持,我才能更进一步提高.一,原理介绍说明:1.单片机还是采用PIC中最经典的PIC16F877A,端口多,功能全,特别是他有8K的ROM,这是我选择的主要原因,因为储存液晶的字库需要很大的空间.2.液晶显示还是用的KS0108系列,主要是他性价比高,指令简单,特别是公司也在用.3.时钟/日历芯片用的DALLOS的DS1302芯片,他可以储存从2000-2099年的日历,及实时时钟,可以方便的读写.4.温度测量还是用的DS18B20,这在我上一实例中已经用过,有兴趣可以查阅.5.本万年历可以显示实时时钟,精确到秒,年,月,日,星期,阴历,温度,生肖等,显示的信息量大. 6,可以通过按键自由设定时钟及日历,按"设置"键可以在秒,分,时,日,月,星期,年之间来回切换,要设置的单元以闪烁提醒.通过"+"."-"按键可以把要设置的单元设定到预想状态.二,程序说明:本程序有许多小的模块,现分列如下:1.主程序/**************************************************** 标题:万年历** 作者:Wujieflash ** 日期:2008年1月13日** 说明:包含文件***************************************************/ #include#include "ziku.h"#include "lcd_init.h"#include "ds1302.h"#include "ds18b20.h"#include "keyscan.h"#include "yinli.h"//子程序//LCD显示空白边框子程序void LCDShowTable(){uch i;SlectScreen(1); //写左半屏SetLine(0); //起使页SetColumn(0); //起使列for(i=0;i//显示固定字符子程序void LCDShowGudingWord(){Show8X16_2(0,24,s0);Show8X16_2(0,32,s0);Show8X16(2,1,s0);Show8X16(2,9,s0);Show16X16_3(6,40,ri);Show16X32(2,24,ss0);Show16X32(2,40,ss0);Show8X16_2(0,64,s0);Show8X16_2(0,72,s0);Show8X16_2(0,80,maohao);Show8X16_2(0,88,s0);Show8X16_2(0,96,s0);Show8X16_2(0,104,maohao);Show8X16_2(0,112,s0);Show8X16_2(0,119,s0);Show8X16(2,80,s0);Show8X16(2,88,s0);Show16X16_2(4,64,shiyi);Show16X16_2(4,80,yue);Show16X16_2(4,95,chu);Show16X16_2(4,111,yi);Show16X16_3(6,72,sheng);Show16X16_3(6,88,xiao);Show16X16_3(6,104,shu);Show16X16_2(0,40,nian);Show16X16(4,2,yue);Show16X16_3(6,8,xing);Show16X16_3(6,24,qi);Show16X16(2,96,danwei1);Show8X16_2(0,8,s2);Show8X16_2(0,16,s0);}/*----------------------------------------------------------*/ //TRM1初始化子程序void TMR1init(){//TRM1 INITIALT1CON=0X30; //8分频TMR1IF=0; //清中断标志TMR1IE=1; //使能定时器1中断TMR1L=0XDB; //初始值(定时0.5S)TMR1H=0X0B;TMR1ON=1; //开定时器1}//冒号闪烁子程序void FlashMaohao(){static uch timecount=0;if(TMR1IF==1){TMR1ON=0;TMR1IF=0;TMR1L=0XDB; //重新付初值TMR1H=0X0B;flag++;flag=flag%2; //闪烁标志在0-1间翻转TMR1ON=1;timecount++;if(timecount==120)//1分钟采样一次温度{timecount=0;get_temp(); //温度转换子程序}}if(flag==0){Show8X16_2(0,80,maohao);Show8X16_2(0,104,maohao);}if(flag==1){Show8X16_2(0,80,noshu);//清除Show8X16_2(0,104,noshu);}}//主程序void main(){TMR1init(); //定时器1初始化keyinit(); //键盘初始化LCDinit(); //LCD操作初始化LCDShowTable(); //显示空白表格LCDShowGudingWord(); //显示固定字符//Set1302(DisCash); //设置初始时间(默认写入我写程序的时间) get_temp(); //读取温度while(1){v_Get1302(clock); //读取时间、日历display();YangToYin(clock[6]/16*10+clock[6]&0x0f,clock[4]/16*10+clock[4]&0x0f,clock[3]/16*1 0+clock[3]&0x0f);FlashMaohao(); //冒号闪烁KeyScan(); //键盘扫描}}2.测温程序:/**************************************************** 标题:DS18B20测温** 作者:Wujieflash ** 日期:2008年1月13日** 说明:使用DS18B20芯片测温****************************************************/# define DQ RC3 //定义18B20数据端口# define DQ_DIR TRISC3 //定义18B20D口方向寄存器# define DQ_HIGH() DQ_DIR =1 //设置数据口为输入# define DQ_LOW() DQ = 0; DQ_DIR = 0 //设置数据口为输出unsigned char TLV=0 ; //采集到的温度高8位unsigned char THV=0; //采集到的温度低8位unsigned char TZ=0; //转换后的温度值整数部分//------------------------------------------------//延时函数//系统初始化函数void init(){ADCON1=0X07; //设置A口为普通数字口TRISA=0X00; //设置A口方向为输出//TRISC3=0; //设置D口方向为输出}//-----------------------------------------------//复位DS18B20函数reset(void){char presence=1;while(presence){DQ_LOW() ; //主机拉至低电平delay(2,90); //延时503usDQ_HIGH(); //释放总线等电阻拉高总线,并保持15~60us delay(2,8); //延时70usif(DQ==1) presence=1; //没有接收到应答信号,继续复位else presence=0; //接收到应答信号delay(2,70); //延时430us}}//-----------------------------------------------//写18b20写字节函数void write_byte(uch val){uch i;uch temp;for(i=8;i>0;i--){temp=val&0x01; //最低位移出DQ_LOW();NOP();NOP();NOP();NOP();NOP(); //从高拉至低电平,产生写时间隙if(temp==1) DQ_HIGH(); //如果写1,拉高电平delay(2,7); //延时63usDQ_HIGH();NOP();NOP();val=val>>1; //右移一位}}//------------------------------------------------//18b20读字节函数uch read_byte(void){uch i;uch value=0; //读出温度static bit j;for(i=8;i>0;i--){value>>=1;DQ_LOW();NOP();NOP();NOP();NOP(); //6usDQ_HIGH(); //拉至高电平NOP();NOP();NOP(); //4usj=DQ;if(j) value|=0x80;delay(2,7); //63us}return(value);}//-------------------------------------------------//启动温度转换函数void get_temp(){int i;DQ_HIGH();reset(); //复位等待从机应答write_byte(0XCC); //忽略ROM匹配write_byte(0X44); //发送温度转化命令for(i=10;i>0;i--){delay(201,132); //调用多次延迟函数,确保温度转换完成所需要的时间}reset(); //再次复位,等待从机应答write_byte(0XCC); //忽略ROM匹配write_byte(0XBE); //发送读温度命令TLV=read_byte(); //读出温度低8THV=read_byte(); //读出温度高8位DQ_HIGH(); //释放总线TZ=(TLV>>4)|(THV<<4);}3.日历显示程序/*************************************************** * 标题:DS1302读写** 作者:Wujieflash ** 日期:2008年1月14日** 说明:日历显示范围:2000年--2099年****************************************************/ #define RST RC0#define SCLK RC1#define IO RC2uch flag=0;uch second=1,minute=1,hour=1,year=1,month=1,date=1,day=1; uch clock[]={0};uch DisCash[]={0x00,0x30,0x09,0x16,0x01,0x03,0x09};/////往1302写入1Byte数据////////////////////////void RTInputByte(uch d){uch i;TRISC=0x00;for(i=8; i>0; i--){IO = d&0x01; //取最低位SCLK = 1; //上升沿发送SCLK = 0; //恢复d = d >> 1;}}///////从1302读取1Byte数据////////////////////////uch RTOutputByte(void){uch i,val=0;TRISC2=1; //设置为输入for(i=8; i>0; i--){val = val >>1;if(IO)val=val|0x80;// 从最低位开始接收SCLK = 1; //下降沿接收SCLK = 0;}return(val);}///////先写地址,后写命令/数据////////////////////////// void W1302(uch ucAddr, uch ucDa){RST = 0;SCLK = 0;RST = 1; //打开DS1302RTInputByte(ucAddr); // /* 地址,命令*/RTInputByte(ucDa); // /* 写1Byte数据*/SCLK = 1;RST = 0; //关闭DS1302}///////先写地址,后读命令/数据////////////////////////uch R1302(uch ucAddr){uch ucData;RST = 0;SCLK = 0;RST = 1;RTInputByte(ucAddr); // /* 地址,命令*/ucData = RTOutputByte(); // /* 读1Byte数据*/ SCLK = 1;RST = 0;return(ucData);}/////////向1302写入秒分时日月星期年*/////////////void Set1302(uch *pClock){uch i;uch ucAddr = 0x80; //起使地址W1302(0x8e,0x00); ///* 控制命令,WP=0,允许写操作*/ for(i =7; i>0; i--){W1302(ucAddr,*pClock); ///* 秒分时日月星期年*/ pClock++;ucAddr +=2; //写地址加2}W1302(0x8e,0x80); // /* 控制命令,WP=1,写保护*/}////////从1302读出秒分时日月星期年*////////////////// void v_Get1302(unsigned char ucCurtime[]){unsigned char i;unsigned char ucAddr = 0x81;for(i=0;i/////////与LCD的显示接口//////////////////////void display(){uch i;for(i=0;i4.按键扫描与服务程序/*************************************************** * 标题:按键扫描和服务** 作者:Wujieflash ** 日期:2008年1月17日** 说明:当按键按下,选中的单元就会闪烁****************************************************/ uch k=0;//键盘初始化子程序void keyinit(){TRISD0=1;TRISD0=1;TRISD0=1;}/*----------------------------------------------------------*/ //键盘扫描子程序void KeyScan(){int d;if(RD0==0) //设置键按下{k++; //选定入口值k=k%8;}while(1){if(RD0==1)break;//等待按键松开}switch(k)//键盘服务入口{case 1://设置秒{d=R1302(0x81);//读取秒d=d/16*10+d%16;//转换为16进制second=flag; //设置秒的闪烁标志minute=1; //其余变量不闪烁hour=1;year=1;month=1;date=1;day=1;if(second==0) //闪烁{Show8X16_2(0,111,noshu);Show8X16_2(0,119,noshu);}if(RD1==0) //秒数值加1{d++;if(d>0x3b)d=0;//大于59就为0 d=d/10*16+d%10;W1302(0x80,d);//写入DS1302 while(1){if(RD1==1)break;//等待键松开}}if(RD2==0)//数值减1{d--;if(d0x3b)d=0;d=d/10*16+d%10;W1302(0x82,d);while(1){if(RD1==1)break;}}if(RD2==0){d--;if(d0x17)d=0;d=d/10*16+d%10;W1302(0x84,d);while(1){if(RD1==1)break;}}if(RD2==0){d--;if(d0x1f)d=1;d=d/10*16+d%10;W1302(0x86,d); while(1){if(RD1==1)break; }}if(RD2==0){d--;if(d0x0c)d=1;d=d/10*16+d%10; W1302(0x88,d); while(1){if(RD1==1)break; }}if(RD2==0){d--;if(d0x07)d=1;d=d/10*16+d%10; W1302(0x8a,d); while(1){if(RD1==1)break; }}if(RD2==0){d--;if(d0x63)d=0;d=d/10*16+d%10; W1302(0x8c,d); while(1){if(RD1==1)break;}}if(RD2==0){……5.液晶显示程序/**************************************************** 标题:LCD操作** 作者:Wujieflash ** 日期:2008年1月12日** 说明:KS0108系列液晶不带字库****************************************************/#include#define E RA0 //液晶使能端#define RW RA1 //读写控制端#define DI RA2 //数据/指令通道#define CSA RA5 //片选#define CSB RA3 //片选#define nop() asm("nop")////////////////////////基本子函数/////////////////////////延时void delay(char x,char y){char z;do{z=y;do{;}while(--z);}while(--x);}//其指令时间为:7+(3*(Y-1)+7)*(X-1)如果再加上函数调用的call 指令、页面设定、传递参数花掉的7 个指令。
(完整word版)基于PIC16F877A的数字钟设计
电子工程系项目考核(报告)项目名称:数字时钟项目姓名班级学号课程名称一、项目要求:数码管默认显示00:00。
数码管1,2 表示小时,数码管3,4 表示分钟。
如此,实现时钟功能.要求能够整点报时、闹钟提示;并附带有秒表功能。
按键可以调整时钟时间、切换显示页面和设定闹钟时间等。
二、项目原理分析在项目用的单片机开发板上单片机的IO 口接四位数码管的各段。
同时开发板共阴数码管的阴极由138 译码器的输出端控制。
在该项目中我采用了数码管的动态显示,即每位数码管点亮2ms 时间左右,由于人的视觉暂留现象及发光二极管的余辉效应,只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感,动态显示的效果和静态显示是一样的,能够节省大量的I/O 端口,而且功耗更低。
在实现了数码管的动态显示的基础上在主程序中通过计算定时器1的中断次数,从而得到计时时间和秒表时间的基准时间。
同时在主程序中添加按键处理程序,实现时钟的开始、中断和校时,同时实现闹钟定时和切换显示等功能,还有秒表计时功能。
三、硬件电路图以及原理3。
1 硬件电路图如下:3。
2硬件原理:该项目中,主要的功能模块有:数码管显示模块;按键模块;蜂鸣器模块。
数码管显示模块主要是由芯片PIC16F877A内部的定时器1的定时中断实现数码管的动态显示.按键模块主要利用矩阵式按键实现多按键功能,矩阵式按键原理是在一端加高电平,然后检测另一端是否为高电平来判断按键是否按下,通过不同的定义可以让按键实现不同的功能。
蜂鸣器模块通过三极管的开关作用和驱动作用由芯片控鸣叫与否。
四、程序说明以及程序流程图该时钟默认显示页面为时钟计时页面,按键SW1 控制时钟、秒表的开始和中断,按按键SW1一次,如果数码管在显示秒表,则开始计秒功能;否则,开始正常计时;再按一次SW1则实现中断功能.按键SW2实现是数码管的选位,从第一个数码管开始,按一次就选中下一位数码管,循环选择。
SW3实现的是加1功能,每按一次就在SW2选中的位上加1。
PIC16F877A例程---DS18B20
#include <pic.h>#include <pic1687x.h>__CONFIG(0x3F32); //芯片配置字#define LCDRS RB2#define LCDRW RB1#define LCDE RB0#define LCDDA TA PORTD#define DS18B20 RE0#define TRIS_B20 TRISE0void LCD1602_INIT(void);void WRITE_LCD_CMD (char cmd);void WRITE_LCD_DA TA (char data);void LCD_Display(char *s);void LCD_Display_location (char line, char col);void LCD1602_BUSY();void US_delay ( int t);void itoa10(unsigned char *buf, int i);int strlen (const char *s);void DS18B20_INIT();void WRITE_DS18B20_CMD(char cmd);float READ_DS18B20 ();char bank1 DA T_BUFF1[]= "Temperature:";char Found_DS18B20[]="DS1820 FOUND";char DS18B20_NOT_Found[]="DS1820 NOT FOUND"; char bank1 DA T_BUFF2[]= " ";#define CLRLCD 0X01 //清屏命令#define LCDMOD 0X38 //8位,两行,5*7点#define TURNON 0X0F //#define CURMODE 0X06 //#define ORG1 0X80 //LCD 第一行首地址#define ORG2 0XC0 //LCD 第二行首地址#define SKIPROM 0XCC#define READSCRACHPAD 0XBE#define TCONVERT 0X44#define DS18b20_RESET 10#define DSRECOVER 1float temperature;char bank1 atemperature[10]; // used for store ascii code of digital temperature */void main(){int len;ADCON1=0X07;LCD1602_INIT();LCD_Display(DA T_BUFF1);LCDE=0;LCD_Display_location (1,0);while (1){DS18B20_INIT();WRITE_DS18B20_CMD(SKIPROM);WRITE_DS18B20_CMD(TCONVERT);TRIS_B20=0;DS18B20=0;TRIS_B20=1;while(1){ //判断转换是否完成if (DS18B20) break;else continue;}DS18B20_INIT();WRITE_DS18B20_CMD(SKIPROM);WRITE_DS18B20_CMD(READSCRACHPAD);temperature=READ_DS18B20();itoa10(atemperature, (int) (temperature * 10));// so use temperature * 10 to enlarge the temperature len=strlen(atemperature);atemperature[len]=atemperature[len-1];atemperature[len-1]='.';atemperature[len+1]=0;LCD_Display_location (0,0);LCD_Display (DA T_BUFF1); //LCD第一行显示Tempereture: 字符LCD_Display_location (1,0);LCD_Display (DA T_BUFF2);LCD_Display_location (1,2);LCD_Display (atemperature); //LCD第二行显示当前温度值LCD_Display (DA T_BUFF2);US_delay(5000); //每隔0.5秒读取一次温度值}}int strlen(const char * s){const char *cp;cp = s;while(*cp++)continue;return cp-s-1;}void LCD_Display(char *s){int len;int atmp;len=strlen(s);for (atmp=0; atmp<len; atmp++)WRITE_LCD_DA TA(s[atmp]);}void LCD1602_BUSY(){// char tmpbusy;TRISB &= 0xF8;TRISD=0XFF;LCDRS=0;LCDRW=1;LCDE=1;while(LCDDA TA & 0X80);}void LCD_Display_location (char line, char col){char pos;LCD1602_BUSY();pos = line * 0X40 + 0X80 + col;WRITE_LCD_CMD(pos);}void WRITE_LCD_DA TA(char data) {LCD1602_BUSY();TRISB & =0XF8;TRISD=0;LCDDA TA=data;LCDRS=1;LCDRW=0;LCDE=0;asm("NOP");asm("NOP");LCDE=1;}void WRITE_LCD_CMD(char cmd) {LCD1602_BUSY();TRISB & =0XF8;TRISD=0;LCDDA TA=cmd;LCDRS=0;LCDRW=0;LCDE=0;asm("NOP");asm("NOP");LCDE=1;}void LCD1602_INIT(void){LCD1602_BUSY();TRISB &= 0XF8;TRISD=0;WRITE_LCD_CMD(CLRLCD);WRITE_LCD_CMD(LCDMOD);WRITE_LCD_CMD(TURNON);WRITE_LCD_CMD(CURMODE);LCD_Display_location (0,0);}void DS18B20_INIT(){TRIS_B20=0;DS18B20=0;US_delay(20);TRIS_B20=1;US_delay(10);}void WRITE_DS18B20_CMD(char cmd) {char tmp;char i;TRIS_B20=0;for(tmp=8;tmp>0;tmp--){TRIS_B20=0;DS18B20= 0;asm ("NOP");asm ("NOP");asm ("NOP");asm ("NOP");asm ("NOP");if (cmd & 0x01){TRIS_B20=1;US_delay(1);for (i=5;i>0;i--);}else{DS18B20=0 ;US_delay(1);for (i=5;i>0;i--);TRIS_B20=1;}cmd=cmd/2;}}float READ_DS18B20 (){char tmp=0x01;float t;union{char c[2];int x;}temp;temp.x=0;while (tmp){ // read first 8 bitsTRIS_B20=0;DS18B20=0;asm("NOP");TRIS_B20=1;if (DS18B20)temp.c[0] |= tmp;tmp=tmp<<1;US_delay(2);}tmp=1;while (tmp){ // read first 8 bitsTRIS_B20=0;DS18B20=0;asm("NOP");TRIS_B20=1; // release the busasm("NOP");if (DS18B20) // "1" presentedtemp.c[1] |= tmp;tmp=tmp<<1;US_delay(2);}t=((float) temp.x)/16.0 ;return t;}void itoa10(unsigned char *buf, int i){unsigned int rem;unsigned char *s,length=0;s = buf;if (i == 0)*s++ = '0';else{if (i < 0){*buf++ = '-';s = buf;i = -i;}while (i){++length;rem = i % 10;*s++ = rem + '0';i /= 10;}for(rem=0; ((unsigned char)rem)<length/2; rem++){*(buf+length) = *(buf+((unsigned char)rem));*(buf+((unsigned char)rem)) = *(buf+(length-((unsigned char)rem)-1));*(buf+(length-((unsigned char)rem)-1)) = *(buf+length);}}*s=0;}void US_delay( int i){unsigned char j;while(i--){j=3;while(j--);}}。
lcd1602_pic16f877a_程序_代码
uint i;
uchar j;
for(i=0;i<2;i++)
{
j&=0x00;
j|=(dat&0xf0);
PORT=j;
PORT&=0x0f;//清高四位
PORT|=(dat&0xf0);//写高四位
if(x==1)
RS=1;
else
RS=0;
delay(3);
EN=1;
delay(3);
EN=0;
lcd_write(0x01,0);//显示清零,数据指针d location(uint x,uint y)
{
if(x==1)
{
lcd_write(0x80+y,0);
}
if(x==2)
{
lcd_write(0xc0+y,0);
}
}
void lcd_prins(uint x,uint y,uint z)//这里不能用uchar z,否则当z=6578,即四位或五位数时,放不下而导致出错
//lcd_single_prins(uint x,uint y,uint z);
////
//2013,01,07 //
/***********************************************/
#define uchar unsigned char
#define uint unsigned int
void delay(uint x);
void lcd_write(uchar dat,uchar x);
//延时函数
void delay(uint x)
{
基于PIC16F877A单片机的车控系统
基于PIC16F877A单片机的车控系统标题1:单片机车控系统的设计及实现单片机车控系统是一种能够给车辆进行智能化控制的系统,它可以提高车辆的安全性和驾驶体验。
本论文主要研究了基于PIC16F877A单片机的车控系统的设计和实现方法。
通过对系统的硬件和软件进行详细的分析和研究,最终成功实现了一个完整的车控系统,并进行了实验和测试。
在实验和测试的过程中,发现该车控系统具有良好的控制性能和可靠性,能够满足实际应用的需要。
标题2:PIC16F877A单片机的基础知识和应用PIC16F877A单片机是一种常用的微控制器,具有广泛的应用领域。
在本论文中,我们系统地介绍了PIC16F877A单片机的基础知识、内部结构和应用技巧。
通过对单片机进行程序设计、调试和测试,我们总结出了一些经验和技巧,可以提高单片机的运行效率和稳定性。
此外,我们还对PIC16F877A的特性进行了分析和评估,提出了一些改进和优化方案,以适应不同的应用环境。
标题3:车用电子控制系统的原理和设计车用电子控制系统是指在汽车中使用的一种综合的控制系统,它通过电子芯片和软件程序来实现对车辆的各种控制和管理。
在本论文中,我们对车用电子控制系统做了详细的介绍,包括其原理、组成和应用技巧。
在讲述原理和设计过程中,我们着重讲述了电控系统的稳定性、可靠性和安全性问题,并提出了解决方案。
标题4:车载环境监测传感器的设计及应用车载环境监测传感器是在车辆中采集环境数据的一种装置。
它可以采集温度、湿度、气体、震动等多种信息,并对车辆进行实时监测和处理。
在本论文中,我们对车载环境监测传感器的设计和应用进行了研究和测试。
通过对传感器的硬件和软件进行设计和编程,我们成功地实现了对车载环境数据的采集和分析,并进行了实际应用的调试和测试。
标题5:无线通信技术在车控系统中的应用无线通信技术是一种广泛应用于车辆控制系统中的技术,它可以实现车辆与外部环境的实时信息交换和控制。
PIC16F877A 单片机为控制核心语音小车
PIC16F877A 单片机为控制核心,用语音识别芯片RSC-364、射频发送模块F05C 、编码芯片PT2262 组成语音无线遥控器(用于对控制指令的采集);采用射频接收模块J05C 和解码芯片PT2272 组成无线接收模块(用于对控制指令的接收);采用三节干电池串联(约4.5V)的方式对系统供电的语音控制小车。
经试验证实小车能实现语音无线控制,根据事先录制的语音指令能够实现前进、退后和左右转。
通过自制的编码盘小车还附加有测速及路程显示功能。
经测试,小车反应灵敏,运行稳定。
关键词:语音控制;PIC16F877A;RSC -364;测速显示0 引言随着现代科技的发展,仪器产品的智能化已经是一个不可避免的趋势。
智能仪器在一些特殊的场合,它可以按照预先设定的模式在一个环境里自动的运作,基本不需要人为的管理。
本文设计的语音控制智能小车,就是这样的一种装置。
小车以PIC16F877A 单片机为控制核心,加上语音识别芯片RSC-364、射频发送模块F05C 、编码芯片PT2262 组成语音无线遥控器,并且采用射频接收模块J05C 和解码芯片PT2272 组成无线接收模块,实现小车和控制者的互动,小车能根据命令实现前进、后退和左右转等动作。
通过外围电路又可以实现自动测速并显示等功能。
1 小车整体框架及原理本设计语音控制小车系统主要由PIC16F877A 为核心的车载控器部分、遥控器携带语音控制部分两大控制单元和车体部分组成小车硬件控制系统结构示意图如下:图1 控制系统结构示意图1.1 车载控制单元车载控制部分包括无线接收电路(由射频接收模块J05C 和解码芯片PT2272 组成) 、车载主控芯片电路、电机驱动电路及测速显示电路。
工作流程:接收遥控器发出的无线电信号,解码后送入车载主控芯片,经过计算产生相应的控制信号,驱动两个电机工作,使小车产生预期的动作。
本设计使用了两个电机控制小车的动作,具体在驱动部分讲述。
如何利用PIC16F877A单片机读写AT24C系列储存器
如何利用PIC16F877A单片机读写AT24C系列储存器
AT24C系列在增强型PIC实验板上编程的硬件原理图如下图所示,U7为实验板上24C02芯片,SDA与单片机的RB5口相连,SCL与单片机RB4相连,七段数码管D5、D7、D8组成了显示单元,字形码的数据通过RC口送入,各数码管的显示片选信号分别不同的RA口进行控制。
在MPLab IDE软件中新建工程,加入源程序代码,同时进行芯片型号的选择和配置位的设置,我们实验所用的芯片型号为PIC16F877A。
编写的程序代码如下,其中程序流程图如下图所示。
软件代码
编好程序后将编译好的HEX码通过ICD2仿真烧写器烧入单片机芯片,上电运行,主程序中在O×01地址写入了“O×55”,在O×02地址写入了“O×aa”,然后在while循环中读出O×02地址的值,也就是我们之前写入的“O×55”,读出后显示在数码管上,我们可以看到数码管显示“170”,即“O×aa”相应的十进制数。
PIC16F877A数字时钟时钟程序
;Digit clock;-----------------------------------------------;DA TE :20101205;Author:Tang HS;M C U :PIC16F877A;FileName : ClockPIC.ASM;-----------------------------------------------------------;Date: {2010/12/07.14:35}-V er01--CS-ICD:0xAFCE---ISP:0xb7ce----;功能: 1.LED显示:时分秒;格式:[ hh mm ss ] 备注:按键未定义;------------------------------------------------------------;-----------------------------------------------------------;Date: {2010/12/07.22:15}-V er01--CS-ICD:0xAFCE---ISP:0xb7ce----;功能: 1.LED显示:时分秒;格式:[ hh mm ss ] 备注:按键未定义; 2.RB0-SET_KEY;RB1-ADD_KEY;RB2-SUB_KEY;RB3-EXIT_KEY;------------------------------------------------------------;Date: {2010/12/09.18:06}-V er02--CS-ICD:0xAFCE---ISP:0xef0e----;************************************************************;Date: {2010/12/10.00:47}-V er03--CS-ICD:0xb08d---ISP:0xfaa7----;功能: 1.LED显示:时分秒;格式:[ hh mm ss ] 备注:按键未定义; 2.RB0-SET_KEY;RB1-ADD_KEY;RB2-SUB_KEY;RB3-EXIT_KEY 都OK ; 3.MOVLW 纠正MOVV REG,1 引起的SUB_不良;;--------------------------------------------------------------;Date: {2010/12/10.13:10}-V er03.1--CS-ICD:0xb08b---ISP:0xfaa4----; 4.时差。
PIC16F877A-SPI-TC77(温度传感器)
PIC16F877A-SPI-TC77(温度传感器)---------------------------------借鉴,TCK(0-1024℃)分辨率:0.25℃TC77:分辨率0.0625℃#include#define CS RC2void initPORT();void initMSSP();void delay(unsigned char time);void display(float data);float ReadTC77();const unsigned chardisp[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};void main(){float temp;initPORT();initMSSP();while(1){temp=ReadTC77();display(temp);}}/*初始化PIC 单片机端口*/void initPORT(){TRISB=0x00; //控制段选PORTB=0x00;TRISC=0xf0; //与温度传感器连接PORTC=0x00;TRISA=0x00; //控制位选PORTA=0xff;}/*初始化MSSP 模块的SPI 模式*/void initMSSP() {SSPSTAT=0x00;SSPCON=0x30;SSPIF=0;}/*读取温度传感器的13 位数值并且转换成浮点类型*/float ReadTC77(){float result,PowerTwo=1;unsigned char count,HighByte,LowByte;CS=0;SSPBUF=0;while(!SSPIF){}HighByte=SSPBUF; //获取温度寄存器的高字节SSPIF=0;SSPBUF=0;while(!SSPIF){}LowByte=SSPBUF; //获取温度寄存器的低字节SSPIF=0;CS=1;for(count=0;count>count))result+=PowerTwo;PowerTwo=PowerTwo/2.; //注意,不能换成.2,否则会出错} return result; //返回转换浮点结果}/*液晶显示*/void display(float data){unsignedintconver,First,Second,Third,Fourth;conver=data*100;First=conver/1000;Second=conv er/100%10;Third=conver/10%10;Fourth=conver%10;PORTA=0xfe; //显示十位PORTB=disp[First];delay(2);PORTB=0x00;PORTA=0xfd; //显示个位。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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
RCIF ×
RCIE
TXIF ×
TXIE
BCLIF ×
BCLIE
PSPIF ×
PSPIE
GIE控制所只有有的在中SL断E源EP状 态下能运行的模块
PEIE控制了12个中断源 产生中断才能唤醒 SLEEP。
与门:只有所有的输入为1,输出才为1 或门:只要有一个输入为1,输出就为1
中断逻辑示意图
中断控制寄存器:INTCON 相应使能位为1,允许中断;为0,禁止中断。 相应标志位为1,表示有中断发生,必须用软件清0。
➢ 所有的I/O端口,上电复位默认值均为1,即为输 入口。
➢ 每个IO引脚的最大输出电流(拉电流)为20mA, 最大输入电流(灌电流)为25mA。
➢ 端口A、B、E的最大输入电流总和与输出电流总和 均为200mA;
➢ 端口C、D的最大输入电流总和与输出电流总和也 为200mA。
➢ 对I/O 端口的写操作是一个读-修改-写的过程。
4.10 SLEEP工作方式
结束
4.1 输入输出端口
➢ 877A有33根IO引脚。有A、B、C、D、E共5个端口, 其中A端口的有6个引脚,B、C、D口各8个引脚, E口3个引脚。
➢ 各自端口的方向控制寄存器TRISA、TRISB、TRISC、 TRISD、TRISE,控制其相应的端口是作为输出还 是输入。0:输出;1:输入
➢ 一条写IO引脚的指令如RB3=1,实际上是在指令的 开头读入整个B端口,并在指令周期的末尾时刻把 1写入RB端口3的输出锁存器。 如果立即对同一端口操作,如x=PORTB,在指令 周期的开始处,由于前一指令产生在IO口的电平 尚未稳定,读入的可能是引脚的前一个状态而不 是新状态值。
因此连续对同一端口的操作时,最好用一个NOP 指令或者其他不访问该I/O 端口的指令隔开。
当RB4~RB7引脚做为输入时,只要有一个引脚 的逻辑电平发生变化,就会使RB电平中断标志位 置1。这些功能的设置,与OPTION、INTCON有关, 参见相关各章节。
4.1.3 端口C
RC0/T1OSO/T1CKI:IO引脚、TMR1振荡输出、TMR1外部 脉冲输入;
RC1/T1OSI/CCP2:IO引脚、TMR1振荡输入、CCP2; RC2/CCP1:IO引脚、CCP1; RC3/SCK/SCL:IO引脚、SPI的时钟线、I2C的时钟线; RC4/SDI/SDA:IO引脚、SPI的数据输入、I2C的数据线; RC5/SDO:IO引脚、SPI的数据输出; RC6/TX/CK:IO引脚、异步串行通信的发送、同步串行通
➢ 中断返回:程序执行到”RETFIE”时,按照后入先 出的原则,自动从堆栈中弹出地址给PC,GIE=1, 程序返回到中断前要执行的程序,程序恢复中断
前程序的运行状态。
PIC16F877A有15个中断源,每个中断源都有自 己的使能控制位(IE)和中断标志位(IF)。
EEIF EEIE SSPIF SSPIE
第四章
PIC16F877A 功能及其编程
制作:王骞
2015.9
4.1 输入输出端口
4.2 中断
4.3 定时/计数器TMR0
4.4 定时/计数器TMR1
4.5 定时/计数器TMR2
4.6 A/D转换器
4.7 CCP模块(Capture/Compare/PWM)
4.8 异步串行通信(USART)
4.9 EEPROM的读写
×
× CCP1IF ×
CCP1IE
CCP2IF ×
CCP2IE
TMR1IF ×
TMR1IE
TMR2IF ×
TMR2IE
PSPIF ×
PSPIE
T0IF ×
T0IE
INTF ×
INTE
RBIF ×
RBIE
+ PEIE ×
唤醒CPU (如果当前处于睡眠模式)
+ GIE
×
中断CPU 当前的程序
ADIF ×
RE1/WR/AN6:IO引脚、Байду номын сангаас行从动口的写控制、 模拟电压输入通道AN6;
RE2/CS/AN7:IO引脚、并行从动口的片选控制、 模拟电压输入通道AN7。
返回目录
4.2 中断
➢ 中断的概念:正常程序运行时发生了事先设定的 事件,需要暂停原来运行的程序而转到处理目前 需要马上处理的事件。
4.1.2 端口B
1、端口B有8个引脚: RB0/INT:IO引脚、INT中断; RB1、RB2、RB4、RB5:IO引脚; RB3/PGM:IO引脚、低电压编程电压引脚; RB6/PGC:IO引脚、编程时钟线; RB7/PGD:IO引脚、编程数据线。 2、如果使用PIC KIT3作为调试工具,RB6、RB7引脚