频率计使用8253/8254可编程计数器

时间:2016-10-14 00:23:59

标签: counter avr

我正在学习如何使用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;
}
}

0 个答案:

没有答案