PIC16F877A与PC机串行通信C语言源程序

合集下载

最新PIC16F877A单片机中文文献

最新PIC16F877A单片机中文文献

最新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功能及其编程
RA3=1; NOP(); RA4=0;
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

用C语言写的一个PIC16F877的时闹钟程序

用C语言写的一个PIC16F877的时闹钟程序

用C语言写的一个PIC16F877的时闹钟程序单片机用16F877,主时钟用20MHz,用32768作定时时间。

可以实现2路定闹,每一路都可分别设置和开关,采用4x4键盘,16x2的字符型LCD显示。

连线在程序开头有说明。

程序的功能:(1)上电后LCD背光打开,并显示倒计时5秒,然后时钟开始工作。

(2)用模式键(*)切换模式,如显示时间、日期、闹钟1、闹钟2等,并且可以用上、下键控制加1、减1或是闹钟的On、Off。

(3)原程序有16个键,包括0~9数字键,可以直接输入要设置的时间值,但后来将数字键取消了,你仍然可以通过修改程序的部分注释恢复此功能。

(4)闹钟有2路,时间到后闹2分钟,可按任意键取消本次闹钟。

闹钟响时有2种音调,是用PIC的PWM实现的。

(5)按任意键可打开背光,1分钟后自动关闭背光。

(6)RA0~RA3为按键扫描输入,应接下拉电阻。

