找回密码
 立即注册
查看: 173|回复: 11

通过SPI发出两路ADC数据,通过FPGA读到的数据不对,请问为什么

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:2
  • 最近打卡:2025-05-29 10:34:58
已绑定手机

1

主题

6

回帖

23

积分

新手上路

积分
23
发表于 2025-5-28 18:36:38 | 显示全部楼层 |阅读模式
源码:


/*------------------------------------------------------------------*/
/* --- STC MCU International Limited -------------------------------*/
/* --- STC 8H1K08 QFN20 ADC & SPI Demo (简化版) --------------------*/
/*------------------------------------------------------------------*/

#define MAIN_Fosc        11059200L    // 定义主时钟 11.0592MHz

#include    "STC8Gxxx.h"
#include "intrins.h"

/*************    宏定义    **************/
#define FILTER_LENGTH    16      // 滤波器长度
#define SEND_INTERVAL    100     // 发送间隔(ms)
#define ADC_CLK_DIV      5       // ADC时钟分频(Fosc/2/6=921.6kHz)

/*************    变量声明    **************/
u16 ADC_Raw[2][FILTER_LENGTH] = {0}; // 初始化ADC数据存储
u16 ADC_Filtered[2] = {0};           // 滤波后的ADC值
u8 filter_index = 0;                 // 滤波器索引
bit current_channel = 0;             // 当前采样通道标志 0:P3.5, 1:P3.6

/*************    函数声明    **************/
void System_Init(void);
u16 Get_ADC10bitResult(u8 channel);
void SPI_SendData(u16 dat);
void ADC_Filter_Process(void);
void delay_us(u16 us);
void delay_ms(u16 ms);

/**********************************************/
void main(void)
{
    u16 send_counter = 0;
    System_Init();
   
    while(1)
    {
        // 交替采样两个通道
        if(current_channel == 0)
        {
            ADC_Raw[0][filter_index] = Get_ADC10bitResult(13);  // P3.5
            current_channel = 1;
        }
        else
        {
            ADC_Raw[1][filter_index] = Get_ADC10bitResult(14);  // P3.6
            current_channel = 0;
            filter_index = (filter_index + 1) % FILTER_LENGTH;
        }
        
        // 定时发送数据
        if(++send_counter >= SEND_INTERVAL)
        {
            send_counter = 0;
            ADC_Filter_Process();
            
            // 仅发送两路ADC数据
            SPI_SendData(ADC_Filtered[0]);  // 通道1数据
            SPI_SendData(ADC_Filtered[1]);  // 通道2数据
        }
        
        delay_us(100);  // 控制采样间隔
    }
}

/***********************************
系统初始化(完整配置)
***********************************/
void System_Init(void)
{
    // === 1. 初始化SPI ===
    P1M1 &= ~0x3C;  // P1.2~P1.5设为推挽输出
    P1M0 |= 0x3C;
    P12 = 1;        // SS默认高电平
    SPCTL = 0xF0;   // SPEN=1, MSTR=1, CPOL=CPHA=0
    SPSTAT = 0xC0;  // 清除标志
   
    // === 2. 初始化ADC ===
    P3M0 &= ~0x60;  // P3.5/P3.6设为高阻输入
    P3M1 |= 0x60;
    ADC_CONTR = 0x80; // 开启ADC电源
    ADCCFG = (1<<5) | ADC_CLK_DIV; // 右对齐, Fosc/2/(n+1)
   
    // 配置采样时间(STC8H特有)
    P_SW2 |= 0x80;
    ADCTIM = 0x3F;  // 最长采样时间(保证精度)
    P_SW2 &= ~0x80;
   
    delay_ms(10);    // 稳定延时
}

/***********************************
获取10位ADC结果
***********************************/
u16 Get_ADC10bitResult(u8 channel)
{
    ADC_RES = 0;
    ADC_RESL = 0;
    ADC_CONTR = 0x80 | (1<<6) | channel;
    _nop_(); _nop_(); _nop_(); _nop_(); // 小延时
    while(!(ADC_CONTR & 0x20)); // 等待完成
    ADC_CONTR &= ~0x20;
    return (ADC_RES << 8) | ADC_RESL;
}

/***********************************
ADC移动平均滤波
***********************************/
void ADC_Filter_Process(void)
{
    u32 sum0 = 0, sum1 = 0;
    u8 i;
   
    for(i=0; i<FILTER_LENGTH; i++)
    {
        sum0 += ADC_Raw[0][i];
        sum1 += ADC_Raw[1][i];
    }
   
    ADC_Filtered[0] = sum0 / FILTER_LENGTH;
    ADC_Filtered[1] = sum1 / FILTER_LENGTH;
}

