⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 这是我从朋友那搞到的pic学习资料
💻 C
字号:
/* ****************************************************************
** 功能描述: 采用B口电平变化中断查键方式识别键盘,按下K1键时第一个数码管数码管显示1,按下K2键时显示2,按下K3键时显示3,按下K4键时显示4
*************************************************************** */
#include	"pic18.h"		/* PIC18系列的头文件 */
const	char	table[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90, 0x88,0x83,0xc6,0xa1,0x86,0x8e};
						/* 不带小数点的显示段码表,依顺序为0-F共16个 */
const	char	table0[10]={0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10};
						/* 带小数点的0-9显示段码表 */
unsigned	char	key=0;		// 按键键值,=1表示1号键按下,…,=4表4号键按下
unsigned	char	PORTB_keyflag=0;		//=1有键按下,=0无按按下

/* ****************************************************************
** 函 数 名: initial()
** 功能描述: 系统初始化子程序,放在程序首部
*************************************************************** */
void	initial()
{
	INTCON=0x00;				/* bit7-bit0:关总中断 */
	ADCON1=0X07;				/* 设置数字输入输出口 */
	PIE1=0;					/* PIE1 的中断不使能 */			
	PIE2=0;					/* PIE2 的中断不使能 */	
	PIE3=0;					/* PIE3 的中断不使能 */	
}

/* ****************************************************************
** 函 数 名: SPIinitial()
** 功能描述: SPI输出初始化子程序
*************************************************************** */
void	SPIinitial()
{
	TRISA=TRISA&0xdf;		/* 设置RA5输出74HC595锁存信号的引脚为输出 */
	TRISC=TRISC&0xd7;		// SDO(RC5)引脚为输出,SCK(RC3)引脚为输出
	SSPCON1=0x30;			// SSPEN=1;CKP=1,FOSC/4
	SSPSTAT=0xC0;			// 时钟下降沿发送数据
	SSPIF=0;					// 清除SSPIF标志
}

/* ****************************************************************
** 函 数 名: SPILED()
** 功能描述: SPI传输数据(发送数据)子程序
*************************************************************** */
void  	SPILED(char	data)
{
	SSPBUF=data;				/* 启动 SPI 发送 */
	do
	{
	  ;
	}while(SSPIF==0);		/* 等待SPI 发送完成 */
	SSPIF=0;					/* 清SPI 发送完成标志 */
}

/* ****************************************************************
** 函 数 名: display(unsigned  char  data)
** 功能描述: 在第8个数码管显示数据,其余7个不显示(全暗)
*************************************************************** */
void	display(unsigned  char  data)
{
	unsigned  char  k;

	RA5=0;					/* 准备锁存显示数据 */
	data=table[data];		/* 查与显示数据对应的段码 */
	SPILED(data);			/* 发送显示段码 */
	for(k=1;k<8;k++)
	{
		SPILED(0Xff);		/* 发送当前数码管不显示段码 */
	}
	RA5=1;					/* 给锁存信号,显示数字 */
}

/* ****************************************************************
** 函 数 名: PORTB_Interrupt_Initial()
** 功能描述: PORTB口电平变化中断初始化
*************************************************************** */
void	PORTB_Interrupt_Initial()
{
	TRISB=TRISB|0xf0;	// PORTB工作在电平变化中断方式,bit7-bit4设置为输入
	INTCON=INTCON|0x08;		// RBIE=1,使能RB电平变化中断
	INTCON=INTCON&0xfe;		// RBIF=0,清RB电平变化中断标志
	INTCON2=INTCON2&0x7f;	// 在电平变化中断方式下,B口电平弱上拉,RBPU=0
	RBIP=0;					// RB电平变化中断为低优先级中断 
	TRISB1=0;				// 设置K1为输出
	TRISA3=0;				// 设置K2为输出
	TRISE0=0;				// 设置K3为输出
	TRISE1=0;				// 设置K4为输出

	RB1=0;					/* 设置K1-K4平时为低电平,4个键的另一端均接到
RB4上,平时RB4为高电平(上拉),有键
按下后,被K1-K4下拉为低电平,产生中断 */
	RA3=0;
	RE0=0;
	RE1=0;
	PORTB=PORTB;				// 设置PORTB口电平变化初始条件	
}

/* ****************************************************************
** 函 数 名: DELAY_PORTB_Interrupt()
** 功能描述: PORTB口电平变化中断查键延时防抖子程序
*************************************************************** */
void 	DELAY_PORTB_Interrupt()
{
	unsigned  int  i;

	for(i = 553; i>0;i--)
		i=i;
}	

/* ****************************************************************
** 函 数 名: KEYSCAN_PORTB_Interrupt()
** 功能描述: PORTB口电平变化中断查键键扫描子程序
*************************************************************** */
void	KEYSCAN_PORTB_Interrupt()
{
	if(RB4==0)					// 有键按下
	{
		DELAY_PORTB_Interrupt();// 若有键按下,则软件延时防抖
		if (RB4==1)	return;		// 防抖后无键按下,是抖动,不做按键处理,返回
		//以下为防抖后仍有键按下的查键值
		RB1=0;					// 设置K1为低电平
		RA3=0;					// 设置K2为低电平
		RE0=1;					// 设置K3为高电平
		RE1=1;					// 设置K4为高电平,判断按键是否在K1、K2之间
		if(RB4==0)				// 按键是k1k2中的一个
		{
			RA3=1;			// (只有)K1为低电平
			if(RB4==0)key=1;	// 仅K1为低电平时RB4被下拉,K1键按下
			else	key=2;		// K1k2为低电平RB4被下拉,K1没按下,是K2按下
			PORTB_keyflag=1;	//新键按下标志,=1表示有新键按下
			RB1=0;			//设置电平变化产生中断的初始条件
			RA3=0;
			RE0=0;
			RE1=0;
			PORTB=PORTB;
			return;
		}

		RB1=1;		// 不是在K1k2间按下,查K3k4,设K1K2为高电平,不查K1k2
		RA3=1;
		RE0=0;				// 设置K3为低电平
		RE1=0;				// 设置K4为低电平
		if(RB4==0)			// 若有键按下(无键按下可视为防抖)
		{
			RE1=1;			// 仅设置K3为低电平
			if(RB4==0)key=3;	// 仅K3为低电平时RB4被下拉,K3键按下
			else	key=4;		// K3k4为低电平RB4被下拉,K3没按下,是K4按下
		}
		PORTB_keyflag=1;		//新键按下标志,=1表示有新键按下
	}

	RB1=0;					//设置电平变化产生中断的初始条件
	RA3=0;
	RE0=0;
	RE1=0;
	PORTB=PORTB;
}

/* ****************************************************************
** 函 数 名: interrupt	low_priority	LOW_ISR()
** 功能描述: 低优先级中断子程序:PORTB口RB电平变化中断
*************************************************************** */
void	interrupt low_priority	LOW_ISR()
{
	if(RBIF==1)						//PORTB口RB电平变化中断
	{
		KEYSCAN_PORTB_Interrupt();	//查键子程序
		RBIF=0;						//清中断标志
	}
}

main()
{
	initial();
	SPIinitial();					/* spi显示初始化 */
	PORTB_Interrupt_Initial();		// PORTB口电平变化中断初始化
	IPEN=1;							// 使能中断高低优先级
	INTCON=INTCON|0xc0;				//打开总中断和外围接口中断
	display(0XFF);					/* 清数码管当前显示即清屏 */
	while(1)
	{
		if(PORTB_keyflag==1)			// 若有按键按下
		{
			display(key);			//显示按键键值(1-4)
			PORTB_keyflag=0;		//清按键按下标志
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -