OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3820|回复: 4

使用操作系统时ADC采样卡死,UCOSII和RTOS都是一样的结果

[复制链接]

3

主题

6

帖子

0

精华

初级会员

Rank: 2

积分
97
金钱
97
注册时间
2013-11-18
在线时间
19 小时
发表于 2020-11-17 13:30:46 | 显示全部楼层 |阅读模式
103RC的MINI板、407ZG探索者板使用操作系统后出现一个情况,在未使用ADC采样时操作系统正常运行,使用ADC采样后,操作系统跑到ADC采样代码卡死,UCOSII和FreeRTOS都实测过,一样的结果。不使用操作系统就都正常了,各位道友有没有遇见过此类问题的,一起分享下你们宝贵的经验。我把三个都贴出来大家帮忙看下,谢谢。 官方ADC初始化DEMO.png 采样.png 未使用操作系统.png 不用操作系统正常.png RTOS初始化.png RTOS任务.png 卡在这里.png UCOSII初始化.png UCOS任务.png


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

9

主题

100

帖子

0

精华

高级会员

Rank: 4

积分
800
金钱
800
注册时间
2019-8-15
在线时间
425 小时
发表于 2020-11-17 15:19:59 | 显示全部楼层
不知道你的函数是怎么实现的,看看你的堆栈设置,是否是有溢出了
回复 支持 反对

使用道具 举报

80

主题

931

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3348
金钱
3348
注册时间
2013-5-28
在线时间
468 小时
发表于 2020-11-17 16:57:19 | 显示全部楼层
你如果是仿真,那得关注,仿真软件会给把ADC的DR数据读走,然后你逻辑就是错的了
回复 支持 反对

使用道具 举报

3

主题

6

帖子

0

精华

初级会员

Rank: 2

积分
97
金钱
97
注册时间
2013-11-18
在线时间
19 小时
 楼主| 发表于 2020-11-20 09:13:26 | 显示全部楼层
问题是在没有做电压判断屏蔽该函数,只读ADC和电压值时也是卡住的,这句:Get_Adc_Average(ADC_Channel_15,10);不能通过,应该是这个版本的线程与ADC有干扰,我试过7.0的FreeRTOS能正常运行,当然系统是我自己移植的,没有用官网的9.0代码。
回复 支持 反对

使用道具 举报

3

主题

6

帖子

0

精华

初级会员

Rank: 2

积分
97
金钱
97
注册时间
2013-11-18
在线时间
19 小时
 楼主| 发表于 2020-11-20 09:17:28 | 显示全部楼层
而且不能用官网ADC采样函数,用了也会卡住,我用的DMA做接收的,暂时可以用。
//使用DMA
volatile u16 BAT_adc;
volatile float BAT_vol;
void ADC_DMA_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        ADC_InitTypeDef ADC_InitStructure;
        DMA_InitTypeDef DMA_InitStructure;
       
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_ADC1,ENABLE);       

        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;                 
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
        GPIO_Init(GPIOC,&GPIO_InitStructure);
        DMA_DeInit(DMA1_Channel1);
        DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;//ADC地址
        DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&BAT_adc; //内存地址
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //方向(从外设到内存)
        DMA_InitStructure.DMA_BufferSize = 1; //传输内容的大小
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址固定
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; //内存地址固定
        DMA_InitStructure.DMA_PeripheralDataSize =
        DMA_PeripheralDataSize_HalfWord ; //外设数据单位
        DMA_InitStructure.DMA_MemoryDataSize =
        DMA_MemoryDataSize_HalfWord ;    //内存数据单位
        DMA_InitStructure.DMA_Mode = DMA_Mode_Circular  ; //DMA模式:循环传输
        DMA_InitStructure.DMA_Priority = DMA_Priority_High ; //优先级:高
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;   //禁止内存到内存的传输
       
        DMA_Init(DMA1_Channel1, &DMA_InitStructure);  //配置DMA1的4通道
        DMA_Cmd(DMA1_Channel1,ENABLE);

        ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立ADC模式
        ADC_InitStructure.ADC_ScanConvMode = DISABLE;  //禁止扫描方式
        ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//开启连续转换模式
        ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //不使用外部触发转换
        ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //采集数据右对齐
        ADC_InitStructure.ADC_NbrOfChannel = 1; //要转换的通道数目
        ADC_Init(ADC1, &ADC_InitStructure);
       
        RCC_ADCCLKConfig(RCC_PCLK2_Div8);//配置ADC时钟,为PCLK2的8分频,即9Hz
        ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 1, ADC_SampleTime_55Cycles5);//配置ADC1通道11为55.5个采样周期
       
        ADC_DMACmd(ADC1,ENABLE);
        ADC_Cmd(ADC1,ENABLE);

        ADC_ResetCalibration(ADC1);//复位校准寄存器
        while(ADC_GetResetCalibrationStatus(ADC1));//等待校准寄存器复位完成

        ADC_StartCalibration(ADC1);//ADC校准
        while(ADC_GetCalibrationStatus(ADC1));//等待校准完成

        ADC_SoftwareStartConvCmd(ADC1, ENABLE);//由于没有采用外部触发,所以使用软件触发ADC转换
}
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-4 02:06

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表