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

📄 adrevesion.c

📁 适用于microchip 18f系列
💻 C
字号:
/*使用AD做出可以调节时间的时钟
	使用定时器中断来判断按键抖动,并且能够读入任何按键,
	不需要根据每一台机器改变而设置不同的按键AD值。
	程序作了模块化,使各个部分以函数形式调用,而不再是所有东西都放在主程序中
*/

//未完

#include <p18f452.h> 
#include <delays.h>
#pragma config WDT = OFF

//
// Defines for I/O ports that provide LCD data & control
// PORTD[0:3]-->DB[4:7]: Higher order 4 lines data bus with bidirectional
//					  : DB7 can be used as a BUSY flag
// PORTA,2 --> [E] : LCD operation start signal control 
// PORTD,5 --> [RW]: LCD Read/Write control
// PORTD,4 --> [RS]: LCD Register Select control
//		      	   : "0" for Instrunction register (Write), Busy Flag (Read)
//				   : "1" for data register (Read/Write)
//
#define CPU_SPEED		16				// CPU speed is 16 Mhz !!
#define LCD_RS			PORTDbits.RD4	// The definition of control pins
#define LCD_RW			PORTDbits.RD5
#define LCD_E			PORTAbits.RA2
#define LCD_DATA		LATD			// PORTD[0:3] as LCD DB[4:7]
//#define LCD_CTRL		LATA
#define DIR_LCD_DATA	TRISD	


//  LCD Module commands
#define DISP_2Line_8Bit	0b00111000
#define DISP_2Line_4Bit	0b00101000
#define DISP_ON			0x00C		// Display on
#define DISP_ON_C		0x00E		// Display on, Cursor on
#define DISP_ON_B		0x00F		// Display on, Cursor on, Blink cursor
#define DISP_OFF		0x008		// Display off
#define CLR_DISP		0x001		// Clear the Display
#define ENTRY_INC		0x006		//
#define ENTRY_INC_S		0x007		//
#define ENTRY_DEC		0x004		//
#define ENTRY_DEC_S		0x005		//
#define DD_RAM_ADDR		0x080		// Least Significant 7-bit are for address
#define DD_RAM_UL		0x080		// Upper Left coner of the Display	

#pragma udata
		
unsigned char 	Temp_CMD ;
unsigned char 	Str_Temp ;
unsigned char	Out_Mask ;		
//----------------------------------------------------------------
#pragma	code
void OpenLCD(void);
void WriteCmdLCD( unsigned char LCD_CMD);
void WriteDataLCD( unsigned char LCD_CMD);
void putcLCD(unsigned char LCD_Char);
void LCD_CMD_W_Timing( void );
void LCD_DAT_W_Timing( void );
void LCD_Set_Cursor(unsigned char CurY, unsigned char CurX);
void SetDDRamAddr (unsigned char DDRamAddr);
void putrsLCD( const rom char *Str );
void putsLCD( char *Str);
void puthexLCD(unsigned char HEX_Val);
void LCD_L_Delay(void);
void LCD_S_Delay(void);
void LCD_Clr(void);
//----------------------------------------------------------------

void LCD_Clr(void)
{
WriteCmdLCD(CLR_DISP) ;
	LCD_L_Delay() ;
}
 
void OpenLCD(void)

{
	ADCON1=(ADCON1 & 0xF0)|0b00001110;	// Set AN0 for analog input
 	LCD_E=0;									
	
	LCD_DATA = 0x00;					// LCD DB[4:7] & RS & R/W --> Low

	DIR_LCD_DATA = 0x00;				// LCD DB[4:7} & RS & R/W are output function
	TRISAbits.TRISA2=0;					// Set E pin as output

	LCD_DATA = 0b00000011 ;
	LCD_CMD_W_Timing() ;
	LCD_L_Delay() ;

	LCD_DATA = 0b00000011 ;
	LCD_CMD_W_Timing() ;
	LCD_L_Delay() ;

	LCD_DATA = 0b00000011 ;
	LCD_CMD_W_Timing() ;
	LCD_L_Delay() ;

	LCD_DATA = 0b00000010 ;
	LCD_CMD_W_Timing() ;
	LCD_L_Delay() ;

	WriteCmdLCD(DISP_2Line_4Bit) ;
	LCD_S_Delay() ;

	WriteCmdLCD(DISP_ON) ;
	LCD_S_Delay() ;

	WriteCmdLCD(ENTRY_INC) ;
	LCD_S_Delay() ;

	WriteCmdLCD(CLR_DISP) ;
	LCD_L_Delay() ;

 		
}

