历史上的今天

今天是:2024年08月27日(星期二)

正在发生

2020年08月27日 | PIC16F887 串口 LCD1602 按键

发布者:TranquilVibes 来源: eefocus关键字:PIC16F887  串口  LCD1602  按键 手机看文章 扫描二维码
随时随地手机看文章

#include

#include

#include

#include

#define uchar unsigned char

#define uint unsigned int


/* CONFIG1 */

#pragma config FOSC = XT        /* Oscillator Selection bits (XT oscillator: Crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN) */

#pragma config WDTE = OFF       /* Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register) */

#pragma config PWRTE = OFF      /* Power-up Timer Enable bit (PWRT disabled) */

#pragma config MCLRE =ON        /* RE3/MCLR pin function select bit (RE3/MCLR pin function is digital input, MCLR internally tied to VDD) */

#pragma config CP = OFF         /* Code Protection bit (Program memory code protection is disabled) */

#pragma config CPD = OFF        /* Data Code Protection bit (Data memory code protection is disabled) */

#pragma config BOREN = OFF      /* Brown Out Reset Selection bits (BOR disabled) */

#pragma config IESO = OFF       /* Internal External Switchover bit (Internal/External Switchover mode is disabled) */

#pragma config FCMEN = OFF      /* Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled) */

#pragma config LVP = OFF        /* Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming) */


/* CONFIG2 */

#pragma config BOR4V = BOR40V   /* Brown-out Reset Selection bit (Brown-out Reset set to 4.0V) */

#pragma config WRT = OFF        /* Flash Program Memory Self Write Enable bits (Write protection off) */



void delaya_US( unsigned char n );



void LCD_CSH( void );



void LCD_WRITE_4( unsigned char R1, unsigned char FLAG );



void LCD_WRITE( unsigned char R1, unsigned char FLAG );



unsigned char LCD_READ( void );



void LCD_BUSY( void );



void delaya( unsigned int n );



/* LCD显示相关 */

#define DATA 1                                       /* LCD写数据时为1 */

#define COM 0                                       /* LCD写命令时为0 */

#define LINE1 0b10000000

#define LINE2 0b11000000


#define LCD_E RD6

#define LCD_RW RD5

#define LCD_RS RD4


/* ======延时(n×10)us */

void delaya_US( unsigned char n )

{

unsigned char j;

for ( j = 0; j < n; j++ )

{

NOP(); NOP();

}

}



/* LCD初始化 */

void LCD_CSH( void )

{

TRISD = 0x00;  /* RD方向输出 */


delaya( 20 );


LCD_WRITE_4( 0b0011, COM );

delaya( 5 );

LCD_WRITE_4( 0b0011, COM );

delaya_US( 10 );

LCD_WRITE_4( 0b0011, COM );

delaya_US( 10 );


LCD_WRITE_4( 0b0010, COM );


LCD_BUSY();

LCD_WRITE( 0b00101000, COM );

LCD_WRITE( 0b00001100, COM );

LCD_WRITE( 0b00000001, COM );

delaya( 2 );

LCD_WRITE( 0b00000110, COM );

}



/* LCD写4位命令 */

void LCD_WRITE_4( unsigned char R1, unsigned char FLAG )

{

LCD_RW = 0; NOP();

LCD_RS = FLAG;

PORTD &= 0xF0;

LCD_E = 1; NOP();

PORTD |= R1;

NOP(); NOP();

LCD_E = 0; NOP();

LCD_RS = 0; NOP();

PORTD &= 0xF0;

}



/* LCD写命令 */

void LCD_WRITE( unsigned char R1, unsigned char FLAG )

