智能车学习(十五)——K60野火2013版例程

一、中断函数注册方法:

1、格式:

配置某个功能的中断
注册中断函数
开启中断

2、一个例子

pit_init_ms(PIT0,5);//定时中断初始化
set_vector_handler(PIT0_VECTORn ,PIT0_IRQHandler);      //设置PIT0的中断服务函数为 PIT0_IRQHandler
enable_irq (PIT0_IRQn);

 

二、ADC模块

1、ADC通道管脚对应表

typedef enum
{
    // ---------------------------------ADC0-------------------------
    ADC0_DP0,
    ADC0_DP1,
    PGA0_DP,        //不支持ADC,需要配置 ADC PGA register 设置放大增益
    ADC0_DP3,
    //软件触发不支持B通道
    ADC0_SE4b,      // PTC2     不支持软件ADC
    ADC0_SE5b,      // PTD1     不支持软件ADC
    ADC0_SE6b,      // PTD5     不支持软件ADC
    ADC0_SE7b,      // PTD6     不支持软件ADC

    ADC0_SE8,       // PTB0
    ADC0_SE9,       // PTB1
    ADC0_SE10,      // PTA7
    ADC0_SE11,      // PTA8
    ADC0_SE12,      // PTB2
    ADC0_SE13,      // PTB3
    ADC0_SE14,      // PTC0
    ADC0_SE15,      // PTC1
    ADC0_SE16,      // ADC0_SE16
    ADC0_SE17,      // PTE24
    ADC0_SE18,      // PTE25
    ADC0_DM0,       // ADC0_DM0
    ADC0_DM1,       // ADC0_DM1
    RES0,           // 保留
    RES1,           // 保留
    DAC0_OUT,       // DAC0输出 不支持ADC
    RES2,           // 保留
    RES3,           // 保留
    Temp0_Sensor,   // Temperature Sensor,内部温度测量,可用ADC函数
    Bandgap0,       // 温度补偿结构带隙基准源   不支持ADC
    RES4,           // 保留
    VREFH0,         // 参考高电压,可用ADC函数 ,结果恒为 2^n-1
    VREFL0,         // 参考低电压,可用ADC函数 ,结果恒为 0
    Module0_Dis,    // 不支持 ADC

    // ---------------------------------ADC1-------------------------
    ADC1_DP0,
    ADC1_DP1,
    PGA1_DP,        // 不支持 ADC
    ADC1_DP3,
    ADC1_SE4a,      // PTE0
    ADC1_SE5a,      // PTE1
    ADC1_SE6a,      // PTE2
    ADC1_SE7a,      // PTE3

    ADC1_SE4b = ADC1_SE4a,  // PTC8     不支持软件ADC ,传递 ADC1_SE4b 到软件ADC函数里,会当作 ADC1_SE4a 处理。
    ADC1_SE5b = ADC1_SE5a,  // PTC9     不支持软件ADC
    ADC1_SE6b = ADC1_SE6a,  // PTC10    不支持软件ADC
    ADC1_SE7b = ADC1_SE7a,  // PTC11    不支持软件ADC

    ADC1_SE8,       // PTB0
    ADC1_SE9,       // PTB1
    ADC1_SE10,      // PTB4
    ADC1_SE11,      // PTB5
    ADC1_SE12,      // PTB6
    ADC1_SE13,      // PTB7
    ADC1_SE14,      // PTB10
    ADC1_SE15,      // PTB11
    ADC1_SE16,      // ADC1_SE16
    ADC1_SE17,      // PTA17
    VREF_OUTPUT,    // VREF Output
    ADC1_DM0,       // ADC1_DM0
    ADC1_DM1,       // ADC1_DM1
    RES5,           //保留
    RES6,
    DAC1_OUT,
    RES7,           //保留
    RES8,
    Temp1_Sensor,
    Bandgap1,       // 温度补偿结构带隙基准源   不支持ADC
    RES9,
    VREFH1,         // 参考高电压,可用ADC函数 ,结果恒为 2^n-1
    VREFL1,         // 参考低电压,可用ADC函数 ,结果恒为 0
    Module1_Dis,    // 不支持 ADC

} ADCn_Ch_e;

 

2、精度选择

//精度位数
typedef enum ADC_nbit
{
    ADC_8bit   = 0x00,
    ADC_10bit  = 0x02,
    ADC_12bit  = 0x01,
    ADC_16bit  = 0x03
} ADC_nbit;

 

