Electricity/FWLIB/source/ENS1_WAVEGEN.c

192 lines
8.4 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
*Copyright (C),2023 , NANOCHAP
*File name: ENS1_WAVEGEN.C
*Author:
*Version: V1.0
*Date: 2023-11-
*Description: 波形生成器电刺激功能实现
*Function List:
1 int wavegen_driverA_sine_test(CMSDK_WAVE_GEN_TypeDef *CMSDK_WAVEGEN_DRVA, uint16_t incount);
2 void wavegen_Stop(CMSDK_WAVE_GEN_TypeDef *CMSDK_WAVEGEN_DRVA);
3 void wavegen_Init(void);
4 void wavegen_Start(void);
History:
1.V1.0
Date:
Author:
Modification: 初版
*/
#include <stdio.h>
#include "ENS1_WAVEGEN.h"
#include "ENS1_CLOCK.h"
#include "ENS1_BOOST.h"
// 全局变量
static EMS_Config_TypeDef g_ems_config = {0};
static volatile uint8_t g_ems_running = 0;
static volatile uint32_t g_ems_count = 0;
/* --------------------------------------------------------------- */
/* 波形生成器驱动器A正弦波测试 */
/* --------------------------------------------------------------- */
int wavegen_driverA_sine_test(CMSDK_WAVE_GEN_TypeDef *CMSDK_WAVEGEN_DRVA, uint16_t incount)
{
int return_val = 0;
int err_code = 0;
puts("\n驱动器A正弦波测试\n");
CMSDK_WAVEGEN_DRVA->WAVE_GEN_DRV_REST_T_REG = 100; //死区时间10ms //交替模式下死区时间失效即使CONFIG_REG使能了死区时间也无效
//CMSDK_WAVEGEN_DRVA->WAVE_GEN_DRV_SILENT_T_REG = 200; //静默时间20ms
CMSDK_WAVEGEN_DRVA->WAVE_GEN_DRV_CLK_FREQ_REG = 0x00000020; //32MHz ==PCLK
CMSDK_WAVEGEN_DRVA->WAVE_GEN_DRV_CLK_FREQ_REG = 32; //32MHz ==PCLK //MHz为单位
CMSDK_WAVEGEN_DRVA->WAVE_GEN_DRV_HLF_WAVE_PRD_REG = 100; //正半周期脉宽10ms有交替方波
CMSDK_WAVEGEN_DRVA->WAVE_GEN_DRV_NEG_HLF_WAVE_PRD_REG = 100; //负半周期脉宽10ms无交替方波
#if 1//无需静默时间
CMSDK_WAVEGEN_DRVA->WAVE_GEN_DRV_CONFIG_REG = 0x00000050; //bit 0:rest enable 正半周期和负半周期中间的休息时间
//1:negative enable 负半周期发生使能,如果不使能,则没有负半周期的波形(注意交替模式只会对正半周期起作用)
//2: silent enable 负半周期结束后的静默时间
//3: source B enable 负脉宽方向使能位1负脉宽在负半周期0负脉宽在正半周期
//4: alternating the positive side ,正极交替产生包络
//5: continue mode ,连续模式
//6: multi-electrode ,多电极模式
#else //需要静默时间
/*交替模式下config寄存器说明
正脉宽交替无负脉宽无死区时间无静默时间0x50 或 0x51 或 0x58 或 0x59
正脉宽交替无死区时间无负脉宽有静默时间0x54 或 0x55 或 0x5C 或 0x5D
正脉宽交替,无死区时间,负脉宽不交替但有波形,无静默时间 0x5A 或 0x5B
正脉宽交替无死区时间负脉宽不交替但有波形且波形在正脉宽上因为源B失能了无静默时间 0x52 或 0x53
正脉宽交替无死区时间负脉宽不交替但有波形且波形在正脉宽上因为源B失能了有静默时间 0x56 或 0x57
正脉宽交替,无死区时间,负脉宽不交替但有波形,有静默时间 0x5E 或 0x5F
*/
// CMSDK_WAVEGEN_DRVA->WAVE_GEN_DRV_CONFIG_REG = 0x5F; //bit 0:rest enable 正半周期和负半周期中间的死区时间
//1:negative enable 负半周期发生使能,如果不使能,则没有负半周期的波形
//2: silent enable 负半周期结束后的静默时间
//3: source B enable
//4: alternating the positive side ,正极交替产生包络
//5: continue mode ,连续模式
CMSDK_WAVEGEN_DRVA->WAVE_GEN_DRV_CONFIG_REG = 0x34; //静默时间、交替模式和多电极使能 //6: multi-electrode ,多电极模式
#endif
CMSDK_WAVEGEN_DRVA ->WAVE_GEN_DRV_ISEL_REG = 0x04; // 总电流 = 单元电流ISEL * WAVE_GEN_DRV_IN_WAVE_REG
for(int i=0; i<64; i++){
CMSDK_WAVEGEN_DRVA->WAVE_GEN_DRV_IN_WAVE_ADDR_REG = i;
//CMSDK_WAVEGEN_DRVA->WAVE_GEN_DRV_IN_WAVE_REG = sine_data[i]; //正弦波数据数组,根据数组中的点描绘正半周期的波形
// CMSDK_WAVEGEN_DRVA->WAVE_GEN_DRV_IN_WAVE_REG = saw_data[i]; //三角波数据
CMSDK_WAVEGEN_DRVA->WAVE_GEN_DRV_IN_WAVE_REG = incount; //方波数据固定值0x80
}
CMSDK_WAVEGEN_DRVA->WAVE_GEN_DRV_ALT_LIM_REG = 3200;// 3200 需要设置一个正半周期下需要再生成多少个周期波形。设置10kHz=0.1ms=100us100us=A*(1/32us),所以A=3200。
CMSDK_WAVEGEN_DRVA->WAVE_GEN_DRV_ALT_SILENT_LIM_REG = 0; // 交替后静默的时钟数无死区时间设置。在这种情况下驱动器B连续交替。//包络下波形的静默时间
CMSDK_WAVEGEN_DRVA->WAVE_GEN_DRV_DELAY_LIM_REG = 0x00000000; // 延迟时钟数
CMSDK_WAVEGEN_DRVA->WAVE_GEN_DRV_NEG_SCALE_REG = 0x00000001; //负半周期幅值倍乘系数如超过255则从0开始增长
CMSDK_WAVEGEN_DRVA->WAVE_GEN_DRV_NEG_OFFSET_REG = 0x00000000; //负半周期幅值偏移量如超过255则从0开始增长
//如正半周期幅值为250此处设置为10则负半周期幅值为5
CMSDK_WAVEGEN_DRVA->WAVE_GEN_DRV_INT_REG = 0x0;// 中断寄存器设置为0
CMSDK_WAVEGEN_DRVA->WAVE_GEN_DRV_CTRL_REG = 0x00000001; //使能驱动器
/* 生成返回值 */
if (err_code != 0) {
puts("\n错误 : 驱动器A测试失败\n");
return_val = 1;
err_code = 0;
}
return(return_val);
}
void wavegen_Stop(CMSDK_WAVE_GEN_TypeDef *CMSDK_WAVEGEN_DRVA)
{
CMSDK_WAVEGEN_DRVA ->WAVE_GEN_DRV_ISEL_REG = 0; //范围 0x00 - 0x07
for(int i=0; i<64; i++){
CMSDK_WAVEGEN_DRVA->WAVE_GEN_DRV_IN_WAVE_ADDR_REG = i;
CMSDK_WAVEGEN_DRVA->WAVE_GEN_DRV_IN_WAVE_REG = 0; //最大值0xff
}
}
// 初始化波形生成器
void wavegen_Init(void)
{
// 设置MTP等待周期
CMSDK_MTPREG->MTP_CR = 0x00000002;
// 注意时钟配置已在ClockInit()中完成,这里不再重复配置
// 使用HSI作为主频 32MHz
// CMSDK_SYSCON->HSI_CTRL = (CMSDK_SYSCON->HSI_CTRL & ~CMSDK_SYSCON_HSI_FREQ_Msk) | (0x3 << CMSDK_SYSCON_HSI_FREQ_Pos); //HSI=32MHz
// 使能UART和WAVE_GEN外设时钟不覆盖TIMER0时钟
CMSDK_SYSCON->APB_CLKEN |= 0x1003|0x4000; // 使用|=而不是=,避免覆盖其他时钟使能
// 升压电压选择
boost_voltage_select_26V();
puts("ENS1 - WAVE_GENERATOR_DRIVER_A_Test - $Revision: R001\n");
}
// 启动波形生成器
void wavegen_Start(void)
{
g_ems_running = 1;
g_ems_count = 0;
}
// 电刺激参数配置
void EMS_Configure(EMS_Config_TypeDef *config)
{
if(config != NULL) {
g_ems_config = *config;
}
}
// 启动电刺激
void EMS_Start(void)
{
wavegen_Start();
printf("电刺激已启动\n");
}
// 停止电刺激
void EMS_Stop(void)
{
g_ems_running = 0;
g_ems_count = 0; // 重置计数器
wavegen_Stop(WAVE_GEN_DRVA_BLK0);
printf("电刺激已停止\n");
}
// 更新电刺激强度
void EMS_UpdateIntensity(uint16_t intensity)
{
g_ems_config.intensity = intensity;
}
// 电刺激主循环处理函数(在主循环中调用)
void EMS_Process(void)
{
if(g_ems_running) {
g_ems_count++;
// 根据配置生成不同强度的方波
if(g_ems_count < 1280) {
wavegen_driverA_sine_test(WAVE_GEN_DRVA_BLK0, g_ems_config.intensity);
} else if(g_ems_count < 1280*256) {
// 休息时间
} else if(g_ems_count < 1280*2) {
wavegen_driverA_sine_test(WAVE_GEN_DRVA_BLK0, g_ems_config.intensity);
} else {
// 重置计数器,开始新的周期
g_ems_count = 0;
}
}
}