{

unsigned char R2;


LCD_BUSY();

LCD_RW = 0; NOP();

LCD_RS = FLAG;

R2 = (R1 >> 4) & 0x0F;

PORTD &= 0xF0; NOP();

LCD_E = 1;

PORTD |= R2;

NOP(); NOP();

LCD_E = 0;


R2 = R1 & 0x0F;

PORTD &= 0xF0; NOP();

LCD_E = 1; NOP();

PORTD |= R2;

NOP(); NOP();

LCD_E = 0; NOP();

LCD_RS = 0; NOP();

PORTD &= 0xF0;

}



/* 读LCD状态 */

unsigned char LCD_READ( void )

{

unsigned char R1;

TRISD = 0x0F;

LCD_RS = 0; NOP();

LCD_RW = 1;

NOP(); NOP();

LCD_E = 1;

NOP(); NOP();

NOP(); NOP();

R1 = 0;

R1 = (PORTD << 4) & 0xF0;

LCD_E = 0;

NOP(); NOP();

NOP(); NOP();

LCD_E = 1;

NOP(); NOP();

R1 |= (PORTD & 0x0F);

LCD_E = 0; NOP();

LCD_RW = 0;

TRISD = 0x00;

return(R1);

}



/* 检测LCD是否忙 */

void LCD_BUSY( void )

{

unsigned char R1;

do

{

R1 = LCD_READ();

}

while ( (R1 & 0x80) == 0x80 );

}



/* ======延时(n)ms */

void delaya( unsigned int n )

{

unsigned int j;

unsigned char k;

for ( j = 0; j < n; j++ )

for ( k = 246; k > 0; k-- )

NOP();

}



/*

 * ***********************************************************************

 * 显示屏字符串写入函数

 * ***********************************************************************

 */

void LCD_write_str( unsigned char x, unsigned char y, char *s )

{

if ( y == 0 )

{

LCD_WRITE( 0x80 + x, COM );

}else {

LCD_WRITE( 0xC0 + x, COM );

}


while ( *s )

{

LCD_WRITE( *s, DATA );

s++;

}

}



#define K1 RC0

#define K2 RC1

int Keyscan( void )

{

TRISC |= 0x03;                   /*按键是输入 */

if ( K1 == 0 )

{

delaya( 5 );

if ( K1 == 0 )

{

while ( K1 == 0 )

;       /* 等待按键松开 */

return(1);

}

}

if ( K2 == 0 )

{

delaya( 5 );

if ( K2 == 0 )

{

while ( K2 == 0 )

;  /* 等待按键松开 */

return(2);

}

}

return(0);

}



/*********************************************************************************

 * 【函 数 名】: void send_cmd(unsigned char dat)

 * 【功    能】: 串口发送数据命令

 **********************************************************************************/

void send( unsigned char dat )

{

TXREG = dat;

while ( TRMT != 1 )

;  /* 等待发送完成 */

}



/*********************************************************************************

 * 【函 数 名】: Print_Str(unsigned char *s)

 * 【功    能】: 串口发送 一个字符串

 **********************************************************************************/

void Print_Str( unsigned char *s )

{

while ( *s != '' )

{

send( *s++ );

}

}


void dispaly_rtctime(unsigned char h,unsigned char m,unsigned char s)

{

    char xianshi[15];

    char count=0;

    xianshi[count++]='0'+h%100/10;

    xianshi[count++]='0'+h%10;

     xianshi[count++]=':';

    xianshi[count++]='0'+m%100/10;

    xianshi[count++]='0'+m%10;

     xianshi[count++]=':';

    xianshi[count++]='0'+s%100/10;

    xianshi[count++]='0'+s%10;

    xianshi[count++]=0;

    LCD_write_str(0,0,xianshi);

}



#define LED RB0


int led_flash = 0;                  /* 为1就闪烁灯定时器闪烁  串口接受会改变这个值 */

unsigned int T1_10MS;                        /* 频率 */

char recdata;                        /* 接受字符 */

char rev_ifg = 0;

char rev_buffer[5];                  /* 装下信息 */

char rev_buffer_count = 0;

int time = 0;    /* 计时 */

char ledifg = 0;

