【辉芒微】FT61F0A ADC采集
本文最后更新于31 天前,其中的信息可能已经过时,如有错误请发送邮件到tudougin@163.com

1. 12-bit 模/数转换器

​ ADC 模块可将模拟输入信号转换成 12-bit 的数字信号。ADC 可在不同的时钟速度下运行,并且在高达2MHz 的时钟速度下 (即 100 kHz 的采样率,10 μs/采样) 仍具有 11-bit 精度。

image-20250513213846089

​ 模拟输入信号可选择为 7 个 I/O (ANx) 通道之一、内部运放输出(OP0OUT)或 1 个内部通道 (1/4VDD)。ADC 由指令、I/O (PA4 / PB3) 或 PWM 触发。在触发和 ADC 采样之间可增加延时或前沿消隐(Leading Edge Blanking, LEB)。

image-20250513215728325

2. ADC 转换步骤

2.1 ADC准备

  1. 设置 ADCEN = 1,打开 ADC 模块时钟。
  2. 配置端口:
  • 设置 TRISx = 1,禁止引脚输出驱动。
  • 设置 ANSELAx = 1,关闭数字输入、弱上拉和弱下拉功能。
  1. 配置 ADC 模块:
  • 选择 ADC 转换时钟源(SysClk/N;N = 2, 4, 8, 16, 32, 64 / LIRC 256 kHz 或 32 kHz)。
  • 选择 ADC 参考电压(内部参考电压为 0.5V,2.0V,3.0V / VREF+可选 VDD/PA1,VREF−可选 GND/PA0)。
  • 选择 ADC 触发条件:软件、PA4/PB3-ADC_ETR 或 PWM,有或无 LEB。
  • 选择转换结果格式(左对齐或右对齐)。
  • 使能阈值比较(可选)。
  1. 配置 ADC 中断 (可选):
  • 使能 ADC 转换完成中断。
  • 使能外设总中断。
  • 关闭全局中断(如需执行中断服务程序则使能)。
  1. 打开 ADC 模块。然后等待所需稳定时间 TST (~15 µs),当 VADC-REF选择内部参考电压时,则需等待内部参考电压的稳定时间 TVRINT (参阅” TVRINT”,章节 16.7) 和 TST时间的较长者,即 max(TVRINT,TST)。

​ 软件触发(ADEX = 0),GO/DONE 由指令置位后立即启动 A/D 转换。如果由 PA4/PB2 或 PWM 触发,则有一定的延迟时间。在使能 LEB 前,需先设置 ADEX 和 ADON 寄存器。如果 LEBEN=1,则将忽略 ETGSEL,触发源即为 LEB 的触发源。此时由 LEB 定时器溢出触发 ADC自动转换。

2.1.1 软件触发

    ANSELA=0B00000001;            //控制IO的数模输入,1:对应的IO为模拟管脚,0:对应的IO为数字IO,设置AN0为模拟管脚
    ADCON0=0B00000000;
    //Bit[6:4]:000-选择模拟通道AN0
    //Bit2:当软件设定GO/DONE位时启动AD转换(即不用外部触发源)

    ADCON1=0B11100100;
    //Bit7:    1-ADC转换结果右对齐,即装入转换结果时,ADRESH的高4位被设置为0
    //Bit[6:4]:110-ADC转换时钟设置为Fosc/64
    //Bit[3:2]:01-负参考电压-GND
    //Bit[1:0]:00-正参考电压-内部参考电压

    ADCON2=0B01000000;
    //Bit[7:6]:01-ADC内部参考电压2V

    ADCON3=0B00000000;
    ADDLY=0B00000000;            //外部触发延时
    ADCMPH=0B00000000;            //ADC比较阈值,用于ADC结果高8位比较
    ADON=1;                        //使能ADC

    DelayUs(200);  //打开ADC模块后,需等待ADC稳定时间Tst(~15us);当选择内部参考电压时需等待内部参考电压的稳定时间Tvrint(~450us)
    DelayUs(200);     
    DelayUs(50);     

