单片机笔记---测量计算输入的脉冲宽度

本文介绍了一个基于AVR单片机M128的程序设计,该程序利用定时器和输入捕捉功能来测量外部脉冲的宽度。通过配置定时器1并设置中断服务例程,实现了对外部脉冲上升沿和下降沿的捕获,并计算脉冲宽度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  使能输入捕捉功能, 测量计算输入的脉冲宽度:

//ICC-AVR application builder : 2006-7-14 10:13:46
// Target : M128
// Crystal: 14.7456Mhz

#include <iom128v.h>
#include <macros.h>

//define PORT B as output for pulse width
#define pulse_out PORTB

//define ICP so we can read the pin
#define ICP PIND4

unsigned char ov_counter;
unsigned int  rising_edge, falling_edge;
unsigned long pulse_clocks;

void port_init(void)
{
 PORTA = 0x00;
 DDRA  = 0x00;
 PORTB = 0xFF;
 DDRB  = 0xFF;
 PORTC = 0x00; //m103 output only
 DDRC  = 0x00;
 PORTE = 0x00;
 DDRE  = 0x00;
 PORTF = 0x00;
 DDRF  = 0x00;
 PORTG = 0x00;
 DDRG  = 0x00;
}

//TIMER0 initialize - prescale:1024
// WGM: Normal
// desired value: 14.44444444KHz
// actual value: -0.001KHz (1444544.4%)
void timer1_init(void)
{
 TCCR1B = 0xc4; //start timer 预分频为64
}

#pragma interrupt_handler timer1_ovf_isr:15
void timer1_ovf_isr(void)
{
  ov_counter++;
}

#pragma interrupt_handler timer1_capt_isr:13
void timer1_capt_isr(void)
{
if (ICP)
{
  rising_edge=ICR1;  //save start time for pulse
  TCCR1B&=0xBF; //set to trigger on falling edge next
  ov_counter=0;
}

else
{
  falling_edge =ICR1;
  TCCR1B|=0x40; 
  pulse_clocks= (unsigned long) falling_edge - (unsigned long) rising_edge
                +(unsigned long) ov_counter*0x10000;
  pulse_out=pulse_clocks/230;
}
}
  

//call this routine to initialise all peripherals
void init_devices(void)
{
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 XDIV  = 0x00; //xtal divider
 XMCRA = 0x00; //external memory
 port_init();

 MCUCR = 0x00;
 EICRA = 0x00; //extended ext ints
 EICRB = 0x00; //extended ext ints
 EIMSK = 0x00;
 TIMSK = 0x00; //timer interrupt sources
 ETIMSK = 0x00; //extended timer interrupt sources
 SEI(); //re-enable interrupts
 //all peripherals are now initialised
}

void main(void)

  port_init();
  init_devices();
  timer1_init();
  TIMSK=0x24;
  SEI();
  while(1)
  {
   ;
  }
}  

在Proteus环境下,使用`iom16v.h`库和数码管(通常是指5x7点阵字符型数码管)配合Keypad组件进行简单计算器功能的编程,首先需要了解这两个库的基本用途。 `iom16v.h`是一个I/O口操作的头文件,它提供了一些函数用于设置和读取IO端口。而Keypad通常有4*4键矩阵,对应数字0-9和运算符+-*/等。 下面是一个简单的示例代码,展示了如何使用`iom16v.h`和假设的Keypad组件(keypad-smallcalc)来获取按键输入并显示在数码管上: ```c #include "iom16v.h" // 包含I/O操作头文件 #include <stdio.h> // 使用printf进行输出 // 定义数码管相关的宏,这里简化为直接映射数字到特定位 #define DIGIT_0 0b00000001 #define ... // 其他数字和运算符的定义类似 void keypad_init() { // 初始化键盘矩阵和数码管,具体取决于硬件连接 // 这部分通常是通过配置IO口来完成,实际代码会因硬件不同而变化 } void display_num(int num) { for (int i = 0; i < 8; ++i) { // 将二进制数转换为5x7点阵数码管的显示模式 set_port_pin(io_port, num & 0x01); // 右移一位,按位与 num >>= 1; delay_ms(1); // 每位之间稍作延时 } } int main(void) { keypad_init(); while (true) { int key = read_keypad(); // 假设read_keypad函数从Keypad获取按键值 if (key >= 0 && key <= 9) { // 确保按键在有效范围内 display_num(key); } else if (key == 'A') { // 示例处理加法键 // 进行加法计算,并更新当前显示 // 实际代码中应包含更多的运算逻辑 } // 更多的运算符处理类似... // ... } return 0; } ``` 注意,这个代码只是一个基本框架,实际的代码会更复杂,需要处理各种错误情况、清除数码管、以及真正的算术运算。此外,`iom16v.h`的具体用法和`read_keypad()`函数的实现依赖于你的硬件设计和所使用的库。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值