主程序// FileName: Main.c// MCU: Microchip PIC16F877// Tool: CCS-C compiler// Author: KingEDA, MSN:kingeda@, skype:kingeda, E-mail:kingeda@// Website: // Description:// A timer program// Ver 0.1: 2003-03-31, all clock function with date display, 2 way alarm.// Ver 0.2: 2003-05-05, (1) Alarm default is on,modify alarm1 time to 7:00:00,// and alarm2 to 13:30:00.// (2) Backlight will be enabled when alarming.// (3) Automatic adjust day(28,30,31).// (4) Automatic move cursor to next location when set item.// PIN Connection:// RC0~1 : 32768Hz crystal// RC2 : Buzzer// RC3 : LCD Back Light,drive a PNP BJT// RD0~RD7 : to LCD DB0~DB7// RA0~RA3 : keypad col in// RC4~RC7 : keypad line out// 7 8 9 #// 4 5 6 ↑// 1 2 3 ↓// 0 ←→*// RE0 : LCD RS// RE1 : LCD RW// RE2 : LCD E#include "my16f877.h"#device ICD=true//#fuses HS,NOWDT,NOPROTECT,PUT,BROWNOUT #use delay(clock = 24000000)//#use fast_io(C)#use fast_io(E)#define lcd_busy (lcd_read_addr()&0x80) == 0x80#define time_start_addr 0x80+0x04#define time_hourh_addr time_start_addr#define time_hourl_addr time_start_addr+1#define time_minuteh_addr time_start_addr+3#define time_minutel_addr time_start_addr+4#define time_secondh_addr time_start_addr+6#define time_secondl_addr time_start_addr+7#define key_0 0x11#define key_1 0x21#define key_2 0x22#define key_3 0x24#define key_4 0x41#define key_5 0x42#define key_6 0x44#define key_7 0x81#define key_8 0x82#define key_9 0x84#define key_left 0x12#define key_right 0x14#define key_up 0x48#define key_down 0x28#define key_mode 0x18#define key_cancel 0x88char StrPower1[] = " * Power on * ";char StrSetTime[] = " * Adjust time* ";char StrSetDate[] = " * Adjust date* ";char StrAlarm1[] = " * Set alarm 1* ";char StrAlarm2[] = " * Set alarm 2* ";unsigned char PORTC_MAP;#bit BackLightEn = PORTC_MAP.3unsigned char BackLightTimer;int1 led;#bit lcd_rs = PORTE.0#bit lcd_rw = PORTE.1#bit lcd_e = PORTE.2#byte lcd_bus = PORTD#byte lcd_dir = TRISD#define PWM_on 0x0c#define PWM_off 0x00#define PWM_period 200#define PWM_DC 100unsigned char lcd_addr;unsigned char KeyLine;unsigned char KeyOld;unsigned char KeyNew;struct mTime {unsigned char hourh; // hour,0~23unsigned char hourl;unsigned char minuteh; // minute,0~59unsigned char minutel;unsigned char secondh; // second,0~59unsigned char secondl;};struct mTime CurrentTime = {1,2,0,0,0,0};struct mTime AlarmTime1 = {0,7,0,0,0,0}; // 07:00:00 struct mTime AlarmTime2 = {1,3,3,0,0,0}; // 13:30:00 unsigned char AlarmStatus;#bit Alarm1Enable = AlarmStatus.0#bit Alarm2Enable = AlarmStatus.1#bit Alarm1Alarm = AlarmStatus.2#bit Alarm2Alarm = AlarmStatus.3unsigned char Alarm1Cnt; // alarm1 second count unsigned char Alarm2Cnt;unsigned char CurrentMode;#define mode_time 0#define mode_set_time 1#define mode_set_date 2#define mode_set_alarm1 3#define mode_set_alarm2 4unsigned char adjust_item;struct mDate {unsigned char year1; //unsigned char year2;unsigned char year3;unsigned char year4;unsigned char monthh;unsigned char monthl;unsigned char dayh;unsigned char dayl;};struct mDate CurrentDate = {2,0,0,3,0,1,0,1}; unsigned char *pStr;// ------------------------------------------------------- unsigned char lcd_read_addr(){unsigned char ch;lcd_dir = 0xff; // read from lcdlcd_rs = 0;lcd_rw = 1; // instlcd_e = 1;#asmnopnopnop#endasmch = lcd_bus;lcd_e = 0;lcd_dir = 0x00; // set write to lcdreturn ch;}// ------------------------------------------------------- unsigned char lcd_write_data(unsigned char ch) {while (lcd_busy){ restart_wdt(); }lcd_rs = 1; // datalcd_rw = 0; // writelcd_bus = ch; // write outlcd_e = 1;#asmnopnopnop#endasmlcd_e = 0;return 'Y';}// ------------------------------------------------------- unsigned char lcd_write_inst(unsigned char ch) {while (lcd_busy){ restart_wdt(); }lcd_rs = 0; // instlcd_rw = 0; // writelcd_bus = ch;lcd_e = 1;#asmnopnopnop#endasmlcd_e = 0;return 'Y';}// ------------------------------------------------------- unsigned char lcd_read_data(){unsigned char ch;while (lcd_busy){ restart_wdt(); }lcd_dir = 0xff; // read from lcdlcd_rs = 1; // datalcd_rw = 1; // readlcd_e = 1;#asmnopnopnop#endasmch = lcd_bus; // read inlcd_e = 0;lcd_dir = 0x00; // set write to lcdreturn ch;}// ------------------------------------------------------- void lcd_init(){unsigned char Tempch;lcd_addr = 0;delay_ms(100);Tempch = 0x38; // 1-line mode,5x8 dotslcd_write_inst(Tempch); // Function setTempch = 0x0f; // lcd on,cursor on,blink onlcd_write_inst(Tempch); // Display on/offTempch = 0x06; // Increment mode,Entire shift offlcd_write_inst(Tempch);Tempch = 0x01; // clear displaylcd_write_inst(Tempch);delay_ms(3);}// -------------------------------------------------------//#int_timer1//void timer1_interrupt(void)#int_ccp2void ccp2_interrupt(void){//TMR1H = 0x80;if (CurrentTime.secondl==9){CurrentTime.secondl=0;if (CurrentTime.secondh==5){CurrentTime.secondh=0;if (CurrentTime.minutel==9){CurrentTime.minutel=0;if (CurrentTime.minuteh==5){CurrentTime.minuteh=0;if (CurrentTime.hourl==9){CurrentTime.hourl=0;CurrentTime.hourh++;}else if((CurrentTime.hourl==3) && (CurrentTime.hourh==2)){CurrentTime.hourl=0;CurrentTime.hourh=0;if ((((CurrentDate.dayl == 8) || (CurrentDate.dayl == 9)) && (CurrentDate.dayh == 2) && (CurrentDate.monthl == 2) && (CurrentDate.monthh == 0)) ||((CurrentDate.dayl == 0) && (CurrentDate.dayh == 3) && ((((CurrentDate.monthl == 4) || (CurrentDate.monthl == 6)|| (CurrentDate.monthl == 9)) && (CurrentDate.monthh == 0)) || ((CurrentDate.monthl == 1) && (CurrentDate.monthh == 1)))) ||((CurrentDate.dayl == 1) && (CurrentDate.dayh == 3))){CurrentDate.dayl=1;CurrentDate.dayh=0;if ((CurrentDate.monthl == 2) && (CurrentDate.monthh == 1)){CurrentDate.monthl = 1;CurrentDate.monthh = 0;if (CurrentDate.year4 == 9){CurrentDate.year4 = 0;if (CurrentDate.year3 == 9){CurrentDate.year3 = 0;if (CurrentDate.year2 == 9){CurrentDate.year2 = 0;CurrentDate.year1++;}elseCurrentDate.year2++;}elseCurrentDate.year3++;}elseCurrentDate.year4++;}else if(CurrentDate.monthl == 9){CurrentDate.monthl = 0;CurrentDate.monthh++;}elseCurrentDate.monthl++;}else if(CurrentDate.dayl == 9){CurrentDate.dayl=0;CurrentDate.dayh++;}elseCurrentDate.dayl++;}elseCurrentTime.hourl++;}elseCurrentTime.minuteh++;}elseCurrentTime.minutel++;}elseCurrentTime.secondh++;}elseCurrentTime.secondl++;if ((Alarm1Alarm == false) & (Alarm2Alarm == false)){led = 0;CCP1CON = PWM_off;}else{if (led == 1){led = 0;PR2 = PWM_period; // set pwm periodCCPR1L = PWM_DC; // set pwm duty cycle//CCP1CON = PWM_on;}else{led = 1;PR2 = PWM_period/2; // set pwm periodCCPR1L = PWM_DC/2; // set pwm duty cycle//CCP1CON = PWM_off;}}Alarm1Cnt++;Alarm2Cnt++;if (BackLightEn == 0)if (((BackLightTimer++)>=60) & (Alarm1Alarm == false) & (Alarm1Alarm == false))BackLightEn = 1; // disable backlight PORTC = PORTC_MAP;//TMR1IF = 0;//PIR1 = PIR2 = 0x00;CCP2IF = 0;}// ------------------------------------------------------- unsigned char get_key(void){unsigned char key_in,tmp;TRISC = 0x03;KeyLine = 0xf0;PORTC = KeyLine | PORTC_MAP;#asmnopnopnop#endasmif ((PORTA & 0x0f) != 0){tmp = 0x10;for (KeyLine = tmp;KeyLine!=0;KeyLine = tmp){PORTC = KeyLine | PORTC_MAP;tmp = KeyLine <<1;#asmnopnopnop#endasmkey_in = PORTA & 0x0f;if (key_in != 0){return (key_in | KeyLine);}}return 0;}elsereturn 0;}// -------------------------------------------------------void set_mode(void){if (CurrentMode == mode_set_alarm2)CurrentMode = mode_time;else{CurrentMode++;adjust_item = 0;}lcd_write_inst(0x01); // clear LCD displaylcd_write_inst(time_start_addr); // set LCD line1 if (CurrentMode == mode_set_time){lcd_write_data(CurrentTime.hourh + '0');lcd_write_data(CurrentTime.hourl + '0');lcd_write_data(':');lcd_write_data(CurrentTime.minuteh + '0');lcd_write_data(CurrentTime.minutel + '0');lcd_write_data(':');lcd_write_data(CurrentTime.secondh + '0');lcd_write_data(CurrentTime.secondl + '0');pStr = StrSetTime;}else if(CurrentMode == mode_set_date){lcd_write_data(CurrentDate.year1 + '0');lcd_write_data(CurrentDate.year2 + '0');lcd_write_data(CurrentDate.year3 + '0');lcd_write_data(CurrentDate.year4 + '0');lcd_write_data('/');lcd_write_data(CurrentDate.monthh + '0');lcd_write_data(CurrentDate.monthl + '0');lcd_write_data('/');lcd_write_data(CurrentDate.dayh + '0');lcd_write_data(CurrentDate.dayl + '0');pStr = StrSetDate;}else if(CurrentMode == mode_set_alarm1){lcd_write_data(AlarmTime1.hourh + '0');lcd_write_data(AlarmTime1.hourl + '0');lcd_write_data(':');lcd_write_data(AlarmTime1.minuteh + '0');lcd_write_data(AlarmTime1.minutel + '0');lcd_write_data(':');lcd_write_data(AlarmTime1.secondh + '0');lcd_write_data(AlarmTime1.secondl + '0');lcd_write_data(' ');lcd_write_data('O');if (Alarm1Enable){lcd_write_data('n');}else{lcd_write_data('f');lcd_write_data('f');}pStr = StrAlarm1;Alarm1Cnt =0;}else if(CurrentMode == mode_set_alarm2) {lcd_write_data(AlarmTime2.hourh + '0');lcd_write_data(AlarmTime2.hourl + '0');lcd_write_data(':');lcd_write_data(AlarmTime2.minuteh + '0');lcd_write_data(AlarmTime2.minutel + '0');lcd_write_data(':');lcd_write_data(AlarmTime2.secondh + '0');lcd_write_data(AlarmTime2.secondl + '0');lcd_write_data(' ');lcd_write_data('O');if (Alarm2Enable){lcd_write_data('n');}else{lcd_write_data('f');lcd_write_data('f');}pStr = StrAlarm2;Alarm2Cnt = 0;}lcd_write_inst(0xc0); // set LCD line2 if (CurrentMode != mode_time){for (;*pStr!=0;pStr++){ // write hint messagelcd_write_data(*pStr);}lcd_write_inst(0x0f); // LCD cursor onlcd_write_inst(time_start_addr); // move cursor to start }else // time mode,write date to second line{lcd_write_inst(0x0c); // LCD sursor off/* lcd_write_inst(0xc0 + 3); // set date start address lcd_write_data(CurrentDate.year1 + '0');lcd_write_data(CurrentDate.year2 + '0');lcd_write_data(CurrentDate.year3 + '0');lcd_write_data(CurrentDate.year4 + '0');lcd_write_data('/');lcd_write_data(CurrentDate.monthh + '0');lcd_write_data(CurrentDate.monthl + '0');lcd_write_data('/');lcd_write_data(CurrentDate.dayh + '0');lcd_write_data(CurrentDate.dayl + '0');*/ }if (CurrentMode == mode_set_time){lcd_write_inst(time_start_addr); // move cursor to start }else if (CurrentMode == mode_set_date){lcd_write_inst(time_start_addr); // move cursor to start }else if (CurrentMode == mode_set_alarm1){lcd_write_inst(time_secondl_addr+3);adjust_item = 6;}else if (CurrentMode == mode_set_alarm2){lcd_write_inst(time_secondl_addr+3);adjust_item = 6;}else{lcd_write_inst(0x0c); // LCD cursor off}}// ------------------------------------------------------- void set_date(void){if (adjust_item == 0) // adjust year{if ((KeyNew >=0) & (KeyNew <= 9)){CurrentDate.year1 = KeyNew;lcd_write_data(CurrentDate.year1 + '0');//lcd_write_inst(time_start_addr);adjust_item ++;}else if (KeyNew == key_left){adjust_item = 7;lcd_write_inst(time_start_addr + 9);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_start_addr + 1);}}else if(adjust_item == 1){if ((KeyNew >=0) & (KeyNew <= 9)){CurrentDate.year2 = KeyNew;lcd_write_data(CurrentDate.year2 + '0');//lcd_write_inst(time_start_addr + 1);adjust_item ++;}else if (KeyNew == key_left){adjust_item --;lcd_write_inst(time_start_addr + 0);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_start_addr + 2);}}else if(adjust_item == 2){if ((KeyNew >=0) & (KeyNew <= 9)){CurrentDate.year3 = KeyNew;lcd_write_data(CurrentDate.year3 + '0');//lcd_write_inst(time_start_addr + 2);adjust_item ++;}else if (KeyNew == key_left){adjust_item --;lcd_write_inst(time_start_addr + 1);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_start_addr + 3);}}else if(adjust_item == 3){if ((KeyNew >=0) & (KeyNew <= 9)){CurrentDate.year4 = KeyNew;lcd_write_data(CurrentDate.year4 + '0');//lcd_write_inst(time_start_addr + 3);adjust_item ++;lcd_write_inst(time_start_addr + 5);}else if (KeyNew == key_left){adjust_item --;lcd_write_inst(time_start_addr + 2);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_start_addr + 5);}}else if(adjust_item == 4)if (((CurrentDate.monthl>2) & (KeyNew == 0)) | ((CurrentDate.monthl == 0) & (KeyNew == 1))| (((CurrentDate.monthl == 1) | (CurrentDate.monthl == 2)) & (KeyNew <2))) {CurrentDate.monthh = KeyNew;lcd_write_data(CurrentDate.monthh + '0');//lcd_write_inst(time_start_addr + 5);adjust_item ++;}else if (KeyNew == key_left){adjust_item --;lcd_write_inst(time_start_addr + 3);}else if (KeyNew == key_right){adjust_item ++;lcd_write_inst(time_start_addr + 6);}}else if(adjust_item == 5){if (((CurrentDate.monthh == 3) & (KeyNew <2)) | ((CurrentDate.monthh != 3) & (KeyNew >=0) & (KeyNew <=9))){CurrentDate.monthl = KeyNew;lcd_write_data(CurrentDate.monthl + '0');//lcd_write_inst(time_start_addr + 6);adjust_item ++;lcd_write_inst(time_start_addr + 8);}else if (KeyNew == key_left){adjust_item --;lcd_write_inst(time_start_addr + 5);}else if (KeyNew == key_right){adjust_item ++;lcd_write_inst(time_start_addr + 8);}}else if(adjust_item == 6)if (((CurrentDate.dayl>1) & ((KeyNew == 1) | (KeyNew == 2))) | ((CurrentDate.dayl == 0) & (KeyNew >0) & (KeyNew<4))| ((CurrentDate.dayl == 1) & (KeyNew <4))){CurrentDate.dayh = KeyNew;lcd_write_data(CurrentDate.dayh + '0');//lcd_write_inst(time_start_addr + 8);adjust_item ++;}else if (KeyNew == key_left){adjust_item --;lcd_write_inst(time_start_addr + 6);}else if (KeyNew == key_right){adjust_item ++;lcd_write_inst(time_start_addr + 9);}}else if(adjust_item == 7){if (((CurrentDate.dayh == 3) & (KeyNew <2)) | ((CurrentDate.dayh != 3) & (KeyNew >=0) & (KeyNew <=9))){CurrentDate.dayl = KeyNew;lcd_write_data(CurrentDate.dayl + '0');//lcd_write_inst(time_start_addr + 9);adjust_item ++;lcd_write_inst(time_start_addr + 0);}else if (KeyNew == key_left){adjust_item --;lcd_write_inst(time_start_addr + 8);}else if (KeyNew == key_right){adjust_item = 0;lcd_write_inst(time_start_addr + 0);}}}// -------------------------------------------------------void set_time(void){if (adjust_item == 0) // set hourh{if (((CurrentTime.hourl <4) & (KeyNew < 3)) | ((CurrentTime.hourl >3) & (KeyNew <2))){CurrentTime.hourh = KeyNew;lcd_write_data(CurrentTime.hourh + '0'); // refresh hourh//lcd_write_inst(0x10); // move cursor backadjust_item ++;}else if(KeyNew == key_left){adjust_item = 5;lcd_write_inst(time_secondl_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_hourl_addr);}}else if (adjust_item == 1) // set hourl{if (((CurrentTime.hourh == 2) & (KeyNew < 4)) | ((CurrentTime.hourh < 2) & (KeyNew <=9))){CurrentTime.hourl = KeyNew;lcd_write_data(CurrentTime.hourl + '0'); // refresh hourl//lcd_write_inst(0x10); // move cursor backadjust_item ++;lcd_write_inst(time_minuteh_addr);}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_hourh_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_minuteh_addr);}}else if (adjust_item == 2) // set minuteh{if (KeyNew <6){CurrentTime.minuteh = KeyNew;lcd_write_data(CurrentTime.minuteh + '0');//lcd_write_inst(0x10); // move cursor backadjust_item ++;}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_hourl_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_minutel_addr);}}else if (adjust_item == 3) // set minutel{if ((KeyNew >=0) & (KeyNew <=9)){CurrentTime.minutel = KeyNew;lcd_write_data(CurrentTime.minutel + '0');//lcd_write_inst(0x10); // move cursor backadjust_item ++;lcd_write_inst(time_secondh_addr);}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_minuteh_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_secondh_addr);}}else if (adjust_item == 4) // set secondh{if (KeyNew <6){CurrentTime.secondh = KeyNew;lcd_write_data(CurrentTime.secondh + '0');//lcd_write_inst(0x10); // move cursor backadjust_item ++;}else if(KeyNew == key_left){adjust_item --;&nb, sp; lcd_write_inst(time_minutel_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_secondl_addr);}}else if (adjust_item == 5) // set secondl{if ((KeyNew >=0) & (KeyNew <=9)){CurrentTime.secondl = KeyNew;lcd_write_data(CurrentTime.secondl + '0');//lcd_write_inst(0x10); // move cursor backadjust_item = 0;lcd_write_inst(time_hourh_addr);}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_secondh_addr);}else if(KeyNew == key_right){adjust_item = 0;lcd_write_inst(time_hourh_addr);}}}// -------------------------------------------------------void set_alarm1(void){if (adjust_item == 0) // set hourh{if (((AlarmTime1.hourl <4) & (KeyNew < 3)) | ((AlarmTime1.hourl >3) & (KeyNew <2))){AlarmTime1.hourh = KeyNew;lcd_write_data(AlarmTime1.hourh + '0'); // refresh hourh//lcd_write_inst(0x10); // move cursor backadjust_item ++;}else if(KeyNew == key_left){adjust_item = 6;lcd_write_inst(time_secondl_addr + 3);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_hourl_addr);}}else if (adjust_item == 1) // set hourl{if (((AlarmTime1.hourh == 2) & (KeyNew < 4)) | ((AlarmTime1.hourh < 2) & (KeyNew <=9))){AlarmTime1.hourl = KeyNew;lcd_write_data(AlarmTime1.hourl + '0'); // refresh hourl//lcd_write_inst(0x10); // move cursor backadjust_item ++;lcd_write_inst(time_minuteh_addr);}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_hourh_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_minuteh_addr);}}else if (adjust_item == 2) // set minuteh{if (KeyNew <6){AlarmTime1.minuteh = KeyNew;lcd_write_data(AlarmTime1.minuteh + '0');//lcd_write_inst(0x10); // move cursor backadjust_item ++;}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_hourl_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_minutel_addr);}}else if (adjust_item == 3) // set minutel{if ((KeyNew >=0) & (KeyNew <=9)){AlarmTime1.minutel = KeyNew;lcd_write_data(AlarmTime1.minutel + '0');//lcd_write_inst(0x10); // move cursor backadjust_item ++;lcd_write_inst(time_secondh_addr);}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_minuteh_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_secondh_addr);}}else if (adjust_item == 4) // set secondh{if (KeyNew <6){AlarmTime1.secondh = KeyNew;lcd_write_data(AlarmTime1.secondh + '0');//lcd_write_inst(0x10); // move cursor backadjust_item ++;}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_minutel_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_secondl_addr);}}else if (adjust_item == 5) // set secondl{if ((KeyNew >=0) & (KeyNew <=9)){AlarmTime1.secondl = KeyNew;lcd_write_data(AlarmTime1.secondl + '0');//lcd_write_inst(0x10); // move cursor backadjust_item ++;lcd_write_inst(time_secondl_addr+3);}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_secondh_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_secondl_addr+3);}}else if (adjust_item == 6) // set on/off{if ((KeyNew == key_up) | (KeyNew == key_down)){if (Alarm1Enable){Alarm1Enable =false; // disable alarm1lcd_write_data('f');lcd_write_data('f');}else{Alarm1Enable =true; // enable alarm1lcd_write_data('n');lcd_write_data(' ');}//lcd_write_inst(time_secondl_addr+3);adjust_item = 0;lcd_write_inst(time_hourh_addr);Alarm1Cnt = 0;}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_secondl_addr);}else if(KeyNew == key_right){adjust_item = 0;lcd_write_inst(time_hourh_addr);}}}// -------------------------------------------------------void set_alarm2(void){if (adjust_item == 0) // set hourh{if (((AlarmTime2.hourl <4) & (KeyNew < 3)) | ((AlarmTime2.hourl >3) & (KeyNew <2))){AlarmTime2.hourh = KeyNew;lcd_write_data(AlarmTime2.hourh + '0'); // refresh hourh//lcd_write_inst(0x10); // move cursor backadjust_item ++;}else if(KeyNew == key_left){adjust_item = 6;lcd_write_inst(time_secondl_addr+3);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_hourl_addr);}}else if (adjust_item == 1) // set hourl{if (((AlarmTime2.hourh == 2) & (KeyNew < 4)) | ((AlarmTime2.hourh < 2) & (KeyNew <=9))){AlarmTime2.hourl = KeyNew;lcd_write_data(AlarmTime2.hourl + '0'); // refresh hourl//lcd_write_inst(0x10); // move cursor backadjust_item ++;lcd_write_inst(time_minuteh_addr);}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_hourh_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_minuteh_addr);}}else if (adjust_item == 2) // set minuteh{if (KeyNew <6){AlarmTime2.minuteh = KeyNew;lcd_write_data(AlarmTime2.minuteh + '0');//lcd_write_inst(0x10); // move cursor backadjust_item ++;}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_hourl_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_minutel_addr);}}else if (adjust_item == 3) // set minutel{if ((KeyNew >=0) & (KeyNew <=9)){AlarmTime2.minutel = KeyNew;lcd_write_data(AlarmTime2.minutel + '0');//lcd_write_inst(0x10); // move cursor backadjust_item ++;lcd_write_inst(time_secondh_addr);}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_minuteh_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_secondh_addr);}}else if (adjust_item == 4) // set secondh{if (KeyNew <6){AlarmTime2.secondh = KeyNew;lcd_write_data(AlarmTime2.secondh + '0');//lcd_write_inst(0x10); // move cursor backadjust_item ++;}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_minutel_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_secondl_addr);}}else if (adjust_item == 5) // set secondl{if ((KeyNew >=0) & (KeyNew <=9)){AlarmTime2.secondl = KeyNew;lcd_write_data(AlarmTime2.secondl + '0');//lcd_write_inst(0x10); // move cursor backadjust_item ++;lcd_write_inst(time_secondl_addr+3);}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_secondh_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_secondl_addr+3);}}else if (adjust_item == 6) // set on/off{if ((KeyNew == key_up) | (KeyNew == key_down)){if (Alarm2Enable){Alarm2Enable =false; // disable alarm2lcd_write_data('f');lcd_write_data('f');}else{Alarm2Enable =true; // enable alarm2lcd_write_data('n');lcd_write_data(' ');}//lcd_write_inst(time_secondl_addr+3);adjust_item = 0;lcd_write_inst(time_hourh_addr);Alarm2Cnt = 0;}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_secondl_addr);}else if(KeyNew == key_right){adjust_item = 0;lcd_write_inst(time_hourh_addr);}}}// -------------------------------------------------------void main(void){unsigned char cnt;TRISC = 0x03; // PORTC.3 drive led,low activePORTC_MAP = 0x00;led = 0;BackLightEn = 0;BackLightTimer = 0;PORTC = PORTC_MAP;TRISA = 0xff; // low half byte as keyscan inTRISE = 0x00;ADCON0 = 0x00;ADCON1 = 0x06; // all digital I/Oslcd_init();INTCON = 0x00;lcd_write_inst(0x80); // set lcd ddram addressfor (pStr = StrPower1;*pStr!=0;pStr++){lcd_write_data(*pStr);}lcd_write_inst(0x0c); // LCD cursor offPIR1 = PIR2 = 0x00;T1CON = 0x0f; // T1CON: -- T1CKPS1 T1CPS0 T1OSCEN /T1SYNC TMR1CS TMR1ONTMR1H = 0x80;TMR1L = 0x00;。

