STM32
直播中

麦特拉布

13年用户 1137经验值
私信 关注
[问答]

PWM波形是如何生成的?求解

ADC模块是什么?
CCU6单元是什么?是由哪些部分组成的?
PWM波形是如何生成的?

回帖(6)

李泓翔

2021-12-22 13:58:14
ADC环境例程与库函数学习

ADC模块

ADC模块:即模数转换模块/AD转换模块,功能是将电压信号转换为相应的数字信号。实际应用中,这个电压信号可能由温度、湿度、压力等实际物理量经过传感器和相应的变换电路转化而来。经过AD转换,MCU(微处理器;单片机)就可以处理这些物理量。

//以下是两句常用语
#include "headfile.h"
#pragma section all "cpu0_dsram"//这两句为常用


uint16 adc_result;
uint16来源

/* 16bit unsigned:  0..65535 [0x0000..0xFFFF]*/
/* [cover parentID={66E964CA-35D5-4013-BB61-1E824636D713}] uint16 [/cover] */
typedef unsigned short      uint16;


主函数

int core0_main(void)
{
disableInterrupts();//禁用中断
get_clk();//获取时钟频率  务必保留


//用户在此处调用各种初始化函数等
adc_init(ADC_0, ADC0_CH0_A0);//初始化ADC0 通道0 使用A0引脚


enableInterrupts();//启动中断
while (TRUE)
    {
     //通过将A0引脚接到GND或者核心板VCC  查看FSS窗口中打印出来的ADC结果
     //A0接到GND时 结果应该在0附近
     //A0接到VCC时 结果应该在4095附近
     //悬空时 结果可能是任意数,没有任何意义,所以大家不要问悬空的时候为什么结果是这么多呢?
     adc_result = adc_mean_filter(ADC_0, ADC0_CH0_A0, ADC_12BIT, 10);//采集10次求平均  分辨率12位
     //将结果通过串口打印,可以先学习printf例程,了解如何使用printf
        printf("adc_result: %dn", adc_result);
     systick_delay_ms(STM0, 100);
    }
}


//以下又是一波客套话
#pragma section all restore


systick_delay_ms意义


//------------------------------------以下宏定义用于延时------------------------------------
#define systick_delay_ms(stmn, time) systick_delay(stmn, time*1000000)   //设置延时时间  单位ms


ADC均值滤波