2.1.2 PA4/PB3-ADC_ETR触发

    ANSELA=0B00000001;          //控制IO的数模输入,1:对应的IO为模拟管脚,0:对应的IO为数字IO,设置AN0为模拟管脚
    ADCON0=0B00000100;
    //Bit[6:4]:000-选择模拟通道AN0
    //Bit2:1-当外部触发源触发时启动AD转换

    ADCON1=0B11100100;
    //Bit7: 1-ADC转换结果右对齐,即装入转换结果时,ADRESH的高4位被设置为0
    //Bit[6:4]:110-ADC转换时钟设置为Fosc/64
    //Bit[3:2]:01-负参考电压-GND
    //Bit[1:0]:00-正参考电压-内部参考电压

    ADCON2=0B01010111;
    //Bit[7:6]:01-ADC内部参考电压2V
    //Bit[5:4]:01-上升沿触发
    //Bit[3]:00-LEB计数器第8位
    //Bit[2:0]:111-触发源选ADC_ETR

    ADCON3=0B00000000;
    //Bit[3]:0-禁止LEB结束时触发ADC转换
    LEBCON = 0B00000000;
    //Bit[7]:0-禁止LEB
    //Bit[6:5]:00-LEB信号源,TIM1_CH1
    //Bit[3]:0-上升沿触发LEB

    ADDLY=0B00000000;           //外部触发延时
    ADCMPH=0B00000000;          //ADC比较阈值,用于ADC结果高8位比较
    ADON=1;                     //使能ADC

    DelayUs(200);  //打开ADC模块后,需等待ADC稳定时间Tst(~15us);当选择内部参考电压时需等待内部参考电压的稳定时间Tvrint(~450us)
    DelayUs(200);   
    DelayUs(50); 

2.1.3 定时器触发

    ANSELA=0B00000001;          //控制IO的数模输入,1:对应的IO为模拟管脚,0:对应的IO为数字IO,设置AN0为模拟管脚
    ADCON0=0B00000100;
    //Bit[6:4]:000-选择模拟通道AN0
    //Bit2:1-当外部触发源触发时启动AD转换

    ADCON1=0B11100100;
    //Bit7: 1-ADC转换结果右对齐,即装入转换结果时,ADRESH的高4位被设置为0
    //Bit[6:4]:110-ADC转换时钟设置为Fosc/64
    //Bit[3:2]:01-负参考电压-GND
    //Bit[1:0]:00-正参考电压-内部参考电压

    ADCON2= 0B01000000;//0B01010000;
    //Bit[7:6]:01-ADC内部参考电压2V
    //Bit[5:4]:01-上升沿触发
    //Bit[3]:00-LEB计数器第8位
    //Bit[2:0]:000-触发源选TIM1_CH1

    ADCON3=0B00001000;
    //Bit[3]:1 LEB结束时触发ADC转换
    LEBCON = 0B10000000;
    //Bit[7]:0-使能LEB
    //Bit[6:5]:00-LEB信号源,TIM1_CH1
    //Bit[3]:0-上升沿触发LEB

    ADDLY=0B00000000;           //外部触发延时
    ADCMPH=0B00000000;          //ADC比较阈值,用于ADC结果高8位比较
    ADON=1;                     //使能ADC

    DelayUs(200);  //打开ADC模块后,需等待ADC稳定时间Tst(~15us);当选择内部参考电压时需等待内部参考电压的稳定时间Tvrint(~450us)
    DelayUs(200);   
    DelayUs(50);    
    TCKSRC = 0B00000000;  //系统时钟
    PCKEN |= 0B00000010;  //打开TIMER1时钟
    TIM1CR1 = 0B00000000; //向上计数
    TIM1CR2 = 0B00000000;
    TIM1SMCR = 0B00000000;
    TIM1ETR = 0B00000000;
    TIM1IER = 0B00000000;
    TIM1CCMR1 = 0B01100000; //PWM1模式
    TIM1CCER1 = 0B00000001; //OC1输出到相应引脚,高电平有效
    TIM1CNTRL = 0;
    TIM1CNTRH = 0;
    TIM1PSCRL = 31; //预分频L
    TIM1PSCRH = 0; //预分频H
    TIM1ARRL = 255;
    TIM1ARRH = 0;  //周期寄存器
    TIM1CCR1L = 128;
    TIM1CCR1H = 0; //占空比寄存器
    TIM1CR1 |= 0B00000001;//使能计数器
    TIM1EGR = 0B00000001; //产生更新事件 

    TIM1BKR = 0B10000000;//pwm输出使能

