【沧海拾昧】Proteus8仿真stm32:ADC转换程序
#C0102
沧海茫茫千钟粟,且拾吾昧一微尘
——《沧海拾昧集》@CuPhoenix
【阅前敬告】
沧海拾昧集仅做个人学习笔记之用,所述内容不专业不严谨不成体系
如有问题必是本集记录有谬,切勿深究
目录
一、原理图绘制
二、多位七段数码管
三、ADC引脚
四、代码
五、仿真问题
一、原理图绘制
![](/assets/blank.gif)
图中所用到的元件和元件在库中的名称对照表如下:
元件名 | 库中名称 |
---|---|
可变电阻 | POT-HG |
STM32F103R6 | STM32F103R6 |
4位7段共阴数码管 | 7SEG-MPX4-CC |
高电平 | POWER |
地 | GROUND |
二、多位七段数码管
1、共阴管是CC,共阳管是CA,对应的译码表如下。
![](/assets/blank.gif)
2、输入信号A~G、DP的有效信号看是共阴还是共阳,对应的片选信号1~4是低电平有效,从左到右依次为第1位至第4位。
片选位数 | 1 | 2 | 3 | 4 |
---|---|---|---|---|
片选码 | 0x0e00 | 0x0d00 | 0x0b00 | 0x0700 |
3、输出的示例。数字码0x6f,片选码0x0e00,输出码即二者相加0x0e6f。
GPIO_Write(GPIOC, 0x0e6f );
![](/assets/blank.gif)
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++){}}
}
仿真结果。
![](/assets/blank.gif)
三、ADC引脚
![](/assets/blank.gif)
图源 @夜路难行々
四、代码
#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); // 校准ADCwhile(ADC_GetCalibrationStatus(ADC1));ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 软件触发ADCwhile (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);#elseRCC_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);#endifRCC_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){}
}
#endifvoid delay(){int i=0,j=0;for(i=0;i<5;i++){for(j=0;j<100;j++){}}
}
五、仿真问题
![](/assets/blank.gif)
仿真遇到问题。无论如何调节输入,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也不行。
此问题悬而未决,若有大神路过欢迎赐教!
敬谢诸君。
京华西山之巅。
【沧海拾昧】Proteus8仿真stm32:ADC转换程序相关推荐
- 【沧海拾昧】Keil uVision5新建stm32工程并联合Proteus 8 Professional简单仿真
#C0101 沧海茫茫千钟粟,且拾吾昧一微尘 --<沧海拾昧集>@CuPhoenix [阅前敬告] 沧海拾昧集仅做个人学习笔记之用,所述内容不专业不严谨不成体系 如有问题必是本集记录有谬, ...
- 【沧海拾昧】MATLAB/Simulink仿真的基本操作
#C0402 沧海茫茫千钟粟,且拾吾昧一微尘 --<沧海拾昧集>@CuPhoenix [阅前敬告] 沧海拾昧集仅做个人学习笔记之用,所述内容不专业不严谨不成体系 如有问题必是本集记录有谬, ...
- 【沧海拾昧】微机原理:存储器系统
#C0302 沧海茫茫千钟粟,且拾吾昧一微尘 --<沧海拾昧集>@CuPhoenix [阅前敬告] 沧海拾昧集仅做个人学习笔记之用,所述内容不专业不严谨不成体系 如有问题定为本集记录有谬, ...
- 【沧海拾昧】微机原理:8086/8088中断系统
#C0305 沧海茫茫千钟粟,且拾吾昧一微尘 --<沧海拾昧集>@CuPhoenix [阅前敬告] 沧海拾昧集仅做个人学习笔记之用,所述内容不专业不严谨不成体系 如有问题定为本集记录有谬, ...
- 【沧海拾昧】WiFi串口通信ESP8266模块基本介绍(附野火WiFi透传实例)
#C0104 沧海茫茫千钟粟,且拾吾昧一微尘 --<沧海拾昧集>@CuPhoenix [阅前敬告] 沧海拾昧集仅做个人学习笔记之用,所述内容不专业不严谨不成体系 [如有问题必是本集记录有谬 ...
- 【沧海拾昧】C# .Net 基本控件介绍
#C0201 沧海茫茫千钟粟,且拾吾昧一微尘 --<沧海拾昧集>@CuPhoenix [阅前敬告] 沧海拾昧集仅做个人学习笔记之用,所述内容不专业不严谨不成体系 如有问题必是本集记录有谬, ...
- 【沧海拾昧】微机原理:可编程中断控制器8259A芯片
#C0306 沧海茫茫千钟粟,且拾吾昧一微尘 --<沧海拾昧集>@CuPhoenix [阅前敬告] 沧海拾昧集仅做个人学习笔记之用,所述内容不专业不严谨不成体系 如有问题定为本集记录有谬, ...
- 【沧海拾昧】微机原理:可编程计数器/定时器8253芯片
#C0303 沧海茫茫千钟粟,且拾吾昧一微尘 --<沧海拾昧集>@CuPhoenix [阅前敬告] 沧海拾昧集仅做个人学习笔记之用,所述内容不专业不严谨不成体系 如有问题定为本集记录有谬, ...
- 【沧海拾昧】用MATLAB画一张简单的图
#C0401 沧海茫茫千钟粟,且拾吾昧一微尘 --<沧海拾昧集>@CuPhoenix [阅前敬告] 沧海拾昧集仅做个人学习笔记之用,所述内容不专业不严谨不成体系 如有问题定为本集记录有谬, ...
最新文章
- 使用PCA对特征数据进行降维
- 一个创业者的自我修养2019版
- python性能分析工具_Python Profilers 分析器
- HALCON示例程序clip.hdev曲别针方向识别
- matlab linspace
- Java 计算两个日期时间差,天数、时、分、秒
- 泰晤士计算机排名2021,THE2021年世界大学专业排名-计算机
- 作文 深海机器人_海底寻宝机器人
- 吴裕雄 15-MySQL LIKE 子句
- libtorch下tensor与img的互相转换
- 使用C#如何写入/读取注册表信息
- Mintec.MineSight.3D.v7.0.3
- 计算机毕业设计JAVA鸿鹄教育培训mybatis+源码+调试部署+系统+数据库+lw
- 成功破解某app加密接口
- Microsoft JScript 运行时错误: Automation 服务器不能创建对象
- linux 如何清理垃圾文件,清理Linux系统垃圾文件操作方法图文步骤详解
- 什么是云计算机服务,云平台是什么意思 云服务平台有哪些【详细介绍】
- Unity 优化Unity切换后台的问题
- 笔记本新增一块1T固态,如何将系统迁移到新的固态,无缝对接(无需重装系统,迁移后直接用)。
- 4G浏览器 随机遇而生
热门文章
- 理解对数——你需要了解的方方面面
- 手势解锁java后端设计_canvas手势解锁源码
- javacv从入门到精通——第一章:javacv介绍
- 【毕业设计】大数据网络舆情热点分析系统 - python 情感分析
- 介绍一款小尺寸高通方案无线路由WiFi模块SKW103_支持无线中继,视频传输,智能网关
- jshell如何导入外部包
- ADC 动态参数分析matlab code的几个问题(span,spanh取值问题,幅度比例因子的添加等)
- 单片机定时器c语言程序,单片机C语言编程定时器的几种表达方式
- OLED屏幕详解-显示原理
- 阳阳买苹果,每个苹果0.8元,阳阳第一天买两个,第二天开始每天买前一天的两倍,直到购买的苹果个数为不超过100的最大值,编程求阳阳每天平均花多少钱?