//-------------------------------------------------------------------------------------------------------------------
//  @brief      ADC均值滤波
//  @param      adcn            选择ADC模块(ADC_0、ADC_1、ADC_2)
//  @param      ch              选择ADC通道
//  @param      count           均值滤波次数
//  @return     void
//  Sample usage:               adc_mean_filter(ADC_0, ADC0_CH0_A0, ADC_12BIT, 5);//采集5次 然后返回平均值
//-------------------------------------------------------------------------------------------------------------------
uint16 adc_mean_filter(VADCN_enum vadc_n, VADC_CHN_enum vadc_chn, VADC_RES_enum vadc_res, uint8 count)
{


ZF_ASSERT(count);//断言次数不能为0


    sum = 0;
   
    for(i=0; i     {
        sum += adc_convert(vadc_n, vadc_chn, vadc_res);
    }
        sum = sum/count;
            return (uint16)sum;
}


ADC转换


//-------------------------------------------------------------------------------------------------------------------
//  @brief      ADC转换一次即获取一次信息
//  @param      adcn            选择ADC模块(ADC_0、ADC_1、ADC_2)
//  @param      ch              选择ADC通道
//  @return     void
//  Sample usage:               adc_convert(ADC_0, ADC0_CH0_A0, ADC_12BIT);
//-------------------------------------------------------------------------------------------------------------------
uint16 adc_convert(VADCN_enum vadc_n, VADC_CHN_enum vadc_chn, VADC_RES_enum vadc_res)
{
Ifx_VADC_RES result;
uint8 temp;
do
{
  result = IfxVadc_getResult(&MODULE_VADC.G[vadc_n], vadc_chn%16);
} while (!result.B.VF);


temp = 4 - (vadc_res * 2);
return((result.U&0x0fff)>>temp);
}


LED闪烁模块
//老客套话了
#include "headfile.h"
#pragma section all "cpu0_dsram"


uint8 gpio_status;
//GPIO(General Purpose I/O Ports)意思为通用输入/输出端口,通俗地说,就是一些引脚,可以通过它们输出高低电平或者通过它们读入引脚的状态-是高电平或是低电平。


int core0_main(void)
{
disableInterrupts();
get_clk();//获取时钟频率  务必保留


//用户在此处调用各种初始化函数等


//需要特别注意P20_2是不能用于输出的,仅仅只有输入的功能
//需要特别注意P20_2是不能用于输出的,仅仅只有输入的功能
//需要特别注意P20_2是不能用于输出的,仅仅只有输入的功能


//设置P20_8为输出 默认输出低电平  PUSHPULL:推挽输出
gpio_init(P20_8, GPO, 0, PUSHPULL);
gpio_init(P20_9, GPO, 0, PUSHPULL);
gpio_init(P21_4, GPO, 0, PUSHPULL);
gpio_init(P21_5, GPO, 0, PUSHPULL);


//设置P21_2为输入 PULLUP:上拉输入
gpio_init(P21_2, GPI, 0, PULLUP);  


enableInterrupts();


while (TRUE)
    {
     //获取gpio状态
     gpio_status = gpio_get(P21_2);
     
     //将gpio状态打印到FSS窗口
     printf("gpio_status: %dn", gpio_status);


     gpio_toggle(P20_8);//翻转IO
     gpio_toggle(P20_9);
     gpio_toggle(P21_4);
     gpio_toggle(P21_5);


     systick_delay_ms(STM0, 100);
    }
}


#pragma section all restore


枚举上下拉选项


// 枚举上下拉选项
typedef enum   
{
    NO_PULL, //无输入上下拉
    PULLUP,  //输入上拉
PULLDOWN, //输入下拉
PUSHPULL, //推挽输出
OPENDRAIN, //开漏输出
}GPIOMODE_enum;


GPIO状态获取


//-------------------------------------------------------------------------------------------------------------------
//  @brief      GPIO状态获取
//  @param      pin         选择的引脚 (可选择范围由 common.h 内PIN_enum枚举值确定)
//  @return     uint8       0:低电平 1:高电平
//  Sample usage:           uint8 status = gpio_get(P00_0);//获取P00_0引脚电平
//-------------------------------------------------------------------------------------------------------------------
uint8 gpio_get(PIN_enum pin)
{
    return IfxPort_getPinState(get_port(pin), pin&0x1f);
}


GPIO 翻转


//-------------------------------------------------------------------------------------------------------------------
//  @brief      GPIO 翻转
//  @param      pin         选择的引脚 (可选择范围由 common.h 内PIN_enum枚举值确定)
//  @return     void        
//  Sample usage:           gpio_toggle(P00_0);//P00_0引脚电平翻转
//-------------------------------------------------------------------------------------------------------------------
void gpio_toggle(PIN_enum pin)
{
IfxPort_togglePin(get_port(pin), pin&0x1f);
}


周期定时器中断
#include "headfile.h"
#pragma section all "cpu0_dsram"


int core0_main(void)
{
        disableInterrupts();
        get_clk();//获取时钟频率  务必保留
       
    //在此处调用各种初始化函数等
   
        //使用CCU6_0模块的通道0 产生一个 100ms的周期中断
        pit_interrupt_ms(CCU6_0, PIT_CH0, 100);
       
    //中断函数在isr.c中 函数名称为cc60_pit_ch0_isr
        //中断相关的配置参数在isr_config.h内
        //可配置参数有 CCU6_0_CH0_INT_SERVICE 和 CCU6_0_CH0_ISR_PRIORITY
        //CCU6_0_CH0_INT_SERVICE 中断服务者,表示改中断由谁处理,0:CPU0 1:CPU1 3:DMA  不可设置为其他值
        //CCU6_0_CH0_ISR_PRIORITY 中断优先级 优先级范围1-255 越大优先级越高 与平时使用的单片机不一样


        //需要特备注意的是  不可以有优先级相同的中断函数 每个中断的优先级都必须是不一样的
    enableInterrupts();
   
    while (TRUE)
    {
                //在isr.c的中断函数,函数定义的第二个参数固定为0,请不要更改,即使你用CPU1处理中断也不要更改,需要CPU1处理中断只需要在isr_config.h内修改对应的宏定义即可
            //程序运行之后 PIT中断每执行一次就会打印一次
        //将结果通过串口打印,可以先学习printf例程,了解如何使用printf
    }
}


#pragma section all restore


捕获/比较单元6(CCU6模块)

CCU是一个具有特定应用模式的16位高分辨率捕获和比较单元,主要用于AC驱动控制。特殊操作模式支持使用霍尔传感器或反电动势检测的无刷DC电机。
CCU6单元由一个有三个捕获/比较通道定时器T12块和一个有一个捕获比较通道定时器T13定时器块组成。T12通道可以独立产生PWM信号、接受捕获的触发信号或他们联合产生控制信号模式来驱动AC电机或变频器。
注:捕获/比较模块被命名CCU6(捕获/比较单元6)。该模块内部的捕获/比较通道被命名为CC6x。
PIT中断

//------------------------------------以下代码用于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中断参数相关定义
//------------PIT中断参数相关定义------------
#define CCU6_0_CH0_INT_SERVICE        0        //定义CCU6_0 PIT通道0中断服务类型,即中断是由谁响应处理 0:CPU0 1:CPU1 3:DMA  不可设置为其他值
#define CCU6_0_CH0_ISR_PRIORITY 30        //定义CCU6_0 PIT通道0中断优先级 优先级范围1-255 越大优先级越高 与平时使用的单片机不一样


#define CCU6_0_CH1_INT_SERVICE        0
#define CCU6_0_CH1_ISR_PRIORITY 31


#define CCU6_1_CH0_INT_SERVICE        0
#define CCU6_1_CH0_ISR_PRIORITY 32


#define CCU6_1_CH1_INT_SERVICE        0
#define CCU6_1_CH1_ISR_PRIORITY 33


编码器
#include "headfile.h"
#pragma section all "cpu0_dsram"


int16 speed;


int core0_main(void)
{
        disableInterrupts();
       
        get_clk();//获取时钟频率  务必保留


        //用户在此处调用各种初始化函数等
       
        //第一个参数 表示选择使用的定时器
        //第二个参数 表示选择的计数引脚    计数引脚与方向引脚不可交换
        //第三个参数 表示选择的方向引脚
        gpt12_init(GPT12_T2, GPT12_T2INB_P33_7, GPT12_T2EUDB_P33_6);
   
    enableInterrupts();


        while (TRUE)
    {
            speed = gpt12_get(GPT12_T2);
            gpt12_clear(GPT12_T2);
            //打印采集到的编码器数据,可以先学习printf例程,了解如何使用printf
            printf("speed: %dn", speed);
            systick_delay_ms(STM0, 100);


                //旋转编码器越快显示的数据越大,正转数值为正,反正数值为负
    }
}


#pragma section all restore


GPT12初始化(编码器采集)
//-------------------------------------------------------------------------------------------------------------------
//  @brief      GPT12初始化(编码器采集)
//  @param      gptn                 选择所使用的GPT12定时器
//  @param      count_pin                 设置计数引脚
//  @param      dir_pin             设置计数方向引脚
//  @return     void
//  Sample usage:                   gpt12_init(GPT12_T2, GPT12_T2INA_P00_7, GPT12_T2EUDA_P00_8);//使用T2定时器   P00_7引脚进行计数    计数方向使用P00_8引脚
//-------------------------------------------------------------------------------------------------------------------
void gpt12_init(GPTN_enum gptn, GPT_PIN_enum count_pin, GPT_PIN_enum dir_pin)
{
        IfxGpt12_enableModule(&MODULE_GPT120);
    IfxGpt12_setGpt1BlockPrescaler(&MODULE_GPT120, IfxGpt12_Gpt1BlockPrescaler_4);
    IfxGpt12_setGpt2BlockPrescaler(&MODULE_GPT120, IfxGpt12_Gpt2BlockPrescaler_4);
        gpt12_mux(gptn, count_pin, dir_pin);


        switch(gptn)
        {
                case GPT12_T2:
                {
                        IfxGpt12_T2_setCounterInputMode(&MODULE_GPT120, IfxGpt12_CounterInputMode_risingEdgeTxIN);
                        IfxGpt12_T2_setDirectionSource(&MODULE_GPT120, IfxGpt12_TimerDirectionSource_external);
                        IfxGpt12_T2_setMode(&MODULE_GPT120, IfxGpt12_Mode_counter);
                        IfxGpt12_T2_run(&MODULE_GPT120, IfxGpt12_TimerRun_start);
                }break;


                case GPT12_T3:
                {
                        IfxGpt12_T3_setCounterInputMode(&MODULE_GPT120, IfxGpt12_CounterInputMode_risingEdgeTxIN);
                        IfxGpt12_T3_setDirectionSource(&MODULE_GPT120, IfxGpt12_TimerDirectionSource_external);
                        IfxGpt12_T3_setMode(&MODULE_GPT120, IfxGpt12_Mode_counter);
                        IfxGpt12_T3_run(&MODULE_GPT120, IfxGpt12_TimerRun_start);
                }break;


                case GPT12_T4:
                {
                        IfxGpt12_T4_setCounterInputMode(&MODULE_GPT120, IfxGpt12_CounterInputMode_risingEdgeTxIN);
                        IfxGpt12_T4_setDirectionSource(&MODULE_GPT120, IfxGpt12_TimerDirectionSource_external);
                        IfxGpt12_T4_setMode(&MODULE_GPT120, IfxGpt12_Mode_counter);
                        IfxGpt12_T4_run(&MODULE_GPT120, IfxGpt12_TimerRun_start);
                }break;


                case GPT12_T5:
                {
                        IfxGpt12_T5_setCounterInputMode(&MODULE_GPT120, IfxGpt12_CounterInputMode_risingEdgeTxIN);
                        IfxGpt12_T5_setDirectionSource(&MODULE_GPT120, IfxGpt12_TimerDirectionSource_external);
                        IfxGpt12_T5_setMode(&MODULE_GPT120, IfxGpt12_Mode_counter);
                        IfxGpt12_T5_run(&MODULE_GPT120, IfxGpt12_TimerRun_start);
                }break;


                case GPT12_T6:
                {
                        IfxGpt12_T6_setCounterInputMode(&MODULE_GPT120, IfxGpt12_CounterInputMode_risingEdgeTxIN);
                        IfxGpt12_T6_setDirectionSource(&MODULE_GPT120, IfxGpt12_TimerDirectionSource_external);
                        IfxGpt12_T6_setMode(&MODULE_GPT120, IfxGpt12_Mode_counter);
                        IfxGpt12_T6_run(&MODULE_GPT120, IfxGpt12_TimerRun_start);
                }break;


        }
}
举报

盛越熊

2021-12-22 13:58:29
GPT12定时器编号
typedef enum  // 枚举GPT12 定时器编号
{
    GPT12_T2,
        GPT12_T3,
        GPT12_T4,
        GPT12_T5,
        GPT12_T6,
}GPTN_enum;


枚举GPT12引脚
//此枚举定义不允许用户修改
typedef enum //枚举GPT12引脚
{
        GPT12_T2INA_P00_7,  GPT12_T2INB_P33_7,        //T2定时器 计数引脚可选范围
        GPT12_T2EUDA_P00_8, GPT12_T2EUDB_P33_6,        //T2定时器 计数方向引脚可选范围
       
        //在LQFP144封装中没有P10_4 、P10_7
        GPT12_T3INA_P02_6,  GPT12_T3INB_P10_4,        //T3定时器 计数引脚可选范围
        GPT12_T3EUDA_P02_7, GPT12_T3EUDB_P10_7, //T3定时器 计数方向引脚可选范围


        //在LQFP144封装中没有P10_8
        GPT12_T4INA_P02_8,  GPT12_T4INB_P10_8,        //T4定时器 计数引脚可选范围
        GPT12_T4EUDA_P00_9, GPT12_T4EUDB_P33_5, //T4定时器 计数方向引脚可选范围


        GPT12_T5INB_P10_3,        GPT12_T5INA_P21_7,  //T5定时器 计数引脚可选范围
        GPT12_T5EUDB_P10_1, GPT12_T5EUDA_P21_6, //T5定时器 计数方向引脚可选范围


        //在LQFP144封装中没有P10_0
        GPT12_T6INB_P10_2,  GPT12_T6INA_P20_3,  //T6定时器 计数引脚可选范围
        GPT12_T6EUDB_P10_0, GPT12_T6EUDA_P20_0, //T6定时器 计数方向引脚可选范围
}GPT_PIN_enum;


GPT12计数读取(编码器采集)
//-------------------------------------------------------------------------------------------------------------------
//  @brief      GPT12计数读取(编码器采集)
//  @param      gptn                 选择所使用的GPT12定时器
//  @return     void
//  Sample usage:                   speed = gpt12_get(GPT12_T2);//使用T2定时器
//-------------------------------------------------------------------------------------------------------------------
int16 gpt12_get(GPTN_enum gptn)
{
        switch(gptn)
        {
                case GPT12_T2: return (int16)IfxGpt12_T2_getTimerValue(&MODULE_GPT120);
                case GPT12_T3: return (int16)IfxGpt12_T3_getTimerValue(&MODULE_GPT120);
                case GPT12_T4: return (int16)IfxGpt12_T4_getTimerValue(&MODULE_GPT120);
                case GPT12_T5: return (int16)IfxGpt12_T5_getTimerValue(&MODULE_GPT120);
                case GPT12_T6: return (int16)IfxGpt12_T6_getTimerValue(&MODULE_GPT120);
                default: return 0;
        }
}


清除GPT12计数(编码器采集)
//-------------------------------------------------------------------------------------------------------------------
//  @brief      清除GPT12计数(编码器采集)
//  @param      gptn                 选择所使用的GPT12定时器
//  @return     void
//  Sample usage:                   gpt12_clear(GPT12_T2);//使用T2定时器
//-------------------------------------------------------------------------------------------------------------------
void gpt12_clear(GPTN_enum gptn)
{
        switch(gptn)
        {
                case GPT12_T2: IfxGpt12_T2_setTimerValue(&MODULE_GPT120, 0); break;
                case GPT12_T3: IfxGpt12_T3_setTimerValue(&MODULE_GPT120, 0); break;
                case GPT12_T4: IfxGpt12_T4_setTimerValue(&MODULE_GPT120, 0); break;
                case GPT12_T5: IfxGpt12_T5_setTimerValue(&MODULE_GPT120, 0); break;
                case GPT12_T6: IfxGpt12_T6_setTimerValue(&MODULE_GPT120, 0); break;
        }
}


串口的发送与中断接受
#include "headfile.h"
#pragma section all "cpu0_dsram"


uint8 uart_buff;


int core0_main(void)
{
        disableInterrupts();
        get_clk();//获取时钟频率  务必保留


        //用户在此处调用各种初始化函数等
        uart_init(UART_0, 115200, UART0_TX_P14_0, UART0_RX_P14_1);
       
        //在本库中,对于串口的接收与发送都是通过中断完成的,因此想要正常的使用串口功能务必保证中断是开启的,也就是调用了enableInterrupts()
    enableInterrupts();
   
        //调用enableInterrupts函数之后 才开始发送或者接收数据
        uart_putstr(UART_0, "n---uart test---n");


        //串口的中断函数全部都在isr.c中。


        //串口中断相关的配置参数都在isr_config.h中
        //可配置参数有 ERU_CH0_CH4_INT_SERVICE 和 ERU_CH0_CH4_INT_PRIO
       
        //UART0_INT_SERVICE 中断服务者,表示改中断由谁处理,0:CPU0 1:CPU1 3:DMA  不可设置为其他值
        //UART0_TX_INT_PRIO 发送中断优先级 优先级范围1-255 越大优先级越高 与平时使用的单片机不一样
       
        //UART0_RX_INT_PRIO        接收中断优先级
        //UART0_ER_INT_PRIO 错误中断优先级


        //其他串口中断参数同理


        //需要特备注意的是  不可以有优先级相同的中断函数 每个中断的优先级都必须是不一样的
       
    while (TRUE)
    {
            //查询是否有数据,如果有则接收
            if(uart_query(UART_0, &uart_buff))
            {
                    //将收到的数据,再发出去
                    uart_putchar(UART_0, uart_buff);
            }


        //使用u***转ttl连接单片机的串口,在电脑上打开串口助手,任意发送字符,
            //单片机收到后会返回发送的字符,串口助手就会显示刚才发送的东西
    }
}


#pragma section all restore


串口初始化
//-------------------------------------------------------------------------------------------------------------------
//  @brief      串口初始化
//  @param      uartn           串口模块号(UART_0,UART_1,UART_2,UART_3)
//  @param      baud            串口波特率
//  @param      tx_pin          串口发送引脚
//  @param      rx_pin          串口接收引脚
//  @return     uint32          实际波特率
//  Sample usage:               uart_init(UART_0,115200,UART0_TX_P14_0,UART0_RX_P14_1);       // 初始化串口0 波特率115200 发送引脚使用P14_0 接收引脚使用P14_1
//-------------------------------------------------------------------------------------------------------------------
void uart_init(UARTN_enum uartn, uint32 baud, UART_PIN_enum tx_pin, UART_PIN_enum rx_pin)
{
        boolean interrupt_state = disableInterrupts();


        volatile Ifx_ASCLIN *moudle = IfxAsclin_getAddress((IfxAsclin_Index)uartn);


        IfxAsclin_Asc_initModuleConfig(&uart_config, moudle);                 //初始化化配置结构体


        uart_set_buffer(uartn);//设置缓冲区
        uart_set_interrupt_priority(uartn);//设置中断优先级


    uart_config.baudrate.prescaler    = 4;
    uart_config.baudrate.baudrate     = (float32)baud;
    uart_config.baudrate.oversampling = IfxAsclin_OversamplingFactor_8;


    IfxAsclin_Asc_Pins pins;//设置引脚
    pins.cts = NULL;
    pins.rts = NULL;
    uart_mux(uartn, tx_pin, rx_pin, (uint32 *)&pins.tx, (uint32 *)&pins.rx);
    pins.rxMode = IfxPort_InputMode_pullUp;
    pins.txMode = IfxPort_OutputMode_pushPull;
    pins.pinDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1;
    uart_config.pins = &pins;


    IfxAsclin_Asc_initModule(uart_get_handle(uartn), &uart_config);


    restoreInterrupts(interrupt_state);
}


GPIO中断参数相关定义
//------------GPIO中断参数相关定义------------
//通道0与通道4是公用一个中断函数 在中断内部通过标志位判断是谁触发的中断
#define ERU_CH0_CH4_INT_SERVICE 0        //定义ERU通道0和通道4中断服务类型,即中断是由谁响应处理 0:CPU0 1:CPU1 3:DMA  不可设置为其他值
#define ERU_CH0_CH4_INT_PRIO          40        //定义ERU通道0和通道4中断优先级 优先级范围1-255 越大优先级越高 与平时使用的单片机不一样


//通道1与通道5是公用一个中断函数 在中断内部通过标志位判断是谁触发的中断
#define ERU_CH1_CH5_INT_SERVICE 0        //定义ERU通道1和通道5中断服务类型,同上
#define ERU_CH1_CH5_INT_PRIO          41        //定义ERU通道1和通道5中断优先级 同上


//通道2与通道6是公用一个中断函数 在中断内部通过标志位判断是谁触发的中断
#define ERU_CH2_CH6_INT_SERVICE 3        //定义ERU通道2和通道6中断服务类型,同上
#define ERU_CH2_CH6_INT_PRIO          5        //定义ERU通道2和通道6中断优先级 同上


//通道3与通道7是公用一个中断函数 在中断内部通过标志位判断是谁触发的中断
#define ERU_CH3_CH7_INT_SERVICE 0        //定义ERU通道3和通道7中断服务类型,同上
#define ERU_CH3_CH7_INT_PRIO          43        //定义ERU通道3和通道7中断优先级 同上


读取串口接收的数据(查询接收)
//-------------------------------------------------------------------------------------------------------------------
//  @brief      读取串口接收的数据(查询接收)
//  @param      uartn           串口模块号(UART_0,UART_1,UART_2,UART_3)
//  @param      *dat            接收数据的地址
//  @return     uint8           1:接收成功   0:未接收到数据
//  Sample usage:               uint8 dat; uart_query(UART_0,&dat);       // 接收串口0数据  存在在dat变量里
//-------------------------------------------------------------------------------------------------------------------
uint8 uart_query(UARTN_enum uartn, uint8 *dat)
{
        if(IfxAsclin_Asc_getReadCount(uart_get_handle(uartn)) >0)
        {
                *dat = IfxAsclin_Asc_blockingRead(uart_get_handle(uartn));
                return 1;
        }
    return 0;
}


串口字节输出
//-------------------------------------------------------------------------------------------------------------------
//  @brief      串口字节输出
//  @param      uartn           串口模块号(UART_0,UART_1,UART_2,UART_3)
//  @param      dat             需要发送的字节
//  @return     void        
//  Sample usage:               uart_putchar(UART_0, 0xA5);       // 串口0发送0xA5
//-------------------------------------------------------------------------------------------------------------------
void uart_putchar(UARTN_enum uartn, uint8 dat)
{
//        IfxAsclin_Asc_blockingWrite(uart_get_handle(uartn),dat);
        Ifx_SizeT count = 1;
        (void)IfxAsclin_Asc_write(uart_get_handle(uartn), &dat, &count, TIME_INFINITE);
}


串口发送数组
//-------------------------------------------------------------------------------------------------------------------
//  @brief      串口发送数组
//  @param      uartn           串口模块号(UART_0,UART_1,UART_2,UART_3)
//  @param      *buff           要发送的数组地址
//  @param      len             发送长度
//  @return     void
//  Sample usage:               uart_putbuff(UART_0,&a[0],5);
//-------------------------------------------------------------------------------------------------------------------
void uart_putbuff(UARTN_enum uartn, uint8 *buff, uint32 len)
{
        while(len)
        {
                uart_putchar(uartn, *buff);
                len--;
                buff++;
        }
}


串口发送字符串
//-------------------------------------------------------------------------------------------------------------------
//  @brief      串口发送字符串
//  @param      uartn           串口模块号(UART_0,UART_1,UART_2,UART_3)
//  @param      *str            要发送的字符串地址
//  @return     void
//  Sample usage:               uart_putstr(UART_0,"i lvoe you");
//-------------------------------------------------------------------------------------------------------------------
void uart_putstr(UARTN_enum uartn, const int8 *str)
{
    while(*str)
    {
        uart_putchar(uartn, *str++);
    }
}


Printf函数打印
#include "headfile.h"
#pragma section all "cpu0_dsram"


uint16 num;


int core0_main(void)
{
        disableInterrupts();
        get_clk();//获取时钟频率  务必保留


    //用户在此处调用各种初始化函数等
        printf("printf demon");


    enableInterrupts();


    while (TRUE)
    {
            num++;
            printf("printf num :%dn", num);
            systick_delay_ms(STM0, 100);
            //注意事项1 printf打印的数据会通过串口发送出去
            //注意事项2 printf所使用的串口和波特率可以在TC264_config.h文件中修改
            //注意事项3 printf所使用的串口默认在get_clk函数中进行了初始化,如果不想使用printf则可以在TC264_config.h文件中将PRINTF_ENABLE宏定义设置为0即可
    }
}


#pragma section all restore


GPIO触发中断
#include "headfile.h"
#pragma section all "cpu0_dsram"






int core0_main(void)
{
        disableInterrupts();
        get_clk();//获取时钟频率  务必保留


    //用户在此处调用各种初始化函数等


        //特别注意通道2 与 通道3都被摄像头占用,由于中断共用的关系,因此通道6 与 通道7也不能使用
        //TC264的外部中断不像K60单片机那样所有IO都支持,TC264只有部分支持具体可以查看***_eru.h中ERU_PIN_enum枚举定义


        eru_init(ERU_CH0_REQ0_P15_4, RISING);        //ERU通道0 使用P15_4引脚  上升沿中断
        eru_init(ERU_CH4_REQ13_P15_5, RISING);        //ERU通道4 使用P15_5引脚  上升沿中断
        //通道0与4共用中断,中断内通过标志位判断


        eru_init(ERU_CH1_REQ10_P14_3, RISING);        //ERU通道1 使用P14_3引脚  上升沿中断
        eru_init(ERU_CH5_REQ1_P15_8, RISING);        //ERU通道5 使用P15_8引脚  上升沿中断
        //通道1与5共用中断,中断内通过标志位判断




        //中断函数在isr.c中
        //函数名称分别为eru_ch0_ch4_isr 与 eru_ch1_ch5_isr


        //中断相关的配置参数在isr_config.h内
        //可配置参数有 ERU_CH0_CH4_INT_SERVICE 和 ERU_CH0_CH4_INT_PRIO
        //ERU_CH0_CH4_INT_SERVICE 中断服务者,表示改中断由谁处理,0:CPU0 1:CPU1 3:DMA  不可设置为其他值
        //ERU_CH0_CH4_INT_PRIO              中断优先级 优先级范围1-255 越大优先级越高 与平时使用的单片机不一样


        //ERU其他中断也是同理


        //需要特备注意的是  不可以有优先级相同的中断函数 每个中断的优先级都必须是不一样的


    enableInterrupts();


    while (TRUE)
    {
                //在isr.c的中断函数,函数定义的第二个参数固定为0,请不要更改,即使你用CPU1处理中断也不要更改,需要CPU1处理中断只需要在isr_config.h内修改对应的宏定义即可
            //程序运行之后,使用杜邦线将P15_4、P15_5、P14_3、P15_8连接到GND,然后在断开,在连接如此往复
        //将提示信息通过串口打印,可以先学习printf例程,了解如何使用printf
    }
}




#pragma section all restore
举报

洪茗苞

2021-12-22 13:59:04
eru初始化(gpio中断)
//-------------------------------------------------------------------------------------------------------------------
//  @brief      eru初始化(gpio中断)
//  @param      eru_pin         设置eru通道及引脚
//  @param      trigger         设置触发方式
//        @return                void
//  Sample usage:                                eru_init(ERU_CH0_REQ0_P15_4, RISING);//eru通道0 使用P10_7引脚,上升沿触发中断
//-------------------------------------------------------------------------------------------------------------------
void eru_init(ERU_PIN_enum eru_pin, TRIGGER_enum trigger)
{
    boolean interrupt_state = disableInterrupts();


    IfxScu_Req_In *reqPin;


        reqPin = eru_mux(eru_pin);


    IfxScuEru_initReqPin(reqPin, IfxPort_InputMode_pullUp);


    IfxScuEru_InputChannel inputChannel = (IfxScuEru_InputChannel)reqPin->channelId;


    IfxScuEru_InputNodePointer triggerSelect = (IfxScuEru_InputNodePointer)(eru_pin/3);
    IfxScuEru_OutputChannel    outputChannel = (IfxScuEru_OutputChannel)(eru_pin/3);


    switch(trigger)
    {
            case RISING:
            {
                    IfxScuEru_disableFallingEdgeDetection(inputChannel);
                    IfxScuEru_enableRisingEdgeDetection(inputChannel);
            }break;


            case FALLING:
            {
                    IfxScuEru_enableFallingEdgeDetection(inputChannel);
                    IfxScuEru_disableRisingEdgeDetection(inputChannel);
            }break;


            case BOTH:
            {
                    IfxScuEru_enableFallingEdgeDetection(inputChannel);
                    IfxScuEru_enableRisingEdgeDetection(inputChannel);
            }break;


            default: ZF_ASSERT(FALSE);
    }


    IfxScuEru_enableTriggerPulse(inputChannel);
    IfxScuEru_connectTrigger(inputChannel, triggerSelect);


    IfxScuEru_setFlagPatternDetection(outputChannel, inputChannel, TRUE);
    IfxScuEru_enablePatternDetectionTrigger(outputChannel);
    IfxScuEru_setInterruptGatingPattern(outputChannel, IfxScuEru_InterruptGatingPattern_alwaysActive);




        volatile Ifx_SRC_SRCR *src = &MODULE_SRC.SCU.SCU.ERU[(int)outputChannel % 4];
        IfxSrc_Tos eru_service;
        uint8 eru_priority;
        switch((eru_pin/3)%4)
        {
                case 0:
                {
                        eru_service  = (IfxSrc_Tos)ERU_CH0_CH4_INT_SERVICE;
                        eru_priority = ERU_CH0_CH4_INT_PRIO;
                }break;


                case 1:
                {
                        eru_service  = (IfxSrc_Tos)ERU_CH1_CH5_INT_SERVICE;
                        eru_priority = ERU_CH1_CH5_INT_PRIO;
                }break;


                case 2:
                {
                        eru_service  = (IfxSrc_Tos)ERU_CH2_CH6_INT_SERVICE;
                        eru_priority = ERU_CH2_CH6_INT_PRIO;
                }break;


                case 3:
                {
                        eru_service  = (IfxSrc_Tos)ERU_CH3_CH7_INT_SERVICE;
                        eru_priority = ERU_CH3_CH7_INT_PRIO;
                }break;


        }
#pragma warning 507
        IfxSrc_init(src, eru_service, eru_priority);
#pragma warning default
        IfxSrc_enable(src);


    restoreInterrupts(interrupt_state);
}


枚举ERU通道
typedef enum  // 枚举ERU通道
{
        //一个通道只能选择其中一个引脚作为 外部中断的输入
        //例如通道0 可选引脚为P10_7 和 P15_4,
        //在LQFP144封装中没有P10_7
        ERU_CH0_REQ4_P10_7   = 0*3,  ERU_CH0_REQ0_P15_4,                                                //通道0可选引脚   LQFP没有P10_7引脚
        //在LQFP144封装中没有P10_8
        ERU_CH1_REQ5_P10_8   = 1*3,  ERU_CH1_REQ10_P14_3,                                                //通道1可选引脚   LQFP没有P10_8引脚
        ERU_CH2_REQ7_P00_4   = 2*3,  ERU_CH2_REQ14_P02_1, ERU_CH2_REQ2_P10_2,        //通道2可选引脚
        ERU_CH3_REQ6_P02_0   = 3*3,  ERU_CH3_REQ3_P10_3,  ERU_CH3_REQ15_P14_1,        //通道3可选引脚


        //通道4与通道0 共用中断函数 在中断内通过判断标志位来识别是哪个通道触发的中断
        ERU_CH4_REQ13_P15_5  = 4*3,  ERU_CH4_REQ8_P33_7,                                                //通道4可选引脚
        //通道5与通道1 共用中断函数
        ERU_CH5_REQ1_P15_8   = 5*3,                                                                                                //通道5可选引脚
        //通道6与通道2 共用中断函数
        ERU_CH6_REQ12_P11_10 = 6*3,  ERU_CH6_REQ9_P20_0,                                                //通道6可选引脚
        //通道7与通道3 共用中断函数
        ERU_CH7_REQ16_P15_1  = 7*3,  ERU_CH7_REQ11_P20_9,                                                //通道7可选引脚
}ERU_PIN_enum;


//特别注意通道2 与 通道3都被摄像头占用,意味着只有两个外部中断可供用户使用


EEPROM(Dflash)保存参数

概述

在实际的应用中,保存在单片机RAM中的数据,掉电后就丢失了,保存在单片机的FLASH中的数据,又不能随意改变,也就是不能用它来记录变化的数值。但是在某些场合,我们又确实**需要记录下某些数据,而它们还时常需要改变或更新,掉电之后数据还不能丢失。**比如,我们的家用电表度数,电视机里边的频道记忆,一般都是使用EEPROM来保存数据,特点就是掉电后存储的数据不丢失。
一般情况下,EEPROM拥有30万到100万次的寿命,也就是它可以反复写入30-100万次,而读取次数是无限的。
24C02是一个常用的基于IIC通信协议的EEPROM元件,例如ATMEL公司的AT24C02、CATALYST公司的CAT24C02和ST公司的ST24C02等芯片。
IIC是一个通信协议,它拥有严密的通信时序逻辑要求,而EEPROM是一个元件,只是这个元件采样了IIC协议的接口与单片机相连而已,二者并没有必然的联系,EEPROM可以用其它接口,I2C也可以用在其它很多器件上。

#include "headfile.h"
#pragma section all "cpu0_dsram"


#define EXAMPLE_EEPROM_SECTOR        (0)


uint8  write_data1;
uint16 write_data2;
uint32 write_data3;
float  write_data4;




uint8  read_data1;
uint16 read_data2;
uint32 read_data3;
float  read_data4;


uint32 write_buf;


int core0_main(void)
{
disableInterrupts();
get_clk();//获取时钟频率  务必保留


    //用户在此处调用各种初始化函数等
write_data1 = 66;
write_data2 = 6666;
write_data3 = 666666;
write_data4 = 6666.66;




//检查当前页是否有数据,如果有数据则需要擦除整个扇区,
if(flash_check(EXAMPLE_EEPROM_SECTOR, 0) || flash_check(EXAMPLE_EEPROM_SECTOR, 1) || flash_check(EXAMPLE_EEPROM_SECTOR, 2) || flash_check(EXAMPLE_EEPROM_SECTOR, 3))
{
eeprom_erase_sector(EXAMPLE_EEPROM_SECTOR);
}


//当写入的数据不是32位时,建议将数据放入uint32 类型的变量中,在将该变量作为参数传入到eeprom_page_program函数
write_buf = write_data1;


//将数据写入EXAMPLE_EEPROM_SECTOR扇区的第0页
eeprom_page_program(EXAMPLE_EEPROM_SECTOR, 0, &write_buf);
write_buf = write_data2;
eeprom_page_program(EXAMPLE_EEPROM_SECTOR, 1, &write_buf);
write_buf = write_data3;
eeprom_page_program(EXAMPLE_EEPROM_SECTOR, 2, &write_buf);


//保存浮点数的时候,使用float_conversion_uint32宏定义进行转换后在保存
write_buf = float_conversion_uint32(write_data4);
eeprom_page_program(EXAMPLE_EEPROM_SECTOR, 3, &write_buf);


//读取eeprom中的数据
read_data1 = flash_read(EXAMPLE_EEPROM_SECTOR, 0, uint8);
read_data2 = flash_read(EXAMPLE_EEPROM_SECTOR, 1, uint16);
read_data3 = flash_read(EXAMPLE_EEPROM_SECTOR, 2, uint32);
read_data4 = flash_read(EXAMPLE_EEPROM_SECTOR, 3, float);


printf("read_data1: %dn",  read_data1);
printf("read_data2: %dn",  read_data2);
printf("read_data3: %ldn", read_data3);
printf("read_data4: %fn",  read_data4);


    enableInterrupts();


    while (TRUE)
    {


    }
}


#pragma section all restore


校验FLASH是否有数据
//-------------------------------------------------------------------------------------------------------------------
//  @brief      校验FLASH是否有数据
//  @param      sector_num  需要写入的扇区编号   参数范围0-11
//  @param      page_num   当前扇区页的编号     参数范围0-1023
//  @return      返回1有数据,返回0没有数据,如果需要对有数据的区域写入新的数据则应该对所在扇区进行擦除操作
//  @since      v1.0
//  Sample usage:               flash_check(0,0);//校验0号扇区,第0页是否有数据
//-------------------------------------------------------------------------------------------------------------------
uint8 flash_check(uint32 sector_num, uint32 page_num)
{
ZF_ASSERT(EEPROM_SECTOR_NUM>sector_num);
ZF_ASSERT(EEPROM_SECTOR_PAGE_NUM>page_num);
uint32 sector_addr = IfxFlash_dFlashTableEepLog[sector_num].start;
uint32 page_addr = sector_addr + page_num * IFXFLASH_DFLASH_PAGE_LENGTH;


uint32 temp = *(uint32 *)page_addr;
if(0 != temp) return 1;


return 0;
}


擦除扇区
//-------------------------------------------------------------------------------------------------------------------
//  @brief      擦除扇区
//  @param      sector_num  需要写入的扇区编号   参数范围0-11
//  @return     void
//  @since      v1.0
//  Sample usage:               eeprom_erase_sector(0);
//-------------------------------------------------------------------------------------------------------------------
void eeprom_erase_sector(uint32 sector_num)
{
ZF_ASSERT(EEPROM_SECTOR_NUM>sector_num);


uint32 flash = 0;
uint16 end_init_sfty_pw;
uint32 sector_addr = IfxFlash_dFlashTableEepLog[sector_num].start;


end_init_sfty_pw = IfxScuWdt_getSafetyWatchdogPassword();


IfxScuWdt_clearSafetyEndinit(end_init_sfty_pw);
    IfxFlash_eraseSector(sector_addr);
    IfxScuWdt_setSafetyEndinit(end_init_sfty_pw);


    IfxFlash_waitUnbusy(flash, IfxFlash_FlashType_D0);
}


编程一页
//-------------------------------------------------------------------------------------------------------------------
//  @brief      编程一页
//  @param      sector_num  需要写入的扇区编号   参数范围0-11
//  @param      page_num  需要写入的页编号     参数范围0-1023
//  @param      buf      需要写入的数据地址   传入的数组类型必须为uint32
//  @return     void
//  @since      v1.0
//  Sample usage: eeprom_page_program(0,0, &buf);
//-------------------------------------------------------------------------------------------------------------------
void eeprom_page_program(uint32 sector_num, uint32 page_num, uint32 *buf)
{
ZF_ASSERT(EEPROM_SECTOR_NUM>sector_num);
ZF_ASSERT(EEPROM_SECTOR_PAGE_NUM>page_num);


uint32 errors = 0;
uint32 flash = 0;
uint16 end_init_sfty_pw;
uint32 sector_addr = IfxFlash_dFlashTableEepLog[sector_num].start;


end_init_sfty_pw = IfxScuWdt_getSafetyWatchdogPassword();


uint32 page_addr = sector_addr + page_num * IFXFLASH_DFLASH_PAGE_LENGTH;
errors = IfxFlash_enterPageMode(page_addr);
ZF_ASSERT(0 == errors);


IfxFlash_waitUnbusy(flash, IfxFlash_FlashType_D0);


IfxFlash_loadPage(page_addr, buf[0], 0);


IfxScuWdt_clearSafetyEndinit(end_init_sfty_pw);
IfxFlash_writePage(page_addr);
IfxScuWdt_setSafetyEndinit(end_init_sfty_pw);


IfxFlash_waitUnbusy(flash, IfxFlash_FlashType_D0);
}


将浮点数转换为二进制数据
//-------------------------------------------------------------------------------------------------------------------
//  @brief      将浮点数转换为二进制数据
//  @param      float_data  需要转换的浮点数
//  @return      返回整型数据
//  @since      v1.0
//  Sample usage:        float_conversion_uint32(write_data4);
//-------------------------------------------------------------------------------------------------------------------
#define     float_conversion_uint32(float_data)     (*(uint32 *)&float_data)








uint8 flash_check(uint32 sector_num, uint32 page_num);
void eeprom_erase_sector(uint32 sector_num);
void eeprom_page_program(uint32 sector_num, uint32 page_num, uint32 *buf);


#endif
举报

张秀荣

2021-12-22 14:00:07
使用宏定义对flash进行数据读取
//-------------------------------------------------------------------------------------------------------------------
//  @brief      使用宏定义对flash进行数据读取
//  @param      sector_num  需要写入的扇区编号
//  @param      page_num   需要读取的页
//  @param      type   读取的数据类型
//  @return      返回给定地址的数据
//  @since      v1.0
//  Sample usage:               flash_read(0,0,uint32);//读取0号扇区  第0也数据 类型为uint32
//-------------------------------------------------------------------------------------------------------------------
#define     flash_read(sector_num,page_num,type)      (*(type *)((uint32)((EEPROM_BASE_ADDR + (sector_num)*EEPROM_SECTOR_SIZE) + (page_num*8))))


GTM模块输出PWM以及设定占空比
#include "headfile.h"
#pragma section all "cpu0_dsram"




int core0_main(void)
{
disableInterrupts();
get_clk();//获取时钟频率  务必保留


    //用户在此处调用各种初始化函数等
gtm_pwm_init(ATOM0_CH4_P02_4, 50,    0);//ATOM 0模块的通道4 使用P02_4引脚输出PWM  PWM频率50HZ  占空比百分之0/GTM_ATOM0_PWM_DUTY_MAX*100  GTM_ATOM0_PWM_DUTY_MAX宏定义在***_gtm_pwm.h
gtm_pwm_init(ATOM0_CH5_P02_5, 1000,  0);
gtm_pwm_init(ATOM0_CH6_P02_6, 10000, 0);
gtm_pwm_init(ATOM0_CH7_P02_7, 30000, 0);


gtm_pwm_init(ATOM1_CH7_P00_8, 30000, 5000);
//每个通道都可以输出不同频率的PWM


pwm_duty(ATOM0_CH4_P02_4, 5000);//设置占空比为百分之5000/GTM_ATOM0_PWM_DUTY_MAX*100
pwm_duty(ATOM0_CH5_P02_5, 5000);
pwm_duty(ATOM0_CH6_P02_6, 5000);
pwm_duty(ATOM0_CH7_P02_7, 5000);


    enableInterrupts();


    while (TRUE)
    {


    }
}


#pragma section all restore


PWM初始化
//-------------------------------------------------------------------------------------------------------------------
//  @brief      PWM初始化
//  @param      pwmch       PWM通道号及引脚
//  @param      freq        PWM频率
//  @param      duty        PWM占空比
//  @return     void
//  Sample usage:           gtm_pwm_init(ATOM0_CH7_P02_7, 50, 1000);     //ATOM 0模块的通道7 使用P02_7引脚输出PWM  PWM频率50HZ  占空比百分之1000/GTM_ATOM0_PWM_DUTY_MAX*100
// GTM_ATOM0_PWM_DUTY_MAX宏定义在***_gtm_pwm.h  默认为10000
//-------------------------------------------------------------------------------------------------------------------
void gtm_pwm_init(ATOM_PIN_enum pwmch, uint32 freq, uint32 duty)
{
IfxGtm_Atom_Pwm_Config g_atomConfig;
IfxGtm_Atom_Pwm_Driver g_atomDriver;


IfxGtm_Atom_ToutMap *atom_channel;
atom_channel = gtm_atom_mux(pwmch);


switch(atom_channel->atom)
{
case 0: IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, duty <= GTM_ATOM0_PWM_DUTY_MAX); break;
case 1: IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, duty <= GTM_ATOM1_PWM_DUTY_MAX); break;
case 2: IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, duty <= GTM_ATOM2_PWM_DUTY_MAX); break;
case 3: IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, duty <= GTM_ATOM3_PWM_DUTY_MAX); break;
}