2.2 读取通道ADC值

uint GET_ADC_DATA(uchar adcChannel)
{
    ADCON0&=0B00001111;
    ADCON0|=adcChannel<<4;
    DelayUs(2);                     //TACQ延时2us,外部串联电阻小于21kΩ
                                   //TACQ延时4us,外部串联电阻43kΩ
    //TACQ时间:必做,通道切换到GO/DONE置1的时间,保证内部 ADC 输入电容充满。
    //TACQ > 0.09*(R+1)us;R为外部串联电阻(kΩ),串联电阻越小越好,最大不要超过50kΩ
    // ADCIF = 1;
    GO = 1; //软件读取时,GO置1,芯片立即读取;外部触发(PA4/PB3-ADC_ETR 或 PWM)时只能依靠ADCIF标志位判断,这里换成ADCIF置1清零
    NOP();                         //采样保持时间0~1TAD
    NOP();
    //DelayUs(12);                   //采样保持时间(ADDLY +6) *TAD
    // while(ADCIF == 0);    //ADC 转换完成标志位
    while(GO);
    //从GO = 1 ---> 从GO = 0,转换过程需要16TAD
    //TAD(us)与转换时钟Fosc/ADCS[2:0]有关
    return (uint)(ADRESH<<8|ADRESL);
}

3. 示例代码

​ ADC配置为软件触发模式,正参考电压源为内部基准电压(VADC_REF 2V),以确保稳定的采样基准。系统通过轮询方式监测按键输入状态,每次检测到按键被有效按下时,触发 ADC 启动转换流程。转换完成后,读取 ADC 结果并进行串口输出显示。

void main(void){
    DelayMs(10);
    sysInit();
    gpioInit();
    adcInit();
    usartInit(); 
    DelayMs(100);
    while (1) {
        uint32_t milliVolt = 0;
        uint16_t adcValuex = 0;
        if (DemoPortIn == 0) {  // 检测按键按下
            DelayMs(10);        // 消抖处理
            if (DemoPortIn == 0) {
                // 等待按键释放
                while (DemoPortIn == 0);
                milliVolt=(uint32_t)adcValuex*2000/4096;
                DemoPortOut = ~DemoPortOut;
            }   
            uint8_t Str[50] = {0};
            sprintf(Str,"当前引脚电压为%d mV\r\n",milliVolt);
            UART_SendString(Str);
        }
        DelayMs(50);  // 稍作延时避免过度轮询
    }
}
uint16_t GET_ADC_DATA(uint8_t adcChannel){
    ADCON0&=0B00001111;
    ADCON0|=adcChannel<<4;
    DelayUs(4);                     //TACQ延时2us,外部串联电阻小于21kΩ
    GO = 1; 
    NOP();                         
    NOP();
    while(GO);
    return (uint16_t)(ADRESH<<8|ADRESL);
}
void adcInit(void){
    ANSELA=0B00011000;            //控制IO的数模输入,1:对应的IO为模拟管脚,0:对应的IO为数字IO,设置AN0为模拟管脚
    ADCON0=0B00000000;
    //Bit2:当软件设定GO/DONE位时启动AD转换(即不用外部触发源)

    ADCON1=0B11100100;
    //Bit7:    1-ADC转换结果右对齐,即装入转换结果时,ADRESH的高4位被设置为0
    //Bit[6:4]:110-ADC转换时钟设置为Fosc/64
    //Bit[3:2]:01-负参考电压-GND
    //Bit[1:0]:01-正参考电压-内部 VADC-REF

    ADCON2=0B01000000;

    ADCON3=0B00000000;
    ADDLY=0B00000000;            //外部触发延时
    ADCMPH=0B00000000;            //ADC比较阈值,用于ADC结果高8位比较
    ADON=1;                        //使能ADC

    DelayUs(200);  //打开ADC模块后,需等待ADC稳定时间Tst(~15us);当选择内部参考电压时需等待内部参考电压的稳定时间Tvrint(~450us)
    DelayUs(200);     
    DelayUs(50);     
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