用51单片机设计一个系统,对输入的占空比10%-90%,频率为20-2KHZ可调的矩形信号进行测量并且显示,请帮我写出程序
时间: 2023-12-03 08:43:32 浏览: 43
以下是基于51单片机的程序设计,可实现对输入占空比为10%-90%,频率为20-2KHZ可调的矩形信号的测量和显示:
```
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
// 时钟频率
#define FOSC 11059200L
// 定义LCD1602引脚连接
sbit RS = P2^0;
sbit EN = P2^1;
sbit RW = P2^2;
#define LCD1602_DATAPINS P0
// 定义计数器引脚连接
sbit COUNTER_IN = P3^2;
sbit COUNTER_OUT = P3^3;
// 定义计数器定时器
uchar high_count, low_count;
// 定义计数器输出频率和占空比
uint freq, duty;
// 函数声明
void delay(uint ms);
void init_timer0();
void init_counter();
void display_lcd(uint freq, uint duty);
void main()
{
// 初始化定时器0
init_timer0();
// 初始化计数器
init_counter();
// 初始化LCD1602
RS = 0;
RW = 0;
EN = 0;
LCD1602_DATAPINS = 0xff;
delay(15);
LCD1602_DATAPINS = 0x30;
EN = 1;
delay(5);
EN = 0;
delay(5);
LCD1602_DATAPINS = 0x30;
EN = 1;
delay(5);
EN = 0;
delay(5);
LCD1602_DATAPINS = 0x30;
EN = 1;
delay(5);
EN = 0;
delay(5);
LCD1602_DATAPINS = 0x38;
EN = 1;
delay(5);
EN = 0;
delay(5);
LCD1602_DATAPINS = 0x08;
EN = 1;
delay(5);
EN = 0;
delay(5);
LCD1602_DATAPINS = 0x01;
EN = 1;
delay(5);
EN = 0;
delay(5);
LCD1602_DATAPINS = 0x06;
EN = 1;
delay(5);
EN = 0;
delay(5);
LCD1602_DATAPINS = 0x0c;
EN = 1;
delay(5);
EN = 0;
while (1)
{
// 等待计数器输出一个完整的周期
while (COUNTER_OUT == 0);
while (COUNTER_OUT == 1);
// 计算频率和占空比
freq = FOSC / 12 / (high_count * 256 + low_count);
duty = high_count * 100 / (high_count + low_count);
// 显示频率和占空比
display_lcd(freq, duty);
}
}
// 延时函数
void delay(uint ms)
{
uchar i, j;
while (ms--)
{
for (i = 0; i < 20; i++)
for (j = 0; j < 110; j++);
}
}
// 初始化定时器0
void init_timer0()
{
TMOD &= 0xf0;
TMOD |= 0x01;
TH0 = (65536 - FOSC / 12 / 1000) / 256;
TL0 = (65536 - FOSC / 12 / 1000) % 256;
TR0 = 1;
ET0 = 1;
EA = 1;
}
// 定时器0中断服务程序
void timer0_isr() interrupt 1
{
high_count = 0;
low_count = 0;
}
// 初始化计数器
void init_counter()
{
COUNTER_IN = 1;
COUNTER_OUT = 1;
}
// 显示LCD1602
void display_lcd(uint freq, uint duty)
{
uchar str[16];
sprintf(str, "Freq:%6dHz", freq);
RS = 0;
RW = 0;
LCD1602_DATAPINS = 0x80;
EN = 1;
delay(5);
EN = 0;
delay(5);
for (uchar i = 0; i < 12; i++)
{
LCD1602_DATAPINS = str[i];
RS = 1;
RW = 0;
EN = 1;
delay(5);
EN = 0;
delay(5);
}
sprintf(str, "Duty:%5d%%", duty);
RS = 0;
RW = 0;
LCD1602_DATAPINS = 0xc0;
EN = 1;
delay(5);
EN = 0;
delay(5);
for (uchar i = 0; i < 12; i++)
{
LCD1602_DATAPINS = str[i];
RS = 1;
RW = 0;
EN = 1;
delay(5);
EN = 0;
delay(5);
}
}
```
程序主要分为三部分:
1. 初始化定时器0:使用定时器0作为计数器的计时基准,设置定时器0为工作方式1,即16位定时器模式,并设置定时器0的重载值,使其每1ms产生一次中断。
2. 初始化计数器:将计数器的输入和输出引脚设置为高电平,并等待输入信号触发计数器。
3. 测量并显示:等待计数器输出完整的一个周期后,计算输入信号的频率和占空比,并将结果显示在LCD1602上。其中,计算频率的公式为:F = FOSC / 12 / (高8位计数器值 * 256 + 低8位计数器值),计算占空比的公式为:D = 高8位计数器值 * 100 / (高8位计数器值 + 低8位计数器值)。
请注意,由于51单片机的时钟频率为11.0592MHz,因此在计算频率和占空比时需要将其作为参考频率。另外,本程序使用的LCD1602驱动程序需要根据具体的硬件连接进行修改,以确保正确的显示效果。