查看: 1141|回复: 0

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

[复制链接]
  • TA的每日心情
    开心
    2024-3-26 15:16
  • 签到天数: 266 天

    [LV.8]以坛为家I

    3298

    主题

    6545

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32003
    最后登录
    2024-4-9
    发表于 2020-7-23 09:57:25 | 显示全部楼层 |阅读模式
    手把手学习NXP S08P 系列单片机(五)

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



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


    这一期将要向大家介绍的外设是模数转换器(ADC),模拟比较器(ACMP)以及触摸传感接口(TSI)本文包含较多的代码,那些源代码都可以在NXP官网www.nxp.com/S08P-Lite或飞锐泰克官网www.free-tech.com.cn免费下载。
    本文是以S08PT60为例进行讲解,文中包含的寄存器描述等内容来源于该芯片的《参考手册》。如需了解更多信息,请下载对应芯片的参考手册进行学习。
    ADC

    1,简介
    ADC(Analog-to-Digital) 可以将连续变化的模拟量转化为离散的数字信号,典型的ADC将模拟信号转化成标识为一定比例电压值的数字信号。
    S08PT系列的ADC拥有12位精度,最多16个通道,最高可设置深度为8的FIFO,并具有结果自动比较功能。

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

    配置寄存器ADC_APCTLx,配置相关管脚I/O口功能;
    配置寄存器ADC_SC3,配置时钟源、时钟分频、工作模式;
    配置寄存器ADC_SC1,选择通道;

    4,代码
    使用ADC对电位器的电压进行采样,并读取ADC采样结果。
    ADC函数
    1. /* 初始化ADC

    2. * */

    3. void ADC_Init( void )

    4. {

    5.     /* 选择通道12 */

    6.     ADC_APCTL1 = 0x00;

    7.     ADC_APCTL2 = 0x10;

    8.     /* 时钟源选择总线时钟 */

    9.     ADC_SC3_ADICLK = CLOCK_SOURCE_BUS_CLOCK;

    10.     /* 4分频 */

    11.     ADC_SC3_ADIV   = ADC_ADIV_DIVIDE_4;

    12.     /* 12位精度 */

    13.     ADC_SC3_MODE   = ADC_MODE_12BIT;

    14.     /* 短采样 */

    15.     ADC_SC3_ADLSMP = 0;

    16. }

    17. /*触发指定通道ADC采集,并等待转换完成,读取结果

    18. * */

    19. unsigned short ADC_GetResult( unsigned char channel)

    20. {

    21.     ADC_SC1 = channel; // initial the ADC conversion, select ADC channel

    22.     while( !ADC_SC1_COCO );

    23.     return ADC_R;

    24. }

    25. 主函数

    26. void main(void)
    复制代码
    以下是ADC模块的讲解与演示的视频:
    模拟比较器(ACMP)


    1,简介


    S08P系列的ACMP可以对两个模拟电压进行比较,并将比较后的结果作为数字逻辑输出。
    模拟比较器可以选择连接外部信号的PIN作为V+或V-的输入,也可以选择内部6位DAC作为V+或V-的输入。另外还可以软件配置电压迟滞值,可以任意输出极性触发中断。
    8.png
    2,寄存器
    9.png
    3,配置步骤
    配置寄存器ACMP_C1选择DAC输出电压及使能DAC;
    配置寄存器ACMP_C0选择输入;
    配置寄存器ACMP_C2选择输入管脚;
    配置寄存器ACMP_CS使能比较器。


    4,代码
    选择ACMP1接入外部电位器电压信号(PTA1)作为V-输入,内部DAC给定的值作为V+输入,ACMP对这两个量进行比较,并将比较结果赋值给LED0,通过观察LED0得到比较结果。

    1. /* 配置模拟比较器

    2. * 外部管脚PTA1/ACMP1的值和内部DAC比较

    3. * 不开中断

    4. * */

    5. void ACMP_Init ( void )

    6. {

    7.     ACMP_C1_DACVAL = 35;             //参考电压为5V时:  6bit DAC: (36/64)*5 = 2.81V

    8.     ACMP_C1 |= ACMP_C1_DACEN_MASK | ACMP_C1_DACREF_MASK;    // 使能DAC, 选择VDDA为参考电压

    9.     ACMP_C0_ACPSEL = 0x03;          // ACMP 正相输入: DAC output

    10.     ACMP_C0_ACNSEL = 0x01;          // ACMP 负相输入: 外部信号 PTA1/ACMP1

    11.     ACMP_C2_ACIPE = 0x02;            // 使能ACMP1的输入为PTA1

    12.     /* 不打开中断 */

    13.     ACMP_CS_ACIE = 0;

    14.     ACMP_CS_ACE = 1;   // 使能ACMP

    15. }

    16. void main(void) {


    17.       ACMP_Init();
    18. …               
    19.       for(;;) {

    20.         delay_ms(100);

    21.         PIN_LED0_PD =ACMP_CS_ACO;

    22.       } /* loop forever */

    23. }
    复制代码

    以下是ACMP模块的讲解与演示的视频:
    触摸按键(TSI)

    1,简介


    Touch Sensing Input (TSI)原理:
    TSI模块由片内恒流源、开关、比较器、计数器和参考振荡器组成。触摸电极和地之间构成一个电容,这个电容和TSI内部的恒流源和比较器构成一个振荡器A,同样芯片内由另一组电容、恒流源、比较器构成参考振荡器B。
    测量结果由振荡器A的采样周期与振荡器B的频率决定,最终体现为计数器的值。TSI测量开始时清空计数器,同时开始对电极充放电(启动振荡器A),完成N次扫描后(N是设定的已知数),停止计数,并将计数器的值写入TSI_CNT作为测量结果。测量结果由以下公式给出(具体推导请看参考手册):
    13.png
    除了触摸电极的电容C_elec,其他值在程序中都是给定的。当有人体接近触摸电极时,等效地增大了电极与地之间的有效面积,使得电极板电容值增大(C_elec变大),计数器的值会变大。当检测值大于设定阈值时,TSI的触发标志位将置位,从而实现了对触摸感应事件的响应。
    S08P系列的TSI模块不但灵敏,而且抗干扰能力很强。如果应用场景复杂,请参考官方软件库Touch-Sensing for MCU
    11.png
    2,寄存器
    12.png
    3,配置步骤

    配置寄存器TSI_CS0,选择触发模式(软件触发或硬件触发);
    配置寄存器TSI_CS1,设置电极振荡输出的分频和扫描次数;
    配置寄存器TSI_CS2,设置电极振荡器和参考振荡器的充放电电流,振荡器电压
    配置寄存器TSI_CS0,使能TSI模块。

    4,代码
    读取上电复位后计数器中的值作为初始值,然后将后面计数器的值与初始值不断读取比较,当有触摸时,计数器的值发生明显变化,点亮LED7。
    初始化
    1. /* TSI初始化

    2. * */void TSI_Init2(void)

    3. {

    4.     TSI_CS0 = 0;             //初始化TSI CS0

    5.     TSI_CS0_STM = TSI_SOFTWARE_TRIGGER_SCAN;    //软件触发扫描

    6.    

    7.     TSI_CS1 = 0;             //初始化TSI CS1

    8.     TSI_CS1_NSCN = 31;   //扫描通道32次

    9.     TSI_CS1_PS = 1;        //2分频



    10.     TSI_CS2 = 0;              //初始化TSI CS2

    11.     TSI_CS2_EXTCHRG = TSI_CHARGE_CURRENT_32uA;  //给电极振荡器充放电的电流源32 uA

    12.     TSI_CS2_REFCHRG = TSI_CHARGE_CURRENT_64uA;  //给参考振荡器充放电的电流源64 uA



    13.     TSI_CS0_TSIEN = 1;     //使能TSI

    14. }

    15. 基本函数:



    16. /* 选择通道 */

    17. void TSI_SetMeasuredChannel(uint8_t channel)

    18. {

    19.     TSI_CS3_TSICH   = channel;

    20. }

    21. /* 触发开始转换 */

    22. void TSI_StartSoftwareTrigger(void)

    23. {

    24.     TSI_CS0_SWTS    = 1;

    25. }

    26. /* 返回完成标志 */

    27. uint8_t TSI_GetEndOfScanFlag()

    28. {

    29.     return (TSI_CS0_EOSF);

    30. }

    31. /* 清除标志 */

    32. void TSI_ClearEndOfScanFlag(void)

    33. {

    34.     TSI_CS0_EOSF = 1;

    35. }

    36. /* 读计数值 */

    37. uint16_t TSI_GetCounter(void)

    38. {

    39.     return (uint16_t)(TSI_CNT);

    40. }
    复制代码
    任务函数:
    1. void main(void) {



    2.     TSI_Init2();



    3.     tsi_Test();

    4.     for(;;) {        

    5.         delay_ms(1000);

    6.     } /* loop forever */

    7. }



    8. uint16_t pad2init_value; //初始化时读取的参考值

    9. uint16_t pad2_value; // 实时值

    10. uint16_t sum;

    11. /* 触摸按键测试

    12. * */

    13. void tsi_Test(void)

    14. {        

    15.     uint8_t channel =2;// 测试通道

    16.     int i;

    17.     TSI_SetMeasuredChannel(channel); // 设置通道

    18.     TSI_ClearEndOfScanFlag();//清标志位

    19.     /* 重复采集初始值,再取平均值 */

    20.     for(i=0;i<8;i++)

    21.     {

    22.         delay_ms(100);

    23.         TSI_StartSoftwareTrigger();

    24.         while(TSI_GetEndOfScanFlag()==0);

    25.         sum += TSI_GetCounter();

    26.         TSI_ClearEndOfScanFlag();

    27.     }

    28.     Pad2init_value = sum/8;

    29.     /* 值变化后点亮LED */

    30.     while(1)

    31.     {

    32.         TSI_StartSoftwareTrigger();

    33.         delay_ms(200);

    34.         pad2_value =TSI_GetCounter();

    35.         if(pad2_value > pad2init_value + 50)

    36.         {

    37.             PIN_LED7_PD =0;//点亮LED1

    38.         }

    39.         else

    40.         {

    41.             PIN_LED7_PD =1; //关闭LED1

    42.         }

    43.         PIN_LED0_PD =!PIN_LED0_PD;

    44.     }

    45. }
    复制代码

    以下是TSI模块的讲解与演示的视频:

    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加油站

    签到签到
    回复

    使用道具 举报

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

    本版积分规则

    关闭

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

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

    GMT+8, 2024-4-19 20:30 , Processed in 0.499407 second(s), 22 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

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