查看: 6233|回复: 0

手把手学习NXP S08P 系列单片机(四)

[复制链接]
  • TA的每日心情
    开心
    2025-7-11 08:53
  • 签到天数: 301 天

    连续签到: 2 天

    [LV.8]以坛为家I

    3934

    主题

    7555

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    40175
    最后登录
    2025-9-3
    发表于 2020-6-11 14:07:52 | 显示全部楼层 |阅读模式
    手把手学习NXP S08P 系列单片机(四)

    手把手学习NXP S08P系列单片机的往期内容有:




    S08P系列微控制器是NXP推出的基于8位内核的微控制器,该系列产品在单一芯片上集成了丰富而关键的功能特性,例如触摸传感接口(TSI)、EEPROM和电机控制FlexTimer等,这些高度集成的外设可以帮助用户简化PCB设计和降低系统成本。


    这一期将要向大家介绍的外设是实时计时器(RTC),定时器(包含MTIM和FTM)以及可编程循环冗余检验模块(CRC)。


    本文包含较多的代码,那些源代码都可以在NXP官网www.nxp.com/S08P-Lite或飞锐泰克官网www.free-tech.com.cn免费下载,在文末也附有讲解操作视频帮助您理解与学习。


    本文是以S08PT60为例进行讲解,文中包含的寄存器描述与原理图来源于该芯片的《参考手册》。如需了解更多信息,请下载对应芯片的参考手册进行学习。


    RTC


    1,简介


    S08P系列的实时计数器(RTC)是一个独立的定时器,它的一大特点在于可以在芯片的STOP3模式下仍然继续运行,所以RTC通常用于时间,日历或其他任务计划功能。
    RTC模块有三个时钟源,默认外部晶振作为时钟源,也可以把时钟源配置为片内低功耗晶振或者总线时钟。
    它的周期性中断和外部触发的脉冲输出都是可编程的。


    2,寄存器
    S08PT60的RTC控制寄存器如下表所示:
    1.png
    3,配置步骤


    a.配置寄存器RTC_SC2,选择时钟源和分频系数;


    b.配置寄存器RTC_MOD,配置模值;


    c.配置寄存器RTC_SC1,开中断;


    4,代码


    通过代码,让RTC产生1s的周期性中断。
    RTC初始化
    1. void RTC_Init( void )
    2. {    //RTC interrupt interval: 1s = 16MHz / 1000 / 16000
    3.     RTC_SC2_RTCLKS = 0x3;    // 时钟源: bus clock 16MHz
    4.     RTC_SC2_RTCPS = 0x7;     // 分频:1000
    5.     RTC_MOD        = 15999;  // 模值:16000
    6.     RTC_SC1_RTIE = 1;         // 开中断}
    复制代码
    RTC中断
    1. interrupt VectorNumber_Vrtc void  Rtc_ISR(void)
    2. {    /* 清除中断 */
    3.     RTC_SC1_RTIF =1;
    4.     PIN_LED2_PD =!PIN_LED2_PD;
    5. }
    复制代码
    主函数
    1. #include <hidef.h> /* for EnableInterrupts macro */#include "derivative.h" /* include peripheral declarations */#include "commonTypes.h"
    2. #include "port.h"
    3. #include "wdog.h"
    4. #include "rtc.h"
    5. #include "ics.h"
    6. void ics_init(void);
    7. void main(void)
    8. {    DisableInterrupts;
    9.     __RESET_WATCHDOG();       
    10.     wdog_disable();
    11.        
    12.     ics_init(); //bus clock is 16M
    13.     port_init();
    14.     RTC_Init();       
    15.     EnableInterrupts;
    16.     led_write(0x00);
    17.     while(1);
    18. }
    复制代码
    以下是RTC模块的讲解与演示的视频:
    定时器

    1,简介


    S08P系列MCU有两种定时器:8位的modulo timer (MTIM)和FlexTimer Module (FTM)。
    MTIM是一个简单的8位定时器,具有几个可选时钟源和一个独立的可编程中断。
    FTM是一个16位的2到8通道定时器。它功能强大,可以用于中断、输入捕获、输出比较、产生PWM信号等功能,其产生的PWM波形带有死区插入、产生互补波形和故障管理等功能,因此非常适合用于驱动单相或者三相电机。

    2,寄存器

    MTIM有以下四个寄存器:
    2.png
    FTM的寄存器非常多,具体参照RM _P305,以下介绍本次用到的几类寄存器。由于S08P系列的寄存器都是8位的,为了操作超过8位的数据,所以有些功能使用了高/低两个寄存器。如下表所示:
    3.png
    3,配置步骤
    MTIM:


    a.置寄存器MTIMx_CLK,选择时钟源和分频系数;
    b.配置寄存器MTIMx_MOD,配置模值;
    c.配置寄存器MTIMx_SC,使能定时器;


    FTM:


    a.配置寄存器FTMx_MOD,配置模值;
    b.配置寄存器FTMx_CnSC,配置中断、通道、模式;
    c.配置寄存器FTMx_CnV,设置计数器值;
    d.配置寄存器FTMx_SC,选择时钟源和分频系数(注意:这里选择时钟,就相当于启动定时器)。


    4,代码

    以下将用代码实现两个功能,一是用MTIM做一个1ms中断,使用中断做一个通用的ms延时函数;二是使用FTM做PWM输出,驱动蜂鸣器;并在主函数中延时开关蜂鸣器。

    MTIM 1 ms 中断
    1. /* 初始化MTIM0
    2. * 定时时间为1ms
    3. * 开中断
    4. * */
    5. void MTIM0_Init( void )
    6. {
    7.     //MTIM interrupt interval: CLKS/PS/MOD=16M/64/250=1KHz
    8.     MTIM0_CLK_CLKS = 0x00;      //时钟源:总线时钟
    9.     MTIM0_CLK_PS = 0x6;         //分频系数: 64
    10.     MTIM0_MOD        = 249;       //模值: 250
    11.     MTIM0_SC_TRST = 1;          // 计数器复位
    12.     MTIM0_SC_TOIE = 1;          // 使能TOF中断
    13.     MTIM0_SC_TSTP = 1;          // 停止计数
    14. }
    15. void MTIM0_Start(void)
    16. {
    17.     MTIM0_SC_TSTP   = 0;      // 开始计数
    18. }
    复制代码
    中断函数:
    1. /* MTIM0 溢出中断函数 */
    2. interrupt VectorNumber_Vmtim0 void  Mtim0_ISR(void)
    3. {
    4. static int i=0;
    5.     if(MTIM0_SC_TOF)
    6.     {
    7.         MTIM0_SC_TOF = 0; // clear the flag       
    8.     }
    9.     system_tick++;
    10.     if(i++ > 999)
    11.     {
    12.             i=0;
    13.             PIN_LED0_PD =!PIN_LED0_PD;
    14.     }
    15. }
    复制代码
    通用ms延时函数
    1. /* ms 延时函数 */
    2. void delay_ms(uint16_t t)
    3. {
    4.         system_tick = 0;
    5.         while( system_tick < t );                       
    6. }
    复制代码
    使用FTM模块实现PWM输出
    1. /* 初始化FTM1
    2.   * CH0 PWM模式输出
    3.   * 定时周期为4000
    4.   * */
    5. void FTM1_Init( void )
    6. {
    7.     //FTM frequency = CLKS/PS/MOD = 16MHz/2/4000=2KHz
    8.     FTM1_MOD = 3999;
    9.     FTM1_C0SC = 0x28;            //边沿对齐PWM输出模式
    10.     FTM1_C0V = 1999;             //50% 占空比
    11.     FTM1_SC = 0x00;                // disabled the FTM
    12. }

    13. /  * 启动定时器 */
    14. void FTM1_Start( void )
    15. {
    16.     FTM1_SC = 0x08; //向上计数、选择时钟2分频总线时钟
    17. }
    复制代码
    主函数
    1. #include <hidef.h> /* for EnableInterrupts macro */
    2. #include "derivative.h" /* include peripheral declarations */
    3. #include "commonTypes.h"
    4. #include "port.h"
    5. #include "wdog.h"
    6. #include "ics.h"
    7. #include "mtim.h"
    8. #include "ftm.h"
    9. uint16_t system_tick =0;
    10. void ics_init(void);
    11. void delay_ms(uint16_t t);
    12. void main(void) {
    13.     DisableInterrupts;
    14.     __RESET_WATCHDOG();
    15.     wdog_disable();
    16.     ics_init();//时钟初始化,总线时钟16M

    17.     MTIM0_Init();// 初始化MTIM0,定时1ms
    18.     MTIM0_Start();// 启动MTIM0
    19.     /* 初始化FTM1 */
    20.     FTM1_Init();
    21.     FTM1_Start();
    22.     FTM1_C0V =0;//关闭蜂鸣器
    23.        
    24.     port_init();        // 初始化IO口
    25.     EnableInterrupts;
    26.     delay_ms(2000);
    27.     led_write(0x00);//关闭LED
    28.     for(;;) {
    29.         FTM1_C0V =2000;//打开蜂鸣器
    30.         delay_ms(100);
    31.         FTM1_C0V =0; //关闭蜂鸣器
    32.         delay_ms(1000);
    33.         FTM1_C0V =100;
    34.         delay_ms(100);
    35.         FTM1_C0V =0;
    36.         delay_ms(1000);
    37.     }
    38. }
    复制代码
    以下是定时器模块的讲解与演示的视频:


    CRC


    1,简介


    循环冗余检查(CRC)是一种数据传输检错功能。它需要先将准备传输的数据进行多项式计算,并将得到的结果附在帧的后面再进行传输。接收设备也执行类似的算法,进行差错检测,以保证数据传输的正确性和完整性。
    S08P系列的硬件16/32位CRC生成器,具有可编程的初始值和多项式,数据反转和补码输出的功能,可以提供高效准确的CRC计算。
    2,寄存器

    4.png

    3,配置步骤

    a.配置寄存器CRC_CTRL以选择位宽,是否启用数据反向和补码等功能。
    b.配置寄存器CRC_P2:CRC_P3,写入多项式
    c.将CRC_CTRL [WAS]位置1,允许CRC_D2:CRC_D3写入初始值
    d.给数据寄存器D2\D3写入初始值
    e.清除CRC_CTRL [WAS],开始CRC计算;
    f.给 D3写入计算数据;
    g.从D2D3得到计算结果

    4,代码
    用代码实现16位CCITT CRC计算。

    CRC

    1. /* 16位CCITT CRC计算
    2. * data 计算数据
    3. * len  数据长度
    4. * return 返回结果
    5. * */uint16_t ccitt_crc16(uint8_t* data,uint8_t len)
    6. {
    7.     uint16_t r;
    8.     CRC_CTRL = CRC_CTRL_WAS_MASK; // 16-bit CRC, ready to dummy seed
    9.     CRC_P2P3 = 0x1021;    /* 多项式 */
    10.     CRC_D2D3 = 0xFFFF;    /* 初始值 */
    11.     CRC_CTRL = 0x00;
    12.     while(len--)
    13.     {
    14.         CRC_D3 = *data;
    15.         data++;
    16.     }    // Get result in CRC_D2:CRC_D3 here
    17.     r =CRC_D2;
    18.     r <<=8;
    19.     r|= CRC_D3;
    20.     return r;
    21. }
    复制代码
    主函数
    1. #include <hidef.h> /* for EnableInterrupts macro */
    2. #include "derivative.h" /* include peripheral declarations */
    3. #include "commonTypes.h"
    4. #include "wdog.h"
    5. #include "ics.h"
    6. #include "mtim.h"
    7. #include "uart.h"
    8. #include "uart_buff.h"
    9. #include "printf.h"
    10. uint16_t system_tick =0;
    11. uint8_t temp_buff[16];
    12. volatile uint16_t crc;
    13. void delay_ms(uint16_t t);
    14. uint16_t ccitt_crc16(uint8_t* data,uint8_t len);
    15. void ics_init(void);
    16. void main(void)
    17. {
    18.     int i;
    19.     DisableInterrupts;
    20.     __RESET_WATCHDOG();
    21.     wdog_disable();
    22.     MTIM0_Init();
    23.     MTIM0_Start();
    24.     ics_init();//16M总线时钟
    25.     Init_SCI2(16000000,115200);//串口配置
    26.     EnableInterrupts;

    27.     for(;;)
    28.     {
    29.         for(i=0;i<16;i++)
    30.         {
    31.             temp_buff[i]=0xf0 + i;
    32.         }
    33.         crc = ccitt_crc16(temp_buff,16);
    34.         printf("CRC = %04x\n",crc);//打印返回值
    35.         delay_ms(1000);
    36.      }
    37. }
    复制代码
    以下是定时器模块的讲解与演示的视频:


    S08P系列产品



    S08P系列产品是基于恩智浦S08内核的5V 8位高性能微控制器,该系列基于恩智浦独特设计的5V平台,集成了PWM波输出、EEPROM、触摸接口、ADC、比较器等丰富的外设资源,可在2.7到5.5V电压下工作,提供卓越的抗干扰能力,可满足工业控制和人机交互等严苛应用环境中的抗干扰需求,并符合电器安全标准IEC60730。
    S08P系列包含了多种性能丰富,各具特色的子系列产品,用户可以根据不同的需求选择不同性能、不同性价比的产品。如需了解S08P系列不同型号产品的更多信息,请参看文章《8位S08P 5V MCU推荐选型》。
      
    飞锐泰克公司



    北京飞锐泰克科技有限公司是从事电子元器件代理、推广、技术支持及嵌入式产品开发的技术型科技公司。2009年得到世界知名的NXP公司授权,推广NXP MCU。飞锐泰克希望通过技术方面的服务,能够让客户更深入的了解NXP单片机产品的优越性能和便捷的开发平台,帮助客户有效的降低成本,迅速的提升利润空间。



    文章出处:恩智浦MCU加油站


    qiandao qiandao
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-9-4 08:01 , Processed in 0.089835 second(s), 20 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表