十万火急。请求大侠们指点
小弟使用STM8L采集16个电压值,改写ST库配置完了,一次采样16路电压,在DMA中断中读取采样值。在主函数中五次启动AD转换,再把采样值转存到v_tem1【16】~v_tem5【5】五个数组中,不知为什么这五个数组中每一路的采样值都在跳变,硬件电压没问题。
主程序如下。
#include "STM8L151M8.h"
#define ADC1_DR_ADDRESS ((uint)0x5344)
#define BUFFER_SIZE ((uint) 0x10)
#define BUFFER_ADDRESS ((uint)(&Buffer))
uint arr[16]={0};
uint v_tem1[16]={0},v_tem2[16]={0},v_tem3[16]={0};
uint v_tem4[16]={0},v_tem5[16]={0};
uint Buffer[BUFFER_SIZE]={0};
FunctionalState ProcessStatus = DISABLE;
main()
{
uchar j;
clock_cfg();
ports_init();
adc_cfg();
dma_cfg();
Adc_DmaCmd(ADC1, ENABLE); //Enable DMA for ADC.
_asm("rim"); //Enable globle interrupt
while (1)
{
//第一次采样16个A/D 通道的值,存放在数组v_tem1【16】中。
ADC1_CR1|=0x02;
while(ProcessStatus!=ENABLE); //等待DMA中断转换结束。
for(j=0;j<16;j++)
v_tem1[j]=arr[j]; //把DMA中断的中转值存入v_tem1[16],
ProcessStatus = DISABLE;
仿真结果如下,不知道为什么每一路都在跳变。
ADC1_CR1|=0x02;
while(ProcessStatus!=ENABLE);
for(j=0;j<16;j++)
v_tem2[j]=arr[j];
ProcessStatus = DISABLE;
ADC1_CR1|=0x02;
while(ProcessStatus!=ENABLE);
for(j=0;j<16;j++)
v_tem3[j]=arr[j];
ProcessStatus = DISABLE;
ADC1_CR1|=0x02;
while(ProcessStatus!=ENABLE);
for(j=0;j<16;j++)
v_tem4[j]=arr[j];
ProcessStatus = DISABLE;
//第五次采样相同16个通道的值,存放在数组v_tem1【16】中。
ADC1_CR1|=0x02;
while(ProcessStatus!=ENABLE);
for(j=0;j<16;j++)
v_tem5[j]=arr[j];
ProcessStatus = DISABLE;
_asm("nop");
_asm("nop");
while(1);
}
}
/***************************************************
ADC配置程序
****************************************************/
void adc_cfg(void)
{
ADC1_CR1=0x20; /*Overrun interrupt disable,10-bit resolution,Analog watchdog interrupt
disable,EOC interrupt disable,Single conversion mode selected,Conversion
start disable,A/D modle has't enabled.*/
ADC1_CR2=0x00; /*Clock prescaler equal CK,Active edge for external triggers disable,
Software start selected,select 4 ADC clock cycle samping time.*/
ADC1_CR1|=0x01; //Enable the ADC model.
//ADC1_SQR1=0x00; //DMA enabled,It default status is enable.
ADC1_SQR2=0x7F; //Select channels 16 to 22 for scan.
ADC1_SQR3=0xFC; //Select channels 10 to 15 for scan
ADC1_SQR4=0x07; //Select channels 0 to 2 for scan.
}
/****************************************************
DMA 配置程序
*****************************************************/
void dma_cfg(void)
{
SYSCFG_RMPCR1&=0xFC; //Configure ADC-DMA channel remapping on DMA channel0.
DMA1_C0CR=0x00; //Reset value
DMA1_C0CR|=0x30;
/*
The channel works as regular channel,Memory in increment
mode,Circular mode disabled,Date transfer from the peripheral
to memory,Half transaction interrupt disabled,Transaction
complete interrupt disabled,Channel has't been enabled.
*/
DMA1_C0SPR&=0xC7; /*Clear old priority and memory data size option,
This is recommened by ST peripheral firmware library*/
DMA1_C0SPR|=0x38; //Set channel priority level Very high,Transfer size is 16-bit mode
DMA1_C0NDTR=BUFFER_SIZE; //Cofigure 16 half_word data transfer.
DMA1_C0PARH = (uchar)(ADC1_DR_ADDRESS >> (uchar)8); //The map of ADC data register high
DMA1_C0PARL = (uchar)(ADC1_DR_ADDRESS); //The map of ADC data register low
DMA1_C0M0ARH = (uchar)(BUFFER_ADDRESS >> 8); //Memory 0 address pointer(HSB)
DMA1_C0M0ARL = (uchar)(BUFFER_ADDRESS); //Memory 0 address pointer(LSB)
DMA1_C0CR|=0x01; //Channel enable.
DMA1_C0CR|=0x02; //Enable the Transaction complete interrupt.
DMA1_GCSR&=0x03; //Timeout is zero.
DMA1_GCSR|=0x01; //Enable globle DMA module
}
//配置时钟
void clock_cfg(void)
{
//Sysclk configuration
CLK_SWCR|=0x02; //Enable sysclk switch.
CLK_SWR=0x01; //switch to HSI.
CLK_CKDIVR=0x00; //prescaling factor is 1.
while(CLK_SCSR!=0x01); //wait for HSI selected as system clock source
CLK_PCKENR2|=0x10; //enable the SYSCLK clock to DMA1 peripheral
CLK_PCKENR2|=0x01; //enable the SYSCLK clock to ADC peripheral
}
DMA中断函数如下:
@far @interrupt void DMA1_CHANNEL0_1_IRQHandler (void)
{
unsigned char i;
for(i=0;i<16;i++)
{
arr[i]=Buffer[i]; //把采集的16路AD值装入中转数组arr[16]中,
}
DMA1_C0SPR&=0xFD;
ProcessStatus = ENABLE;
}
|