[PIC®/AVR®/dsPIC®产品] PIC16F1933单片机AD4通道采样问题

[复制链接]
 楼主| 郑朝清 发表于 2025-3-21 20:47 | 显示全部楼层 |阅读模式
使用PIC16F1933单片机编写4通道AD转换程序。通道编号AN0,AN1,AN3,AN4。单片机FOSC位32MHZ。由于单片机的转换结果寄存器只有ADRESH和ADRESL,转换结果会被其他的通道覆盖。如何在程序中做到AD转换结果相互隔离。有啥好方**搞了好几天了。大家帮忙看看。使用以下的代码只能做到AN0,AN1不影响,AN3,AN4还是不行。
  1. /*-------- 多通道ADC采样函数 --------*/
  2. void ADC_ScanChannels(void) {
  3.     for(unsigned char i=0; i<ADC_CHANNELS; i++) {
  4.         // 切换ADC通道
  5.         ADCON0bits.CHS = adc_channels[i]; // 选择当前通道
  6.         __delay_us(5);  // 等待通道切换稳定(至少2.4us@32MHz)
  7.         
  8.         // 启动转换并等待完成
  9.         ADCON0bits.GO = 1;      // 启动AD转换
  10.         while(ADCON0bits.GO);   // 等待转换完成
  11.         
  12.         // 读取并存储结果(右对齐处理)
  13.         adc_results[i] = ((ADRESH << 8) | ADRESL);
  14.         
  15.         // 清除旧结果寄存器
  16.         ADRESH = 0x00;
  17.         ADRESL = 0x00;
  18.     }
  19. }

弓长月月鸟 发表于 2025-3-21 21:36 | 显示全部楼层
每次只采集一路AD ,采集下一路时,将之前采集的通道关闭即可
xionghaoyun 发表于 2025-3-22 13:46 | 显示全部楼层
使能一路关闭一路
t60yz 发表于 2025-3-24 14:52 | 显示全部楼层
增加延迟(比如 10-20µs)或者添加一次空转换(丢弃首次转换结果)。

t60yz 发表于 2025-3-24 14:54 | 显示全部楼层
确认AN3和AN4是否正确配置为模拟输入
lcczg 发表于 2025-3-24 15:46 | 显示全部楼层
什么叫AN3,AN4还是不行,具体点讲讲。
21mengnan 发表于 2025-3-24 16:21 | 显示全部楼层
这个应该可以在MCC配置的,你看看是不是哪儿没弄对。初始化配置对了吗
 楼主| 郑朝清 发表于 2025-3-24 20:16 | 显示全部楼层
lcczg 发表于 2025-3-24 15:46
什么叫AN3,AN4还是不行,具体点讲讲。

已解决。用微芯的AI助手。
  1. void ADC_Init(void)
  2. {
  3.    TRISAbits.TRISA0 = 1;//RA0配置为输入
  4.    ANSELAbits.ANSA0 = 1;//RA0配置为模拟量输入
  5.    TRISAbits.TRISA1 = 1;//RA1配置为输入
  6.    ANSELAbits.ANSA1 = 1;//RA1配置为模拟量输入
  7.    TRISAbits.TRISA3= 1;//RA3配置为输入
  8.    ANSELAbits.ANSA3 = 1;//RA3配置为模拟量输入
  9.    TRISAbits.TRISA5 = 1;//RA5配置为输入AN4
  10.    ANSELAbits.ANSA5 = 1;//RA5配置为模拟量输入AN4
  11.    ADCON0bits.CHS = 0;//AN0通道
  12.    ADCON1bits.ADFM = 1;//1 = 右对齐。装入转换结果时,ADRESH的高6位被设置为0
  13.    ADCON1bits.ADCS = 0b110;//A/D 转换时钟选择位000 = FOSC/64
  14.    ADCON1bits.ADNREF = 0;//A/D负参考电压配置位0 = VREF- 与 VSS 连接
  15.    ADCON1bits.ADPREF = 0b00;//A/D 正参考电压配置位00 =VREF+ 与VDD连接
  16.    ADCON0bits.ADON = 1;//使能ADC
  17. }

  18. // 选择AD通道
  19. void ADC_SelectChannel(unsigned char channel) {
  20.     ADCON0bits.CHS = channel; // 选择通道
  21.     __delay_us(2);            // 稳定时间
  22. }

  23. // 开始AD转换并读取结果
  24. unsigned int ADC_Read(void) {
  25.     ADCON0bits.GO_nDONE = 1; // 开始转换
  26.     while (ADCON0bits.GO_nDONE); // 等待转换完成
  27.     return (ADRESH << 8) | ADRESL; // 读取结果
  28. }
 楼主| 郑朝清 发表于 2025-3-24 20:17 | 显示全部楼层
t60yz 发表于 2025-3-24 14:54
确认AN3和AN4是否正确配置为模拟输入
  1. void ADC_Init(void)
  2. {
  3.    TRISAbits.TRISA0 = 1;//RA0配置为输入
  4.    ANSELAbits.ANSA0 = 1;//RA0配置为模拟量输入
  5.    TRISAbits.TRISA1 = 1;//RA1配置为输入
  6.    ANSELAbits.ANSA1 = 1;//RA1配置为模拟量输入
  7.    TRISAbits.TRISA3= 1;//RA3配置为输入
  8.    ANSELAbits.ANSA3 = 1;//RA3配置为模拟量输入
  9.    TRISAbits.TRISA5 = 1;//RA5配置为输入AN4
  10.    ANSELAbits.ANSA5 = 1;//RA5配置为模拟量输入AN4
  11.    ADCON0bits.CHS = 0;//AN0通道
  12.    ADCON1bits.ADFM = 1;//1 = 右对齐。装入转换结果时,ADRESH的高6位被设置为0
  13.    ADCON1bits.ADCS = 0b110;//A/D 转换时钟选择位000 = FOSC/64
  14.    ADCON1bits.ADNREF = 0;//A/D负参考电压配置位0 = VREF- 与 VSS 连接
  15.    ADCON1bits.ADPREF = 0b00;//A/D 正参考电压配置位00 =VREF+ 与VDD连接
  16.    ADCON0bits.ADON = 1;//使能ADC
  17. }
g36xcv 发表于 2025-3-27 17:01 | 显示全部楼层
在使用 PIC16F1933 单片机进行 4通道 AD 转换 时,由于 ADRESH 和 ADRESL 只能保存一个通道的转换结果,并且在转换过程中新的转换结果会覆盖之前的结果,因此需要一些技巧来确保每个通道的转换结果能够相互隔离。
dongnanxibei 发表于 2025-3-27 19:52 | 显示全部楼层
微芯的AI助手是什么,求分享
旧时光放映机 发表于 2025-3-27 20:40 | 显示全部楼层
如果采集的信号有噪声,如何通过程序来降低噪声的影响呢
星辰伴梦 发表于 2025-3-27 21:45 | 显示全部楼层
在进行AD转换时,如果通道切换过快,会不会导致结果不准确呢
治愈糖果屋 发表于 2025-3-28 14:23 | 显示全部楼层
添加空转换听起来有点复杂
暖心小太阳 发表于 2025-3-28 15:42 | 显示全部楼层
增加延迟确实是一种方法,那延迟时间需要根据什么来确定呢
暖茶轻语 发表于 2025-3-28 17:12 | 显示全部楼层
选择AD通道的函数中,稳定时间设置为2微秒,这个时间是固定的吗
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

87

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部