timer - 如何使用计时器计算按钮的总按下时间
问题描述
我是 pic 控制器的新手。我正在使用图片 16F887。我想计算按下按钮的总时间。而那个时候我想用作为延迟来闪烁led。我可以通过替换之前的 LED 闪烁延迟来更改该按钮按下时间以更改延迟。我如何通过更正以下代码来做到这一点
#include <htc.h>
#define _XTAL_FREQ 8000000
#define SWITCH RB0
#define LED RD2
long int total_count = 0,count = 0,count1 = 0;
char flag =0,flag1 =0;
char i=0,k=0;
void Init_Timer1() // Timer Initialization at 0.6ms
{
TMR1ON = 0x01;
TMR1IF = 0;
TMR1H = 0xFB;
TMR1L = 0x4F;
TMR1IE = 1;
INTCON |= 0xC0;
}
void Extern()
{
INTCON |= 0XD0;
INTEDG = 1; // Rising Edge Detect
}
void interrupt ISR(void)
{
if(INTF)//External Interrupt Flag
{
INTF=0;
TMR1IF = 0;
TMR1H = 0xFB;
TMR1L = 0x4F;
TMR1ON = 0x01;
count++;
}
if(TMR1IF) // Timer1 Interrupt flag
{
TMR1IF = 0;
TMR1H = 0xFB;
TMR1L = 0x4F;
TMR1ON = 0x01;
}
}
void main()
{
Extern();
Init_Timer1();
TRISD2 = 0;
TRISB0 = 1;
LED=0;
while(1)
{
if(RB0 == 0 && flag==0)
{
flag=1;
}
if(RB0 == 1 && flag==1)
{
LED=1;
for(i=0;i<count;i++);
LED=0;
flag1=0;
}
}
}
解决方案
您似乎掌握了重要的想法,但可能错过了一些细节。
/*
* File: main.c
* Author: dan1138
* Target: PIC16F887
* Compiler: XC8 v1.45
* IDE: MPLABX v5.25
*
* Created on March 23, 2020, 4:22 PM
*/
// CONFIG1
#pragma config FOSC = INTRC_NOCLKOUT // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON // RE3/MCLR pin function select bit (RE3/MCLR pin function is MCLR)
#pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF // Brown Out Reset Selection bits (BOR disabled)
#pragma config IESO = OFF // Internal External Switchover bit (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
#pragma config LVP = OFF // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)
// CONFIG2
#pragma config BOR4V = BOR40V // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF // Flash Program Memory Self Write Enable bits (Write protection off)
#include <xc.h>
#define _XTAL_FREQ 8000000ul
#define SWITCH RB0
#define SWITCH_DIR TRISB0
#define SWITCH_PRESSED (0)
#define LED RD2
#define LED_DIR TRISD2
#define LED_OFF (0)
#define LED_ON (1)
#define GPIO_IN (1)
#define GPIO_OUT (0)
volatile unsigned long ButtonPressedTicks;
volatile unsigned char ButtonPressedState;
volatile unsigned char T2_Ticks;
volatile unsigned long TicksForLedToBlink;
void Init_TIMER2(void) // Initialize TIMER2 to assert an interrupt every 20 milliseconds
{
TMR2IE = 0; // Disable TIMER2 interrupts
T2CON = 0; // Stop TIMER2
T2CONbits.T2CKPS = 0b10; // Set TIMER2 prescale for 1:16
T2CONbits.TOUTPS = 0b0100; // Set TIMER2 postscale for 1:10
PR2 = (_XTAL_FREQ/(4ul*16ul*10ul*50ul))-1ul;
TMR2IF = 0; // Clear pending interrupt requests
TMR2IE = 1; // Enable TIMER2 interrupts
PEIE = 1; // Enable peripheral interrupts
T2CONbits.TMR2ON = 1; // Turn on TIMER2
}
void Init_INT(void)
{
INTE = 0; // Disable external interrupts
INTEDG = 0; // Falling Edge Detect
INTF = 0; // Clear pending interrupt requests
}
void interrupt ISR(void)
{
// Handle external interrupt assert
if (INTE)
{
if (INTF)
{
INTF = 0;
INTE = 0; // Disable external interrupts
LED = LED_ON;
T2CONbits.TMR2ON = 0; // Turn off TIMER2
TMR2 = 0;
TMR2IF = 0; // Clear pending interrupt requests
T2CONbits.TMR2ON = 1; // Turn on TIMER2
ButtonPressedTicks = 0;
ButtonPressedState = 1;
}
}
// TIMER2 interrupt assert
if (TMR2IE)
{
if (TMR2IF)
{
TMR2IF = 0;
T2_Ticks++;
if(ButtonPressedState == 1)
{
if (SWITCH == SWITCH_PRESSED)
{
ButtonPressedTicks++;
}
else
{
if(ButtonPressedTicks < 2) // SWITCH press too short, must be a bounce
{
ButtonPressedTicks = 0; // Start over
LED = LED_OFF;
INTF = 0;
INTE = 1; // Enable external interrupts
}
else
{
TicksForLedToBlink = ButtonPressedTicks;
}
ButtonPressedState = 2;
}
}
}
}
}
void main(void)
{
unsigned char T2_TicksStart;
unsigned char BlinkTicks;
unsigned long BlinkTime;
ANSEL = 0;
ANSELH = 0;
Init_INT();
Init_TIMER2();
LED_DIR = GPIO_OUT;
LED = LED_OFF;
SWITCH_DIR = GPIO_IN;
ButtonPressedTicks = 0;
ButtonPressedState = 0;
TicksForLedToBlink = 0;
T2_Ticks = 0;
GIE = 1; // Enable the interrupt system
while (1)
{
if((ButtonPressedState == 2) && (TicksForLedToBlink > 0))
{
LED = LED_OFF;
BlinkTime = 0;
while(BlinkTime < TicksForLedToBlink)
{
T2_TicksStart = T2_Ticks;
BlinkTicks = 0;
while(BlinkTicks < 1)
{
BlinkTicks = T2_Ticks;
BlinkTicks -= T2_TicksStart;
}
BlinkTime += BlinkTicks;
}
LED = LED_ON;
BlinkTime = 0;
while(BlinkTime < TicksForLedToBlink)
{
T2_TicksStart = T2_Ticks;
BlinkTicks = 0;
while(BlinkTicks < 1)
{
BlinkTicks = T2_Ticks;
BlinkTicks -= T2_TicksStart;
}
BlinkTime += BlinkTicks;
}
}
if(INTE == 0) INTE = 1; // Enable external interrupts
}
}
我看不到“修复”您发布的代码的明确方法。
此代码使用您的说明材料尚未涵盖的概念。
如果您将此作为已完成的作业提交,您的教师会知道您是从互联网上获得的。
推荐阅读
- php - 在 php 中上传后,某些图像已损坏
- python - Python 预提交失败但未进行更正
- javascript - 如何用 HTML5 + Javascript 做类似 Visio 的图表?
- laravel - Laravel 中的多个存在验证
- python - 我无法保持在 1 秒内
- express - 这两种使用 express 中间件的方法有区别吗?
- excel - 如何将 Excel 数据或文件直接打开到 Gridview
- python - 符号 self(x) 有什么作用?
- python - 如何调用使用变量本身的跟踪变量的函数
- python-3.x - Jupyter 笔记本无法启动(Windows 10)