脑部活动的时候,会有微弱的电波产生,将这些生物电采集下来,可以用于脑部活动分析。目前已知δ(1-3Hz)、θ(4-7Hz)、α(8-13Hz)、β(14-30Hz)四种波形段的活动。不同的波段代表不同的活动
δ波:频率为1~3Hz,幅度为20~200μV。当人在婴儿期或智力发育不成熟、成年人在极度疲劳和昏睡或麻醉状态下,可在颞叶和顶叶记录到这种波段。
θ波:频率为4~7Hz,幅度为5~20μV。在成年人意愿受挫或者抑郁以及精神病患者中这种波极为显著。但此波为少年(10-17岁)的脑电图中的主要成分。
α波:频率为8~13Hz(平均数为10Hz),幅度为20~100μV。它是正常人脑电波的基本节律,如果没有外加的刺激,其频率是相当恒定的。人在清醒、安静并闭眼时该节律最为明显,睁开眼睛(受到光刺激)或接受其它刺激时,α波即刻消失。
β波:频率为14~30Hz,幅度为100~150μV。当精神紧张和情绪激动或亢奋时出现此波,当人从噩梦中惊醒时,原来的慢波节律可立即被该节律所替代。
此工程主要是基于Funpack11期的NXP LPC55S69开发板作为主控,通过SPI采集32Bit的ADC AD7177芯片的数据,将数据计算之后,通过USB FS模拟的串口,将数据发给上位机
如下是原理图:
实物图:
程序里,ADC配置两通道,100Hz连续采样模式,代码:
void EEG_AD7175_Setup(void)
{
ad717x_st_reg *ReadReg;
AD717X_Init(&EEG_AD7177,EEG_ad7175_2_regs,27);
/**************** ADC MODE *****************/
ReadReg=AD717X_GetReg(EEG_AD7177,AD717X_ADCMODE_REG);
ReadReg->value=AD717X_ADCMODE_REG_REF_EN | AD717X_ADCMODE_REG_MODE(0) | AD717X_ADCMODE_REG_CLKSEL(3);
AD717X_WriteRegister(EEG_AD7177,AD717X_ADCMODE_REG);
/**************Interface MODE******************/
ReadReg=AD717X_GetReg(EEG_AD7177,AD717X_IFMODE_REG);
ReadReg->value=AD717X_IFMODE_REG_DATA_WL32;
AD717X_WriteRegister(EEG_AD7177,AD717X_IFMODE_REG);
/**************** CH 0 *****************/
/********AD717X_Channel0_REG*********/ //
ReadReg=AD717X_GetReg(EEG_AD7177,AD717X_CHMAP0_REG);//Setup 0;AIN0 +;AIN1 -
ReadReg->value=AD717X_CHMAP_REG_CH_EN | AD717X_CHMAP_REG_SETUP_SEL(0) | AD717X_CHMAP_REG_AINPOS(0) | AD717X_CHMAP_REG_AINNEG(1);
AD717X_WriteRegister(EEG_AD7177,AD717X_CHMAP0_REG);
/********AD717X_SETUPCON0_REG*********/ //disable buff;ext Vref;
ReadReg=AD717X_GetReg(EEG_AD7177,AD717X_SETUPCON0_REG);
ReadReg->value=AD717X_SETUP_CONF_REG_BI_UNIPOLAR | AD717X_SETUP_CONF_REG_AIN_BUF(3) | AD717X_SETUP_CONF_REG_REF_SEL(0);
AD717X_WriteRegister(EEG_AD7177,AD717X_SETUPCON0_REG);
/**********AD717X_FILTCON0_REG**********/ //Sinc1+5;
ReadReg=AD717X_GetReg(EEG_AD7177,AD717X_FILTCON0_REG);
// ReadReg->value=AD717X_FILT_CONF_REG_ENHFILTEN | AD717X_FILT_CONF_REG_ENHFILT(5) | AD717X_FILT_CONF_REG_ODR(0x0a);//1000 SPS;
ReadReg->value=AD717X_FILT_CONF_REG_ODR(0x0e);//100 SPS
AD717X_WriteRegister(EEG_AD7177,AD717X_FILTCON0_REG);
/**************** CH 1 *****************/
/********AD717X_Channel1_REG*********/ //
ReadReg=AD717X_GetReg(EEG_AD7177,AD717X_CHMAP1_REG);//Setup 1;AIN2 +;AIN3 -
ReadReg->value=AD717X_CHMAP_REG_CH_EN | AD717X_CHMAP_REG_SETUP_SEL(0) | AD717X_CHMAP_REG_AINPOS(2) | AD717X_CHMAP_REG_AINNEG(3);
AD717X_WriteRegister(EEG_AD7177,AD717X_CHMAP1_REG);
}
ADC采集的时候,不停的查询ADC转换是否完成,如果是,就判断是那个通道的数据,再将数据寄存器里的值通过SPI读取出来,并计算为浮点数
代码如下:
void AD7177_Voltage_Cal(int32_t *input,float *output)
{
uint32_t *p;
p=input;
if(*p<0x80000000)
{
*output=(float)(*p)/2147483648*EEG_AD7177_Reference*1000/969.627;
}
else
{
*output=-(float)(*p-0x80000000)/2147483648*EEG_AD7177_Reference*1000/969.627;
}
}
uint8_t AD7177_ReadNewDataStatus(void)
{
ad717x_st_reg *adc_status;
AD717X_ReadRegister(EEG_AD7177,AD717X_STATUS_REG);
adc_status=AD717X_GetReg(EEG_AD7177,AD717X_STATUS_REG);
if((adc_status->value & AD717X_STATUS_REG_RDY)==0x00)
{
if((adc_status->value & AD717X_STATUS_REG_CH(1))==AD717X_STATUS_REG_CH(1))
{
return 2;
}
else if((adc_status->value & AD717X_STATUS_REG_CH(2))==AD717X_STATUS_REG_CH(2))
{
return 3;
}
else if((adc_status->value & AD717X_STATUS_REG_CH(3))==AD717X_STATUS_REG_CH(3))
{
return 4;
}
else
{
return 1;
}
}
else
{
return 0;
}
}
void AD7177_Voltage_Read_Single(float *volt)
{
int32_t data;
AD717X_ReadData(EEG_AD7177,&data);
AD7177_Voltage_Cal(&data,volt);
}
int main(void) {
/* Init board hardware. */
uint8_t Hello_World_CDC[]="Hello World,CDC\r\n";
// uint32_t AD7177_ID;
uint8_t ch;
float volt;
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitBootPeripherals();
#ifndef BOARD_INIT_DEBUG_CONSOLE_PERIPHERAL
/* Init FSL debug console. */
BOARD_InitDebugConsole();
#endif
if (SysTick_Config(SystemCoreClock / 1000U))
{
while (1)
{
}
}
EEG_AD7175_Setup();
PRINTF("Hello World\r\n");
MessageSend("%s",Hello_World_CDC);
/* Force the counter to be placed into memory. */
volatile static int i = 0 ;
/* Enter an infinite loop, just incrementing a counter. */
while(1) {
i++ ;
GPIO_PortToggle(BOARD_INITLEDSPINS_LED_BULE_GPIO, BOARD_INITLEDSPINS_LED_BULE_PORT, 1<<BOARD_INITLEDSPINS_LED_BULE_PIN);
/* 'Dummy' NOP to allow source level single stepping of
tight while() loop */
__asm volatile ("nop");
//USB_DeviceInterface0CicVcomTask();
ch=AD7177_ReadNewDataStatus();
if(ch==1)
{
AD7177_Voltage_Read_Single(&volt);
//MessageSend("Voltage(uV):%f,",volt);
MessageSend("%f,",volt);
// PRINTF("%FmV\r\n",volt);
}
if(ch==2)
{
AD7177_Voltage_Read_Single(&volt);
MessageSend("%f\n",ch,volt);
}
/*
AD7177_ID=AD7177_Read_ChipID();
MessageSend("AD7177 ID:0x%X\r\n",AD7177_ID);
SysTick_DelayTicks(1000U);
*/
}
return 0 ;
}
下图是使用VOFA+作为上位机并使用图形显示结果,数字单位是uV
第一次使用IDE作为MCU开发工具,学习到许多新的东西,掉过许多坑,比如有的IDE只是爆警告,没有报错,但是一运行,MCU就爆Hardfault错位。LPC55S69这颗芯片还要继续探索它的性能和能力,吐槽一下PLU性能赢弱,成了鸡肋。