- 打卡等级:初来乍到
- 打卡总天数:2
- 最近打卡:2025-05-29 10:34:58
已绑定手机
新手上路
- 积分
- 23
|
源码:
/*------------------------------------------------------------------*/
/* --- 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);
}
|
|