一 課題目標
本課題是用51系列單片機來實現(xiàn)頻率計,并利用LCD1602液晶顯示器來顯示所測頻率值。
二 課題分析
LCD頻率計是利用十進制數字顯示被測信號頻率的數字測量儀器。根據定義,頻率就是在1s內信號變化的周期數。在一個單片機系統(tǒng)中,對頻率的測量就是要對外部信號的計數,每到1s,將計數所得的數值送到顯示器上。在這里,我們重要是學習和掌握如何使用LCD1602液晶顯示器來顯示所測頻率。這里要求實現(xiàn)對0~200kHz的信號頻率進行準確測量,測量誤差不超過±1Hz。頻率計的功能是測出1s、對輸入的脈沖計數和數字顯示的硬件電路及相應的程序。實驗原理圖如下:
三 實驗元件及器材:
一個AT89S52、一個發(fā)光二極管、一個1602液晶顯示器、一個1K電阻、一個10K電阻、兩個20pF電容、一個1uF電容、下載線插座、一個按鍵開關、一個晶振、若干導線。
四 硬件電路設計及描述:
五 軟件設計流程及描述:
#include
#define uchar unsigned char
uchar disp[];
uchar T0count, T1count;
void display()
{
uchar i,j,k;
uchar code dispcode[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09};
for(i=0;i<8;i++)
{
P2=0;
P0=dispcode[disp[i]];
P2=k;
for(j=250;j>0;j--);
k=k>>1;
}
P2=0;
}
#define LINE1 0
#define LINE2 1
#define LINE1_HEAD 0x80
#define LINE2_HEAD 0xC0
#define LCD_DELAY_TIME 40
#define DATA_MODE 0x38
#define OPEN_SCREEN 0x0C
#define DISPLAY_ADDRESS 0x80
#define CLEARSCREEN LCD_en_command(0x01)
#define HIGH 1
#define LOW 0
#define TRUE 1
#define FALSE 0
#define MSB 0x80
#define LSB 0x01
#define LCDIO P2
sbit LCD1602_RS=P1^1;
sbit LCD1602_RW=P1^2;
sbit LCD1602_EN=P1^3;
#define LCDIO_delay(void);
void LCD_en_command(uchar command);
void LCD_en_dat(uchar temp);
void LCD_set_xy(uchar x, uchar y);
void LCD_write_char(uchar x,uchary,uchar dat);
void LCD_write_string(uchar X,uchar Y,uchar *s);
void LCD_init(void);
void delay_nms(unsigned int n);
void LCD_delay(void)
{
unsigned char i;
for(i=LCD_DELAY_TIME;i>0;i--){;}
}
void LCD_en_command(unsigned char command)
{
LCDIO=command;
LCD1602_RS=LOW;
LCD1602_RW=LOW;
LCD1602_EN=LOW;
LCD_delay();
LCD1602_EN=HIGH;
}
void LCD_en_dat(unsigned char dat)
{
LCDIO=dat;
LCD1602_RS=HIGH;
LCD1602_RW=LOW;
LCD1602_EN=LOW;
LCD_delay();
LCD1602_EN=HIGH;
}
void LCD_set_xy(uchar x, uchar y)
{
unsigned char address;
if (y== LINE1)
address= LINE1_HEAD+x;
else
address= LINE2_HEAD+x;
LCD_en_command(address);
}
void LCD_write_char( uchar x,uchar y,uchar dat)
{
LCD_set_xy( x,y );
LCD_en_dat(dat);
}
void LCD_write_string(uchar X,uchar Y,uchar *s)
{
LCD_set_xy( X,Y );
while(*s)
{
LCD_en_dat(*s);
s++;
}
}
void LCD_init(void)
{
CLEARSCREEN;
LCD_en_command(DATA_MODE);
LCD_en_command(OPEN_SCREEN);
LCD_en_command(DISPLAY_ADDRESS);
CLEARSCREEN;
delay_nms(40);
}
void delay_nms(unsigned int n)
{
unsigned int i;
unsigned char j;
for(i=n;i>0;i--)
{for (j=250;j>0;j--);
for(j=250;j>0;j--); }
}
void main(void)
{
uchar string[]="0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09";
uchar i,k;
delay_nms(400);
LCD_init();
LCD_write_string(3,LINE1,"Char left");
while(1)
{
LCD_write_string(0,LINE2,string);
delay_nms(1000);
k=string[0];
for(i=0;i<16;i++)
{
string[i]=string[i+1];
}
string[i]=k;
}
}
void init()
{
T0count=0;
T1count=0;
TH0=0;
TL0=0;
}
void main()
{
init();
TMOD=0X15;
TH1=(65536-5*120000/12)/256;
TL1=(65536-5*120000/12)%256;
ET1=1;
ET0=1;
EA=1;
TR1=1;
TR0=1;
T2MOD=0X2;
RCAP2H=245;
RCAP2L=74;
TR2=1;
while(1)
{
display();
}
}
void time0()interrupt 1
{
T0count++;
}
void time1()interrupt 3
{
TH1=(65536-5*120000/12)/256;
TL1=(65536-5*120000/12)%256;
if(T1count==19)
{
calc();
init();
}
else T1count++;
}
五 源程序及代碼:
六 思考與討論:
通過這次單片機的實訓,使我們增進了對單片機的感性認識,使我們掌握了頻率計的內部功能模塊的應用,了解和掌握了單片機應用系統(tǒng)的軟硬件設計過程、方法及實現(xiàn),為以后設計和實現(xiàn)單片機應用系統(tǒng)打下良好基礎。進一步加強綜合應用能力及單片機應用系統(tǒng)開發(fā)和設計能力的訓練。