×
单片机 > 单片机程序设计 > 详情

PIC16F887 串口 LCD1602 按键

发布时间:2021-06-15 发布时间:
|

#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 != '


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
Keil(MDK-ARM)系列教程(七)_菜单