//*********************************************
//     _    ______________________________
// RS  _>--<______________________________
//     _____
// RW       \_____________________________
//                  __________________
// E   ____________/                  \___
//     _____________                ______
// DB  _____________>--------------<______
//***********************************************
// Write Command to LCD module
//
void WriteCmdLCD( unsigned char LCD_CMD) 
{
	Temp_CMD = (LCD_CMD & 0xF0)>>4 ;			// Send high nibble to LCD bus
	LCD_DATA= (LCD_DATA & 0xF0)|Temp_CMD ;
	LCD_CMD_W_Timing () ;

	Temp_CMD = LCD_CMD & 0x0F ;				// Send low nibble to LCD bus
	LCD_DATA= (LCD_DATA & 0xF0)|Temp_CMD ;
	LCD_CMD_W_Timing () ;

	LCD_S_Delay() ;							// Delay 100uS for execution
}

//***********************************************
// Write Data to LCD module
//
void WriteDataLCD( unsigned char LCD_CMD) 
{
	
	Temp_CMD = (LCD_CMD & 0xF0)>>4 ;			// Send high nibble to LCD bus
	LCD_DATA= (LCD_DATA & 0xF0)|Temp_CMD ;
	LCD_DAT_W_Timing () ;

	Temp_CMD = LCD_CMD & 0x0F ;				// Send low nibble to LCD bus
	LCD_DATA= (LCD_DATA & 0xF0)|Temp_CMD ;
	LCD_DAT_W_Timing () ;

	LCD_S_Delay() ;							// Delay 100uS for execution
}

void putcLCD(unsigned char LCD_Char)
{
	WriteDataLCD(LCD_Char) ;

}
void LCD_CMD_W_Timing( void )
{
	LCD_RS = 0 ;	// Set for Command Input
	Nop();
//	LCD_RW = 0 ;
	Nop();
	LCD_E = 1 ;
	Nop();
	Nop();
	LCD_E = 0 ;
}

void LCD_DAT_W_Timing( void )
{
	LCD_RS = 1 ;	// Set for Data Input
	Nop();
//	LCD_RW = 0 ;
	Nop();
	LCD_E = 1 ;
	Nop();
	Nop();
	LCD_E = 0 ;
}

//***********************************************
//     Set Cursor position on LCD module
//			CurY = Line (0 or 1)
//      	CurX = Position ( 0 to 15)
//
void LCD_Set_Cursor(unsigned char CurY, unsigned char CurX)
{
	WriteCmdLCD( 0x80 + CurY * 0x40 + CurX) ;
	LCD_S_Delay() ;
}

void SetDDRamAddr (unsigned char DDRamAddr)
{
	WriteCmdLCD(DDRamAddr);
	LCD_S_Delay();
}

//***********************************************
//    Put a ROM string to LCD Module
//
void putrsLCD( const rom char *Str )
{
   while (1)
   {
	Str_Temp = *Str ;

		if (Str_Temp != 0x00 )
		   {
			WriteDataLCD(Str_Temp) ;
			Str ++ ;
		   }
		else
			return ;
   }
}

//***********************************************
//    Put a RAM string to LCD Module
//
void putsLCD( char *Str)
{
   while (1)
   {
	Str_Temp = *Str ;

		if (Str_Temp != 0x00 )
		   {
			WriteDataLCD(Str_Temp) ;
			Str ++ ;
		   }
		else
			return ;
   }
}


void puthexLCD(unsigned char HEX_Val)
{
	unsigned char Temp_HEX ;

	Temp_HEX = (HEX_Val >> 4) & 0x0f ;

	if ( Temp_HEX > 9 )Temp_HEX += 0x37 ;
    else Temp_HEX += 0x30 ;

	WriteDataLCD(Temp_HEX) ;

	Temp_HEX = HEX_Val  & 0x0f ;
	if ( Temp_HEX > 9 )Temp_HEX += 0x37 ;
    else Temp_HEX += 0x30 ;

	WriteDataLCD(Temp_HEX) ;
}

// *********************************************************************************
// Delay for atleast 10 ms 
// *********************************************************************************
void LCD_L_Delay(void)
{
	Delay10KTCYx(CPU_SPEED / 2) ;		
}

// *********************************************************************************
// Delay for 100 us
// *********************************************************************************
void LCD_S_Delay(void)
{

	Delay100TCYx(CPU_SPEED) ;	
}


//==================================================================================

void interruptH(void);

