STC15F104W单片机测量脉冲时间
时间: 2023-09-27 20:12:26 浏览: 100
STC15F104W单片机可以通过外部中断功能来测量脉冲时间。具体步骤如下:
1. 配置外部中断引脚:将需要测量脉冲时间的引脚设置为外部中断引脚,可以使用P3.2或P3.3引脚。
2. 配置外部中断触发方式:通过IE寄存器的EX0或EX1位来选择外部中断0或1,再通过IT0或IT1位来选择触发方式,可以选择电平触发或边沿触发。
3. 编写中断服务程序:当外部中断触发时,会自动跳转到中断服务程序中执行,可以在中断服务程序中测量脉冲时间。可以使用定时器来测量时间差,比如使用定时器1来测量高电平时间,使用定时器0来测量低电平时间。
4. 计算脉冲时间:脉冲时间等于高电平时间加上低电平时间。
注意事项:
1. 需要在程序中打开中断总开关EA和相应的中断开关IE。
2. 需要在程序中配置定时器的计数方式、计数值和中断开关。
3. 需要在程序中定义中断服务程序,并在中断服务程序中清除标志位。
4. 需要注意测量脉冲时间的精度,可以通过调整定时器的计数值来提高精度。
相关问题
STC15F104W单片机测量脉冲高电平时间代码
以下是基于STC15F104W单片机的测量脉冲高电平时间的代码:
```c
#include <STC15F104W.h>
#define TRIG P1_2
unsigned long pulse_width = 0;
void delay_us(unsigned int us)
{
unsigned char i;
while(us--)
{
for(i = 0; i < 12; i++);
}
}
void delay_ms(unsigned int ms)
{
unsigned char i, j;
while(ms--)
{
for(i = 0; i < 20; i++)
{
for(j = 0; j < 110; j++);
}
}
}
void timer0_init()
{
TMOD &= 0xF0; //设置定时器0为模式1, TH0的高4位为计数值
TMOD |= 0x01;
TH0 = 0;
TL0 = 0;
TR0 = 1; //启动定时器0
}
void main()
{
TRIG = 0; //将TRIG设置为低电平
delay_ms(1000); //等待传感器稳定
while(1)
{
TRIG = 1; //将TRIG设置为高电平
delay_us(10); //等待10us
TRIG = 0; //将TRIG设置为低电平
while(!INT0); //等待INT0中断触发
TR0 = 0; //停止计时器0
pulse_width = TH0 * 256 + TL0; //计算脉冲宽度
TH0 = 0;
TL0 = 0;
TR0 = 1; //重新启动定时器0
//将脉冲宽度传输到其他设备或进行其他操作
}
}
```
在上述代码中,我们使用定时器0来测量脉冲的高电平时间。在主函数中,我们先将TRIG设置为低电平,并等待传感器稳定。然后不断执行测量脉冲宽度的操作。在操作中,我们先将TRIG设置为高电平,等待10us后将其设置为低电平,然后等待INT0中断触发。当INT0中断触发时,表示脉冲已经结束,我们停止定时器0并计算脉冲宽度。最后,我们将脉冲宽度传输到其他设备或进行其他操作。
STC15F104W单片机测量外部脉冲输入PWM高电平时间代码
以下是STC15F104W单片机测量外部脉冲输入PWM高电平时间的代码:
```c
#include <reg52.h>
#define FOSC 11059200L
#define BAUD 9600
unsigned char Timer0_Reload = 0;
unsigned char Timer1_Reload = 0;
unsigned char Counter = 0;
unsigned int H_Time = 0;
bit Flag = 0;
void Timer0_Init(void); // 定时器0初始化函数
void Timer1_Init(void); // 定时器1初始化函数
void UART_Init(void); // 串口初始化函数
void main()
{
EA = 1; // 开启总中断
Timer0_Init(); // 定时器0初始化
Timer1_Init(); // 定时器1初始化
UART_Init(); // 串口初始化
while (1)
{
if (Flag) // 如果高电平时间已经测量完成
{
Flag = 0;
H_Time = TH1 * 256 + TL1; // 计算高电平时间
printf("High level time: %dus\r\n", H_Time); // 打印高电平时间
TH1 = 0; // 定时器1计数值清零
TL1 = 0; // 定时器1计数值清零
}
}
}
void Timer0_Init(void)
{
TMOD &= 0xF0; // 清除定时器0模式位
TMOD |= 0x01; // 定时器0为模式1,13位定时器
TH0 = (65536 - FOSC / 1000 / 12); // 定时器0初值,1ms
TL0 = (65536 - FOSC / 1000 / 12); // 定时器0初值,1ms
ET0 = 1; // 定时器0中断允许
TR0 = 1; // 定时器0启动
}
void Timer1_Init(void)
{
TMOD &= 0x0F; // 清除定时器1模式位
TMOD |= 0x10; // 定时器1为模式1,16位定时器
TH1 = 0; // 定时器1初值
TL1 = 0; // 定时器1初值
ET1 = 1; // 定时器1中断允许
}
void UART_Init(void)
{
SCON = 0x50; // 串口工作方式1,允许接收
TMOD &= 0x0F; // 清除定时器1模式位
TMOD |= 0x20; // 定时器1为模式2,8位自动重装定时器
TH1 = TL1 = 256 - FOSC / 12 / 32 / BAUD; // 定时器1初值
TR1 = 1; // 定时器1启动
}
void Timer0_ISR(void) interrupt 1
{
TH0 = (65536 - FOSC / 1000 / 12); // 重置定时器0计数值
TL0 = (65536 - FOSC / 1000 / 12); // 重置定时器0计数值
Counter++; // 计数器自增
if (Counter >= 10) // 如果计数器计数到10次
{
Flag = 1; // 标志位设为1,表示高电平时间已经测量完成
Counter = 0; // 计数器清零
}
}
void Timer1_ISR(void) interrupt 3
{
TH1 = Timer1_Reload / 256; // 定时器1重装初值
TL1 = Timer1_Reload % 256; // 定时器1重装初值
Timer1_Reload = 0; // 定时器1重载值清零
}
void UART_ISR(void) interrupt 4
{
if (RI) // 如果收到数据
{
RI = 0; // 接收中断标志位清零
Timer1_Reload = TH1 = TL1 = 0; // 定时器1重载初值清零
}
if (TI) // 如果发送数据
{
TI = 0; // 发送中断标志位清零
}
}
```
在上面的代码中,我们通过定时器0来控制计数器的计数,每次计数到10次时,就表示外部脉冲输入高电平时间已经测量完成,定时器1的计数值就是测量的高电平时间。定时器1的计数值通过串口发送出来。
阅读全文