/***********************************
SPI发送函数(简化版)
***********************************/
void SPI_SendData(u16 dat)
{
    P12 = 0;              // 拉低片选
    SPDAT = dat >> 8;     // 发送高字节
    while(!(SPSTAT & 0x80));
    SPSTAT = 0xC0;
   
    SPDAT = (u8)dat;      // 发送低字节
    while(!(SPSTAT & 0x80));
    SPSTAT = 0xC0;
    P12 = 1;              // 释放片选
    delay_us(10);         // 从机处理时间
}

/***********************************
延时函数
***********************************/
void delay_us(u16 us)
{
    while(us--) _nop_(), _nop_(), _nop_(), _nop_();
}

void delay_ms(u16 ms)
{
    while(ms--) delay_us(1000);
}


回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:2
  • 最近打卡:2025-05-29 10:34:58
已绑定手机

1

主题

6

回帖

23

积分

新手上路

积分
23
发表于 2025-5-28 18:37:22 | 显示全部楼层
原理图:
截图202505281837199148.jpg
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:2
  • 最近打卡:2025-05-29 10:34:58
已绑定手机

1

主题

6

回帖

23

积分

新手上路

积分
23
发表于 2025-5-28 18:39:59 | 显示全部楼层
输出的数据是右对齐,读到的电压值E0,实际VIN_EXT_AD值是0.8V左右
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:2
  • 最近打卡:2025-05-29 10:34:58
已绑定手机

1

主题

6

回帖

23

积分

新手上路

积分
23
发表于 2025-5-28 18:41:27 | 显示全部楼层
用之前梁博发的STC8G的源码,接收的值如图,并且输入的ADC值,取到的数也不会变
截图202505281841226834.jpg

点评

可以用万用表量一下实际的引脚电压 按道理讲用例程读不到,就可以排除软件问题了。 不过需要注意的是,你这个芯片是8H,应该用8H系列的测试例程来测试  详情 回复 发表于 2025-5-29 07:21
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:468
  • 最近打卡:2025-06-16 07:06:57
已绑定手机

79

主题

5131

回帖

9138

积分

超级版主

DebugLab

积分
9138
发表于 2025-5-28 20:15:12 | 显示全部楼层
8H系列IO上电高阻
注意ADC和SPI的IO模式
ADC IO要设置为高阻
SPI(主机),MOSI推挽,SCLK推挽
先用逻辑分析仪或示波器测量SPI(主机)的MOSI(推挽),输出固定值(如0x5A),信号正常后再使用SPI调试ADC
也可以使用串口调试ADC,使用printf串口助手显示
更多内容请阅读新手必读
https://www.stcaimcu.com/thread-16535-1-1.html
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:499
  • 最近打卡:2025-06-16 10:06:31
已绑定手机
已实名认证

112

主题

2390

回帖

6014

积分

版主

积分
6014
发表于 2025-5-29 07:21:20 | 显示全部楼层
jpkn*** 发表于 2025-5-28 18:41
用之前梁博发的STC8G的源码,接收的值如图,并且输入的ADC值,取到的数也不会变 ...

可以用万用表量一下实际的引脚电压
按道理讲用例程读不到,就可以排除软件问题了。
不过需要注意的是,你这个芯片是8H,应该用8H系列的测试例程来测试
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:342
  • 最近打卡:2025-06-16 08:01:58
已绑定手机

4

主题

397

回帖

1891

积分

金牌会员

积分
1891
发表于 2025-5-29 08:09:00 | 显示全部楼层
你用的是8H还是8G,它俩ADC有些不太一样
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:2
  • 最近打卡:2025-05-29 10:34:58
已绑定手机

1

主题

6

回帖

23

积分

新手上路

积分
23
发表于 2025-5-29 10:34:58 | 显示全部楼层
Debu*** 发表于 2025-5-28 20:15
8H系列IO上电高阻
注意ADC和SPI的IO模式
ADC IO要设置为高阻

输出固定0X5A是没问题的,所以感觉是ADC取数上有问题,但是没找到问题在哪
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:2
  • 最近打卡:2025-05-29 10:34:58
已绑定手机

1

主题

6

回帖

23

积分

新手上路

积分
23
发表于 2025-5-29 10:36:19 | 显示全部楼层
haiya*** 发表于 2025-5-29 08:09
你用的是8H还是8G,它俩ADC有些不太一样

你好,我硬件用的8H,能帮忙指出有哪些区别啊,我固定输出0x5A是没问题的,但是输出的ADC值不太对,所以感觉是ADC的取数有问题
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:208
  • 最近打卡:2025-06-16 08:41:37
已绑定手机

67

主题

1913

回帖

4297

积分

荣誉版主

无情的代码机器

积分
4297
发表于 2025-5-29 11:20:11 | 显示全部楼层
试下用8H实验箱例程“52-16路ADC转换-取平均值-软件防抖-串口2输出结果”能串口正常输出吗
https://www.stcaimcu.com/data/do ... -DEMO-CODE-V9.6.zip
三天不学习,赶不上刘少奇~
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-6-16 13:03 , Processed in 0.190348 second(s), 105 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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