PIC16单片机Timer0详解:中断与输出功能

需积分: 46 47 下载量 15 浏览量 更新于2024-08-08 收藏 5.02MB PDF 举报
" Timer0中断和输出在PIC16F18324微控制器中的实现与应用" 在PIC16F18324微控制器中,Timer0是一个重要的定时/计数器资源,用于执行精确的时间间隔测量和中断驱动的任务。这个定时器具有两种模式:8位和16位,其工作原理和中断机制如下: 26.6 Timer0中断: Timer0中断由两个条件触发: 1. 当8位的TMR0L寄存器的值与TMR0H寄存器的值匹配时。 2. 当16位的TMR0从FFFFh计满并返回到零时。 中断标志位TMR0IF在这些条件满足时被置1。如果后分频比(T0OUTPS<3:0>)设置为1:1,即无分频操作,那么每次匹配或计满都会使TMR0IF标志置1。否则,根据分频比,标志位会在每发生T0OUTPS+1次匹配或计满时置1。若TMR0中断被允许(PIE0寄存器的TMR0IE位设为1),中断事件会触发CPU中断,如果设备处于休眠模式,它也会被唤醒。 26.7 Timer0输出: Timer0的输出可以通过RxyPPS输出选择寄存器连接到任何I/O引脚,增加了设计的灵活性。此外,这个输出还可以为其他外设如模数转换器的自动转换触发提供信号。Timer0的输出状态可以通过T0CON0寄存器的Timer0输出位(T0OUT)进行软件监控。 当TMR0在8位模式下匹配或16位模式下计满返回时,TMR0_out会延迟一个后分频时钟周期翻转。在匹配事件发生时,输出会在每T0OUTPS+1次匹配时翻转。由于在Timer0的总周期内会发生两次匹配,因此输出的占空比默认为50%。 关于PIC16F18324微控制器的其他特性: - 它是一款低功耗单片机,适用于通用和低功耗应用,具有C编译器优化的RISC架构和48条指令。 - 支持高达32MHz的时钟输入和125ns的最小指令周期。 - 包括16级深的硬件堆栈、4个8位定时器和3个16位定时器,以及多种复位和保护功能,如上电复位(POR)、上电延时定时器(PWRT)、欠压复位(BOR)和低功耗BOR(LPBOR)。 - 配备7KB闪存程序存储器、512字节数据SRAM和256字节EEPROM。 - 具有直接、间接和相对寻址模式,适用于不同工作场景。 - 支持多种工作电压和温度范围,以及工业级和扩展级温度等级。 - 超低功耗(XLP)特性包括休眠模式、看门狗定时器、辅助振荡器以及不同工作模式下的电流消耗。 - 提供空闲模式、打盹模式和休眠模式以减少功耗,并有外设模块禁止功能(PMD)来关闭未使用的外设以降低功耗。 - 数字外设包括可配置逻辑单元(Configurable Logic Cell, CLC)、比较捕获/脉宽调制(Comparator Capture/ Pulse Width Modulation, CCP/PWM)等。 这个微控制器集成了丰富的模拟和数字外设,结合其低功耗特性和灵活的PPS功能,使得它成为许多嵌入式系统设计的理想选择。Timer0中断和输出的精细控制是实现精准定时和事件驱动编程的关键,从而在实际应用中发挥重要作用。

重写下面代码;timer_handle_t itcs_timer_init(timer_handle_t handle, timer_event_cb_t cb_event) { timer_priv_t *timer_priv = handle; if (timer_priv->idx < 0 || timer_priv->idx >= CONFIG_TIMER_NUM) { return NULL; } set_clock_type("cpu-pclk"); // printf("enter timer init fun in driver\n"); uint32_t tempreg = 0; switch (timer_priv->idx) { case 0: timer_priv->base = ITCS_TIMER0_BASE; break; case 1: timer_priv->base = ITCS_TIMER1_BASE; break; default: break; } // printf("unit %d ,timeridx %d, base addr // %08x\n",timer_priv->idx,timer_priv->timeridx,timer_priv->base); switch (timer_priv->timeridx) { case 1: tempreg = readl(timer_priv->base + TIMER_CCR_CONTROL_C1); tempreg |= CCR_RST_ENABLE; writel(tempreg, timer_priv->base + TIMER_CCR_CONTROL_C1); tempreg = readl(timer_priv->base + TIMER_IER_C1); tempreg &= ~(IER_EVNT_ENABLE | IER_ITRV_ENABLE | IER_M1_ENABLE | IER_M2_ENABLE | IER_M3_ENABLE); writel(tempreg, timer_priv->base + TIMER_IER_C1); if (timer_priv->idx == 0) { timer_priv->irq = TTC0_TIMER1_IRQn; request_irq(TTC0_TIMER1_IRQn, itcs_timer_irq, "itcs_timer_irq01", timer_priv); } else { timer_priv->irq = TTC1_TIMER1_IRQn; request_irq(TTC1_TIMER1_IRQn, itcs_timer_irq, "itcs_timer_irq11", timer_priv); } break; case 2: tempreg = readl(timer_priv->base + TIMER_CCR_CONTROL_C2); tempreg |= CCR_RST_ENABLE; writel(tempreg, timer_priv->base + TIMER_CCR_CONTROL_C2); tempreg = readl(timer_priv->base + TIMER_IER_C2); tempreg &= ~(IER_EVNT_ENABLE | IER_ITRV_ENABLE | IER_M1_ENABLE | IER_M2_ENABLE | IER_M3_ENABLE); writel(tempreg, timer_priv->base + TIMER_IER_C2); if (timer_priv->idx == 0) { timer_priv->irq = TTC0_TIMER2_IRQn; request_irq(TTC0_TIMER2_IRQn, itcs_timer_irq, "itcs_timer_irq02", timer_priv); } else { timer_priv->irq = TTC1_TIMER2_IRQn; request_irq(TTC1_TIMER2_IRQn, itcs_timer_irq, "itcs_timer_irq12", timer_priv); } break; case 3: tempreg = readl(timer_priv->base + TIMER_CCR_CONTROL_C3); tempreg |= CCR_RST_ENABLE; writel(tempreg, timer_priv->base + TIMER_CCR_CONTROL_C3); tempreg = readl(timer_priv->base + TIMER_IER_C3); tempreg &= ~(IER_EVNT_ENABLE | IER_ITRV_ENABLE | IER_M1_ENABLE | IER_M2_ENABLE | IER_M3_ENABLE); writel(tempreg, timer_priv->base + TIMER_IER_C3); if (timer_priv->idx == 0) { timer_priv->irq = TTC0_TIMER3_IRQn; request_irq(TTC0_TIMER3_IRQn, itcs_timer_irq, "itcs_timer_irq03", timer_priv); // printf("unit timer1 ret=%08x , request irq3 success!\n",ret); } else { timer_priv->irq = TTC1_TIMER3_IRQn; request_irq(TTC1_TIMER3_IRQn, itcs_timer_irq, "itcs_timer_irq13", timer_priv); // printf("unit timer1 ret=%08x , request irq3 success!\n",ret); } break; default: return NULL; } timer_priv->cb_event = cb_event; // printf("init status irq id num:%d\n",timer_priv->irq); // printf("INIT TIMER %d Timer Count No %d SUCCESS\n", timer_priv->idx, // timer_priv->timeridx); return (timer_handle_t)timer_priv; }

2023-02-17 上传