W806-ADC-PWM-TIM尝鲜
这是目录
- 前言
- 一、编程
- 1. ADC编程
- 1.1、查端口
- 2、PWM编程
- 2.1、查手册
- 2.2、PWM编程
- 3、TIM编程
- 3.1、编程
- 4、 完整程序及计算方式
- 5、效果展示
本文使用环境:
电脑:windows10
主控:W806(240MHZ)
编译环境:平头哥的CDK
注意:本文默认已经搭建好平台。
前言
写这篇问章的目的是记录一下自己的ADC使用路程,前期这个ADC我是一直没有看明白,后面才搞的是懂非懂。
当然本文肯定不止使用ADC,那样显得没有技术水平,SO,为了提升技术难度,在adc的基础上加了一点点东西:
使用PB0产生100KHZ动态变化的的PWM,然后由PA1的ADC获取到,并转化成实际的电压。B0产生的PWM通过不断的改变比较值可以输出不同的电压,所以就能够满足ADC的采集要求,这里需要注意的是,不能直接测量电源电压,要不然要烧。。。。。
完整程序下载:
https://download.csdn.net/download/qq_37280428/48278788
一、编程
1. ADC编程
官方也有ADC的demo,所以这里主要说一下ADC的初始化以及,值读取出来后如何转化成实际的电压值。
具体的参考官方程序,
1.1、查端口
要编程之前我们首先要确定使用的外设IO,所以第一步打开官方数据手册,看看哪些口是可以使用的,打开如下文档。
直接ctrl+F,可以发现这个编号是非常奇怪的。
我们使用A1即可,默认也是A0所以问题不大,同时我们看一下文档中关于ADC的章节。
明确说明了,ADC最多只能是2.4V,所以,这就是之前说的不能直接接电源电压。。。。。。
同时查看ADC的参数信息(W806 MCU 芯片规格书 V2.0):这参数一般般
2、PWM编程
2.1、查手册
首先查手册,设计指导书和规格书都可以查,发现有很多的IO都是可以选择的,这里选择B0,PWM0。
除此之外,我们还需要打开一个手册:
翻到如下章节:
PWM时钟频率是3-160KHz,这都是后续需要设置的地方。
2.2、PWM编程
PWM的初始化需要特别注意,如果单独使用PWM0,使用官方的教程没有问题,但是如果你想使用 多路PWM,并且需要每一路单独输出PWM,就需要对PWM的初始化做修改。官方的初始化如下:(这个初始化不能完成每一路PWM单独输出)
static void PWM_Init(void)
{// 输出100KHz、占空比40%的波形hpwm.Instance = PWM;hpwm.Init.AutoReloadPreload = PWM_AUTORELOAD_PRELOAD_ENABLE;hpwm.Init.CounterMode = PWM_COUNTERMODE_EDGEALIGNED_DOWN;hpwm.Init.Prescaler = 4;hpwm.Init.Period = 99; // 40M / 4 / 100K - 1hpwm.Init.Pulse = 0; // 0% DUTYhpwm.Init.OutMode = PWM_OUT_MODE_5SYNC;hpwm.Channel = ch;HAL_PWM_Init(&hpwm);
}
其中Pulse 表示占空比,such as:Pulse 设置成0 就表示低电平,设置成Period /2就表示50%的占空比,设置成Period 就表示高电平,中间的就是高电平和低电平之比。动态改变这个值就可以输出可占空比波形。特别需要注意的是,由于ADC的输入电压不能高于2.4V所以,这里我做了限幅,在下面的完整程序中有设置,为什么是70? 3.3*0.7 = 2.31V 满足要求。
#define adc_max 70
同时这里需要注意两个点:
1、频率设置
系统默认输出的是100K的信号,那问题来了 这100K是如何设置的呢???
经过我的不断尝试,我发现,PWM的时钟输入默认是40MHz,所以这里直接按照40MHz,计算。这里直接给公式,自己去算。
输出频率 khz = 40000kHZ/4(分频系数)/(Period+1)
2、输出模式
观察上述代码的OutMode 设置的是PWM_OUT_MODE_5SYNC,字面意思,5通道同步模式,也就是说,每个通道输出的PWM都是一样的,如果单独输出需要修改为独立模式。按住ctrl然后单击PWM_OUT_MODE_5SYNC,即可跳转到宏定义的地方:
// PWM_Out_Mode
#define PWM_OUT_MODE_INDEPENDENT 0x00
#define PWM_OUT_MODE_2SYNC 0x01
#define PWM_OUT_MODE_2COMPLEMENTARY 0x02
#define PWM_OUT_MODE_5SYNC 0x03
#define PWM_OUT_MODE_BREAK 0x04
这是五种不同的模式,第一种就是独立,所以有需要单独使用没一路PWM的,可以直接改成第一种。
static void PWM_Init(void)
{// 输出100KHz、占空比40%的波形hpwm.Instance = PWM;hpwm.Init.AutoReloadPreload = PWM_AUTORELOAD_PRELOAD_ENABLE;hpwm.Init.CounterMode = PWM_COUNTERMODE_EDGEALIGNED_DOWN;hpwm.Init.Prescaler = 4;hpwm.Init.Period = 99; // 40M / 4 / 100K - 1hpwm.Init.Pulse = 0; // 0% DUTYhpwm.Init.OutMode = PWM_OUT_MODE_INDEPENDENT; //独立通道输出hpwm.Channel = ch;HAL_PWM_Init(&hpwm);
}
其他的完全按照教程走就可以了。
3、TIM编程
3.1、编程
这个编程不再赘述,按照官方demo出来就行。本文设置成==1000000US。==每1S改变一次PWM的值,改变一次输出电压。
4、 完整程序及计算方式
话不多说直接上程序。
#include <stdio.h>
#include "wm_hal.h"#define ADC_Voltage_LSB 0.0013
#define adc_max 70 //PWM输出的最大值,按照周期100来算的。3.3*0.7 = 2.31void Error_Handler(void);
//ADC INIT
static void ADC_Init(void);
ADC_HandleTypeDef hadc;//PWM init
PWM_HandleTypeDef hpwm;
static void PWM_Init(void);
void Error_Handler(void);
uint32_t ch = PWM_CHANNEL_0;//TIME init
TIM_HandleTypeDef htim0;
static void TIM0_Init(void);int main(void)
{SystemClock_Config(CPU_CLK_240M);printf("enter main\r\n");//使用通道0 B0PWM_Init();HAL_PWM_Start(&hpwm, ch);//使用通道0 A0ADC_Init();//定时器 TIME0TIM0_Init();//在wm_it.c文件中,需要修改对应的参数HAL_TIM_Base_Start_IT(&htim0);while (1){;}
}static void TIM0_Init(void)
{htim0.Instance = TIM0;htim0.Init.Unit = TIM_UNIT_US;htim0.Init.Period = 1000000; //1shtim0.Init.AutoReload = TIM_AUTORELOAD_PRELOAD_ENABLE;if (HAL_TIM_Base_Init(&htim0) != HAL_OK){Error_Handler();}
}/* 输出波形的频率: f = 40MHz / Prescaler / (Period + 1);* 输出波形的占空比: * 沿对齐模式(递减):(Pulse + 1) / (Period + 1)* Pulse >= Period:PWM输出一直为高电平* Pulse < Period :PWM输出高电平宽度为(Pulse + 1),低电平宽度为(Period - Pulse)* Pulse = 0 :PWM输出高电平宽度为(1),低电平宽度为(Period)* * 中间对齐模式 :(2 * Pulse + 1) / (2 * (Period + 1))* Pulse > Period :PWM输出一直为高电平* Pulse <= Period:PWM输出高电平宽度为(2 * Pulse + 1),低电平宽度为(2 * (Period - Pulse) + 1)* Pulse = 0 :PWM输出高电平宽度为(1),低电平宽度为(2 * Period + 1)*/
static void PWM_Init(void)
{// 输出100KHz、占空比40%的波形hpwm.Instance = PWM;hpwm.Init.AutoReloadPreload = PWM_AUTORELOAD_PRELOAD_ENABLE;hpwm.Init.CounterMode = PWM_COUNTERMODE_EDGEALIGNED_DOWN;hpwm.Init.Prescaler = 4;hpwm.Init.Period = 99; // 40M / 4 / 100K - 1hpwm.Init.Pulse = 0; // 0% DUTYhpwm.Init.OutMode = PWM_OUT_MODE_5SYNC;hpwm.Channel = ch;HAL_PWM_Init(&hpwm);
}
//1K的频率
static void ADC_Init(void)
{hadc.Instance = ADC;hadc.Init.channel = ADC_CHANNEL_0;hadc.Init.freq = 1000;if (HAL_ADC_Init(&hadc) != HAL_OK){Error_Handler();}
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{}//可以理解成定时器服务函数
//1S
void HAL_TIM_Callback(TIM_HandleTypeDef *htim)
{static int8_t adc_num = 1;static bool adc_flage = 1;if (htim->Instance == TIM0){if(adc_num > adc_max ||adc_num <= 0)adc_flage = !adc_flage;if(0 == adc_flage) adc_num++;elseadc_num--;HAL_PWM_Duty_Set(&hpwm, PWM_CHANNEL_0, adc_num);int16_t value_2 = HAL_ADC_GET_INPUT_VOLTAGE(&hadc) - 14; //14ADC是对地测量值,这个值需要根据实际情况进行测量,我的板子是这么多,不代表你的板子也是。//这一步是防止减出来是负值,会出错的if(0 >= value_2)value_2 = 0;float V_actural = value_2*ADC_Voltage_LSB; //ADC_Voltage_LSB 表示实际电压和ADC数值之间的关系,还是比较线性的。printf(" %d %0.2fV \r\n",value_2,V_actural);}
}void Error_Handler(void)
{while (1){}
}void assert_failed(uint8_t *file, uint32_t line)
{printf("Wrong parameters value: file %s on line %d\r\n", file, line);
}
程序中的ADC_Voltage_LSB表示实际电压和adc数值之间的线性系数 ADC_Voltage_LSB = 理论 / 实际adc读数。
这个系数是我多次测量得出来的结果。
第一列是万用表测出来PWM输出电压(PWM间隔10%,即0.33),第二列是ADC读出来的数值,第三列是理论上PWM的输出电压:当然这只是粗略值,看的出来也还行。
5、效果展示
电压是先变小再变大,然后再变小变大,依次循环。
W806-ADC-PWM-TIM尝鲜相关推荐
- 读标准03-IEEE1451.5标准协议尝鲜实现
读标准03-IEEE1451.5标准协议尝鲜实现 前面两个文章里面已经详细描述了 TEDS 和 Message 的组成,这里 C 的实现分两个部分:分别对 TEDS 和 Message 的 数据结构实 ...
- STM32f103ZET6引脚通道(ADC和TIM)
STM32F103ZET6是一款基于ARM Cortex-M3内核的微控制器,具有三个12位ADC和五个16位TIM.这些功能之间在一定程度上存在差异. 对于ADC,STM32F103ZET6具有三个 ...
- galaxy android 8,三星终于正式升级安卓8.0!Galaxy S8尝鲜
原标题:三星终于正式升级安卓8.0!Galaxy S8尝鲜 经过长时间的测试,在友商陆续吃上奥利奥之后,三星终于开始向Galaxy S8/S8+正式推送安卓8.0,也带来了新的Experience U ...
- 鸿蒙系统开发者公测,公测尝鲜开启!华为Mate40/P40开始和安卓渐行渐远
目前华为官方发布公告,华为EMUI的微博等相关官方媒体账号全部更名为HarmonyOS,这也意味着HarmonyOS将会成为华为在软件系统层面的重心,彻底替代基于Android的华为EMUI. 至于那 ...
- 华为鸿蒙去哪里更新,华为鸿蒙OS正式尝鲜版名单更新,升级?还是不升级?
原标题:华为鸿蒙OS正式尝鲜版名单更新,升级?还是不升级? 请点击[关注],获取更多数码资讯 华为鸿蒙系统正式版本已经开始推送,公测尝鲜版与正式尝鲜版机型名单已经更新:"Mate40系列.M ...
- K3s初探:Rancher架构师带你尝鲜史上最轻量Kubernetes发行版
发布不到两天,GitHub上Star数已近3000,这个业界大热的.史上最轻量的开源Kubernetes发行版,你试过了没? Rancher资深架构师来教你走出尝鲜第一步!使用教程在此! 前 言 昨天 ...
- 特斯拉自动驾驶新能力:识别红绿灯停车标识;尝鲜车主:实用好用
白交 发自 凹非寺 量子位 报道 | 公众号 QbitAI 特斯拉,现在可以买到的最有智能化体验的汽车. 撇开安全话题,自动驾驶的能力和功能,一直走在行业最前沿. 这不,城区道路驾驶里,连交通信号灯 ...
- android oppo 权限,OPPO Reno可尝鲜Android Q:教程如下
原标题:OPPO Reno可尝鲜Android Q:教程如下 5月8日凌晨,Android Q在谷歌I/O开发者大会上正式亮相.在I/O大会现场,谷歌公布了首批Android Q升级名单,其中OPPO ...
- 前端每周清单第 49 期:Webpack 4 Beta 尝鲜,React Windowing 与 setState 分析
前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点:分为新闻热点.开发教程.工程实践.深度阅读.开源项目.巅峰人生等栏目.欢迎关注[前端之巅]微信公众号(ID: fron ...
- 尝鲜Ubuntu Server 12.04 LTS
作为一个尝试远离Windows的Linux初学者,一直都比较关注对初学者来说比较简单的Ubuntu Server. 4月中旬之后有几次都需要装DB服务器,因为希望能够使用最新版本,所以就一直在等Ubu ...
最新文章
- 二分法:二分查找(递归+非递归)实现
- 使用vux+ajax,Vue 应用中结合vux使用微信 jssdk的方法
- php 文件夹里有多少,计算目录php中有多少个文件
- PyCharm 3.0 发布,提供免费开源版本
- 【leetcode】股票买卖系列总结
- SEO实战密码阅读笔记
- 微信公众号php支付设置回调,php微信公众号支付讲解(JSAPI)
- 毕业设计 大学生心理健康管理平台
- 2020年北京给进口摩托车(川崎)交税、验车、上牌照流程
- 鼠标右键没有word、excel/右键不能新建word、ppt等office
- 深度 | 蚂蚁金服DASFAA论文带你深入了解GBDT模型
- UBI文件系统的制作与挂载案例
- Deepin 使用教程:前言
- 百度地图定位经纬度返回4.9E-324有关问题
- 【计算机基础】中英文常用名词对照
- 你真的了解AsyncTask吗?AsyncTask源码分析
- MPU6050传感器数据处理
- sed 注释行的 方法
- UCK Network 以用户至上、体验为王为核心, 打造完善的综合体验平台
- 区块链 fisco bcos 2.72 在多机器上部署多个docker节点 ubuntu
热门文章
- Windows 10 1703创意者更新官方ISO镜像大全
- 计算机网络工程这专业都学什么,网络工程专业学什么
- 如何写一个好的缺陷(Defect)报告
- MATLAB:图像半调转换(halftone)和抖动转换(dither)
- 【优秀毕设V2.0】基于树莓派的OpenCV-Python摄像头人脸追踪及手势识别、网络地址推流及远程控制系统(多功能系统、含演示视频)
- 43.Django04
- SeaWeedfs 分布式网络文件存储介绍
- 计算机系统的还原及备份,win7系统备份与还原功能怎么用?win7系统使用备份与还原功能的方法...
- 机器视觉OpenCV-sobel、robert、gauss算子边缘检测
- 你知道哪六种传统早餐不能吃吗?