int time1 = 0;

unsigned char rtc_hour = 23;

unsigned char rtc_min = 59;

unsigned char rtc_sec = 55;



void main( void )

{

int key = 0;


ANSEL = 0;                            /*选择ADC引脚 */

ANSELH = 0;


T1CON = 0b00100001;                   /* 内部时钟源 (F OSC /4) */

GIE = 1; PEIE = 1; TMR1IE = 1;

TMR1IF = 0;

T1_10MS = 100;                          /* 执行定时器中断的频率 */

T1_10MS = 1000000 / T1_10MS;            /* 多少时间 也就是选择频率 */

T1_10MS = (65535 - T1_10MS / 4);        /* 给到硬件定时器 */

TMR1H = T1_10MS >> 8;

TMR1L = T1_10MS;

    


/* 串口初始化 */

SPBRG = 25;                           /* 4mhz 9600 */

TXSTA = 0X24;

RCSTA = 0X90;

RCIE = 1;

CREN = 1;

SYNC = 0;

SPEN = 1;

GIE = 1;

PEIE = 1;

TRISC6 = 0;

TRISC7 = 1;

RC6 = 1;

RC7 = 1;


/* 小灯是输出 */

TRISB = 0x00;

LED = 1; /* 输出高 不亮的 */

    

    

    LCD_CSH();

delaya( 30 );

    



while ( 1 )

{

key = Keyscan();        /* key 有按键1或者2 否则就是0 */

if ( key != 0 )

{


led_flash = 0;  /*不再闪烁灯 */

}

        

        

}

}



void interrupt high_isr( void )         /* 也可以加 high_priority */