3、接口使用

//外部函数接口声明

 //初始化 ADC0_SE10 ,使用 PTA7 管脚
extern void     adc_init    (ADCn_Ch_e);                //ADC初始化

// ADCn_Ch_e    ADC通道
//ADC_nbit          ADC精度
extern uint16   adc_once    (ADCn_Ch_e, ADC_nbit);      //采集一次一路模拟量的AD值


extern uint16   ad_flt(ADCn_Ch_e adcn_ch, ADC_nbit bit);//与前几次采样平均
extern uint16   ad_ave(ADCn_Ch_e adcn_ch, ADC_nbit bit, uint8 N); //均值滤波
extern void     adc_stop    (ADCn_e);                   //停止ADC转换

 

 

三、DAC模块(智能车不使用)

typedef enum DACn       //DAC模块
{
    DAC0,
    DAC1
} DACn_e;

extern void dac_init(DACn_e);               //DAC一次转换初始化
extern void dac_out(DACn_e, uint16 val);    //DAC一次转换操作

 

四、DMA模块使用(智能车不使用)

1、使用目的

      传输数据使用,这样子的话可以和主程序同时进行。这样子的话,可以在数据量大的时候不占用程序执行的时间。

2、使用方法API

/*!
 *  @brief      DMA初始化,读取端口数据到内存
 *  @param      DMA_CHn         通道号(DMA_CH0 ~ DMA_CH15)
 *  @param      SADDR           源地址( (void * )&PTx_Bn_IN 或 (void * )&PTx_Wn_IN   )
 *  @param      DADDR           目的地址
 *  @param      PTxn            触发端口
 *  @param      DMA_BYTEn       每次DMA传输字节数
 *  @param      count           一个主循环传输字节数
 *  @param      cfg             DMA传输配置,从DMA_cfg里选择
 *  @since      v5.0
 *  @note       DMA PTXn触发源默认上升沿触发传输,若需修改,则初始化后调用 port_init 配置DMA 触发方式
                初始化后,需要调用 DMA_EN 来实现
 *  Sample usage:   uint8 buff[10];
                    dma_portx2buff_init(DMA_CH0, PTB_B0_IN, buff, PTA7, DMA_BYTE1, 10, DADDR_RECOVER);
                    //DMA初始化,源地址:PTB_B0_IN,目的地址:buff,PTA7触发(默认上升沿),每次传输1字节,共传输 10次 ,传输结束后恢复地址

                    port_init(PTA7,ALT1 | DMA_FALLING);             //默认触发源是上升沿,此处改为 下降沿触发

                    DMA_EN(DMA_CH0);                //需要使能 DMA 后才能传输数据
 */
void dma_portx2buff_init(DMA_CHn CHn, void *SADDR, void *DADDR, PTXn_e ptxn, DMA_BYTEn byten, uint32 count, uint32 cfg);

 

五、延时模块使用(精准)

extern void dwt_delay_us(uint32 us);
extern void dwt_delay_ms(uint32 ms);

 

六、Flash使用

1、API使用

/*----------   *DFLASH  写浮点数*   ----------*/
void DFlash_Write_Float(uint16_t Block_Now,unsigned int Order,float Write_Float); 


/*----------   *DFLASH  读浮点数*   ----------*/
float DFlash_Read_Float(uint16_t Block_Now,unsigned int Order);


/*----------   *DFLASH  写整数*   ----------*/
void DFlash_Write_Int(uint16_t Block_Now,unsigned int Order,signed int Write_Int);   


/*----------   *DFLASH  读整数*   ----------*/
signed int DFlash_Read_Int(uint16_t Block_Now,unsigned int Order);

 

2、使用注意点:一定要关闭中断再打开中断

3、一个DEMO:

/*----------   *用户写参数 传递函数*   ----------*/
void write_transfer_function(void)
{
  //整形参数传递
  //user_int_data[0] = data_int_test;                                 //第一个变量为整形测试变量,往后自己添加需要存贮的变量

  
  
  //浮点型参数传递
  //user_float_data[0] = data_float_test;                           //第一个变量为浮点型测试变量,往后自己添加需要存贮的变量
  

  
}