#pragma code InterruptVectorHigh = 0x8
void InterruptVectorHigh (void)
{
  _asm
    goto interruptH //jump to interrupt routine
  _endasm
}
#pragma code


char timer[9]={' ',' ',':',' ',' ',':',' ',' ','\0'};
int clock[3]={4,12,7};
char string[]="Time";
//Timer0初始化------------用于计算1秒钟给中断
void Timer0init(void){
	T0CON=0b10001000;     //16位定时器,未分配预分频
  TMR0H=0x82;						//定时8ms
  TMR0L=0xFF;
  INTCONbits.TMR0IE=1;		//中断允许
  INTCONbits.TMR0IF=0;		//标志位清0
 } 
  
  
//Timer2 初始化----Timer2定时器作为8ms延时判断定时器,以降低cpu在延时时资源被占用的问题
void Timer2init(void){
	T2CON=0b00000000;			//暂时不用启动Timer2,当有按键时,在启动Timer2定时器
	PIE1bits.TMR2IE=1;		//中断允许
	PIR1bits.TMR2IF=0;		//中断标志位置0
	TMR0H=0x82;					//定时8ms
	TMR0L=0xFF;
}

//中断初始化===初始化中断,使能全局和外设中断,并且使能中断优先级
//注意:应在所有其他部分初始化前初始化。	
void Interruptinit(void){
	INTCON=0b11000000;	//全局外设中断使能
	RCONbits.IPEN=1;		//使能中断优先级
}	
	 
//RCONbits.IPEN=1;  中断服务程序----处理时间
#pragma interrupt interruptH

void interruptH(void){
	int i,TMRFL,TMRFH;
	static int a=0;   
	static int K1flag=0; 
	if (INTCONbits.TMR0IF){
		TMR0H=0x82;
		TMR0L=0xFF;
		INTCONbits.TMR0IF=0; 
		a++;
		if(a==125){
			clock[2]++;
			a=0;
			if(clock[2]==60){
				clock[1]++;
				clock[2]=0;
				if(clock[1]==60){
					clock[0]++;
					clock[1]=0;
					if(clock[0]==24){
						clock[0]=0;
						}
					}
				}
			}
		}
	if(PIR1bits.ADIF){
		if(ADRESH==0x7F&&ADRESL==0x00){		//按键K1 暂停
			for(i=0;i<32767;i++);
			if(ADRESH==0x7F&&ADRESL==0x00){
				if(K1flag%2==0){
				T0CONbits.TMR0ON=0;
				K1flag++;
				}
				else if(K1flag%2==1){
				T0CONbits.TMR0ON=1;
				K1flag++;
				}	
			}
			
		}
		if(ADRESH==0x65&&ADRESL==0x40){		//按键K2	分针+1
			//for(i=0;i<32767;i++);
			TMRFL=TMR0L;TMRFH=TMR0H;
			
				if(ADRESH==0x65&&ADRESL==0x40){
					clock[1]++;
					if(clock[1]==60){
						clock[1]=0;
					}
				}
			}
		}
		if(ADRESH==0x53&&ADRESL==0x80){		//按键K3	时针+1
			for(i=0;i<32767;i++);
			if(ADRESH==0x53&&ADRESL==0x80){
				clock[0]++;
				if(clock[0]==24){
				clock[0]=0;
				}
			}
		}
	}
	PIR1bits.ADIF=0;
}

//AD初始化
void ADinitial(void){
	ADCON0=0B10000001;
	ADCON1=0B01001110;
	TRISAbits.TRISA0=1;
	ADCON0bits.GO=1;
	PIE1bits.ADIE=1;
	PIR1bits.ADIF=0;
}

void ADC_Start(void){
	Delay100TCYx (2);
	ADCON0bits.GO =1;
}
	

		

//函数convert将十进制数转换成ASCII码			
char convert(int arr[],char str[]){
	str[0]='0'+arr[0]/10;
	str[1]='0'+arr[0]%10;
	str[3]='0'+arr[1]/10;
	str[4]='0'+arr[1]%10;
	str[6]='0'+arr[2]/10;
	str[7]='0'+arr[2]%10;
}

//秒表
void main()
{
	OpenLCD();
	LCD_Clr();
	Interruptinit();
	Timer2init();
	ADinitial();
	Timer0init();
	while(1){
		LCD_Set_Cursor(0,0);
		putsLCD(string);
		ADC_Start();
		convert(clock,timer);
		LCD_Set_Cursor(1,0);
		putsLCD(timer);
		}
}

⌨️ 快捷键说明

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