pic16f877a编程实例

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引脚设置为输出引脚,并进入一个无限循环。

PIC16f877中文资料1

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等。

PIC196F877A串口通信程序

PIC196F877A串口通信程序

PIC196F877A串口通信程序今天上午完成PIC16F877A 与上位机的串口通信程序!注意:使用MPLAB IDE C 语言编程时,自定义头文件要使用”“包含不能使用串口与单片机的连线原理图串口通信头文件#ifndef T232_H#define T232_H#include “main.h”//定义一帧的开始和结束#define FRAME_BEGIN 0x28//开始帧标志#define FRAME_END 0x29//结束帧标志void init_232() ;void send_str(const char *str) ;char get_char() ;void get_string(char *temp) ;void put_char(char temp) ;#endif串行通信子程序//基于TPDEM1,通过串口调试助手等串口观察软件观察程序,//将TPDEM1通过ICD2 配送的串口延长线与PC 的串口连接,设置PC 的串口为默认设置,如波特率9600,数据位8,无校验位,使用FIFO#include “t232.h”/**Function:init seriel port*/void init_232(){ INTCON=0; TRISC7=1; //RX 置输入TRISC6=0; //TX 清成输出RCSTA=0x90;//连续接受多位数据TXSTA=0x24; SPBRG=25; //9600=4000000/(16*(X+1))->X=25,high speed mode// INTCON=0xC0;//开GIE,外围中断PEIE //RCIE=1; //开接收中断}/**Fuction:send const string to seriel port/void send_str(const char *p){while((*p)!=/0){put_char(*p++) ;}}/Function:get charactor from serial port*/char get_char(){char temp ;while(!RCIF) ; /* set when register is not empty */temp = RCREG ; return RCREG; /* RXD9 and FERR are gone now */}。