IfxGtm_enable(&MODULE_GTM);
if(!(MODULE_GTM.CMU.CLK_EN.U & 0x2))
{
     IfxGtm_Cmu_setClkFrequency(&MODULE_GTM, IfxGtm_Cmu_Clk_0, CLK_FREQ);
     IfxGtm_Cmu_enableClocks(&MODULE_GTM, IFXGTM_CMU_CLKEN_CLK0);
}




    IfxGtm_Atom_Pwm_initConfig(&g_atomConfig, &MODULE_GTM);


    g_atomConfig.atom = atom_channel->atom;
    g_atomConfig.atomChannel = atom_channel->channel;
    g_atomConfig.period = CLK_FREQ/freq;
    g_atomConfig.pin.outputPin = atom_channel;
    g_atomConfig.synchronousUpdateEnabled = TRUE;


    switch(atom_channel->atom)
{
case 0: g_atomConfig.dutyCycle = (uint32)((uint64)duty * g_atomConfig.period / GTM_ATOM0_PWM_DUTY_MAX); break;
case 1: g_atomConfig.dutyCycle = (uint32)((uint64)duty * g_atomConfig.period / GTM_ATOM1_PWM_DUTY_MAX); break;
case 2: g_atomConfig.dutyCycle = (uint32)((uint64)duty * g_atomConfig.period / GTM_ATOM2_PWM_DUTY_MAX); break;
case 3: g_atomConfig.dutyCycle = (uint32)((uint64)duty * g_atomConfig.period / GTM_ATOM3_PWM_DUTY_MAX); break;
}


