【沧海拾昧】Proteus8仿真stm32:ADC转换程序

这篇具有很好参考价值的文章主要介绍了【沧海拾昧】Proteus8仿真stm32:ADC转换程序。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

#C0102


沧海茫茫千钟粟,且拾吾昧一微尘

——《沧海拾昧集》@CuPhoenix


【阅前敬告】

沧海拾昧集仅做个人学习笔记之用,所述内容不专业不严谨不成体系

如有问题必是本集记录有谬,切勿深究


目录

一、原理图绘制

二、多位七段数码管

三、ADC引脚

四、代码

 五、仿真问题


一、原理图绘制

【沧海拾昧】Proteus8仿真stm32:ADC转换程序
ADC转换程序电路原理图

         

图中所用到的元件和元件在库中的名称对照表如下:

元件名 库中名称
可变电阻 POT-HG
STM32F103R6 STM32F103R6
4位7段共阴数码管 7SEG-MPX4-CC
高电平 POWER
GROUND

二、多位七段数码管

1、共阴管是CC,共阳管是CA,对应的译码表如下。

【沧海拾昧】Proteus8仿真stm32:ADC转换程序
数码管译码表

2、输入信号A~G、DP的有效信号看是共阴还是共阳,对应的片选信号1~4是低电平有效,从左到右依次为第1位至第4位。

片选位数 1 2 3 4
片选码 0x0e00 0x0d00 0x0b00 0x0700


3、输出的示例。数字码0x6f,片选码0x0e00,输出码即二者相加0x0e6f。

GPIO_Write(GPIOC, 0x0e6f );
【沧海拾昧】Proteus8仿真stm32:ADC转换程序
在第1位输出“9”

4、输出用的函数GPIO_Write的定义如下,适用于对统一端口的多个引脚的写入。

void GPIO_Write(GPIO_TypeDef *GPIOx, uint16_t ProtVal)

5、多位七段管输出的方法是动态扫描,即逐位输出。在每位输出前面加一个短暂的延时函数,然后清零引脚,动态扫描输出就不会闪烁了。示例如下(在第一位片选码使用0x0e80,加了个小数点)。

 先定义好译码表待查。

const uint16_t SegmentCodes[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
const uint16_t SegmentBit[]={0x0e80,0x0d00,0x0b00,0x0700};

输出内容。

uint16_t temp = 1234;
                        // 输出内容:1234
uint16_t unit[4];
unit[0] = temp / 1000;
unit[1] = temp % 1000 / 100;
unit[2] = temp % 100 / 10;
unit[3] = temp % 10;
                        // 位数拆分
int i = 0;
for(i=0;i<4;i++){
    delay();
    GPIO_Write(GPIOC, 0x0f00 );
    GPIO_Write(GPIOC, SegmentCodes[unit[i]]+SegmentBit[i] );
}
                        // 循环输出各位

短暂的延时。

void delay(){
	int i=0,j=0;
	for(i=0;i<5;i++){
		for(j=0;j<100;j++){}
	}
}

仿真结果。 

【沧海拾昧】Proteus8仿真stm32:ADC转换程序
动态扫描输出四位

三、ADC引脚

【沧海拾昧】Proteus8仿真stm32:ADC转换程序
ADC通道对应的引脚必须正确
图源 @夜路难行々

四、代码

#include "stm32f10x.h"

#define ADC1_DR_Address ((uint32_t)0x4001244C)

ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
__IO uint16_t ADCConvertedValue;
ErrorStatus HSEStartUpStatus;
const uint16_t SegmentCodes[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
                                        // 共阴数码管 0 ~ 9 查码表
const uint16_t SegmentBit[]={0x0e80,0x0d00,0x0b00,0x0700}; 
                                        // 片选 1 ~ 4 查码表

void RCC_Configuration();  // RCC初始化
void GPIO_Configuration();  // GIPO初始化
void delay();


int main(void){
	RCC_Configuration();  
	GPIO_Configuration();
	
	DMA_DeInit(DMA1_Channel1);  // DMA初始化
    DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;  // 外设地址
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCConvertedValue;  // 存储器地址
    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_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  // 半字
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  // 自动重装
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;  // 优先级
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  // 软件触发
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);
	
	DMA_Cmd(DMA1_Channel1, ENABLE);
	
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;  // 单ADC触发
    ADC_InitStructure.ADC_ScanConvMode = ENABLE;  // 连续扫描 否
    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);
	
	ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5);
                            // 选择规则组的输入通道,ADC1通道1,采样时钟55.5个周期
	
	ADC_DMACmd(ADC1, ENABLE);
	
	ADC_Cmd(ADC1, ENABLE);  // ADC1使能
	
	ADC_ResetCalibration(ADC1);  
	while(ADC_GetResetCalibrationStatus(ADC1));
	ADC_StartCalibration(ADC1);  // 校准ADC
	while(ADC_GetCalibrationStatus(ADC1));
	
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);  // 软件触发ADC
	
	while (1){
		uint16_t temp;
		int i = 0;
		uint16_t unit[4];
		temp = (uint16_t)(((double)(ADCConvertedValue) / (double)0xfff ) * (double)3210);
		//temp = ADCConvertedValue;
		unit[0] = temp / 1000;
		unit[1] = temp % 1000 / 100;
		unit[2] = temp % 100 / 10;
		unit[3] = temp % 10;
		for(i=0;i<4;i++){
				delay();
				GPIO_Write(GPIOC, 0x0f00 );
				GPIO_Write(GPIOC, SegmentCodes[unit[i]]+SegmentBit[i] );
		}
  }

	return 0;
	
}

