📄 adrevesion.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 + -