7/15 note3 转载集合

先导知识:

1.关于中断

AVR编程中

#pragma interrupt_handler Timer_interrupt:7是什

总的是中断申明

固定格式为:

#pragma interrupt_handler 中断子程序的函数名:该中断所对应的中断向量号

是定时器中断的声明 ,“7”表示中断向量号,及代表中断的入口地址,不同的向量号所表征的中断是不相同的。7表示的是T1中断向量号,不管是在该中断中发生“比较匹配中断”还是“溢出中断”,都是同样的向量号。
但是这只是某种编译器的编写习惯,如ICC,GCC,其他编译器的编写习惯不太一样,但是,中断向量号是一样的,即使你前面写的是T1中断,数字写成10,它照样进到T0中断(T0初始化过)。

2.关于ccu6

CCU6单元由具有三个捕获/比较通道的定时器T12块和具有一个比较通道的定时器T13块组成。T12通道可以独立地产生PWM信号接受捕获触发器,或 它们可以共同产生控制信号模式来驱动直流电动机或逆变器。一组丰富的状态位,通过阴影寄存器同步更新参数值,并灵活生成中断请求信号提供有效的软件控制。

用CCU6生成T PWM的初始化代码

用CCU6生成PWM,如果是驱动带霍尔传感器的无刷直流电机,就用PWMBC更合适;一般的基于定时器的PWM生成可使用TPWM。

PWM PWMBC TPWM各是什么?

 

#include <Ccu6/TPwm/IfxCcu6_TPwm.h>//需要的头文件



static IfxCcu6_TPwm tPwm;// used globally 申明的全局变量

这两个名字接着写是什么意思



设置中断:

定义中断优先级:

#define IFX_INTPRIO_CCU6 1// priorities are normally defined in Ifx_IntPrioDef.h

添加用户代码:

IFX_INTERRUPT(ccu60ISR_TPwm, 0, IFX_INTPRIO_CCU6)

{

    //user code

}

最后在初始化函数中设置中断:

IfxCpu_Irq_installInterruptHandler(&ccu60ISR_TPwm, IFX_INTPRIO_CCU6);

IfxCpu_enableInterrupts();



初始化模块:

IfxCcu6_TPwm_Config tPwmConfig;// create configuration

IfxCcu6_TPwm_initModuleConfig(&tPwmConfig, &MODULE_CCU60);

tPwmConfig.base.frequency = 400000;// 在内部启动的情况下配置定时器的频率// 此频率将为稍后选择的定时器块设置

tPwmConfig.base.period = 100;// 配置定时器的周期

tPwmConfig.base.waitingTime = 20;// 配置延迟 T13 启动与 T12 同步的等待时间

tPwmConfig.base.activeState = Ifx_ActiveState_high;// 选择输出的活动状态

tPwmConfig.timer = IfxCcu6_TimerId_t13;// 选择通过其生成 PWM 的定时器13

tPwmConfig.clock.t13ExtClockEnabled   = FALSE;

tPwmConfig.clock.t13ExtClockInput     = NULL_PTR;

tPwmConfig.clock.t13countingInputMode = IfxCcu6_CountingInputMode_internal;

                                                                        // 为内部模式配置时钟

tPwmConfig.timer13.counterValue     = 0;

tPwmConfig.timer13.compareValue     = 100;// 配置选定的定时器块

tPwmConfig.timer13.t12SyncEvent     = IfxCcu6_T13TriggerEvent_onCC60RCompare;

tPwmConfig.timer13.t12SyncDirection = IfxCcu6_T13TriggerDirection_onT12CountingUp;

                                                        // 配置同步,如果同步从 T12 开始 

tPwmConfig.channelOut = IfxCcu6_ChannelOut_cout3;//选择要调制的通道输出

// 引脚配置

const IfxCcu6_TPwm_Pins pins = {

    NULL,   // CC60Out pin not used

    NULL,   // CC61Out pin not used

    NULL,   // CC62Out pin not used

    NULL,   // COUT60 pin not used

    NULL,   // COUT61 pin not used

    NULL,   // COUT62 pin not used

    IfxCcu60_COUT63_P00_0_OUT,  // COUT63 pin

    IfxPort_OutputMode_pushPull,

    IfxPort_PadDriver_cmosAutomotiveSpeed1

};

tPwmConfig.pins = &pins;

// 配置中断

tPwmConfig.interrupt1.interruptSource = IfxCcu6_InterruptSource_t13CompareMatch;

tPwmConfig.interrupt1.serviceRequest  = IfxCcu6_ServiceRequest_2;

tPwmConfig.interrupt1.priority        = IFX_INTPRIO_CCU6;

tPwmConfig.interrupt1.typeOfService   = IfxSrc_Tos_cpu0;

// 配置输入和输出触发器

tPwmConfig.trigger.t12ExtInputTrigger   = IfxCcu60_T12HRB_P00_7_IN;

tPwmConfig.trigger.t13ExtInputTrigger   = NULL_PTR;

tPwmConfig.trigger.extInputTriggerMode  = IfxCcu6_ExternalTriggerMode_risingEdge;

tPwmConfig.trigger.t13InSyncWithT12     = TRUE;



tPwmConfig.trigger.outputTriggerEnabled = TRUE;

tPwmConfig.trigger.outputLine           = IfxCcu6_TrigOut_0;

tPwmConfig.trigger.outputTrigger      = IfxCcu6_TrigSel_cout63;

// 初始化模块

IfxCcu6_TPwm_initModule(&tPwm, &tPwmConfig);

经过如上设置TPWM功能就基本可以使用了,例程中的程序也基本就是这样编写的。

TPWM的控制代码:

开始:

IfxCcu6_TPwm_start(&tPwm);

停止:

IfxCcu6_TPwm_stop(&tPwm);