IfxGtm_Atom_Pwm_init(&g_atomDriver, &g_atomConfig);
    IfxGtm_Atom_Pwm_start(&g_atomDriver, TRUE);
}


PWM占空比设置
//-------------------------------------------------------------------------------------------------------------------
//  @brief      PWM占空比设置
//  @param      pwmch       PWM通道号及引脚
//  @param      duty        PWM占空比
//  @return     void
//  Sample usage:           pwm_duty(ATOM0_CH7_P02_7, 5000);//设置占空比为百分之5000/GTM_ATOM0_PWM_DUTY_MAX*100
// GTM_ATOM0_PWM_DUTY_MAX宏定义在***_gtm_pwm.h  默认为10000
//-------------------------------------------------------------------------------------------------------------------
void pwm_duty(ATOM_PIN_enum pwmch, uint32 duty)
{
uint32 period;


IfxGtm_Atom_ToutMap *atom_channel;
atom_channel = gtm_atom_mux(pwmch);


period = IfxGtm_Atom_Ch_getCompareZero(&MODULE_GTM.ATOM[atom_channel->atom], atom_channel->channel);


switch(atom_channel->atom)
{
case 0: duty = (uint32)((uint64)duty * period / GTM_ATOM0_PWM_DUTY_MAX); break;
case 1: duty = (uint32)((uint64)duty * period / GTM_ATOM1_PWM_DUTY_MAX); break;
case 2: duty = (uint32)((uint64)duty * period / GTM_ATOM2_PWM_DUTY_MAX); break;
case 3: duty = (uint32)((uint64)duty * period / GTM_ATOM3_PWM_DUTY_MAX); break;
}
    IfxGtm_Atom_Ch_setCompareOneShadow(&MODULE_GTM.ATOM[atom_channel->atom], atom_channel->channel, duty);
}