PIC单片机串口通讯程序

PIC单片机串口通讯程序
PDF 文件使用 "pdfFactory Pro" 试用版本创建
BSF RCSTA,CREN ;接收允许 BSF STATUS,RP0 BSF TXSTA,TXEN ;发送允许 BCF STATUS,RP0 WAIT BTFSS PIR1,RCIF ;等待接收数据 GOTO WAIT MOVF RCREG,0 ;读取数据 MOVWF INDF ;将接收到的响应字节存入 PIC2 的 RAM INCF FSR MOVWF TXREG ;发送响应字节 LOOPTX BTFSS PIR1,TXIF ;等待写入完成 GOTO LOOPTX BTFSS FSR,7 ;全部数据接收否? GOTO WAIT1 ;没有,继续接收其它数据 BCF RCSTA,RCEN ;接收完,则关断接收和发送数据允许 BSF STATUS,RP0 BCF PIE1,TXEN BCF STATUS,RP0 CALL LED ;调用显示子程序,将接受到的数据显示出来 END ;程序完
2. 单片机 PIC2 编程(接收部分)
LIST P=16F876 #INCLUDE P16F876.INC CBLOCK 0X24 COUNT ENDC ORG 0X0000 NOP START GOTO MAIN MAIN BSF STATUS,RP0 ;初始化程序同发送子程序 MOVLW 0X19 ;波特率设置与 PIC1 相同 MOVWF SPBRG MOVLW 0X04 ;异步高速传输 MOVWF TXSTA BCF STATUS,RP0 MOVLW 0X80 ;串行口工作使能 MOVWF RCSTA BSF STATUS,RP0 BSF TRISC,7 ;与外接电路隔离 BSF TRISC,6 BCF STATUS,RP0 MOVLW 0X30 ;从 30H 单元开始存放发送来的数据 MOVWF FSR

