HC32F448的AD功能采集

参考该单片机的数据手册的例程,程序使用如下内容:

static void AdcInitConfig(void)
{
  unsigned char i=0;
  stc_adc_init_t stcAdcInit;
  
  /* 1. Enable ADC peripheral clock. */
  FCG_Fcg3PeriphClockCmd(ADC_PERIPH_CLK, ENABLE);
  /* 2. Modify the default value depends on the application. */
  (void)ADC_StructInit(&stcAdcInit);
  /* 3. Initializes ADC. */
  (void)ADC_Init(ADC_UNIT, &stcAdcInit);
  /* 4. ADC channel configuration. */
  /* 4.1 Set the ADC pin to analog input mode. */
  
  AdcSetPinAnalogMode(u8port,u16pin);
  /* 4.2 Enable ADC channels. */
  ADC_ChCmd(ADC_UNIT, ADC_SEQ,u8ch , ENABLE);

   
}

结果发现采集的数据值误差过大。后来改设置为过采样(重点为最后四行代码),可以降低误差。

static void AdcInitConfig(void)
{
  unsigned char i=0;
  stc_adc_init_t stcAdcInit;
  
  /* 1. Enable ADC peripheral clock. */
  FCG_Fcg3PeriphClockCmd(ADC_PERIPH_CLK, ENABLE);
  /* 2. Modify the default value depends on the application. */
  (void)ADC_StructInit(&stcAdcInit);
  /* 3. Initializes ADC. */
  (void)ADC_Init(ADC_UNIT, &stcAdcInit);
  /* 4. ADC channel configuration. */
  /* 4.1 Set the ADC pin to analog input mode. */
  
  AdcSetPinAnalogMode(u8port,u16pin);
  /* 4.2 Enable ADC channels. */
  ADC_ChCmd(ADC_UNIT, ADC_SEQ, u8ch , ENABLE);
  ADC_ConvDataAverageConfig(ADC_UNIT, ADC_AVG_CNT64);
  ADC_ConvDataAverageChCmd(ADC_UNIT, u8ch, ENABLE);
  ADC_SetSampleMode(ADC_UNIT, ADC_SPL_MD_OVER);
  ADC_SetOverSampleShift(ADC_UNIT, ADC_OVER_SPL_SHIFT_2BIT);
     
}

每隔250us采集一个数据(DMA方式),一个周期采样80个数值。取样的电流越小,波形越阶梯状明显。

原因:采样动作会有一定的电流消耗,过采样比普通采样次数多。除非增加信号的带载能力。或者降低采样次数。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
小华hc32f448是一款32位的ARM Cortex-M4内核的微控制器。bl24c256是一种I2C总线的串行EEPROM存储器,它具有256K位的存储容量和32个页。 下面是小华hc32f448的bl24c256的DMA程序实例: ```c #include "hc32f4a0.h" #include "i2c.h" #include "dma.h" /* 定义I2C总线地址 */ #define I2C_ADDR 0xA0 /* 定义要写入EEPROM的数据缓冲区 */ uint8_t au8TxData[16] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00}; /* 定义DMA通道0传输完成标志 */ __IO uint8_t u8DmaTranCpltFlag = 0U; /* DMA初始化函数 */ static void DMA_Config(void) { /* 定义DMA初始化结构体变量 */ stc_dma_init_t stcDmaInit; /* 配置DMA模式为内存到外设模式 */ stcDmaInit.u32TransCnt = sizeof(au8TxData); stcDmaInit.u32BlockSize = DMA_BLKSIZE_1BYTE; stcDmaInit.u32SrcAddr = (uint32_t)au8TxData; stcDmaInit.u32DesAddr = (uint32_t)&I2C->TXDR; stcDmaInit.u32SrcInc = DMA_SRC_INC_FIX; stcDmaInit.u32DesInc = DMA_DES_INC_NONE; stcDmaInit.u32TransWidth = DMA_DATAWIDTH_8BIT; stcDmaInit.u32HDataAlign = DMA_HDATAALIGN_BYTE; stcDmaInit.u32LDataAlign = DMA_LDATAALIGN_BYTE; stcDmaInit.u32BurstSize = DMA_BURSTSIZE_1; stcDmaInit.u32SaddrReloadCtl = DMA_SADDR_RELOAD_DISABLE; stcDmaInit.u32DaddrReloadCtl = DMA_DADDR_RELOAD_DISABLE; stcDmaInit.u32IntEn = DMA_INT_ENABLE; stcDmaInit.u32LlpEn = DMA_LLP_ENABLE; stcDmaInit.u32LlpMd = DMA_LLP_ADDR_MD; stcDmaInit.u32ChNum = DMA_CH0; /* 初始化DMA通道0 */ DMA_Init(&stcDmaInit); /* 配置DMA触发源为I2C1发送请求 */ DMA_SetTriggerSrc(DMA_CH0, DMA_TRGSRC_I2C1_TX_REQ); } /* I2C初始化函数 */ static void I2C_Config(void) { /* 定义I2C初始化结构体变量 */ stc_i2c_init_t stcI2cInit; /* 配置I2C时钟 */ M4_CMU->PERCLKEN1 |= CMU_PERCLKEN1_I2C1CKEN; M4_CMU->PERCLKSEL &= ~(CMU_PERCLKSEL_I2C1PS); M4_CMU->PERCLKSEL |= (CMU_PERCLKSEL_I2C1_PLL << CMU_PERCLKSEL_I2C1PS_POS); /* 配置I2C引脚 */ GPIO_SetFunc(GPIO_PORT_E, GPIO_PIN_15, GPIO_FUNC_7_I2C1_SCL); GPIO_SetFunc(GPIO_PORT_E, GPIO_PIN_14, GPIO_FUNC_7_I2C1_SDA); GPIO_SetOpenDrain(GPIO_PORT_E, GPIO_PIN_15|GPIO_PIN_14, Enable); /* I2C初始化结构体变量清零 */ MEM_ZERO_STRUCT(stcI2cInit); /* 配置I2C从机地址 */ stcI2cInit.u8SlaveAddr = I2C_ADDR; /* 配置I2C波特率 */ stcI2cInit.u32Baudrate = 100000U; /* 初始化I2C模块 */ I2C_Init(I2C_CH1, &stcI2cInit); } int main(void) { /* 初始化DMA和I2C模块 */ DMA_Config(); I2C_Config(); /* 配置DMA传输完成中断 */ NVIC_ClearPendingIRQ(DMA_IRQn); NVIC_SetPriority(DMA_IRQn, DDL_IRQ_PRIORITY_DEFAULT); NVIC_EnableIRQ(DMA_IRQn); /* 配置I2C发送请求中断,用于触发DMA数据传输 */ I2C_EnableIrq(I2C_CH1, I2C_CR1_STOPIE | I2C_CR1_TENDIE); while (1) { if (u8DmaTranCpltFlag) { u8DmaTranCpltFlag = 0U; /* 数据发送完成后延时一段时间 */ DDL_Delay1ms(10U); /* 发送读取EEPROM数据的指令 */ I2C_SendData(I2C_CH1, (uint8_t)0x00U); while (!I2C_GetStatus(I2C_CH1, I2C_SR_TENDF)) { /* 等待传输完成标志 */ } /* 启动读取EEPROM数据,读取16个字节的数据 */ I2C_StartReadData(I2C_CH1, I2C_ADDR, au8RxData, sizeof(au8TxData)); } } } /* DMA传输完成中断处理函数 */ void DMA_IRQHandler(void) { if (Set == DMA_GetIntFlag(DMA_CH0, DMA_INT_TC)) { DMA_ClearIntFlag(DMA_CH0, DMA_INT_TC); u8DmaTranCpltFlag = 1U; /* 关闭I2C发送请求中断,停止DMA数据传输 */ I2C_DisableIrq(I2C_CH1, I2C_CR1_STOPIE | I2C_CR1_TENDIE); DMA_Cmd(DMA_CH0, Disable); while (Reset != DMA_GetCmdStatus(DMA_CH0)) { /* 等待DMA通道停止 */ } /* 清除DMA通道错误标志 */ DMA_ClearErrFlag(DMA_CH0, DMA_ERR_CLR_ALL); /* 关闭I2C总线 */ I2C_Cmd(I2C_CH1, Disable); while (Reset != I2C_GetCmdStatus(I2C_CH1)) { /* 等待I2C模块停止 */ } /* 打开I2C总线 */ I2C_Cmd(I2C_CH1, Enable); while (Reset != I2C_GetCmdStatus(I2C_CH1)) { /* 等待I2C模块启动 */ } /* 发送写入EEPROM数据的指令和数据 */ I2C_SendData(I2C_CH1, (uint8_t)0x00U); while (!I2C_GetStatus(I2C_CH1, I2C_SR_TENDF)) { /* 等待传输完成标志 */ } I2C_StartWriteData(I2C_CH1, I2C_ADDR, au8TxData, sizeof(au8TxData)); while (!I2C_GetStatus(I2C_CH1, I2C_SR_TENDF)) { /* 等待传输完成标志 */ } /* 启动读取EEPROM数据,读取16个字节的数据 */ I2C_StartReadData(I2C_CH1, I2C_ADDR, au8RxData, sizeof(au8TxData)); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值