我正在学习如何使用8253可编程计数器,我在理解阅读部分时遇到了问题。我编写了以下程序,我想请求帮助来编辑程序以对计数器进行编程,以便它可以用作频率计数器。我想在LCD上显示频率,而不仅仅是已经显示的计数数字。
#define Counter1 0
#define Counter2 1
#define Counter3 2
#define STILL_COUNTING 0
#define portA 0
#define portB 1
#define portc 2
#define Control_Word 3
sbit RD_8253 at PORTC4_bit;
sbit WR_8253 at PORTC5_bit;
sbit A0_8253 at PORTC6_bit;
sbit A1_8253 at PORTD6_bit;
sbit GATE1_8253 at PORTD4_bit;
sbit OUT1_8253 at PIND5_bit;
sbit RD_8255 at PORTC0_bit;
sbit WR_8255 at PORTC1_bit;
sbit A0_8255 at PORTC2_bit;
sbit A1_8255 at PORTC3_bit;
sbit RS at PORTD1_bit;
sbit E at PORTD0_bit;
unsigned char Address0[4]={0,1,0,1};
unsigned char Address1[4]={0,0,1,1};
void Write_8255(unsigned char Data,unsigned char Register)
{
DDRB=0xFF;
PORTB=Data;
A0_8255=Address0[Register];
A1_8255=Address1[Register];
WR_8255=0;
Delay_ms(100);
WR_8255=1;
}
void Write_8253(unsigned char Data,unsigned char Register){
DDRB=0xFF;
PORTB=Data;
A0_8253=Address0[Register];
A1_8253=Address1[Register];
WR_8253=0;
Delay_ms(100);
Write_8255(Data,portc);
WR_8253=1;
}
void Write_Instruction_LCD(unsigned char Instruction){
RS=0;
PORTB=Instruction;
E=1;
Delay_ms(100);
Write_8255(Instruction,portA);
E=0;
}
void Write_Data_LCD(unsigned char Data){
RS=1;
PORTB=Data;
E=1;
Write_8255(Data,portA);
Delay_ms(100);
E=0;
}
void Intialise(void){
// setting function x3
Write_Instruction_LCD(0x30);
Write_Instruction_LCD(0x30) ;
Write_Instruction_LCD(0x30) ;
Write_Instruction_LCD(0x38); // function set
Write_Instruction_LCD(0x08); // display off
Write_Instruction_LCD(0x01); // clear display
Write_Instruction_LCD(0x06); // entry mode
Write_Instruction_LCD(0x0C); // display on, cursor on, blinking on
}
void SET_DDRAM_ADDRESS(unsigned char Address){
Write_Instruction_LCD(0x80|Address);
}
void WriteString(unsigned char *W,unsigned char Leng){
unsigned char x;
for(x=0;x<Leng;x++)
Write_Data_LCD(W[x]);
}
void LCD_Variable(char Digits, unsigned int Var){
unsigned char Offset=0, Cntr=0, SizeOffset=0, Temp=0;
unsigned int Val=0, VarIn;
char DispArray[5];
unsigned char variable;
VarIn = Var;
for (Cntr = 5; Cntr > 0; Cntr--){
Val = Var%10;
Var = Var/10;
Temp = (char)Val;
DispArray[Cntr-1] = (Temp) + 0x30; // Determine BCD value and convert to ASCII
}
if(Digits == 1){SizeOffset = 4;} //1 character
if(Digits == 2){SizeOffset = 3;} //2 characters
if(Digits == 3){SizeOffset = 2;} //3 characters
if(Digits == 4){SizeOffset = 1;}//4 characters
if(Digits == 5){SizeOffset = 0;} //5 characters
SET_DDRAM_ADDRESS(0x80|(0x00+offset));
for (Cntr = SizeOffset; Cntr < 5; Cntr++){
variable=DispArray[Cntr] ;
Write_Data_LCD(variable) ; // Write ASCII data to the display
Delay_ms(100); // Delay 50 ms
}
}
void main() {
unsigned int count;
unsigned char i;
DDRD=0xFF;
DDD5_bit=0;
DDRC=0xFF;
DDRB=0xFF;
WR_8255=1;
RD_8255=1;
WR_8253=1;
RD_8253=1;
E=1;
//control word portExp
Write_8255(0x80,Control_Word); //All ports OutpuT
Intialise();
SET_DDRAM_ADDRESS(0x00);
OUT1_8253=0;
Write_8253(0xB0,Control_Word);
count=0;
while(1)
{
LCD_Variable(3,count);
GATE1_8253=0;
Write_8253(0xF4,Counter2);
Write_8253(0x01,Counter2);
GATE1_8253=1;
while(OUT1_8253==STILL_COUNTING){;}
count++;
if(count>200)
count=0x00;
}
}