• dsPIC33F配置ADC软件触发轮询与采样中断的注意事项与区别


              最近使用dsPIC33F系列单片机。学习配置了ADC触发及轮询方式。相关心得记录在下,方便以后回忆,请大家多多指导。


    1、对dsPIC系统时钟的配置

    1     PLLFBD = 2;                       // M = PLLFBD + 2  内部FRC=7.37MHz
    2     CLKDIVbits.PLLPRE = 0;            // N1 = 2  
    3     CLKDIVbits.PLLPOST = 0;           // N2 = 2 
    4     
    5     __builtin_write_OSCCONH(0x01);    // 新振荡器 FRC+PLL  
    6     __builtin_write_OSCCONL(0x01);    // 允许切换晶振  
    7       
    8     while(OSCCONbits.COSC != 0b001);  // 等待振荡器 FRC+PLL    
    9     while(OSCCONbits.LOCK != 1);      // 等待振荡器稳定  

          dsPIC时钟来源可以参考dsPIC官方资料。这配置没有多少困难。

    2、对ADC模块的配置

          2.1 轮询方式

     1 void ADC1_Init(void)
     2 {
     3     ADCONbits.FORM = 0;             // Output in Integer Format
     4     ADCONbits.EIE  = 0;             // Enable Early Interrupt
     5     ADCONbits.ORDER = 1;            // Normal Order of conversion
     6     ADCONbits.SEQSAMP = 0;          // Simultaneous sampling 
     7     ADCONbits.ASYNCSAMP = 1;        // Asynchronous sampling
     8     ADCONbits.SLOWCLK = 0;          // High Frequency Clock input
     9     ADCONbits.ADCS = 5;             // Clock divider selection
    10 
    11     //使用软件触发,这里务必设为独立软件触发
    12     ADCPC3bits.TRGSRC7= 1;          // ADC独立软件触发事件
    13 
    14     ADPCFGbits.PCFG15 = 0;           
    15     ADCONbits.ADON = 1;             // Enable the ADC 
    16 }

          2.2 中断方式

     1 void ADC1_Init(void)
     2 {
     3     ADCONbits.FORM = 0;             // Output in Integer Format
     4     ADCONbits.EIE  = 0;             // Enable Early Interrupt
     5     ADCONbits.ORDER = 1;            // Normal Order of conversion
     6     ADCONbits.SEQSAMP = 0;          // Simultaneous sampling 
     7     ADCONbits.ASYNCSAMP = 1;        // Asynchronous sampling
     8     ADCONbits.SLOWCLK = 0;          // High Frequency Clock input
     9     
    10     ADCONbits.ADCS = 5;             // Clock divider selection
    11     ADCPC3bits.TRGSRC7= 1;          // ADC独立软件触发事件
    12 
    13     ADPCFGbits.PCFG15 = 0;       
    14     //配置中断优先级及使能,中断优先级数值越低,优先级越高
    15     IPC29bits.ADCP7IP = 0x01; // Set ADC Pair 7 Interrupt Priority (Level 2)
    16     IFS7bits.ADCP7IF = 0; // Clear ADC Pair 7 Interrupt Flag
    17     IEC7bits.ADCP7IE = 1; // Enable ADC Pair 7 Interrupt
    18     
    19     
    20     ADCONbits.ADON = 1;             // Enable the ADC 
    21 }

    3、main函数内触发及处理

           3.1 轮询方式

           轮询方式需要等待ADC采样完成,才能获取采样后转换的值。获取后,需要手动清除采样完成的标志。

    1     ADC1_Init();                  //ADC模块初始化
    2     while(1)
    3     {
    4         ADCPC3bits.SWTRG7 = 1;           //Trigger the ADC 
    5         while(ADSTATbits.P7RDY == 0);    //Wait until the ADC finish
    6         ADCValue = ADCBUF15;             //Get the ADC Value
    7         ADSTATbits.P7RDY = 0;            //Clear the last finish flag
    8         delay(65535);                    //stop a moment
    9     }

            3.2 中断方式

     1 //等待一段时间就触发采样
     2 while(1)
     3 {
     4     ADCPC3bits.SWTRG7 = 1;           
     5         delay(65534);
     6 }
     7 //采样完成自动进入中断服务函数
     8 void __attribute__((interrupt, no_auto_psv)) _ADCP7Interrupt(void)
     9 {
    10 
    11     IFS7bits.ADCP7IF = 0;           // Clear ADC Pair 7 Interrupt Flag
    12     ADCValue = ADCBUF15;
    13     ADSTATbits.P7RDY = 0;         
    14 }

    4、区别

        使用轮询方式需要不断判断采样是否完成,

         使用中断方式采样完成后会自动进入中断服务函数。节约CPU资源

    5、曾经犯过的错误

           错误的代码逻辑如下:

     1 while(1)
     2 {
     3     ADCPC3bits.SWTRG7 = 1;  
     4     while(ADSTATbits.P7RDY == 0);
     5     delay(65534);
     6 }
     7 
     8 
     9 void __attribute__((interrupt, no_auto_psv)) _ADCP7Interrupt(void)
    10 {
    11     IFS7bits.ADCP7IF = 0; // Clear ADC Pair 7 Interrupt Flag
    12     ADCValue = ADCBUF15;
    13     ADSTATbits.P7RDY = 0;   
    14 }

             dsPIC33F处理逻辑:采样转换完成后ADSTAT相应的位会配置为1.通过判断这个位来判断采样转换是否完成。

             上面的代码错误的逻辑为:

               第3行触发ADC采样转换,

               第12行获取采样转换的结果后,

               第13行将采样转换完成的标准位清零,

               然后,

               程序回到了第四行一直等待,卡死在这里

          解决办法:

               将第四行或者第13行去掉就行。

               其实,当独立软件触发SWTRG为1的时候,采样完成标志位PEND,由硬件自动清零

     

               

  • 相关阅读:
    windows查看端口命令
    lombok
    Linux之文档与目录结构 目录的相关操作 Linux的文件系统
    VMware与Centos系统安装 和重置root密码
    shell 基本命令
    centos 安装教程 服务器配置教程 服务器中安装python 服务器中安装Django 安装MySQL 配置MySQL
    {Django基础十之Form和ModelForm组件}一 Form介绍 二 Form常用字段和插件 三 From所有内置字段 四 字段校验 五 Hook钩子方法 六 进阶补充 七 ModelForm
    {Django基础九之中间件} 一 前戏 二 中间件介绍 三 自定义中间件 四 中间件的执行流程 五 中间件版登陆认证
    {Django基础八之cookie和session}一 会话跟踪 二 cookie 三 django中操作cookie 四 session 五 django中操作session
    老师的blog整理 .网络编程部分 .网络编程部分 前端部分 django基础部分
  • 原文地址:https://www.cnblogs.com/cjyc/p/14986261.html
Copyright © 2020-2023  润新知