void RCC_Configuration()
{
	SystemInit();
  RCC_DeInit();

  RCC_HSEConfig(RCC_HSE_ON);

  HSEStartUpStatus = RCC_WaitForHSEStartUp();

  if(HSEStartUpStatus == SUCCESS)
  {
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
    FLASH_SetLatency(FLASH_Latency_2);
    RCC_HCLKConfig(RCC_SYSCLK_Div1); 
    RCC_PCLK2Config(RCC_HCLK_Div1); 
    RCC_PCLK1Config(RCC_HCLK_Div2);
    RCC_ADCCLKConfig(RCC_PCLK2_Div4); 
  
#ifndef STM32F10X_CL  
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_7);

#else
    RCC_PREDIV2Config(RCC_PREDIV2_Div5);
    RCC_PLL2Config(RCC_PLL2Mul_8);
    RCC_PLL2Cmd(ENABLE);
    while (RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET)
    {}
    RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div5);
    RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_7);
			
#endif
    RCC_PLLCmd(ENABLE);
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
    {
    }
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    while(RCC_GetSYSCLKSource() != 0x08)
    {
    }
  }
	
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
}

void GPIO_Configuration()
{
  GPIO_InitTypeDef GPIO_InitStructure;
	
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
}

#ifdef  USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
{ 
  while (1)
  {
  }
}
#endif

void delay(){
	int i=0,j=0;
	for(i=0;i<5;i++){
		for(j=0;j<100;j++){}
	}
}


 五、仿真问题

【沧海拾昧】Proteus8仿真stm32:ADC转换程序
输出没有值

         仿真遇到问题。无论如何调节输入,ADC的输出均为0。只有在ADC接VDD时,输出为4095(最大值),接与VDD值相等的激励源值也为0。疑似是ADC没有供电。

        网上的两种解决方法均无效:

        ① 如下配置供电网:

供电网 网络连接到供电网
GND GND / VSS / VSSA
VCC / VDD(电压3.3V) VDD / VDDA
VEE -

        ② 使用高版本的Proteus:有说法8.11可以,8.9不行,但笔者用的8.13也不行。

        此问题悬而未决,若有大神路过欢迎赐教!

敬谢诸君。


京华西山之巅。文章来源地址https://www.toymoban.com/news/detail-461070.html