/*----------   *用户读参数 传递函数*   ----------*/
void read_transfer_function(void)
{
    DisableInterrupts;
  //整形参数传递
  //data_int_test = user_int_data[0];                                 //第一个变量为整形测试变量,往后自己添加需要存贮的变量
    
  //浮点型参数传递
  //data_float_test = user__float_data[0];                           //第一个变量为浮点型测试变量,往后自己添
  
  
  EnableInterrupts; 
  
}


/*----------   *flash 写入用户自定义参数函数*   ----------*/
void Write_data(uint8_t SECTOR_NUM)
{
  int int_start = 1,float_start = 101;
  DisableInterrupts;
  flash_erase_sector(SECTOR_NUM);
  write_transfer_function();
  
  
  for(int_start = 1;int_start < 100;int_start++)
    DFlash_Write_Int(SECTOR_NUM,int_start,user_int_data[int_start - 1]);              //从偏移地址1开始,写入整形数据
  
  
  for(float_start = 101;float_start < 200;float_start++)
    DFlash_Write_Float(SECTOR_NUM,float_start,user_float_data[float_start - 101]);   //从偏移地址101开始,写入浮点型数据
  
  
  EnableInterrupts;  
}


/*----------   *flash 读取用户自定义参数函数*   ----------*/
void Read_data(uint8_t SECTOR_NUM)
{
  int int_start = 1,float_start = 101;
  
  
  for(int_start = 1;int_start < 100;int_start++)
    user_int_data[int_start - 1] = DFlash_Read_Int(SECTOR_NUM,int_start);              //从偏移地址1开始,读出整形数据
  
  
  for(float_start = 101;float_start < 200;float_start++)
    user_float_data[float_start - 101] = DFlash_Read_Float(SECTOR_NUM,float_start); //从偏移地址101开始,读出浮点型数据
  
  
  read_transfer_function();
}

 

七、PWM模块使用

1、PWM端口对应:

image

2、API使用:

#define FTM0_PRECISON 3000u     //定义占空比精度,100即精度为1%,1000u则精度为0.1%,用于占空比 duty 形参传入,即占空比为 duty/FTM_PRECISON
#define FTM1_PRECISON 3000u     //定义占空比精度,100即精度为1%,1000u则精度为0.1%,用于占空比 duty 形参传入,即占空比为 duty/FTM_PRECISON
#define FTM2_PRECISON 6000u     //定义占空比精度,100即精度为1%,1000u则精度为0.1%,用于占空比 duty 形参传入,即占空比为 duty/FTM_PRECISON

extern void  FTM_PWM_init(FTMn_e, FTM_CHn_e, uint32 freq, uint32 duty);  //初始化FTM的PWM功能并设置频率、占空比。设置通道输出占空比。同一个FTM,各通道的PWM频率是一样的,共3个FTM

extern void  FTM_PWM_Duty(FTMn_e, FTM_CHn_e,              uint32 duty);  //设置通道占空比,占空比为 (duty * 精度) % ,如果 FTM_PRECISON 定义为 1000 ,duty = 100 ,则占空比 100*0.1%=10%
extern void  FTM_PWM_freq(FTMn_e,            uint32 freq);               //设置FTM的频率(改频率后,需要重新配置占空比)

 

八、脉冲计数

1、方法一:FTM中的正交解码:

/*********************** 正交解码功能 **************************/
//本功能 尚未测试
extern void     FTM_QUAD_Init(FTMn_e ftmn);         //初始化FTM 的正交解码 功能
extern int16    FTM_QUAD_get(FTMn_e ftmn);          //获取FTM 正交解码 的脉冲数(负数表示反方向)
extern void     FTM_QUAD_clean(FTMn_e ftmn);        //清 FTM 正交解码 的脉冲数
void FTM2_QUAD_Int(void) ;
#endif  //_MK60_FTM_H_

 

2、方法二:LPTMR中的低功耗计数

/*       用于脉冲计数        */
extern void     lptmr_pulse_init  (LPT0_ALTn, uint16 count, LPT_CFG);   //计数器初始化设置
extern uint16   lptmr_pulse_get   (void);                               //获取计数值
extern void     lptmr_pulse_clean (void);                               //清空计数值

 

 

九、GPIO使用

/****************************外部使用****************************/

extern void    gpio_init  (PTXn_e, GPIO_CFG, uint8 data);    //初始化gpio
extern void    gpio_ddr   (PTXn_e, GPIO_CFG);                //设置引脚数据方向
extern void    gpio_set   (PTXn_e,           uint8 data);    //设置引脚状态
extern void    gpio_turn  (PTXn_e);                          //反转引脚状态
extern uint8   gpio_get   (PTXn_e);                          //读取引脚状态