GTM_ATOM0_PWM_DUTY_MAX宏定义
#define GTM_ATOM0_PWM_DUTY_MAX     10000                 //GTM_ATOM0 PWM最大占空比  最大占空比越大占空比的步进值越小
#define GTM_ATOM1_PWM_DUTY_MAX     10000                 //GTM_ATOM1 PWM最大占空比  最大占空比越大占空比的步进值越小
#define GTM_ATOM2_PWM_DUTY_MAX     10000                 //GTM_ATOM2 PWM最大占空比  最大占空比越大占空比的步进值越小
#define GTM_ATOM3_PWM_DUTY_MAX     10000                 //GTM_ATOM3 PWM最大占空比  最大占空比越大占空比的步进值越小


中断优先级设置
#include "headfile.h"
#pragma section all "cpu0_dsram"


uint16 adc_result;


int core0_main(void)
{
disableInterrupts();
get_clk();//获取时钟频率  务必保留


    //本例程没有代码


//中断优先级都在isr_config.h中 进行设置


//以及中断的服务者也在isr_config.h中 进行设置


//所有的中断  优先级务必保证不一样,不能有重复的优先级


//在uart、pit、GPIO中断例程中的备注都有提到




    enableInterrupts();


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




#pragma section all restore


中断优先级及中断服务者
#ifndef _isr_config_h
#define _isr_config_h




//ISR_PRIORITY: TC264具有255个中断优先级可以设置 1-255,0优先级表示不开启中断,255为最高优先级
//特别注意
//中断优先级不能设置一样,所有中断优先级都必须设置为不一样的值
//特别注意






//INT_SERVICE:    宏定义决定中断由谁处理,也称为服务提供者(在TC264中,中断被叫做服务),可设置范围0:CPU0 1:CPU1 3:DMA  不可设置为其他值




//如果INT_SERVICE设置为3的话,ISR_PRIORITY的可设置范围则是0-47。
















//------------PIT中断参数相关定义------------
#define CCU6_0_CH0_INT_SERVICE 0 //定义CCU6_0 PIT通道0中断服务类型,即中断是由谁响应处理 0:CPU0 1:CPU1 3:DMA  不可设置为其他值
#define CCU6_0_CH0_ISR_PRIORITY 30 //定义CCU6_0 PIT通道0中断优先级 优先级范围1-255 越大优先级越高 与平时使用的单片机不一样


#define CCU6_0_CH1_INT_SERVICE 0
#define CCU6_0_CH1_ISR_PRIORITY 31


#define CCU6_1_CH0_INT_SERVICE 0
#define CCU6_1_CH0_ISR_PRIORITY 32


#define CCU6_1_CH1_INT_SERVICE 0
#define CCU6_1_CH1_ISR_PRIORITY 33






//------------GPIO中断参数相关定义------------
//通道0与通道4是公用一个中断函数 在中断内部通过标志位判断是谁触发的中断
#define ERU_CH0_CH4_INT_SERVICE 0 //定义ERU通道0和通道4中断服务类型,即中断是由谁响应处理 0:CPU0 1:CPU1 3:DMA  不可设置为其他值
#define ERU_CH0_CH4_INT_PRIO   40 //定义ERU通道0和通道4中断优先级 优先级范围1-255 越大优先级越高 与平时使用的单片机不一样


//通道1与通道5是公用一个中断函数 在中断内部通过标志位判断是谁触发的中断
#define ERU_CH1_CH5_INT_SERVICE 0 //定义ERU通道1和通道5中断服务类型,同上
#define ERU_CH1_CH5_INT_PRIO   41 //定义ERU通道1和通道5中断优先级 同上


//通道2与通道6是公用一个中断函数 在中断内部通过标志位判断是谁触发的中断
#define ERU_CH2_CH6_INT_SERVICE 3 //定义ERU通道2和通道6中断服务类型,同上
#define ERU_CH2_CH6_INT_PRIO   5 //定义ERU通道2和通道6中断优先级 同上


//通道3与通道7是公用一个中断函数 在中断内部通过标志位判断是谁触发的中断
#define ERU_CH3_CH7_INT_SERVICE 0 //定义ERU通道3和通道7中断服务类型,同上
#define ERU_CH3_CH7_INT_PRIO   43 //定义ERU通道3和通道7中断优先级 同上




//------------DMA中断参数相关定义------------
#define ERU_DMA_INT_SERVICE  0 //ERU触发DMA中断服务类型,即中断是由谁响应处理 0:CPU0 1:CPU1 3:DMA  不可设置为其他值
#define ERU_DMA_INT_PRIO    60 //ERU触发DMA中断优先级 优先级范围1-255 越大优先级越高 与平时使用的单片机不一样




//------------串口中断参数相关定义------------
#define UART0_INT_SERVICE  0 //定义串口0中断服务类型,即中断是由谁响应处理 0:CPU0 1:CPU1 3:DMA  不可设置为其他值
#define UART0_TX_INT_PRIO  10 //定义串口0发送中断优先级 优先级范围1-255 越大优先级越高 与平时使用的单片机不一样
#define UART0_RX_INT_PRIO  11 //定义串口0接收中断优先级 优先级范围1-255 越大优先级越高 与平时使用的单片机不一样
#define UART0_ER_INT_PRIO  12 //定义串口0错误中断优先级 优先级范围1-255 越大优先级越高 与平时使用的单片机不一样


#define UART1_INT_SERVICE  0
#define UART1_TX_INT_PRIO  13
#define UART1_RX_INT_PRIO  14
#define UART1_ER_INT_PRIO  15


#define UART2_INT_SERVICE  0
#define UART2_TX_INT_PRIO  16
#define UART2_RX_INT_PRIO  17
#define UART2_ER_INT_PRIO  18


#define UART3_INT_SERVICE  0
#define UART3_TX_INT_PRIO  19
#define UART3_RX_INT_PRIO  20
#define UART3_ER_INT_PRIO  21




#endif


系统定时器完成延时与计时功能
#include "headfile.h"
#pragma section all "cpu0_dsram"


uint16 time;


int core0_main(void)
{
disableInterrupts();
get_clk();//获取时钟频率  务必保留


    //用户在此处调用各种初始化函数等




    enableInterrupts();


    while (TRUE)
    {
     systick_start(STM1); //使用STM1 进行计时
     systick_delay_ms(STM0, 100); //延时100MS  使用STM0定时器  也可以使用STM1定时器
     time = systick_getval_ms(STM1); //读取STM1计时时间
     printf("delay time: %dmsn", time);


    }
}


#pragma section all restore
举报

更多回帖

发帖
×
20
完善资料,
赚取积分