PIC16F877A单片机中文文献

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单片机一样,在配置结构上可分为通用寄存器和特殊功能寄存器两大类。

PIC单片机串口通讯程序

PIC单片机串口通讯程序
PDF 文件使用 "pdfFactory Pro" 试用版本创建
BSF RCSTA,CREN ;接收允许 BSF STATUS,RP0 BSF TXSTA,TXEN ;发送允许 BCF STATUS,RP0 WAIT BTFSS PIR1,RCIF ;等待接收数据 GOTO WAIT MOVF RCREG,0 ;读取数据 MOVWF INDF ;将接收到的响应字节存入 PIC2 的 RAM INCF FSR MOVWF TXREG ;发送响应字节 LOOPTX BTFSS PIR1,TXIF ;等待写入完成 GOTO LOOPTX BTFSS FSR,7 ;全部数据接收否? GOTO WAIT1 ;没有,继续接收其它数据 BCF RCSTA,RCEN ;接收完,则关断接收和发送数据允许 BSF STATUS,RP0 BCF PIE1,TXEN BCF STATUS,RP0 CALL LED ;调用显示子程序,将接受到的数据显示出来 END ;程序完
PIC 单片机串口通讯程序
单片机串口通讯是一个常用的程序模块。PIC 单片机是一款常用的单片机。在网 上搜索到一个 PIC 单片机串口通讯程序。这个 PIC 单片机串口通讯程序站长没有 验证,应该是正确的。假如大家有更好的 PIC 单片机串口通讯程序,请向我t ch[15]; main () { int a; int i,j; int b[6]={88,15,38,26,20,0}; char c; clrscr(); outportb(port+3,0x80); /*准备设置波特率*/ outportb(port,0x0C); /*波特率设置为 9 600 bps*/ outportb(port+1,0x00); outportb(port+3,0x03); /*8 位数据位,奇偶检验,1 位停止位*/ outportb(port+1,0x00); /*关中断*/ inportb(port+5); /*读一次线路状态寄存器,使其复位*/ { printf("\t\tsend data or receive data: (s or r?)\n\n\n"); c=getchar(); switch(c) { case ’s’: case ’S’: { while(!(inportb(port+5)&0x20)); /*发送保持器满则等待*/ outportb(port,0x01); /*否则发送数据 01 通知单片机准备接收*/ for(i=0;i<6;i++) /*共发送 6 个数据*/ { a=b[i]; while(!(inportb(port+5)&0x20)) delay(100); /*发送保持器满,等待*/ outportb(port,a); /*发送 a*/ printf("%d\n",a); /*显示 a*/ while(!(inport(port+5)&1)); /*接收单片机送回的数据*/ ch[i]=inport(port); /*保存*/ } delay(10); for(j=0;j<8;j++) /*显示接收的回送数据*/ printf("\n%d\n",ch[j]); getch(); break; } case’r’: /*接收数据*/ case’R’: { while(!(inportb(port+5)&0x20));

PIC16F877ASPI通信C程序

PIC16F877ASPI通信C程序
TRISB=1; //RB0口为输入关++++++++++++
TRISC=0b00010001;//C口SDO为输出SDI为输入,SCK为输出,RC1输出RC0输入开
TRISD=0; //D口全为输出
PORTD=0;
SSPEN=1;//相应的引脚为一般的I/O口
CKP=1;//空闲时钟为高电平
SMP=1;//在数据信号的末端采样
number如果接受与发送的数据不相等则发生错误error1
#include<pic.h>
//注意RB0要接下拉电阻
__CONFIG(0x3F39);
void CSH(void);//初始化子程序
void DELAY(unsigned int n);//函数声明
char SPI_WRITE(char R); //SPI发送函数
A=SPI_WRITE(number);//发送数据
RC2=1;//完成写操作
DELAY(5);
}
void interrupt ISR(void)
{char a;int k;
if(INTF==1)
{
for (k=1024;k>0;k--)NOP();//DELAY(30);//防抖动
INTF=0;//清标志位
}
void WRITE(char number)
{char A;
RC2=0;//片选信号,低电平有效
SPI_WRITE(0b00000110);//允许写入
RC2=1;//完成写使能
RC2=0;//片选信号,低电平有效
A=SPI_WRITE(0b00000010);//写指令

lcd1602_pic16f877a_程序_代码

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串口通信C#温度实时曲线

PIC16F877A串口通信C#温度实时曲线

PIC16F877A串口通信C#温度实时曲线__77A串口通信C#温度实时曲线、RS232串口通信上位机界面下位机电路图,可以仿真利用虚拟端口仿真效果__77A串口通信C#温度实时曲线、RS232串口通信上位机C#源程序//包含画图程序using System;using System.Collections.Generic;using .cnponentModel;using System.Data;using System.Drawing;using System.Drawing.Drawing2D;using System.Text;using System.Windows.Forms;using System.IO.Ports;namespace CommPort{public partial class Form2 : Form{private int txd;private int rxd;public float pon;//存?放¤?数y据Y的?变?量? private int n;private float x1, x2, y1, y2,y11, y21 ;//画-线?的?坐?标¨private Pen Mypen1;//画-笔¨private Pen Mypen2;//private Graphics grfx;public Point ptlist;//存?放¤?坐?标¨圆2点?__77A串口通信C#温度实时曲线、RS232串口通信// Random rm = new Random();//随?机¨数y产¨生¨器//Timer mytimer = new Timer();//定§时器public Form2(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e) {txd = 0;//接¨收?字?符¤?个?数y计?数y变?量?rxd = 0;//发¤é送¨字?符¤?个?数y计?数y变?量?//count = 0;ptlist = new Point(0, this.pictureBox1.Height);x1 = ptlist.X;x2 = ptlist.X;y1 =ptlist.Y;Mypen1 = new Pen(Color.Blue,1);Mypen2 = new Pen(Color.Red, 2);//y2 =ptlist.Y;string[] ports = System.IO.Ports.SerialPort.GetPortNames();//获?取¨?当前计?算?机¨的?串?行D端?口¨名?称?数y组¨,ê?存?在¨数y组¨里¤?mycomm.ReadTimeout = 32;//设¨¨置?读¨取¨?操¨作未完¨成¨时发¤é生¨超?时之?前的?毫¨秒?数y。

PIC16F877单片机与PC机的串行通信

PIC16F877单片机与PC机的串行通信

PIC16F877单片机与PC机的串行通信
南光群;吴鸿霞
【期刊名称】《湖北理工学院学报》
【年(卷),期】2005(021)006
【摘要】介绍了PIC16F877单片机与PC机实现串行通信的一种方法,并给出了硬件接口电路及通信源程序.
【总页数】4页(P31-34)
【作者】南光群;吴鸿霞
【作者单位】黄石理工学院电气与电子信息工程学院,湖北,黄石,435003;黄石理工学院电气与电子信息工程学院,湖北,黄石,435003
【正文语种】中文
【中图分类】TP368.1
【相关文献】
1.Ti DM642芯片与PIC16F877单片机之间的异步串行通信 [J], 倪炜;李维
2.51单片机与上位PC机的串行通信技术 [J], 张岩
3.基于Proteus仿真软件实现单片机与PC机多字节串行通信 [J], 王忠远;张凤桐
4.用VC++实现PC机与单片机的串行通信 [J], 许江宁
5.利用VB8.0实现PC机与多单片机串行通信的方法 [J], 王平根
因版权原因,仅展示原文概要,查看原文内容请购买。

最新PIC16F877A单片机中文文献

最新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单片机中串行通讯模块的应用

PIC16F877单片机中串行通讯模块的应用
麻恒进
【期刊名称】《电子世界》
【年(卷),期】2002(000)001
【摘要】@@ PIC16F877单片机具有通过两个端口线即可进行在线串行编程、在线调试的特点,因而出现了相对便宜的快速开发工具MPLAB-ICD.该芯片集成了多种外围功能模块,如十位多通道A/D转换模块、同步串行口SSP(synchronous serial port)部件、通用同步异步收发器部件USART(universal
synchronous/asynchronous receiver transmitter)等,从而减少了构成系统时所需的外部器件,提高了设计的速度.随着器件的减少,系统的稳定性也得到了提高.本文将讨论经常用到的USART模块及使用中应注意的几个问题.
【总页数】1页(P30)
【作者】麻恒进
【作者单位】中国航空精密机械研究所第四研究室
【正文语种】中文
【中图分类】TP3
【相关文献】
1.PIC16F877单片机在Scorpion采集站中的应用 [J], 周阿群;祝彩霞;吴秀琴
2.PIC16F877单片机在地震预测系统中的应用 [J], 王一飞;章勇
3.PIC16F877单片机在智能站用电源系统中的应用 [J], 皮大能;南光群;闵小玲
4.PIC16F877单片机在智能站用电源系统中的应用 [J], 皮大能;南光群;闵小玲
5.PIC16F877A单片机在软起动控制器中的应用 [J], 郭继红;李虹飞
因版权原因,仅展示原文概要,查看原文内容请购买。

PIC16F877原理简介

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. 40引脚PIC16F877接脚说明图2. 28引脚PIC16F877接脚图说明图3. 44引脚PIC16F877脚位图说明图4. 44引脚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等。

图5. PIC16F877的RAM配置图(图片来源:Microchip PIC16F87X Data Sheet)1.2 特殊内嵌功能PIC16F877属于内嵌功能较多的单片机,除了CPU、POM、RAM、I/O等基本构造外,还包括以下各种功能,简介如下:A/D converter:模拟数字转换器,最多可以读取8组模拟输入讯号。

PIC单片机与PC机的串行数据交换

PIC单片机与PC机的串行数据交换

PIC单片机与PC机的串行数据交换一、前言美国Microchip公司的PIC系列单片机是一种新型的CMOS工艺单片机,其中,有许多单片机内部带有异步通讯模块,如PIC16F877等系列芯片。

单片机虽然在使用中可等同于一个CPU,但是在许多需要大量计算的运用中,还必须借助微机(PC)的强大数据处理能力,这样就必须通过通信电路实现PIC单片机与微机间的可靠数据传输。

不论PIC单片机内有没有提供串行口,在实现串行通信时都必须通过自己设计硬件电路和编写通信软件来实现,而PIC 单片机要完成较复杂的软件功能时,需利用其内部相关的特殊功能寄存器来实现。

下面介绍PIC16F877与微机间进行异步串行通讯的实现方法,同时给出与微机间进行异步串行通讯的硬件接口电路、程序流程框图、单片机内通信程序等。

二、PIC16877与PC机间进行数据交换的实现要实现PIC16F877与PC机间进行数据交换,在编写程序时首先要设置好USART异步通讯模块工作模式及相关寄存器,现分别介绍如下。

1PIC16F877的USART异步工作设置简介PIC16F877的USART与其他具有USART的PIC单片机一样,可以被设置成为与PC机进行全双工异步通讯,它是一种利用PORTC口的RC6和RC7两个引脚作为通讯的2线制串行通讯接口。

为了把PORTC口的RC6和RC7两个引脚分别设置成串行通讯接口的发送(TX)脚和接收(RX)脚,必须要把USART的接收状态和控制寄存器RCSTA的bit7(SPEN)位和TRISC寄存器的bit7置“1”,把TRISC寄存器的bit6置“0”。

为了使USART分别工作于接收或发送状态,就必须设置相应的状态寄存器和控制寄存器。

在设置接收器时,要注意接收脚对接收信号的采样。

接收脚RX上的数据被采样3次,通过一个三中取二逻辑检测电路来判断RX 脚上的电平是高还是低,以作为采样取值。

另外,要使USART工作在异步通讯方式,就必须要设置通讯的传送、接收速率即波特率,USART的波特率设置是通过控制独立的一个8位波特率发生器BRG实现的。

PIC单片机C语言编程实例

PIC单片机C语言编程实例
/*系统初始化*/ /*B 口变位中断初始化*/ /*利用 SPI 显示初始化*/ /*总中断允许*/
/*等待中断*/
1.1.2 程序清单
下面给出一个调试通过的例程,可作为读者的参考。调试该程序把模板 J7 上的短路跳 针拔下,以免产生冲突。
#include <pic1687x.h>
volatile unsigned char data;
TRISC=0x00;
/*SDO 引脚为输出,SCK 引脚为输出*/
}
1.2.3 程序清单
下面给出已经在实验板上调试通过的一个程序,可作为用户编制其它程序的参考。
#include
<pic1687x.h>
/*该程序用于在 8 个 LED 上依次显示 1~8 等 8 个字符*/
static volatile int table[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,
I;
unsigned char j;
const char table[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90,
0x88,0x83,0xc6,0xa1,0x86,0x8e,0x7f,0xbf,0x89,0xff};
/*B 口“电平变化中断”初始化子程序*/
/*启动发送*/
do
{

}while(SSPIF==0);
/*等待发送完毕*/
SSPIF=0;
/*清除 SSPIF 标志*/
}
/*主程序*/
main()
{
unsigned I;
initial();
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

PIC16F877A与PC机串行通信C语言源程

//*******串口通信程序*********
//*******定义变量*************
#include ;
#define unchar unsigned char
#define uint
unsigned int
unchar
RC_label;//标志位起始位为1结束位为0
unchar
caiji_label;//采集帧格式标志位正确为1错误为0 unchar data RC[100];//存储接收到的数据
unchar data TX1[100];//存储自身参数
unchar data TX2[100];//存储出错指示ERROR
int
RC_buff;//
int
i=0,j=0,k=0;//
//*****变量定义完毕************
//*****子程序区****************
//*****串口初始化程序开始********** void initRS232()
{
//设置TXSTA
CSRC=0;//
TX9=0;//8位数据发送
TXEN=1;//发送使能
SYNC=0;//选择异步模式
BRGH=1;//高速
TRMT=1;//发送寄存器空
TX9D=0;//
//设置RCSTA
SPEN=1;//允许串口工作
RX9=0;//接收8位数据
SREN=1;//
CREN=1;//使能连续接收
ADDEN=0;//
FERR=0;//
OERR=0;//无超速错误
RX9D=0;//
TRISC=0X80;//设置C口
SPBRG=0X19;//设置波特率为9600
}
//*******初始化232完毕********
//*******延时子程序开始*********
void delay(int i)
{for(i;--i;) continue;}
//******延时子程序完毕*******
//******中断初始化子程序开始****** void int_interrupt(void)
{
GTE=1;//
PEIE=1;//
RCIE=1;//
}
//*******中断初始化子程序完毕******** //********中断服务子程序开始********* void interrupt receive(void)
{
if(OERR==1)//判断有无超速错误
{
CREN=0;
CREN=1;
}
if(RCIF==1)
{
RC_buff=RCREG;
if(RC_buff==0x2a)//判断是否是起始标志* {
RC_label=1;
}
if(RC_buff==0x23)//判断是否是结束标志# {
RC_label=0;
}
}
if(RC_label==1)
RC[k++]=RC_buff;//将接收到的数据存储在数组中 else if(RC_label==0)
k=0;
if(RC[1]==0XFE&&RC[2]==0XC0&&RC[3]==0X34&&RC[5]== 0X12)//判断数据采集帧格式是否正确
caiji_label=1;
else caiji_label=0;
//********中断服务子程序完毕**********
//********参数发送子程序开始**********
void TX_serve(void)
{
TX1[]={0X2A,0XFD,0X26,0X30,0X31,0X32};//自身参数存储在TX1中
TX2[]={0X56,0X52,0X52,0X4F,0X52};//出错指示存储在TX2中
if(caiji_label==1)//如果数据采集帧格式正确则发送自身参数帧
{
for(j=0;j<6;j++)
{
TXREG=TX1[j];
delay(20);
}
}
if(caiji_label==0) //如果数据采集帧格式错误则发送出错指示
{
for(j=0;j<5;j++)
{
TXREG=TX2[j];
delay(20);
}
}
}
//********参数发送子程序完毕********** //********主程序开始************** void main()
{
int_interrupt();
initRS232();
TX_serve();
end
}。

相关文档
最新文档