AVR 328pb定时器0基本介绍和使用

AVR 328pb定时器0基本介绍和使用


  • 📌参考ATmega328PB文档.
  • 📍结合参考同架构lgt8f328p中文文档:http://www.prodesign.com.cn/wp-content/uploads/2023/03/LGT8FX8P_databook_v1.0.4.pdf

📗定时器0基本功能描述

  • 两个独立的输出比较单元
  • 双缓冲输出比较寄存器
  • 比较匹配发生时自动清零计数器并自动加载
  • 无干扰脉冲的相位修正的PWM输出
  • 三个独立的中断源:溢出和比较匹配中断 (TOV0、OCF0A和OCF0B)

📑TC0寄存器列表

在这里插入图片描述

  • TC0控制寄存器A- TCCR0A
    在这里插入图片描述
    在这里插入图片描述
  • TC0控制寄存器B- TCCR0B
    在这里插入图片描述
    在这里插入图片描述
  • 波形生成模式位(WGM0[1:0])描述:
    在这里插入图片描述

📘定时器0工作模式

定时计数器0有四种不同的工作模式,包括普通模式(Normal),比较匹配时清零(CTC)模式,快速脉冲宽度调制(FPWM)模式和相位修正脉冲宽度调制(PCPWM)模式,由波形产生模式控制位WGM0[2:0]来选择。

  • 🌿328PB定时器0架构
    在这里插入图片描述
🌿相位修正PWM模式
  • 时序图:
    在这里插入图片描述

当设置WGM0[2:0]=1 或 5 时,定时计数器 0 进入相位修正PWM模式,计数的最大值TOP 分别为MAX(0xFF)或OCR0A。计数器采用双向操作,由BOTTOM递增到TOP,然后又递减到BOTTOM,再重复此操作。计数到达TOP和BOTTOM时均改变计数方向,计数值在TOP或BOTTOM 上均只停留一个计数时钟。在递增或递减过程中,计数值TCNT0与OCR0x匹配时,输出比较信号OC0x将会被清零或置位,取决于比较输出模式COM0x的设置。与单向操作相比,双向操作可获得的最大频率要小,但其极好的对称性更适合于电机控制。

  • 相位修正PWM模式下,当计数到达BOTTOM时置位TOV0标志,当计数到达TOP时把比较缓冲器的值更新到比较值。如果中断使能,在中断服务程序中可以更新比较缓冲器OCR0x寄存器。
    设置OC0x 引脚的数据方向寄存器为输出时才能得到输出比较信号OC0x的波形。波形的频率可用下面的公式来计算:
FOCnxPCPWM = Fclk /N*510 (N由CS0[2:0] 决定)

其中,N表示的是预分频因子(1,8,64,256或者1024)。
在这里插入图片描述

在递增计数过程中,当TCNT0与OCR0x匹配时,波形产生器就清零(置位)OC0x信号。在
递减计数过程中,当TCNT0与OCR0x匹配时,波形产生器就置位(清零)OC0x信号。由此OCR0x 的极值会产生特殊的PWM波。当OCR0x设置为最大值或最小值时,OC0x信号输出会一直保持低电平或高电平。
为了保证输出PWM波在最小值两侧的对称性,在没有发生比较匹配时,有两种情况下也会翻转OC0x信号。第一种情况是,当OCR0x的值由最大值0xFF改变为其他数据时。当OCR0x为最大值,计数值达到最大时,OC0x 的输出与前面降序计数时比较匹配的结果相同,即保持OC0x不变。此时会更新比较值为新的OCR0x的值(非0xFF), OC0x的值会一直保持,直
到升序计数时发生比较匹配而翻转。此时OC0x信号并不以最小值为中心对称,因此需要在TCNT0 到达最大值时翻转 OC0x 信号,此即没有发生比较匹配时翻转 OC0x 信号的第一种情况。第二种情况是,当TCNT0从比OCR0x 高的值开始计数时,因而会丢失一次比较匹配,从而引起不对称情形的产生。同样需要翻转OC0x信号去实现最小值两侧的对称性。

  • 📝相位修正PWM模式测试例程:
/** Timer0_ OC0A_PWM_Pulse.c** Created: 2024/2/1 10:45:11* Author : Administrator*/#include <avr/io.h>void Sys_Clock_Init(void)
{// Crystal Oscillator division factor: 1 PSC  16MHz HSECLKPR=(1<<CLKPCE);CLKPR=(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);}void Gpio_Init(void)
{// Port D initialization  PD6 PD5 OutPut// Function: Bit7=In Bit6=Out Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=InDDRD=(0<<DDD7) | (1<<DDD6) | (1<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);// State: Bit7=T Bit6=0 Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=TPORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);}void Timer0_PWM_Init(void)
{
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 250.000 kHz、
// Mode: Phase correct PWM top=0xFF
// OC0A output: Non-Inverted PWM
// OC0B output: Disconnected
// Timer Period: 2.04 ms
// Output Pulse(s):
//Phase Correct PWM Mode PWM频率
// OC0A Period: 2.04 ms Width: 1.024 ms
//N represents the prescale divider (1, 8, 64, 256, or 1024)
//1 PSC->62.5khZ
//FOCnxPWM = Fclk /N*510 (N由CS0[2:0] 决定)/*TCCR0A=(1<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (0<<WGM01) | (1<<WGM00);//250KHzTCCR0B=(0<<WGM02) | (0<<CS02) | (1<<CS01) | (1<<CS00);//64PSC :PWM频率= 1600 000/64*510*/TCCR0A=(1<<COM0A1) | (0<<COM0A0) | (1<<COM0B1) | (0<<COM0B0) | (0<<WGM01) | (1<<WGM00);TCCR0B=(0<<WGM02) | (0<<CS02) | (1<<CS01) | (0<<CS00);//CS0-CS2:0-7 prescale divider (1, 8, 64, 256, or 1024) 8PSC :PWM频率= 1600 000/8*510=3921HzTCNT0=0x06;OCR0A=0x40;//使能比较器A输出值:0 - 255占空比OCR0B=0x40;//使能比较器B输出值:0 - 255占空比// Ensure that the Timer/Counter 0 is enabledPRR0&= ~(1<<PRTIM0);// Timer/Counter 0 Interrupt(s) initializationTIMSK0=(0<<OCIE0B) | (0<<OCIE0A) | (0<<TOIE0);}int main(void)
{/* Replace with your application code */Sys_Clock_Init();Gpio_Init();Timer0_PWM_Init();while (1){}
}
  • 🔖TCCR0B=(0<<WGM02) | (0<<CS02) | (1<<CS01) | (0<<CS00);:8分频,频率计算:
    在这里插入图片描述

  • 📏PD5和PD6输出波形图:
    在这里插入图片描述

🌿CTC 模式

设置WGM0[2:0]=2 时,定时计数器0进入CTC模式,计数的最大值TOP为OCR0A。在这个模式下,计数方式为每一个计数时钟加一递增,当计数器的数值TCNT0等于TOP时计数器清零。OCR0A定义了计数的最大值,亦即计数器的分辨率。这个模式使得用户可以很容易的控制比较匹配输出的频率,也简化了外部事件计数的操作。
当计数器到达计数的最大值时,输出比较匹配标志OCF0被置位,相应的中断使能置位时将会产生中断。在中断服务程序里可以更新 OCR0A 寄存器即计数的最大值。在这个模式下OCR0A 没有使用双缓冲,在计数器以无预分频器或很低的预分频器工作下将最大值更新为接近最小值的时候要小心。如果写入OCR0A的数值小于当时的TCNT0值时,计数器将丢失一次比较匹配。在下一次比较匹配发生之前,计数器不得不先计数到TOP,然后再从BOTTOM开始计数到OCR0A值。和普通模式一样,计数值回到BOTTOM的计数时钟里置位TOV0标志。
设置OC0x引脚的数据方向寄存器为输出时才能得到输出比较信号OC0x的波形。当COM0x=1时,发生比较匹配时会翻转 OC0x 信号,这种情况下波形的频率可以用下面的公式来计算:
foc0xctc = fsys/(2N(1+OCR0x))
其中,N表示的是预分频因子(1,8,64,256或者1024)。
在这里插入图片描述

从公式可以看出,当设置OCR0A为0x0且无预分频器时,可以获得最大频率为fsys/2的输出波形。
-🔧 使用CodeVisionAVR软件配置CTC模式参数:
在这里插入图片描述

  • 📝定时器0 CTC模式下,使用示例:
/** Timer0_1ms.c** Created: 2024/1/31 20:40:22* Author : Administrator*/#include <avr/io.h>
#include "avr//interrupt.h"ISR(TIMER0_OVF_vect)
{static volatile int iTimes = 0;// Reinitialize Timer 0 valueTCNT0=0x06;// Place your code hereif (++iTimes == 1000){PORTB ^= (1 << PINB5);//1秒钟闪烁一次iTimes = 0;}}void Timer0_Init()
{// Timer/Counter 0 initialization// Clock source: System Clock// Clock value: 250.000 kHz// Mode: Normal top=0xFF// OC0A output: Disconnected// OC0B output: Disconnected// Timer Period: 1 msTCCR0A=(0<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (0<<WGM01) | (0<<WGM00);TCCR0B=(0<<WGM02) | (0<<CS02) | (1<<CS01) | (1<<CS00);TCNT0=0x06;OCR0A=0x00;OCR0B=0x00;// Timer/Counter 0 Interrupt(s) initializationTIMSK0=(0<<OCIE0B) | (0<<OCIE0A) | (1<<TOIE0);//溢出中断启用当TOIE0位写入1,并设置状态寄存器中的I位时,启用定时器/计数器0溢出中断。// Ensure that the Timer/Counter 0 is enabledPRR0&= ~(1<<PRTIM0);
}int main(void)
{/* Replace with your application code */// Crystal Oscillator division factor: 1CLKPR =(1<<CLKPCE);CLKPR =(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);cli();//关中断Timer0_Init();//定时器0初始化,配置1ms中断DDRB = PINB5;//配置PB5为输出模式// Globally enable interruptssei();//开中断while (1){}
}
🌿快速PWM模式

设置WGM0[2:0]=3 或 7 时,定时计数器 0 进入快速PWM模式,可以用来产生高频的PWM波形,计数最大值TOP分别为MAX(0xFF)或OCR0x。快速PWM模式和其他PWM模式不同在于它是单向操作。计数器从最小值0x00累加到TOP后又回到BOTTOM重新计数。
当计数值TCNT0到达OCR0x或BOTTOM时,输出比较信号OC0x会被置位或清零,取决于比较输出模式COM0x的设置,详情见寄存器描述。由于采用单向操作,快速PWM模式的操作
频率是采用双向操作的相位修正PWM模式的两倍。高频特性使得快速PWM模式适用于功率调节,整流以及DAC应用。高频信号可以减小外部元器件(电感电容等)的尺寸,从而降低系统成本。
当计数值到达最大值时,定时计数器溢出标志TOV0将会被置位,并把比较缓冲器的值更新
在这里插入图片描述

  • Fast PWM mode频率计算公式:
    在这里插入图片描述

  • 📑快速PWM例程,使用CodeVisionAVR配置参数:
    在这里插入图片描述

/** Timer0_ OC0A、B_PWM_Pulse.c** Created: 2024/2/1 10:45:11* Author : Administrator*/#include <avr/io.h>void Sys_Clock_Init(void)
{// Crystal Oscillator division factor: 1 PSC  16MHz HSECLKPR=(1<<CLKPCE);CLKPR=(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);}void Gpio_Init(void)
{// Port D initialization  PD6 PD5 OutPut// Function: Bit7=In Bit6=Out Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=InDDRD=(0<<DDD7) | (1<<DDD6) | (1<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);// State: Bit7=T Bit6=0 Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=TPORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);}void Timer0_PWM_Init(void)
{// Timer/Counter 0 initialization// Clock source: System Clock// Clock value: 250.000 kHz// Mode: Fast PWM top=0xFF// OC0A output: Non-Inverted PWM// OC0B output: Non-Inverted PWM// Timer Period: 1.024 ms// Output Pulse(s):// OC0A Period: 1.024 ms Width: 0.257 ms// OC0B Period: 1.024 ms Width: 0.6666 msTCCR0A=(1<<COM0A1) | (0<<COM0A0) | (1<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (1<<WGM00);TCCR0B=(0<<WGM02) | (0<<CS02) | (1<<CS01) | (1<<CS00);TCNT0=0x06;OCR0A=0x40;OCR0B=0xA6;
// Ensure that the Timer/Counter 0 is enabledPRR0&= ~(1<<PRTIM0);// Timer/Counter 0 Interrupt(s) initializationTIMSK0=(0<<OCIE0B) | (0<<OCIE0A) | (0<<TOIE0);}int main(void)
{/* Replace with your application code */Sys_Clock_Init();Gpio_Init();Timer0_PWM_Init();while (1){}
}
  • 🎞定时器0快速PWM模式下,比较器A:PD5和比较器B:PD6输出波形:
    在这里插入图片描述
    在这里插入图片描述
  • 🪓快速模式下Fast PWM top=OCR0A
    在这里插入图片描述
/*Fast PWM top=OCR0A* Timer0_ OC0A_PWM_Pulse.c** Created: 2024/2/1 10:45:11* Author : Administrator*/#include <avr/io.h>void Sys_Clock_Init(void)
{// Crystal Oscillator division factor: 1 PSC  16MHz HSECLKPR=(1<<CLKPCE);CLKPR=(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);}void Gpio_Init(void)
{// Port D initialization  PD6 PD5 OutPut// Function: Bit7=In Bit6=Out Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=InDDRD=(0<<DDD7) | (1<<DDD6) | (1<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);// State: Bit7=T Bit6=0 Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=TPORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);}void Timer0_PWM_Init(void)
{// Timer/Counter 0 initialization// Clock source: System Clock// Clock value: 250.000 kHz// Mode: Fast PWM top=OCR0A// OC0A output: Disconnected// OC0B output: Non-Inverted PWM// Timer Period: 1 ms// Output Pulse(s):// OC0B Period: 1 ms Width: 0.7992 msTCCR0A=(0<<COM0A1) | (0<<COM0A0) | (1<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (1<<WGM00);TCCR0B=(1<<WGM02) | (0<<CS02) | (1<<CS01) | (1<<CS00);TCNT0=0x06;OCR0A=0xF9;OCR0B=0xC7;
// Ensure that the Timer/Counter 0 is enabledPRR0&= ~(1<<PRTIM0);// Timer/Counter 0 Interrupt(s) initializationTIMSK0=(0<<OCIE0B) | (0<<OCIE0A) | (0<<TOIE0);}int main(void)
{/* Replace with your application code */Sys_Clock_Init();Gpio_Init();Timer0_PWM_Init();while (1){}
}
  • 🔖Fast PWM top=OCR0A模式下,由于占用了OCR0A所以只有输出比较器B才有输出。PD6输出:
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/444817.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

记一次java项目本地正常执行,打完包之后执行发现没有对应的类或配置的问题

1、起因 线上有个spark的任务出了问题&#xff08;该任务是通过sparkstreaming读取kafka中的数据&#xff0c;处理完之后推到es中&#xff09;&#xff0c;问题出在kafka中数据是有更新的&#xff0c;但是es中的对应索引中的数据却只更新到月初&#xff0c;因此我需要排查处理…

JavaSE-项目小结-IP归属地查询(本地IP地址库)

一、项目介绍 1. 背景 IP地址是网络通信中的重要标识&#xff0c;通过分析IP地址的归属地信息&#xff0c;可以帮助我们了解访问来源、用户行为和网络安全等关键信息。例如应用于网站访问日志分析&#xff1a;通过分析访问日志中的IP地址&#xff0c;了解网站访问者的地理位置分…

Linux进程通信基础

前要&#xff1a;本节内容主要是管道和共享内存块&#xff0c;而且我们需要明白我们所讲的进程通信本质是为了在内存中传递数据&#xff08;看到同一份资源&#xff09;。 而实际上&#xff0c;我们也可以通过磁盘传递数据&#xff0c;但是为什么不这么做呢&#xff1f;很简单&…

【Linux】Daemon守护进程详解

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;Linux系列专栏&#xff1a;Linux基础 &#x1f525; 给大家…

DRV8313和L298N都是电机驱动,一个是驱动三相FOC无刷直流电机的,一个是驱动有刷电机,使stm32控制无刷电机简单入门知识

DRV8313和L298N都是电机驱动器&#xff0c;但它们之间存在一些关键的区别&#xff1a; DRV83131&#xff1a; 由德州仪器&#xff08;TI&#xff09;制造。 具有集成的场效应晶体管&#xff08;FET&#xff09;。 最大电压为65V。 峰值电流为3A。 适用于三相电机驱动。 L298N…

性能测试常用术语

之前在性能测试过程中&#xff0c;对于某些其中的术语一知半解&#xff0c;导致踩了很多坑。这篇博客&#xff0c;就常见的一些性能测试术语进行一次浅析。。。 负载 对被测系统不断施加压力&#xff0c;直到性能指标超过预期或某项资源使用达到饱和&#xff0c;以验证系统的处…

基于FPGA的OFDM基带发射机的设计与实现

文章目录 前言一、OFDM描述二、本系统的实现参照 1.IEEE 802.11a协议主要参数2.不同调制方式与速率 3. IFFT映射关系4. IEEE 802.11a物理层规范5. PPDU帧格式三、设计与实现 1.扰码2.卷积编码与删余3.数据交织4.符号调制5.导频插入6.IFFT变换 7.循环前缀&加窗8.训练序列生成…

kubekey网页版安装k8s集群操作流程

kubekey可以一键拉起k8s集群并完成kubesphere的部署&#xff0c;以后kubekey简称kk。kk 3.2版本以前都是在宿主机上完成对应的创建集群、添加节点、升级等操作的&#xff0c;3.2版本后开始往页面操作的方向演进&#xff0c;kk 3.2版本现在还是alpha&#xff0c;所以不推荐在生产…

java面向对象基础(面试)

一、面向对象基础 1. 面向对象和面向过程的区别 面向过程把解决问题的过程拆成一个个方法&#xff0c;通过一个个方法的执行解决问题。面向对象会先抽象出对象&#xff0c;然后用对象执行方法的方式解决问题。 2.创建一个对象用什么运算符?对象实体与对象引用有何不同? n…

[C++]继承(续)

一、基类和派生类对象赋值转换 在public继承时&#xff0c;父类和子类是一个“is - a”的关系。 子类对象赋值给父类对象/父类指针/父类引用&#xff0c;我们认为是天然的&#xff0c;中间不产生临时对象&#xff0c;也叫作父子类赋值兼容规则&#xff08;切割/切片&#xff…

如何本地搭建Emby影音管理服务并结合内网穿透实现远程访问本地影音库

文章目录 1.前言2. Emby网站搭建2.1. Emby下载和安装2.2 Emby网页测试 3. 本地网页发布3.1 注册并安装cpolar内网穿透3.2 Cpolar云端设置3.3 Cpolar内网穿透本地设置 4.公网访问测试5.结语 1.前言 在现代五花八门的网络应用场景中&#xff0c;观看视频绝对是主力应用场景之一&…

江科大stm32学习笔记9——OLED调试工具

一、OLED OLED&#xff1a;有机发光二极管&#xff0c;供电3~5.5V&#xff0c;0.96寸OLED通信协议&#xff1a;I2C/SPI&#xff0c;分辨率&#xff1a;128*64 二、调试方式 串口调试&#xff1a;通过串口通信&#xff0c;将调试信息发送到电脑端&#xff0c;电脑使用串口助手…