//如下 4个 函数 的 PTxn 只能是 宏定义,不能是 变量
#define GPIO_SET(PTxn,data)       (PTXn_T(PTxn,OUT)= (data))    //设置输出电平
#define GPIO_TURN(PTxn)           (PTXn_T(PTxn,T)= 1)           //翻转输出电平
#define GPIO_GET(PTxn)            (PTXn_T(PTxn,IN))             //读取引脚输入状态
#define GPIO_DDR(PTxn,ddr)        (PTXn_T(PTxn,DDR) = ddr)      //输入输出状态

 

 

十、LPTMR模块API

/**
 *  @brief LPTMR脉冲计数输入管脚选项
 */
typedef enum
{
    //只有1、2管脚,并没有0、3管脚
    LPT0_ALT1 = 1,      // PTA19
    LPT0_ALT2 = 2       // PTC5
} LPT0_ALTn;

/**
 *  @brief LPTMR脉冲计数触发方式
 */
typedef enum LPT_CFG
{
    LPT_Rising  = 0,    //上升沿触发
    LPT_Falling = 1     //下降沿触发
} LPT_CFG;

#define LPTMR_Flag_Clear()  (LPTMR0_CSR |= LPTMR_CSR_TCF_MASK)         //清除LPT比较标志位

/*          用于延时         */
extern void     lptmr_delay_ms(uint16 ms);      //延时(ms)
extern void     lptmr_delay_us(uint16 us);      //延时(us)

/*       用于定时           */
extern void     lptmr_timing_ms(uint16 ms);     //定时(ms)
extern void     lptmr_timing_us(uint16 ms);     //定时(us)

/*        用于计时           */
extern void     lptmr_time_start_ms(void);      //开始计时(ms)
extern uint32   lptmr_time_get_ms(void);        //获取计时时间 

extern void     lptmr_time_start_us(void);      //开始计时(ns)
extern uint32   lptmr_time_get_us(void);        //获取计时时间 

extern void     lptmr_time_close();             //关闭计时器


/*       用于脉冲计数        */
extern void     lptmr_pulse_init  (LPT0_ALTn, uint16 count, LPT_CFG);   //计数器初始化设置
extern uint16   lptmr_pulse_get   (void);                               //获取计数值
extern void     lptmr_pulse_clean (void);                               //清空计数值


/*      中断复位函数模版    */
extern void lptmr_test_handler(void);                                       //中断复位函数,仅供参考(需用户自行实现)

 

 

十一、串口对应模块

image

 

API使用:

/初始化
extern void uart_init      (UARTn_e, uint32 baud);             //初始化uartx模块
void uart_init_old (UARTn_e uratn, uint32 baud);
//接收相关代码
extern void uart_getchar   (UARTn_e, unsigned char *ch);                //等待接受1个字节
char uart_getchar_old (UARTn_e uratn);
extern char uart_querychar (UARTn_e, char *ch);                //查询接收1个字符
extern char uart_querystr  (UARTn_e, char *str, uint32 max_len); //查询接收字符串
extern char uart_querybuff (UARTn_e, char *str, uint32 max_len); //查询接收buff

extern char uart_query    (UARTn_e);                          //查询是否接收到一个字节


//发送相关代码
extern void uart_putchar   (UARTn_e, char ch);                 //发送1个字节
extern void uart_putbuff   (UARTn_e , uint8 *buff, uint32 len);//发送len个字节buff
extern void uart_putstr    (UARTn_e , const uint8 *str);       //发送字符串



//中断相关代码
extern void uart_rx_irq_en (UARTn_e);                          //开串口接收中断
extern void uart_tx_irq_en (UARTn_e);                          //开串口发送中断
extern void uart_txc_irq_en (UARTn_e);                         //开串口发送完成中断

extern void uart_rx_irq_dis(UARTn_e);                          //关串口接收中断
extern void uart_tx_irq_dis(UARTn_e);                          //关串口发送中断
extern void uart_txc_irq_dis(UARTn_e);                         //关串口发送完成中断

extern void uart3_test_handler(void);                        //中断复位函数,仅供参考(需用户自行实现)
posted @ 2015-12-15 10:10  Blue Mountain  阅读(3398)  评论(0编辑  收藏  举报