到了这里,关于【沧海拾昧】Proteus8仿真stm32:ADC转换程序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于STM32的温湿度检测(程序+Proteus仿真+论文)

    1、主要功能 使用STM32和DHT11温湿度传感器对室内温湿度进行检测,并通过LCD显示。 2、仿真 3、程序源码 4、资源获取 其它毕设/课设资源 基于51单片机的智能温控风扇 基于51单片机的智能水箱控制系统 基于51单片机的智能家居安防系统 基于51单片机的计算器设计 基于单片机的

    2024年02月06日
    浏览(58)
  • 基于STM32单片机的电子钟(Proteus仿真+程序)

    本设计由STM32单片机+液晶1602+按键+RTC时钟组成。 1、采用STM32F103最小系统板。 2、利用STM32内部自带RTC时钟提供时钟信号 3、液晶1602实时显示年月日、时分秒、星期等信息。 4、三个按键可实现年月日、时分秒的设定。 由于在仿真中运行CPU占用率较高,运行时,时间会变慢许多

    2024年02月12日
    浏览(40)
  • 基于STM32单片机的密码锁(Proteus仿真、程序)

    由STM32F103单片机最小系统+ 4*4矩阵键盘+LCD1602液晶显示+蜂鸣器+继电器模块 1、采用STM32F103为主控芯片 2、通过4*4矩阵键盘实现密码输入、功能键等排列如下 1     2    3     删除 4     5    6     修改密码 7     8    9     重新输入 返回  0   确认   紧急开锁键 3、每按下一次

    2024年02月07日
    浏览(44)
  • 【51单片机Keil+Proteus8.9+ADC0804】ADC实验 模拟转数字实验

    一、实验名称 ADC实验 模拟转数字实验 二、设计思路 电路设计 1.选用AT89C51单片机作为电路核心单元,外接8位单通道AD转换器ADC0804芯片和LM016L显示器以及滑动变阻器等其它常用元器件构成电路。 2.将ADC0804芯片的控制引脚RD,WR,INTR接到AT89C51芯片对应引脚,再将ADC0804电压输入引脚

    2024年01月20日
    浏览(30)
  • 基于STM32智能窗帘控制系统仿真设计(含源程序+proteus仿真+讲解视频)

    # 基于STM32智能窗帘设计(含源程序+proteus仿真) 仿真:proteus8.11 程序编译器:keil 5 编程语言:C语言 编号C0007 资料下载链接 基于STM32的简易智能窗帘控制系统仿真设计 实现功能: 有手动,自动两种模式 自动模式下,滑动变阻器模拟光照传感器,通过stm32检测与阈值比较 低于

    2024年02月13日
    浏览(33)
  • 基于STM32单片机的密码锁(Proteus仿真+程序+报告)

    3-基于STM32单片机的密码锁 功能描述如下:          由STM32F103单片机最小系统+ 4*4矩阵键盘+LCD1602液晶显示+蜂鸣器+继电器模块; 1、采用STM32F103为主控芯片。 2、通过4*4矩阵键盘实现密码输入、功能键等排列如下 1     2    3     删除 4     5    6     修改密码 7   

    2024年02月08日
    浏览(44)
  • STM32利用标准库编写同时输出4路PWM信号的程序(Proteus)仿真

    先看看结果: 这个是根据上午发的文章的基础上更改的,很简单,只是用了一个定时器,初始化了4个比较器而已,就可以单独的控制每一路PWM的占空比了,好了,把源文件展示一下,完事去接孩子放学。 PWM.c文件: PWM.h文件: main.c主函数文件: 其实整个过程只是增加了一个

    2024年04月09日
    浏览(37)
  • 基于STM32单片机的温度报警器(数码管)(Proteus仿真+程序)

            本设计由STM32F103单片机最小系统+DS18B20温度传感器+数码管显示模块+声光报警模块+独立按键组成。 1、主控制器是STM32F103单片机 2、DS18B20温度传感器测量温度 3、数码管显示温度值,精度0.1摄氏度 4、三个按键可设置温度上限、下限报警值,温度超过上限、或者温度低

    2024年02月07日
    浏览(44)
  • 基于STM32单片机直流电机控制加减速正反转系统proteus仿真原理图程序

    功能: 0.本项目采用STM32F103C8T6作为单片机系统的控制MCU 1.通过按键可以控制电机,正转、反转、加速、减速、停止。 2.总共六个功能按键可实现正转、反转、加速、减速、停止。 3.启停和正反转均有指示灯,测试采用的霍尔传感器方案 4.采用DC002作为电源接口可直接输入5V给

    2024年02月12日
    浏览(45)
  • 基于STM32单片机的直流电机PWM调速(数码管显示)(Proteus仿真+程序)

          由 STM32单片机+数码管显示模块+键盘模块+L298N电机驱动模块+直流电机 1、采用STM32F103单片机为主控制器 2、四个按键,分别为启动/暂停、方向切换、加速、减速功能 3、数码管显示PWM占空比和电机转动方向(0正转,1反转) 注意:proteus8.11版本才能打开   24、基于STM32单

    2024年02月11日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包