{

unsigned char xianshi[20];


if ( TMR1IF )                   /* 中断一次 */

{

/* 重新给时间 */

TMR1IF = 0;

TMR1H = T1_10MS >> 8;

TMR1L = T1_10MS;


time1++;

if ( time1 > 100 )

{

time1 = 0; /* 1s时间 */


            //更新时间

rtc_sec++;

if ( rtc_sec == 60 )

{

rtc_sec = 0;

rtc_min++;

if ( rtc_min == 60 )

{

rtc_min = 0;

rtc_hour++;

if ( rtc_hour == 24 )

{

rtc_hour = 0;

}

}

}

            //显示时间

            if(led_flash==0)

            {

                dispaly_rtctime(rtc_hour,rtc_min,rtc_sec);

            }

            

            

}



/*下面就是控制小灯闪烁 */

time++;

if ( time > 10 )

{

time = 0;

if ( led_flash == 1 )

{

ledifg = !ledifg;

if ( ledifg == 0 )

LED = 0;

else LED = 1;

}

}

}  else if ( RCIF )

{

/* 串口接受中断 */

RCIF = 0;

recdata = RCREG;

send( recdata );

        

        if ( rev_ifg == 2 )

{

            rev_buffer[rev_buffer_count++] = recdata;       /* 接受 */

if ( rev_buffer_count == 4 )

{

/* 接受到了4个字符 比如2房3床 就是接收到0203 */

                LCD_CSH();

                delaya( 30 );

LCD_write_str( 0, 0, rev_buffer );      /* 显示出来 */

                

                rev_ifg=0;

[1] [2]
关键字:PIC16F887  串口  LCD1602  按键 引用地址:PIC16F887 串口 LCD1602 按键

上一篇:PICC编译错误
下一篇:PIC18F45K80 CAN通讯示例代码

推荐阅读

中国国际工业博览会(简称"中国工博会")是以创新、智能、绿色制造为展示交易主体的国际工业展,将于2018年9月19日至23日在上海举行。今年德承将在中国工博会的工业自动化展(IAS),展示其强固型无风扇计算机、转换型嵌入式系统、工业平板电脑和工业触摸显示器给国内各地的客户。凭借领先的产品和以应用需求为导向的功能,德承在国内外多个行业中实现了新...
9.1 初学者重要提示1、 如果对C语言不熟练的话,可以阅读C语言书:C Primer Plus(第五版)中文版.pdf论坛下载:http://forum.armfly.com/forum.php?mod=viewthread&tid=91219。 2、 为了更好的学习本章知识点,可以看之前做的视频教程第10章,针对H7也将在今年发布视频教程:http://forum.armfly.com/forum.php?mod=viewthread&tid=15408 。9.2 ...
  一、工业机器人内部组成   1.机械部分   机械部分是机器人的血肉组成部分,也就是我们常说的机器人本体部分。这部分主要可以分为两个系统:   (1)驱动系统   要使机器人运行起来,需要各个关节安装传感装置和传动专治,这就是驱动系统。它的作用是提供机器人各部分、各关节动作的原动力。驱动系统传动部分可以是传动系统、电动传动系...
当你读到这里时,或许会问,FFT有什么好讨论的,难道ZDS2022示波器会有什么本质的不同吗?我们不妨简单地回顾一下FFT中几个重要的参数和关系表达式。采样率:示波器的采样频率,用Fs表示。ZDS2022示波器每通道均支持1GS/S采样率,下面将以最高采样率1GS/S为基准描述相关的问题;FFT点数:与示波器死区时间对应的参数是示波器的波形刷新率,又叫波形捕获率...

史海拾趣

问答坊 | AI 解惑

直流逆变器的研究

直流逆变器的研究…

查看全部问答∨

WinCE6.0如何制作SDK

以前在Wince5.0上做SDK都很好用,现在换到6.0 VS2005中我想做个SDK但是做出来的SDK拿去一编译就出错了,用系统默认给的就没问题,在我的SDK制作的过程中,系统提示没有加入一些头文件和库,我想就是这里的问题,使得我做的SDK使用的时候出错。有没 ...…

查看全部问答∨

SPI接口程序

有没有人有YC2440板子WCE系统下的SPI接口程序啊?? 或者例程之类的,能不能给我一份啊??…

查看全部问答∨

wince 2.11是否支持.net

如题, 如果不支持那怎么开发程序(各种语言都可) 如有资料请传给我 shuwu520@sina.com…

查看全部问答∨

分析LED照明趋势,来谈谈吧

 LED的效率趋势如何?以各种光源的发光效率来看,白炽灯和卤素灯只有20~30lm/W,省电灯泡大约在70lm/W,HID能够增加到100lm/W,灯管发光效率目前微增至近120lm/W,不过在2010年分别只有约80lm/W和不到30lm/W的LED和OLED,却都呈现快速改善的态势,未来 ...…

查看全部问答∨

有没有用AVR控制USB芯片PDIUSBD12进行数据传输的啊

有没有用AVR控制USB芯片PDIUSBD12进行数据传输的啊 我最近要做一个AVR16与PC机数据传输的项目,有没有调过USB的 我选择的芯片是PDIUSBD12,如果有调试过的朋友可以联系我么,或者分享给我点经验,谢谢了 (不知道我把帖子发表到这个AVR板块对不 ...…

查看全部问答∨

做了一块单通道功率放大器,单电源供电,加上直流稳压源后按电容有声音,什么情况?

就是用手触碰电解电容的时候稳压电源会有声音,为什么??极性应该没有反,两种接都会有声音。…

查看全部问答∨

【晒心得】+ eZ430-Chronos 无线手表初体验

      于9月7日在德州仪器estore官网下订单,11日发货,14日到达深圳,由于周末不派送,如预期在今天(16日)下午收到。话说联邦快递的服务真心不错,先询问我是否方便收货,询问收货的地点,之后再次通知我去我指定的地点取货 ...…

查看全部问答∨

使用ADSP-CM408F ADC控制器的电机控制反馈采样时序

使用ADSP-CM408F ADC控制器的电机控制反馈采样时序 …

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved