将标准示例的ADC实验与CAN通讯实验集成,ADC失败

2019-07-21 02:15发布

在工程的main函数中如果加入:

CAN1_Mode_Init(CAN_SJW_1tq, CAN_BS2_6tq, CAN_BS1_7tq, 6, CAN_Mode_Normal);

那么while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));会出不来,百思不得其解呀。
代码都是示例代码,未做改动:

[mw_shl_code=c,true]void Adc_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; ADC_CommonInitTypeDef ADC_CommonInitStructure; ADC_InitTypeDef ADC_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //使能GPIOA时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC1时钟 //先初始化ADC1通道5 IO口 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //PA5 通道5 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; //模拟输入 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; //不带上下拉 GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化 RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE); //ADC1复位 RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE); //复位结束 ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式 ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; //两个采样阶段之间的延迟5个时钟 ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //DMA失能 ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4; //预分频4分频。ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz ADC_CommonInit(&ADC_CommonInitStructure); //初始化 ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //12位模式 ADC_InitStructure.ADC_ScanConvMode = DISABLE; //非扫描模式 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //关闭连续转换 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //禁止触发检测,使用软件触发 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //右对齐 ADC_InitStructure.ADC_NbrOfConversion = 1; //1个转换在规则序列中 也就是只转换规则序列1 ADC_Init(ADC1, &ADC_InitStructure); //ADC初始化 ADC_Cmd(ADC1, ENABLE); //开启AD转换器 } [/mw_shl_code]
[mw_shl_code=c,true]int CAN1_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode) { GPIO_InitTypeDef GPIO_InitStructure; CAN_InitTypeDef CAN_InitStructure; CAN_FilterInitTypeDef CAN_FilterInitStructure; #if CAN1_RX0_INT_ENABLE NVIC_InitTypeDef NVIC_InitStructure; #endif //使能相关时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //使能PORTA时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); //使能CAN1时钟 //初始化GPIO GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11| GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //100MHz GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA11,PA12 //引脚复用映射配置 GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_CAN1); //GPIOA11复用为CAN1 GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_CAN1); //GPIOA12复用为CAN1 //CAN单元设置 CAN_InitStructure.CAN_TTCM=DISABLE; //非时间触发通信模式 CAN_InitStructure.CAN_ABOM=DISABLE; //软件自动离线管理 CAN_InitStructure.CAN_AWUM=DISABLE; //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位) CAN_InitStructure.CAN_NART=ENABLE; //禁止报文自动传送 CAN_InitStructure.CAN_RFLM=DISABLE; //报文不锁定,新的覆盖旧的 CAN_InitStructure.CAN_TXFP=DISABLE; //优先级由报文标识符决定 CAN_InitStructure.CAN_Mode= mode; //模式设置 CAN_InitStructure.CAN_SJW=tsjw; //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1tq~CAN_SJW_4tq CAN_InitStructure.CAN_BS1=tbs1; //Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq CAN_InitStructure.CAN_BS2=tbs2; //Tbs2范围CAN_BS2_1tq ~ CAN_BS2_8tq CAN_InitStructure.CAN_Prescaler=brp; //分频系数(Fdiv)为brp+1 CAN_Init(CAN1, &CAN_InitStructure); //初始化CAN1 //配置过滤器 CAN_FilterInitStructure.CAN_FilterNumber = 0; //过滤器0 CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; //32位 CAN_FilterInitStructure.CAN_FilterIdHigh = (((1<<4) | CAN_ULTRASONIC_MODULE_ID) << 8); //1为Host的Module ID,左移8位; CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000; CAN_FilterInitStructure.CAN_FilterMaskIdHigh= (CAN_ULTRASONIC_MODULE_ID<<8);//过滤目标为CAN_ULTRASONIC_MODULE_ID的帧; CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000; CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0; //过滤器0关联到FIFO0 CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; //激活过滤器0 CAN_FilterInit(&CAN_FilterInitStructure); //滤波器初始化 #if CAN1_RX0_INT_ENABLE CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE); //FIFO0消息挂号中断允许. NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 主优先级为1 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 次优先级为0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); #endif return 0; } [/mw_shl_code]
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
4条回答
backroad
2019-07-21 04:49
回复【3楼】正点原子:
---------------------------------

昨天花了老半天终于把这个问题解决了,原因是局部变量没有初始化的问题。

ADC_InitStructure定义后因为没有初始化(在Adc_Init函数中未对ADC_InitStructure.ADC_ExternalTrigConv赋值),但是ADC_Init函数中却有如下调用:

tmpreg1 |= (uint32_t)(ADC_InitStruct->ADC_DataAlign | 
                        ADC_InitStruct->ADC_ExternalTrigConv | 
                        ADC_InitStruct->ADC_ExternalTrigConvEdge | 
                        ((uint32_t)ADC_InitStruct->ADC_ContinuousConvMode << 1));
                        
  /* Write to ADCx CR2 */
  ADCx->CR2 = tmpreg1;

这导致了tmpreg1的取值可能会出现问题。

所以,建议原子哥在库函数的示例工程中,定义结构体后,用memset进行一下初始化。

一周热门 更多>