PIC16F877A之定时TMR0
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
基于PIC16F877A单片机的温度,时间显示
基于PIC16F877A单片机的温度,时间显示以及闹钟设置,硬件和软件配备一,硬件图#include<pic.h>__CONFIG(0x3B31);#define rs RD0#define rw RD1#define en RD2#define BEEP RD3 #define s1 RA0#define s2 RA1#define s3 RA2#define s4 RA3#define uint unsigned int#define uchar unsigned charsigned char set_time[7]={0,58,23,6,1,5,12};//秒分时星期日月年signed char read_time[7]={0,0,0,0,0,0,0};signed char shi=7,fen=15,alarm_time=1,reapeat_fen=2,cent;//闹钟时,闹钟分,闹铃响分钟,闹铃响间隔uchar s1_num,s2_num;const uchar alarm[]={"ALARM TIME:"};const uchar mode[]={"MODE:"};const uchar rpt[]={"RPT:"};const uchar min[]={"min"};void PORT_INIT(){TRISA=0xff;//A口设置为输入ADCON1=0x06;//RA口上电复位为模拟输入口TRISC3=1;//SCL和SDA设置为输入TRISC4=1;TRISD=0x00;//D口设置为输出}void IIC_INIT(){SSPCON=0x28;STAT_SMP=0;SSPADD=4;}void delayms(uint z)//延时函数{uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void delayus(uint k){while(k--);}void write_byte_low(uchar R1,uchar flag0)//写一个字节的低4位,flag0为指令/数据选择位{ //,0为写指令,1为写数据uchar low;rs=flag0;low=R1&0x0f;low=low<<4;PORTD&=0x0f;NOP();PORTD|=low;NOP();//写指令的低4位en=1;delayus(20);en=0;}void lcd_write(uchar dat,uchar flag1)//写指令/数据到1602{uchar dat_high,dat_low;dat_high=dat>>4;write_byte_low(dat_high,flag1);dat_low=dat&0x0f;write_byte_low(dat_low,flag1);NOP();}void write_string(uchar address,uchar const *str)//往指定的地址写字符串{uchar i=0;lcd_write(address,0);while(str[i]!='\0'){lcd_write(str[i],1);delayus(5);i++;}}void LCD_INIT()//初始化函数{rw=0;en=0;delayms(20);write_byte_low(0b0011,0);delayms(1);write_byte_low(0b0011,0);delayus(10);write_byte_low(0b0011,0);delayus(10);write_byte_low(0b0010,0);delayms(1);lcd_write(0x28,0);delayms(5);lcd_write(0x0c,0);delayms(5);lcd_write(0x01,0);delayms(5);lcd_write(0x06,0);delayms(5);}void naoling(){uchar i;for(i=0;i<20;i++){BEEP=1;delayus(5);BEEP=0;delayus(5);}}void IIC_SEND(uchar num){SSPBUF=num;while(STAT_RW==1);//等待发送结束while(SSPIF==0);while(ACKSTAT==1);//等待应答}signed char read_temp()//读温度{signed char temp;SEN=1;while(SEN==1);IIC_SEND(0b10011010);IIC_SEND(0);RSEN=1;while(RSEN==1);IIC_SEND(0b10011011);RCEN=1;while(RCEN==1);// SSPIF=0;// while(SSPIF==0);//等待接收结束temp=SSPBUF;PEN=1;while(PEN==1);return temp;}void dispose()//BCD数据处理{uchar i,temp1,temp2;for(i=0;i<7;i++){temp1=set_time[i]/10;temp2=set_time[i]%10;set_time[i]=temp1*16+temp2;}}void time_csh()//时间初始化{uchar i;dispose();for(i=0;i<7;i++){SEN=1;//起始信号while(SEN==1);//检测起始信号是否已完成IIC_SEND(0xd0);IIC_SEND(i);IIC_SEND(set_time[i]);PEN=1;//停止信号while(PEN==1);}}void read_ds1307()//读时间{uchar k;for(k=0;k<8;k++){SEN=1;//起始信号while(SEN==1);IIC_SEND(0xd0);IIC_SEND(k);PEN=1;//停止信号while(PEN==1);RSEN=1;//重新启动while(RSEN==1);IIC_SEND(0xd1);SSPIF=0;RCEN=1;while(SSPIF==0);//等待接收结束read_time[k-1]=SSPBUF;NOP();NOP();PEN=1;//停止信号while(PEN==1);}}void display_time(){lcd_write(0x80,0);lcd_write(0x32,1);lcd_write(0x30,1);lcd_write(0x30+read_time[6]/16,1);//年lcd_write(0x30+read_time[6]%16,1);lcd_write('-',1);lcd_write(0x30+read_time[5]/16,1);//月lcd_write(0x30+read_time[5]%16,1);lcd_write('-',1);lcd_write(0x30+read_time[4]/16,1);//日lcd_write(0x30+read_time[4]%16,1);lcd_write(0x80+0x0d,0);switch(read_time[3]){case 1:lcd_write('M',1);lcd_write('O',1);lcd_write('N',1);break;case 2:lcd_write('T',1);lcd_write('U',1);lcd_write('E',1);break;case 3:lcd_write('W',1);lcd_write('E',1);lcd_write('D',1);break;case 4:lcd_write('T',1);lcd_write('H',1);lcd_write('U',1);break;case 5:lcd_write('F',1);lcd_write('R',1);lcd_write('I',1);break;case 6:lcd_write('S',1);lcd_write('A',1);lcd_write('T',1);break;case 7:lcd_write('S',1);lcd_write('U',1);lcd_write('N',1);break;lcd_write(0x80+0x40,0);lcd_write(0x30+read_time[2]/16,1);//时lcd_write(0x30+read_time[2]%16,1);lcd_write(':',1);lcd_write(0x30+read_time[1]/16,1); //分lcd_write(0x30+read_time[1]%16,1);lcd_write(':',1);lcd_write(0x30+read_time[0]/16,1); //秒lcd_write(0x30+read_time[0]%16,1);NOP();NOP();cent=read_temp();lcd_write(0x80+0x4b,0);lcd_write(0x30+cent/10,1);lcd_write(0x30+cent%10,1);lcd_write(0xdf,1);lcd_write('C',1);if((shi==(read_time[2]/16*10+read_time[2]%16))&&(fen<=(read_ti me[1]/16*10+read_time[1]%16))&&((read_time[1]/16*10+read_time[1] %16)<(fen+alarm_time)))naoling();}if((shi==(read_time[2]/16*10+read_time[2]%16))&&(fen+reapeat_fe n<=(read_time[1]/16*10+read_time[1]%16))&&((read_time[1]/16*10+re ad_time[1]%16)<(fen+alarm_time+reapeat_fen))){naoling();}if((shi==(read_time[2]/16*10+read_time[2]%16))&&(fen+2*reapeat _fen<=(read_time[1]/16*10+read_time[1]%16))&&((read_time[1]/16*10 +read_time[1]%16)<(fen+alarm_time+2*reapeat_fen))){naoling();}if((shi==(read_time[2]/16*10+read_time[2]%16))&&(fen+3*reapeat _fen<=(read_time[1]/16*10+read_time[1]%16))&&((read_time[1]/16*10 +read_time[1]%16)<(fen+alarm_time+3*reapeat_fen))){naoling();}if((shi==(read_time[2]/16*10+read_time[2]%16))&&(fen+4*reapeat_fen<=(read_time[1]/16*10+read_time[1]%16))&&((read_time[1]/16*10 +read_time[1]%16)<(fen+alarm_time+4*reapeat_fen))){naoling();}}void setting_time(){uchar l,s2_value,setting_flag;if(s2==0){delayms(10);if(s2==0){s2_value++;setting_flag = 1;while(s2==0);//松手检测for(l=0;l<7;l++)//存储当前时间数据//年星期月日时分秒{set_time[l]=read_time[l]/16*10+read_time[l]%16;}while(setting_flag){if(s2==0){delayms(5);if(s2==0){s2_value++;while(s2==0);//松手检测}}if(s2_value==1){lcd_write(0x83,0);//指向年份lcd_write(0x0f,0);//显示游标并闪烁if(s3==0){delayms(5);if(s3==0){set_time[6]++;if(set_time[6]==100){set_time[6]=0;}lcd_write(0x82,0);lcd_write(0x30+set_time[6]/10,1);lcd_write(0x30+set_time[6]%10,1);lcd_write(0x83,0);//指向年份while(s3==0);}}if(s4==0){delayms(5);{set_time[6]--;if(set_time[6]==-1){set_time[6]=99;}lcd_write(0x82,0);lcd_write(0x30+set_time[6]/10,1);lcd_write(0x30+set_time[6]%10,1);lcd_write(0x83,0);//指向年份while(s4==0);}}}if(s2_value==2){lcd_write(0x86,0);//指向月份if(s3==0){delayms(5);{set_time[5]++;if(set_time[5]==13){set_time[5]=1;}lcd_write(0x85,0);lcd_write(0x30+set_time[5]/10,1);lcd_write(0x30+set_time[5]%10,1);lcd_write(0x86,0);//指向月份while(s3==0);}}if(s4==0){delayms(5);if(s4==0){set_time[5]--;{set_time[5]=12;}lcd_write(0x85,0);lcd_write(0x30+set_time[5]/10,1);lcd_write(0x30+set_time[5]%10,1);lcd_write(0x86,0);//指向月份while(s4==0);}}}if(s2_value==3){lcd_write(0x89,0);//指向日if(s3==0){delayms(5);if(s3==0){set_time[4]++;{set_time[4]=1;}lcd_write(0x88,0);lcd_write(0x30+set_time[4]/10,1);lcd_write(0x30+set_time[4]%10,1);lcd_write(0x89,0);//指向日while(s3==0);}}if(s4==0){delayms(5);if(s4==0){set_time[4]--;if(set_time[4]==0){set_time[4]=31;lcd_write(0x88,0);lcd_write(0x30+set_time[4]/10,1);lcd_write(0x30+set_time[4]%10,1);lcd_write(0x89,0);//指向日while(s4==0);}}}if(s2_value==4){lcd_write(0x8f,0);//指向星期if(s3==0){delayms(5);if(s3==0){set_time[3]++;if(set_time[3]==8)set_time[3]=1;}switch(set_time[3]){case1:lcd_write(0x8d,0);lcd_write('M',1);lcd_write('O',1);lcd_write('N',1);bre ak;case2:lcd_write(0x8d,0);lcd_write('T',1);lcd_write('U',1);lcd_write('E',1);brea k;case3:lcd_write(0x8d,0);lcd_write('W',1);lcd_write('E',1);lcd_write('D',1);bre ak;case4:lcd_write(0x8d,0);lcd_write('T',1);lcd_write('H',1);lcd_write('U',1);brea k;case5:lcd_write(0x8d,0);lcd_write('F',1);lcd_write('R',1);lcd_write('I',1);break ;case6:lcd_write(0x8d,0);lcd_write('S',1);lcd_write('A',1);lcd_write('T',1);break;case7:lcd_write(0x8d,0);lcd_write('S',1);lcd_write('U',1);lcd_write('N',1);brea k;}lcd_write(0x8f,0);//指向星期while(s3==0);}}if(s4==0){delayms(5);if(s4==0){set_time[3]--;if(set_time[3]==0){set_time[3]=7;}switch(set_time[3])case1:lcd_write(0x8d,0);lcd_write('M',1);lcd_write('O',1);lcd_write('N',1);bre ak;case2:lcd_write(0x8d,0);lcd_write('T',1);lcd_write('U',1);lcd_write('E',1);brea k;case3:lcd_write(0x8d,0);lcd_write('W',1);lcd_write('E',1);lcd_write('D',1);bre ak;case4:lcd_write(0x8d,0);lcd_write('T',1);lcd_write('H',1);lcd_write('U',1);brea k;case5:lcd_write(0x8d,0);lcd_write('F',1);lcd_write('R',1);lcd_write('I',1);break ;case6:lcd_write(0x8d,0);lcd_write('S',1);lcd_write('A',1);lcd_write('T',1);brea k;case7:lcd_write(0x8d,0);lcd_write('S',1);lcd_write('U',1);lcd_write('N',1);brea k;lcd_write(0x8f,0);//指向星期while(s4==0);}}}if(s2_value==5){lcd_write(0x80+0x41,0);//指向小时if(s3==0){delayms(5);if(s3==0){set_time[2]++;if(set_time[2]==24){set_time[2]=0;}lcd_write(0x80+0x40,0);lcd_write(0x30+set_time[2]/10,1);lcd_write(0x30+set_time[2]%10,1);lcd_write(0x80+0x41,0);//指向小时while(s3==0);}}if(s4==0){delayms(5);if(s4==0){set_time[2]--;if(set_time[2]==-1){set_time[2]=23;}lcd_write(0x80+0x40,0);lcd_write(0x30+set_time[2]/10,1);lcd_write(0x30+set_time[2]%10,1);lcd_write(0x80+0x41,0);//指向小时while(s4==0);}}}if(s2_value==6){lcd_write(0x80+0x44,0);//指向分钟if(s3==0){delayms(5);if(s3==0){set_time[1]++;if(set_time[1]==60){set_time[1]=0;}lcd_write(0x80+0x43,0);lcd_write(0x30+set_time[1]/10,1);lcd_write(0x30+set_time[1]%10,1);lcd_write(0x80+0x44,0);//指向分钟while(s3==0);}}if(s4==0){delayms(5);if(s4==0){set_time[1]--;if(set_time[1]==-1){set_time[1]=59;}lcd_write(0x80+0x43,0);lcd_write(0x30+set_time[1]/10,1);lcd_write(0x30+set_time[1]%10,1);lcd_write(0x80+0x44,0);//指向分钟while(s4==0);}}}if(s2_value==7){lcd_write(0x80+0x47,0);//指向秒if(s3==0){delayms(5);if(s3==0){set_time[0]++;if(set_time[0]==60){set_time[0]=0;}lcd_write(0x80+0x46,0);lcd_write(0x30+set_time[0]/10,1);lcd_write(0x30+set_time[0]%10,1);lcd_write(0x80+0x47,0);//指向分钟while(s3==0);}}if(s4==0){delayms(5);if(s4==0){set_time[0]--;if(set_time[0]==-1){set_time[0]=59;}lcd_write(0x80+0x46,0);lcd_write(0x30+set_time[0]/10,1);lcd_write(0x30+set_time[0]%10,1);lcd_write(0x80+0x47,0);//指向分钟while(s4==0);}}}if(s2_value==8)//这里注意?{s2_value=0;lcd_write(0x0c,0);setting_flag=0;time_csh();}}}}}void naozhong(){write_string(0x80,alarm);lcd_write(0x30+shi/10,1);lcd_write(0x30+shi%10,1);lcd_write('-',1);lcd_write(0x30+fen/10,1);lcd_write(0x30+fen%10,1);write_string(0x80+0x40,mode);lcd_write(0x30+alarm_time,1);write_string(0x80+0x47,rpt);lcd_write(0x30+reapeat_fen/10,1);lcd_write(0x30+reapeat_fen%10,1);write_string(0x80+0x4d,min);}uchar s1_scan(){if(s1==0){delayms(5);if(s1==0){s1_num++;if(s1_num==2){s1_num=0;s2_num=0;lcd_write(0x0c,0);}while(s1==0);lcd_write(0x01,0);if(s1_num==1){naozhong();lcd_write(0x0f,0);}}}return s1_num;}void setting_naozhong(){if(s2==0){delayms(5);if(s2==0){s2_num++;if(s2_num==4){s2_num=0;}while(s2==0);}}switch(s2_num){case 0:{lcd_write(0x8c,0);if(s3==0){delayms(5);if(s3==0){shi++;if(shi==24){shi=0;}lcd_write(0x8b,0);lcd_write(0x30+shi/10,1);lcd_write(0x30+shi%10,1);lcd_write(0x8c,0);//指向小时while(s3==0);}}if(s4==0){delayms(5);if(s4==0){shi--;if(shi==-1){shi=23;}lcd_write(0x8b,0);lcd_write(0x30+shi/10,1);lcd_write(0x30+shi%10,1);lcd_write(0x8c,0);//指向小时while(s4==0);}}break;}case 1:{lcd_write(0x8f,0);if(s3==0){delayms(5);if(s3==0){fen++;if(fen==60){fen=0;}lcd_write(0x8e,0);lcd_write(0x30+fen/10,1);lcd_write(0x30+fen%10,1);lcd_write(0x8f,0);//指向小时while(s3==0);}}if(s4==0){delayms(5);if(s4==0){fen--;if(fen==-1){fen=59;}lcd_write(0x8e,0);lcd_write(0x30+fen/10,1);lcd_write(0x30+fen%10,1);lcd_write(0x8f,0);//指向小时while(s4==0);}}break;}case 2:{lcd_write(0x80+0x45,0);if(s3==0){delayms(5);if(s3==0){alarm_time++;if(alarm_time==10){alarm_time=1;}lcd_write(0x30+alarm_time,1);lcd_write(0x80+0x45,0);//指向小时while(s3==0);}}if(s4==0){delayms(5);if(s4==0){alarm_time--;if(alarm_time==0){alarm_time=9;}lcd_write(0x30+alarm_time,1);lcd_write(0x80+0x45,0);//指向小时while(s4==0);}}break;}case 3:{lcd_write(0x80+0x4c,0);if(s3==0){delayms(5);if(s3==0){reapeat_fen++;if(reapeat_fen==60){reapeat_fen=0;}lcd_write(0x80+0x4b,0);lcd_write(0x30+reapeat_fen/10,1);lcd_write(0x30+reapeat_fen%10,1);lcd_write(0x80+0x4c,0);//指向小时while(s3==0);}}if(s4==0){delayms(5);if(s4==0){reapeat_fen--;if(reapeat_fen==-1){reapeat_fen=59;}lcd_write(0x80+0x4b,0);lcd_write(0x30+reapeat_fen/10,1);lcd_write(0x30+reapeat_fen%10,1);lcd_write(0x80+0x4c,0);//指向小时while(s4==0);}}break;}default:break;}}void main(){PORT_INIT();LCD_INIT();IIC_INIT();time_csh();while(1){switch(s1_scan()){case 0:read_ds1307();display_time();setting_time();break;case 1:setting_naozhong();break;default:break;}} }。
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头文件中文注释
#ifndef _HTC_H_#warning Header file pic168xa.h included directly. Use #include <htc.h> instead. #endif/** Microchip单片机的头文件* PIC 16F873A chip* PIC 16F874A chip* PIC 16F876A chip* PIC 16F877A chip* 中档单片机*/#if defined(_16F874A) || defined(_16F877A)#define __PINS_40#endifvolatile unsigned char INDF @ 0x00;//间接寻址寄存器volatile unsigned char TMR0 @ 0x01;//定时器0volatile unsigned char PCL @ 0x02;//低8位程序计数器volatile unsigned char STATUS @ 0x03;//程序状态寄存器volatile unsigned char FSR @ 0x04;//特殊功能寄存器volatile unsigned char PORTA @ 0x05;//端口A寄存器volatile unsigned char PORTB @ 0x06;//端口B寄存器volatile unsigned char PORTC @ 0x07;//端口C寄存器#ifdef __PINS_40volatile unsigned char PORTD @ 0x08;//端口D寄存器volatile unsigned char PORTE @ 0x09;//端口E寄存器#endifvolatile unsigned char PCLATH @ 0x0A;//高5位程序计数器volatile unsigned char INTCON @ 0x0B;//中断控制寄存器volatile unsigned char PIR1 @ 0x0C;//中断标志寄存器PIR1volatile unsigned char PIR2 @ 0x0D;//中断标志寄存器PIR2volatile unsigned char TMR1L @ 0x0E;//T1低字节计数寄存器volatile unsigned char TMR1H @ 0x0F;//T1高字节计数寄存器volatile unsigned char T1CON @ 0x10;//TMR1控制寄存器volatile unsigned char TMR2 @ 0x11;//定时/计数器TMR2volatile unsigned char T2CON @ 0x12;//TMR2控制寄存器volatile unsigned char SSPBUF @ 0x13;//收/发数据缓冲器volatile unsigned char SSPCON @ 0x14;/*同步串口控制寄存器,对MSSP模块的功能和指标进行设置和定义*/volatile unsigned char CCPR1L @ 0x15;//捕获/比较/PWM寄存器低字节volatile unsigned char CCPR1H @ 0x16;//捕获/比较/PWM寄存器低字节volatile unsigned char CCP1CON @ 0x17;//CCP1CON寄存器volatile unsigned char RCSTA @ 0x18;//USART接收控制兼状态寄存器volatile unsigned char TXREG @ 0x19;//USART发生缓冲器volatile unsigned char RCREG @ 0x1A;//USART接收缓冲器volatile unsigned char CCPR2L @ 0x1B;//捕获/比较/PWM寄存器低字节volatile unsigned char CCPR2H @ 0x1C;//捕获/比较/PWM寄存器低字节volatile unsigned char CCP2CON @ 0x1D;//CCP2CON寄存器volatile unsigned char ADRESH @ 0x1E;//ADC转换结果寄存器高字节volatile unsigned char ADCON0 @ 0x1F;//A/D转换器开关位/* bank 1 registers */volatile unsigned char OPTION @ 0x81;/*/选择寄存器,用于配置TMR0/WDT预分频系数、外部INT中断、TMR0和端口B的弱上拉。
基于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数字时钟时钟程序文件
;Digit clock;-----------------------------------------------;DATE :20101205;Author:Tang HS;M C U :PIC16F877A;FileName : ClockPIC.ASM;-----------------------------------------------------------;Date: {2010/12/07.14:35}-Ver01--CS-ICD:0xAFCE---ISP:0xb7ce----;功能: 1.LED显示:时分秒;格式:[ hh mm ss ] 备注:按键未定义;------------------------------------------------------------;-----------------------------------------------------------;Date: {2010/12/07.22:15}-Ver01--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}-Ver02--CS-ICD:0xAFCE---ISP:0xef0e----;************************************************************;Date: {2010/12/10.00:47}-Ver03--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}-Ver03.1--CS-ICD:0xb08b---ISP:0xfaa4----; 4.时差。
PIC单片机自学笔记之TMR0数字钟
PIC自学笔记之TMR0数字时钟实验环境:Proteus编程语言:汇编编程环境:MPLAB单片机:PIC16F877晶振:4MHz首先声明一点:该数字时钟并不能精确地显示时间,因为定时器置初值的过程中会造成无法弥补的误差。
虽然如此,该文作为一篇针对对TMR0定时器应用,键盘扫描模块和数码管显示模块的一个整合应用,我想应该还算得上比较成功的一次实验。
因而传上来,希望能为刚接触PIC单片机的朋友们做个参考。
功能说明:该数字时钟实验,以定时器0为时钟源,采用1/256预分频,初始时间设定在了该实验完成的那一刻。
时钟的显示是通过八个七段数码管,由八个74HC573来驱动,在驱动器的选择上,选择了74HC138译码器,通过PORTE 的三个I/O口来控制,键盘模块在主程序中,通过循环扫描的方式来获取键盘信息,其中,KEY1是总控制键,按一下可进入分钟的设置,按两下进入小时的设置,按三下退出设置;KEY2和KEY3分别是‘加’和‘减’操作键。
操作流程为,首先按KEY1选择设置分钟还是小时,然后通过KEY2或KEY3调整其值(注:单纯的按KEY2或KEY3不会对时钟进行设置)Proteus仿真图键盘电路仿真效果图部分程序源代码list p=16f877INCLUDE P16F877.INCSECOND equ 20hMINUTE equ 21hHOUR equ 22hBSTA TUS equ 23hBW equ 24hBPCH equ 25hBFSR equ 26hD20 equ 27hCOM0 EQU 28H;公共单元COM1 EQU 29HCOM2 EQU 2AHCOM3 EQU 2BHCOM4 EQU 2CHCOM5 EQU 2DHCOM6 EQU 2EHDIS0 EQU 2FH;显示寄存器单元DIS1 EQU 30HDIS2 EQU 31HDIS3 EQU 32HDIS4 EQU 33HDIS5 EQU 34HDISC EQU 35HDELA Y1 EQU 36H;延时寄存器单元DELA Y2 EQU 37HKEYCOM0 EQU 38H;键盘键值单元KEYCOM1 EQU 39HFLAG EQU 3AH;键盘标志单元KEYDELY EQU 3BHORG 000HGOTO MAINORG 004H;中断入口,此处只用了定时器0的中断TMR0INT:MOVWF BWSW APF STA TUS,0CLRF STA TUSMOVWF BSTA TUSMOVF FSR,0MOVWF BFSRMOVF PCLA TH,0MOVWF BPCHCLRF PCLA TH;以上是入中断前的现场保护;************************BCF STA TUS,RP1;以下开始为时钟计算单元BCF STA TUS,RP0BTFSS INTCON,5;判断定时器0的中断是否被允许,也可以不要,但又的话更稳定GOTO INTOUTBTFSS INTCON,2;判断定时器0溢出标志位GOTO INTOUTBCF INTCON,2;清定时器0中断标志位MOVLW H'3C';定时器0赋初值MOVWF TMR0DECFSZ D20GOTO INTOUTMOVLW D'20';一秒定时到MOVWF D20INCF SECONDMOVLW D'60'XORWF SECOND,0BTFSS STA TUS,ZGOTO DISW;显示CLRF SECONDINCF MINUTEMOVLW D'60'XORWF MINUTE,0BTFSS STA TUS,ZGOTO DISWCLRF MINUTEINCF HOURMOVLW D'24'XORWF HOUR,0BTFSS STA TUS,ZGOTO DISWCLRF HOURDISW:CALL DIS;显示子程序;************************INTOUT: MOVF BPCH,0;中断返回,恢复现场MOVWF PCLA THMOVF BFSR,0MOVWF FSRSW APF BSTA TUS,0MOVWF STA TUSSW APF BW,1SW APF BW,0RETFIEMAIN:BANKSEL PORTA;初始化各相关寄存器clrf PORTAclrf PORTDCLRF PORTEMOVLW H'F0'MOVWF PORTBmovlw h'a0'movwf INTCONMOVLW H'3C'MOVWF TMR0MOVLW D'21'MOVWF D20CLRF SECONDMOVLW D'17';设置开机显示时间小时值MOVWF HOURMOVLW D'24';设置开机显示分钟值MOVWF MINUTECLRF DIS0;CLRF DIS1MOVLW D'4'MOVWF DIS2MOVLW D'2'MOVWF DIS3MOVLW D'7'MOVWF DIS4MOVLW D'1'MOVWF DIS5BANKSEL TRISAMOVLW H'07';定时器0设置为内部时钟源,1/256预分频MOVWF OPTION_REGCLRF TRISECLRF TRISDMOVLW H'F0'MOVWF TRISBCLRF PIE1CLRF PIE2BANKSEL PORTAMOVLW H'02'MOVWF PORTE;数码管选择MOVLW H'40'MOVWF PORTDMOVLW H'05'MOVWF PORTECALL DISGOTO KEYKEYDIS: BTFSS FLAG,0GOTO KEYCALL DISGOTO KEYDIS: MOVF SECOND,0;显示处理MOVWF COM3CALL DIV10;除10子程序,商在COM3中,余数在COM5中MOVF COM5,0MOVWF DIS0MOVF COM3,0MOVWF DIS1MOVF MINUTE,0MOVWF COM3CALL DIV10MOVF COM5,0MOVWF DIS2MOVF COM3,0MOVWF DIS3MOVF HOUR,0MOVWF COM3CALL DIV10MOVF COM5,0MOVWF DIS4MOVF COM3,0MOVWF DIS5MOVLW DIS0MOVWF FSRCLRF DISCDISLOOP: MOVF DISC,0MOVWF PORTEMOVF INDF,0CALL LEDISMOVWF PORTDINCF DISCINCF FSRMOVF DISC,0MOVWF PORTEMOVF INDF,0CALL LEDISMOVWF PORTDINCF DISCINCF DISCINCF FSRMOVLW D'9'XORWF DISC,0BTFSS STA TUS,ZGOTO DISLOOPRETURNLEDIS:ADDWF PCLRETLW H'3F';0RETLW H'06';1RETLW H'5B';2RETLW H'4F';3RETLW H'66';4RETLW H'6D';5RETLW H'7D';6RETLW H'07';7RETLW H'7F';8RETLW H'6F';9KEY: MOVLW KEYCOM0;键盘扫描程序CALL KEYREAD;调用读PORTB状态程序BTFSC STA TUS,ZGOTO KEYCALL DELA Y5MS;延时5MS消抖MOVLW KEYCOM0CALL KEYREADBTFSC STA TUS,ZGOTO KEYBTFSC KEYCOM0,7;确认有键按下后,进而判断是哪个键被按下GOTO KEY0;KEY1处理子程序BTFSC KEYCOM0,6GOTO KEY ADD;加处理BTFSS KEYCOM0,5GOTO KEYGOTO KEYSUB;减处理KEY0: BTFSS PORTB,7GOTO KEY0;等待按键释放BTFSC FLAG,0;FLAG,0在KEY1第一次被按下后被置一,在第三次按下时清零GOTO KEY1BSF FLAG,0BCF INTCON,5BCF INTCON,2KEYLP: BTFSS FLAG,2GOTO KEYGOTO KEYOUTKEY1: INCF FLAGBSF FLAG,0GOTO KEYLPKEY ADD: BTFSS FLAG,0GOTO KEYKADD: BTFSS PORTB,6GOTO KADDMOVLW MINUTEBTFSC FLAG,1MOVLW HOURMOVWF FSRINCF INDFMOVLW D'60'BTFSC FLAG,1;FLAG,1是分和时区分标志MOVLW D'24'XORWF INDF,0BTFSC STA TUS,ZCLRF INDFGOTO KEYDISKEYSUB: BTFSS FLAG,0GOTO KEYKSUB: BTFSS PORTB,5GOTO KSUBMOVLW MINUTEBTFSC FLAG,1MOVLW HOURMOVWF FSRDECF INDFMOVLW D'59'BTFSC FLAG,1MOVLW D'23'BTFSC INDF,7MOVWF INDFCLRWGOTO KEYDISDIV10: MOVLW D'10';除十子程序MOVWF COM4CLRF COM5MOVLW D'8'MOVWF COM6DIV101: BCF STA TUS,CRLF COM3RLF COM5BSF COM3,0MOVF COM4,0SUBWF COM5BTFSS STA TUS,CCALL ADDDECFSZ COM6GOTO DIV101RETURNADD:MOVF COM4,0ADDWF COM5BCF COM3,0RETURNDELA Y5MS:;5MS延时MOVLW D'75'MOVWF DELA Y1DLOOP: MOVLW D'100'MOVWF DELA Y2DLOOP1: DECFSZ DELA Y2GOTO DLOOP1DECFSZ DELA Y1GOTO DLOOPRETURNKEYREAD:MOVWF FSR;读PORTB状态MOVF PORTB,0ADDLW H'F0'XORLW H'F0'MOVWF INDFRETURNKEYOUT: CLRF FLAGBSF INTCON,5GOTO KEYEND。
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万年历程序
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 个指令。
PIC16F877A单片机中文文献
PIC16F877A单片机是microchip公司的产品,它采用14位的RISC指令系统,内部集成了A/D转换器、EEPROM、模拟比较器、带比较和捕捉功能的定时器/计数器、PWM输出、异步串行通信电路等。
1.程序存储器程序存储器和堆栈PIC16F877A单片机内部具有8K×14位的Flash程序存储器,程序存储器具有13位宽度的程序计数器地址范围:0000H-1FFFH。
由程序计数器提供13条地址线进行单元选择,每个单元宽14位,即PIC16F877A的指令字节宽度为14位,能够存放一条PIC单片机系统指令。
在系统上电或其他复位情况下,程序计数器均从0000H地址单元开始工作。
如果遇到调用子程序或系统发生事件中断时,将把当前程序断点处的地址送入8级×14位的堆栈区域进行保护。
堆栈是一个独立的存储区域,在调用的子程序或中断服务程序执行完后,再恢复断点地址。
通过14位程序总线,取出对应程序之灵的机器码,送入指令存储器,将组成的操作码和操作数进行有效分离。
如果操作数为地址,则进入地址复用器;如果操作数为数据,则进入数据复用器。
而操作码将在指令译码和控制单元中转化为相应的功能操作。
PIC的多数指令均是顺序执行,即使条件跳转也是隔行间接跳转。
具有大范围转移功能的指令只有两条:无条件GOTO语句和调用子程序CALL语句。
但它们受到2KB范围的约束。
所以必须将整个程序存储器以2KB为单位进行分页。
PIC16F877A单片机的上电复位地址是0000H,中端口地址是0004H,中断产生时PC指针会自动指向该地址。
在进行中断应用时,特别是涉及多个中断同时打开时,必须要逐个对中断标志进行判断。
编程时,在0000H-0003H单元内要放置一条GOTO跳转指令,跳转到主程序,以避开0004H存储器单元。
2.数据存储器数据存储器PIC单片机的数据存储器与传统的MCS-51单片机一样,在配置结构上可分为通用寄存器和特殊功能寄存器两大类。
PIC16F877A单片机中文文献
PIC16F877A单片机是microchip公司的产品,它采用14位的RISC指令系统,内部集成了A/D转换器、EEPROM、模拟比较器、带比较和捕捉功能的定时器/计数器、PWM输出、异步串行通信电路等。
1.程序存储器程序存储器和堆栈PIC16F877A单片机内部具有8K×14位的Flash程序存储器,程序存储器具有13位宽度的程序计数器地址范围:0000H-1FFFH。
由程序计数器提供13条地址线进行单元选择,每个单元宽14位,即PIC16F877A的指令字节宽度为14位,能够存放一条PIC单片机系统指令。
在系统上电或其他复位情况下,程序计数器均从0000H地址单元开始工作。
如果遇到调用子程序或系统发生事件中断时,将把当前程序断点处的地址送入8级×14位的堆栈区域进行保护。
堆栈是一个独立的存储区域,在调用的子程序或中断服务程序执行完后,再恢复断点地址。
通过14位程序总线,取出对应程序之灵的机器码,送入指令存储器,将组成的操作码和操作数进行有效分离。
如果操作数为地址,则进入地址复用器;如果操作数为数据,则进入数据复用器。
而操作码将在指令译码和控制单元中转化为相应的功能操作。
PIC的多数指令均是顺序执行,即使条件跳转也是隔行间接跳转。
具有大范围转移功能的指令只有两条:无条件GOTO语句和调用子程序CALL语句。
但它们受到2KB范围的约束。
所以必须将整个程序存储器以2KB为单位进行分页。
PIC16F877A单片机的上电复位地址是0000H,中端口地址是0004H,中断产生时PC指针会自动指向该地址。
在进行中断应用时,特别是涉及多个中断同时打开时,必须要逐个对中断标志进行判断。
编程时,在0000H-0003H单元内要放置一条GOTO跳转指令,跳转到主程序,以避开0004H存储器单元。
2.数据存储器数据存储器PIC单片机的数据存储器与传统的MCS-51单片机一样,在配置结构上可分为通用寄存器和特殊功能寄存器两大类。
毕业设计——基于PIC16F877的智能电子钟设计
基于PIC16F877的智能电子钟设计1 引言随着电子技术产业结构调整,生产工艺的飞速发展,人们生活水平的不断提高,家用电器逐渐普及,而随着人们对周围环境便利程度的要求,市场对于智能时钟控制系统的需求也越来越大。
智能钟应实现的主要功能为:能实现二十四小时制的时分秒显示,具有快速手动校时电路,具有整点报时功能,具有闹钟表功能(可设置时分),具有倒计时功能。
2 设计原理及方案2.1 设计原理单片机是一门技术性、应用性很强的学科,实践教学是它的一个极为重要的环节。
不论是硬件扩展、接口应用还是编程方法、程序调试,都离不开实践。
本次设计的目的是通过完成一个涉及PIC单片机都种资源应用并具有综合功能的小系统目标板的设计与编程应用,能够对电子电路、电子元器件、印制电路板等方面的知识进一步加深认识,同时在软件编程、排版调试、焊接技术、相关仪器设备的使用技能等方面得到较全面的锻炼和提高,为今后能够独立进行某些单片机应用系统的开发设计工作打下一定的基础。
该电子时钟不但具有显示时、分、秒的作用,而且用按键还可以实现时间的调整和闹铃的设定。
本次综合实践完成了在单片机数据采集与定时系统的硬件电路设计后的基础上,焊接制作电路板,完成该系统的软件设计与调试。
待仿真成功后,再将程序烧写入单片机中。
2.2 设计方案系统结构整个电子时钟系统电路可分为五大部分:中央处理单元(CPU)、电源电路部分、显示部分、键盘输入部分。
系统由PIC16F877、LED 数码管、按键、发光二极管等部分构成,能实现时间的调整、定时时间的设定,输出等功能。
系统的功能选择由SB0、SB1、SB2、SB3、SB4 完成。
其中SB0 为时间校对,定时器调整功能键,按SB 0 进入调整状态。
SB1 为功能切换键。
第一轮按动 SB1 依次进入一路、二路、三路定时时间设置提示程序,按SB3 进入各路定时调整状态。
定时时间到,二极管发亮。
到了关断时间后灭掉。
如果不进入继续按SB1 键,依次进入时间年位校对、月位校对、日位校对、时位校对、分位校对、秒位校对状态。
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数字时钟时钟程序
;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.时差。
《PIC16系列单片机C程序设计与proteus仿真》学习之2----TMR0定时器中断
/**用TMR0延时中断,产生脉冲**//**设定时器TMR0延时10MS,8位pic单片机晶振4MHZ,则指令周期Tcy=1us,计算如下:1.设预分频比为K,则256*K*Tcy=10_000us,得K=39.06,要取大于此值的最小分频比,即K=642.计算延时常数X,(256-X)*64*Tcy=10_000us,得X=99.75,四舍五入取整,得X=100. */#include<pic.h>__CONFIG(0x3f71);#define LED RB0#define T0_10MS 100 //定义TMR0延时10MS的时间常数char A;void interrupt ISR(void);void main(void){RISB0=0; //设定RB0位输出,其余B口未设置,采用上电默认值,为输入OPTION=0b10000101;//RBPU=1:B口上拉使能,INTEDG=0:下降沿触发,T0CS=0:对内部指令周期计数,T0SE=0:RA4/T0CKI的上升沿计数,PSA=0:预分频分配位给TMRO,PS2PS1PS0=101:TMR0比率为1:64INTCON=0b10100000;//GIE=1:允许全局中断使能,PEIE=0:禁止外设中断使能,T0IE/TMR0IE=1:允许TMR0溢出中断使能,INTE=0:禁止INT引脚中断使能//RBIE=0:禁止RB口高4位电平变化使能,T0IF/TMR0IF=0:TMR0溢出中断标志位--未溢出//INTF=0:未发生INT中断,RBIF=0:RB7:RB4引脚的逻辑状态未发生变化TMR0=T0_10MS; //TMR0赋初值LED=1;A=1;while(1); //原地等待}void interrupt ISR(void){if(T0IF==1){T0IF=0;TMR0=T0_10MS;//TMR0赋初值,必须if(A==1){A=0;LED=0;}else{A=1;LED=1;}}}proteus如下:(已修改)第一步:初步画好仿真图,设置好PIC参数(晶振,配置位)并运行,如下:第二步:设置ANALOGUE ANALYSIS(我们主要看RB0的模拟电压情况),设置方法如下:1.右击---Edit Graph---起始时间50m,终止时间150m---OK2.右击---Add Traces---Name为RB0,Probe P1为RB0---OK3.右击---Edit Graph---Set Y-scales---若此时显示为灰色不可输入状态,那就点确定,会弹出一个窗口“Resimulate?”,点击确定,方波图就出来了,不过默认是0~5V,你现在就可以重新修改Y-scales,如下图:先打勾“Lock values”,在设置Min -1,Max 6----Ok----又会弹出“resimulate?”,确定即可。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
PIC16F877A之定时TMR0
编写下面的实验程序实现的功能是让RC 口所带的8 个LED 一个接一个的
全亮起来,最后达到全亮后再一个一个的灭下去,这样反复循环,使用定时器
查询方式控制延时,而不使用定时器的中断。
中断程序会在以后陆续写到上面
来
tmr0 equ 01hpcl equ 02hstatus equ 03hoption_reg equ 81hintcon equ 0bhportc equ 07htrisc equ 87htmr0data equ 15hcount equ 20hrp0 equ 5horg 0000hnopgoto mainorg 0005hmain nopbsf status,rp0movlw 00hmovwf triscmovlw 07hmovwf option_regbcf status,rp0clrf countloop1movf count,0call readmovwf portcincf count,1movlw 0fhandwf count,1call delaycall delaycall delaycall delaycall delaycall delaycall delaygoto loop1delaybcf intcon,2movlw tmr0datamovwf tmr0delay1btfss intcon,2goto delay1returnread addwf pcl,1retlw b’10000000’retlw b’11000000’retlw b’11100000’retlw b’11110000’retlw b’11111000’retlw b’11111100’retlw b’11111110’retlw b’11111111’retlw b’11111110’retlw b’11111100’retlw b’11111000’retlw b’11110000’retlw b’11100000’retlw b’11000000’retlw b’10000000’retlw b’00000000’end本程序利用的16F877A 的TMR0,具体如何设置请查找
16F877C 中的INTCON、OPTION_REG 、TMR0 等相关特殊工作寄存器的功
能说明。
推荐李学海老师编写的PIC 单片机实用教程。