暂停:

IfxCcu6_TPwm_pause(&tPwm);

恢复:

IfxCcu6_TPwm_resume(&tPwm);

 (定时器T12可以在其三个信道的捕获和/或比较模式下工作。模式也可以组合(例如,一个通道在比较模式下工作,而另一个通道在捕获模式下工作)。定时器T13可以仅在比较模式下工作多通道控制单元产生输出模式,可由T12和/或T13。可以选择调制源并组合用于信号调制。 )

3.什么是pit

PIT是个非常准的定时中断(相比delay函数来说),说好的1ms触发一次中断就是1ms触发一次。

PIT中断的配置也很简单。设置好中断时间间隔(这里是1ms),写好中断处理函数,就可以啦。

关于这几个定时器

好多人问PIT、Systick、LPTMR、PDB到底有什么不同呢,他们不都是定时器吗?干嘛非得用PIT,不用其他的呢?

其实这是一个比较尴尬的问题,如同问自行车、汽车、飞机不都是交通工具吗?都可以从甲地到乙地,干嘛非用某某呢?

好了,一开始我们就说了,PIT是最简单的定时器,用起来极其简单,如果你想周期性的产生中断,OK,用PIT就足够了。

原理:无需了解(2条消息) PIT工作原理_白小白-CSDN博客_pit中断

PIT:  PIT有两个定时器,两个定时器可以连到一起去的。

该计数器的值和上面不一样,它是倒序的,跟systick有点像,从一个值往下递减,减到0的时候重新加载。该定时器还有两个寄存器表示生命周期,可以用来计算该计算机运行了多久,多长时间,对了,该定时器还有一个功能,就是累加(chain)也可以说连接吧,就比如KL25里面有2个TIMER,当第一个TIMER达到0的时候,第二个TIMER减1.

控制寄存器CR也没有几个功能,就是一个模块使能。和一个freeze

每个定时器都有以下的值:

PIT加载值,该值就是该计数器数到0的时候重新加载的值,

PIT当前值:计数当前计数器的值,

PIT时间控制寄存器。可以设置chain累加到前面一个计数器。timer0肯定没有这个功能。TIE中断使能位,TEN时钟使能。

PIT标志位:该位标志了计数器的值达到timer

(Systick是什么呢,它是Cortex内核的定时器,也就是说不管是M3\M4,不管是ST的单片机还是飞思卡尔的单片机,这个定时器的结构和用法是一样的,它也可以产生周期中断,也可以作为精准延时函数。但是他的真正用武之地值操作系统的嘀嗒时钟,也就是为uC/OS等操作系统提供时钟节拍。一来他是内核级别的时钟,中断优先级比其他外设模块要高;二来他比较通用,可以不用改任何代码就移植到其他单片机上。)

正文

zf_ccu6_pit.c

 

#include "IfxCcu6_Timer.h"

#include "SysSe/Bsp/Bsp.h"

#include "isr_config.h"

#include "zf_ccu6_pit.h"

1.pit初始化函数

函数定义:void pit_init(CCU6N_enum ccu6n, CCU6_CHN_enum pit_ch, uint32 time)

调用:pit_init(CCU6_0, PIT_CH0, 5000);    //设置周期中断5000us

说明

ccu6n选择CCU6模块(CCU6_0CCU6_1)

pit_ch选择通道(PIT_CH0、PIT_CH1)

time周期时间 

注意:请使用.h文件中 带时间单位的宏定义函数?啥意思

​​​​​2.pit 关闭

函数定义:void pit_close(CCU6N_enum ccu6n, CCU6_CHN_enum pit_ch)

//  Sample usage:  pit_close(CCU6_0, PIT_CH0);    //关闭CCU60 通道0的计时器
ccu6n选择CCU6模块(CCU6_0CCU6_1)

pit_ch选择通道(PIT_CH0、PIT_CH1)

3.pit开始

void pit_start(CCU6N_enum ccu6n, CCU6_CHN_enum pit_ch)
调用: pit_start(CCU6_0, PIT_CH0);    //打开CCU60 通道0的计时器
4.禁止pit中断

void pit_disable_interrupt(CCU6N_enum ccu6n, CCU6_CHN_enum pit_ch)

//   pit_disable_interrupt(CCU6_0, PIT_CH0);    //禁止CCU60 通道0的中断

5.使能pit中断

void pit_enable_interrupt(CCU6N_enum ccu6n, CCU6_CHN_enum pit_ch)

//   pit_enable_interrupt(CCU6_0, PIT_CH0);    //开启CCU60 通道0的中断

zf_ccu6_pit.h
//------------------------------------以下代码用于PIT中断------------------------------------
#define pit_interrupt_ms(ccu6n, pit_ch, time)  pit_init(ccu6n, pit_ch, time*1000)    //(单位为 毫秒)
#define pit_interrupt_us(ccu6n, pit_ch, time)  pit_init(ccu6n, pit_ch, time)        //(单位为 微秒)

    pit_interrupt_ms(CCU6_0, PIT_CH0, 10);//10ms间隔中断初始化

实战调用

#include "isr_config.h"

#include "isr.h"
//在isr.c的中断函数,函数定义的第二个参数固定为0,请不要更改,即使你用CPU1处理中断也不要更改,需要CPU1处理中断只需要在isr_config.h内修改对应的宏定义即可


//PIT中断函数  示例
uint16 time;
IFX_INTERRUPT(cc60_pit_ch0_isr, 0, CCU6_0_CH0_ISR_PRIORITY)

//分别在:  pit_config.h(内含服务类型编号和优先级编号)


{
    enableInterrupts();//开启中断嵌套
    PIT_CLEAR_FLAG(CCU6_0, PIT_CH0);
    time++;
    printf("pit count: %d\n", time);
}
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值