找回密码
 立即注册
楼主: jpknecoq

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

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

4

主题

397

回帖

1891

积分

金牌会员

积分
1891
发表于 2025-5-29 13:39:44 | 显示全部楼层
jpkn*** 发表于 2025-5-29 10:36
你好,我硬件用的8H,能帮忙指出有哪些区别啊,我固定输出0x5A是没问题的,但是输出的ADC值不太对,所以 ...

8h多是12位的,8g是10位的,第一采集的丢掉不要
截图202505291349486026.jpg
回复 支持 反对

使用道具 举报 送花

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

1

主题

6

回帖

23

积分

新手上路

积分
23
发表于 2025-5-29 14:45:59 | 显示全部楼层
已经调通了,STC8H只作为主机通过SPI发出P3.5和P3.6的ADC数据,数据里加了一些包头,源码:


/*------------------------------------------------------------------*/
/* --- STC MCU ADC + SPI with 16-bit Combined Data Format -----------*/
/*------------------------------------------------------------------*/

#define MAIN_Fosc        11059200L
#define FILTER_LENGTH    16
#define SEND_INTERVAL    100

#include "STC8Gxxx.h"   //头文件见附件
#include "intrins.h"

/************* 协议定义 **************/
#define HEADER_A0    0x00A0
#define HEADER_A1    0x00A1
#define HEADER_A2    0x00A2
#define SYNC_WORD    0xAAAA

/************* 硬件配置 **************/
#define ADC_START    (1<<6)
#define ADC_FLAG     (1<<5)
#define ADC_CLK_DIV  5

/************* 全局变量 **************/
u16 ADC_Raw[2][FILTER_LENGTH] = {0};
u16 ADC_Filtered[2] = {0};
u8 filter_index = 0;
bit current_channel = 0;

/************* 函数声明 **************/
void System_Init(void);
u16 Get_ADC10bitResult(u8 channel);
void SPI_SendData(u16 dat);
void ADC_Filter_Process(void);
void Send_CompleteFrame(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);
            current_channel = 1;
        }
        else
        {
            ADC_Raw[1][filter_index] = Get_ADC10bitResult(14);
            current_channel = 0;
            filter_index = (filter_index + 1) % FILTER_LENGTH;
        }
        
        if(++send_counter >= SEND_INTERVAL)
        {
            send_counter = 0;
            ADC_Filter_Process();
            Send_CompleteFrame();
        }
        
        delay_us(100);
    }
}

/************* 延时函数实现 **************/
void delay_us(u16 us)
{
    while(us--)
    {
        _nop_(); _nop_(); _nop_(); _nop_();
        _nop_(); _nop_(); _nop_(); _nop_();
        /*
         * 对于11.0592MHz时钟:
         * 每个_nop_()执行1个机器周期(12个时钟周期)
         * 8个_nop_() ≈ 8*(12/11.0592) ≈ 8.68us
         * 实际使用时需要根据实测调整循环次数
         */
    }
}

void delay_ms(u16 ms)
{
    while(ms--)
    {
        delay_us(1000); // 近似1ms延时
    }
}

/************* 16位组合数据帧发送 (修正版)**************/
void Send_CompleteFrame(void)
{
    // 帧起始
    SPI_SendData(HEADER_A0);
    SPI_SendData(SYNC_WORD);
    SPI_SendData(SYNC_WORD + HEADER_A0);
   
    // 通道1数据(修正A1校验和)
    SPI_SendData(HEADER_A1);                    // 发送Header A1
    SPI_SendData(ADC_Filtered[0]);              // 发送通道1数据
    SPI_SendData(HEADER_A1 + ADC_Filtered[0]);  // 关键修改: 使用HEADER_A1计算校验和
   
    // 通道2数据
    SPI_SendData(HEADER_A2);
    SPI_SendData(ADC_Filtered[1]);
    SPI_SendData(HEADER_A2 + ADC_Filtered[1]);
   
    delay_us(50); // 帧间延时
}

/************* 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 System_Init(void)
{
    // SPI初始化
    P1M1 &= ~0x3C;
    P1M0 |= 0x3C;
    P12 = 1;
    SPCTL = 0xF0;
    SPSTAT = 0xC0;
   
    // ADC初始化
    P3M0 &= ~0x60;
    P3M1 |= 0x60;
    ADC_CONTR = 0x80;
    ADCCFG = (1<<5) | ADC_CLK_DIV;
    P_SW2 |= 0x80;
    ADCTIM = 0x3F;
    P_SW2 &= ~0x80;
    delay_ms(10);           // 等待ADC稳定
}

/************* ADC采样函数 **************/
u16 Get_ADC10bitResult(u8 channel)
{
    ADC_RES = 0;
    ADC_RESL = 0;
    ADC_CONTR = 0x80 | ADC_START | channel;
    _nop_(); _nop_(); _nop_(); _nop_();
    while(!(ADC_CONTR & ADC_FLAG));
    ADC_CONTR &= ~ADC_FLAG;
    return ((u16)ADC_RES << 8) | ADC_RESL;
}

/************* 数据滤波处理 **************/
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;
}

STC8Gxxx.h

107.26 KB, 下载次数: 1

回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-6-16 16:18 , Processed in 1.981684 second(s), 57 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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