STC15W4K32S4单片机ADC应用实现
感谢北京化工大学何宾老师的课程指导,今天我们分享一个利用STC15W4K32S4单片机实现的ADC应用,我们通过ADC转换实现在LCD1602上显示学号,并能够通过外部中断0和外部中断1分别实现学号左移和右移的功能。
以下是项目代码:
1、lcd1602.h
// 条件编译指令,如果未定义_1602_则定义_1602
#ifndef _1602_
#define _1602_// 引入头文件
#include "reg51.h"
#include "intrins.h"// 定义LCD引脚及寄存器地址
sbit LCD1602_RS = P2^5; // 定义LCD1602_RS为P2.5引脚,RS=0表示传输的是控制指令,RS=1表示传输的是数据
sbit LCD1602_RW = P2^6; // 定义LCD1602_RW为P2.6引脚,R/W=0表示读操作,R/W=1表示写操作
sbit LCD1602_E = P2^7; // 定义LCD1602_E 为P2.7引脚,E=1,单片机将数据放入数据线,一段时间后拉低,数据继续维持一段时间,即写入LCD中
sfr LCD1602_DB = 0x80; // 定义LCD1602_DB为P0端口
sfr P0M1 = 0x93; // 定义P0端口P0M1寄存器地址0x93
sfr P0M0 = 0x94; // 定义P0端口P0M0寄存器地址0x94
sfr P2M1 = 0x95; // 定义P2端口P2M1寄存器地址0x95
sfr P2M0 = 0x96; // 定义P2端口P2M0寄存器地址0x96// 申明函数
void lcdwait(); // 等待LCD空闲函数
void lcdwritecmd(unsigned char cmd); // 写LCD命令函数
void lcdwritedata(unsigned char dat); // 写LCD数据函数
void lcdinit(); // 初始化LCD函数
void lcdsetcursor(unsigned char x, unsigned char y); // 设定LCD光标位置函数
void lcdshowstr(unsigned char x, unsigned char y, unsigned char *str); // 打印字符串函数// 条件预编译指令结束
#endif
2、led1602.c
// 引入头文件
#include "led1602.h"// 实现函数
/*** 函数名:lcdwait()* 参数 :无* 功能 :等待LCD空闲*/
void lcdwait() {LCD1602_DB = 0xFF; // 读取前,置P0端口为FF,引脚相当于悬空_nop_(); // 空操作指令,延迟_nop_();_nop_();_nop_();LCD1602_RS = 0; // 将RS信号拉低LCD1602_RW = 1; // 将RW信号拉高LCD1602_E = 1; // 将E 信号拉高while(LCD1602_DB & 0x80); // 等待标志BF为低,即LCD空闲LCD1602_E = 0; // 将E 信号拉低
}/*** 函数名:lcdwritecmd()* 参数 :cmd 控制指令码* 功能 :写LCD命令*/
void lcdwritecmd(unsigned char cmd) {lcdwait(); // 等待LCD空闲_nop_();_nop_();_nop_();_nop_();LCD1602_RS = 0;LCD1602_RW = 0;LCD1602_DB = cmd; // 将控制指令码放到P0端口LCD1602_E = 1;_nop_();_nop_();_nop_();_nop_();LCD1602_E = 0;
}/*** 函数名:lcdwritecmd()* 参数 :dat 数据码* 功能 :写LCD数据*/
void lcdwritedata(unsigned char dat) {lcdwait(); // 等待LCD空闲_nop_();_nop_();_nop_();_nop_();LCD1602_RS = 1;LCD1602_RW = 0;LCD1602_DB = dat; // 将数据码放到P0端口LCD1602_E = 1;_nop_();_nop_();_nop_();_nop_();LCD1602_E = 0;
}/*** 函数名:lcdinit()* 参数 :无* 功能 :初始化LCD*/
void lcdinit() {lcdwritecmd(0x38); // 发指令0x38,2行模式,5x8点阵,8位宽度lcdwritecmd(0x0c); // 发指令0x0c,打开显示,关闭光标lcdwritecmd(0x06); // 发指令0x06,文字不移动,地址自动加1lcdwritecmd(0x01); // 发指令0x01,清屏
}/*** 函数名:lcdsetcursor()* 参数 :x 在LCD上的列数* y 在LCD上的行数* 功能 :设定LCD光标位置*/
void lcdsetcursor(unsigned char x, unsigned char y) {unsigned char address; // 存储器地址if(y==0) // 在第一行address = 0x00 + x;else // 在第二行address = 0x40 + x;lcdwritecmd(address | 0x80); // 写存储器地址指令
}/*** 函数名:lcdshowstr()* 参数 :x 在LCD上的列数* y 在LCD上的行数* str 需要打印的字符串* 功能 :打印字符串*/
void lcdshowstr(unsigned char x, unsigned char y, unsigned char *str) {lcdsetcursor(x, y); // 设置光标位置while((*str) != '\0') { // 字符串未到结尾lcdwritedata(*str); // 传送字符数据str++; // 字符串地址自增}
}
3、main.c
// 引入头文件
#include "reg51.h"
#include "stdio.h"
#include "led1602.h"#define ADC_POWER 0x80 // 定义ADC_POWER 的值为0x80
#define ADC_FLAG 0x10 // 定义ADC_FLAG 的值为0x10
#define ADC_START 0x08 // 定义ADC_START 的值为0x08
#define ADC_SPEEDLL 0x00 // 定义ADC_SPEEDLL的值为0x00
#define ADC_SPEEDL 0x20 // 定义ADC_SPEEDL 的值为0x20
#define ADC_SPEEDH 0x40 // 定义ADC_SPEEDH 的值为0x40
#define ADC_SPEEDHH 0x60 // 定义ADC_SPEEDHH的值为0x60sfr AUXR = 0x8E; // 申明AXUR寄存器的地址为0x8E
sfr ADC_CONTR = 0xBC; // 申明ADC_CONTR控制寄存器的地址为0xBC
sfr ADC_RES = 0xBD; // 申明ADC_RES结果寄存器的地址为0xBD
sfr ADC_RESL = 0xBE; // 申明ADC_RESL结果寄存器的地址为0xBE
sfr P1ASF = 0x9D; // 申明P1ASF模拟功能控制寄存器的地址为0x9D// 在外部数据区定义变量,用于存储学号
xdata long num1 _at_ 0x100; // 定义长整形变量num1
xdata float num2 _at_ 0x120; // 定义浮点数变量num2unsigned char ch = 4;
bit flag = 1; // ADC转换完成标识
unsigned char tstr[50]; // 数据存储缓冲器/*** 函数名:delay* 参数 :n 延迟时间长度,单位毫秒* 功能 :延时指定的毫秒时间*/
void delay(unsigned int n) { unsigned int i, j; for(i = n; i > 0; i--) {for(j = 114; j > 0; j--);}
}/*** 函数名:adc_int* 参数 :无* 功能 :ADC中断响应函数*/
void adc_int() interrupt 5 {unsigned char i = 0;ADC_CONTR &= !ADC_FLAG; // 将ADC_FLAG标志清零num1 = 2016014446;num2 = 2016014446;sprintf(tstr + 10, "%lld", num1); // 将数据传送至缓冲区flag = 1; // ADC转换完成ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch; // 启动ADC
}/*** 函数名:move_left* 参数 :无* 功能 :外部中断0中断响应函数,实现学号在LCD上左移*/
void move_left() interrupt 0 {unsigned char i;for(i = 0; i < 11; i++){lcdwritecmd(0x01); // 清屏lcdwait(); // 等待LCD空闲lcdshowstr(0, 0, tstr+10+i); // 右移数组地址,写字符串lcdwait();delay(3000); // 延时等待}
}/*** 函数名:move_right* 参数 :无* 功能 :外部中断1中断响应函数,实现学号在LCD上右移*/
void move_right() interrupt 2 {unsigned char i;for(i = 6; i < 17; i++){lcdwritecmd(0x01); // 清屏lcdwait(); // 等待LCD空闲lcdshowstr(i, 0, tstr+10); // 右移光标位置,写字符串lcdwait();delay(3000); // 延时等待}
}/*** 函数名:main* 参数 :无* 功能 :主函数,在LCD上打印学号,响应中断*/
void main() {unsigned int i, k;P0M0 = 0; // 通过P0M0和P0M1寄存器将P0口定义为准双向(双向IO),弱上拉(上拉电阻很大,提供的驱动电流很小,叫弱上拉)P0M1 = 0;P2M0 = 0; // 通过P2M0和P2M1寄存器将P2口定义为准双向,弱上拉P2M1 = 0;P1ASF = 0xFF; // 将P1端口用于ADC输入ADC_RES = 0; // 将ADC_RES寄存器清零ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch; // 配置ADC_CONTR寄存器for(i = 0; i < 10000; i++);IE = 0xA0; // 允许ADC中断lcdwait(); // 等待LCD空闲lcdinit(); // 初始化LCDIT0 = 1; // 开启外部中断0和外部中断1EX0 = 1;IT1 = 1;EX1 = 1;EA = 1;while(1) { if(flag == 1) {flag = 0;for(k = 0; k < 16; k++) {// 循环打印学号lcdwritecmd(0x01);lcdwait();lcdshowstr(k, 0, tstr+10);if(k > 6)lcdshowstr(0, 0, tstr+26-k);lcdwait();delay(500);}}}
}
有关讲解的视频欢迎关注我们的公众号:落饼枫林,查看历史推送:STC15W4K32S4单片机ADC应用实现。
想要学习更多单片机的知识也欢迎参加何老师在爱课程网站上的单片机原理及应用的课程:https://www.icourse163.org/learn/BUCT-1205804839#/learn/announce
STC15W4K32S4单片机ADC应用实现相关推荐
- 一个单片机ADC的挖坑填坑之旅
[导读] 本文来解析一个盆友在使用STM32采集电池电压踩过的坑.以STM32F4 的ADC属于逐次逼近SAR 型ADC为例进行分析,参考STM32F405xx Datasheet,对于如何编写AD ...
- STM8单片机ADC带缓存的连续采样模式
在上一篇文章中说了STM8的ADC连续采样模式,为了提高采样的精度和速率,STM8单片机还提供了带缓存的连续采样模式,也就是说ADC会连续采集8个数据,放在缓存中,读取数据时可以一次从缓存中读取8 ...
- 单片机ADC采样算法----递推平均值采样法
在上一篇文章单片机ADC采样算法---平均值采样法中分析了平均值采样法的使用,上篇文章中的平均值采样法是连续采样100个数据,然后求平均值,这种方法存在一个问题,就是采集100个值之后,下一次又重新采 ...
- 单片机ADC采样算法----平均值采样法
单片机在模拟电路中使用的时候,经常需要用到AD功能,而通过单片机ADC采集回来的数据往往不能直接使用,在不同场合下需要对采集到的数据要通过不同的算法对数据进行处理,先来看看最简单的平均值采样法. 平均 ...
- 51单片机ADC模数转换
51单片机ADC模数转换 ADC介绍 1.ADC简介 ADC(analog to digital converter)也称为模数转换器,是指一个将模拟信号转变为数字信号.单片机在采集 ...
- STC8单片机ADC采样注意事项
STC8单片机ADC采样注意事项 STC8单片机ADC采样注意事项 最近在做一个模块,使用宏晶公司的STC8单片机开发,模块主要使用了单片机的ADC采样功能,因为需要10个以上的通道,而且模块要经常震 ...
- CH559L单片机ADC介绍以及ADC采样案例
CH559L单片机ADC介绍以及ADC采样案例 ✨本案例基于Keil环境下开发.
- 1.ME32F103单片机ADC和DMA
1. ME32F103单片机ADC和DMA 1.1 ADC配置 ADC_Init(10000, VDDA); // 设置ADC时钟频率和参考电压 ADC_SetupChannels(AD10 < ...
- adc0832工作原理详解_单片机ADC的工作原理
单片机的ADC可以将模拟量转化为数字量 不同品牌的单片机ADC的配置方法有一定的差异,但基本方法和原理是一样的,启动ADC转换后,可以等待转换完成然后读取数据,或者设置为转换完成产生中断然后读取数据. ...
最新文章
- python编程下载安卓版-python编程入门
- php获取 POST请求的数据
- 关于ASP.NET未能映射路径问题
- 项目管理(6):备战pmp
- 解析/etc/inittab 文件(转)
- 调整地面材质_【C4DtoA 13】Arnold渲染器(材质七): Shadow Matte Shader
- 1.4.2.PHP5.6 狐教程-环境(Mac下 PHP开发环境 配置及安装 php5.6.x nginx mysql)
- 基于聚类算法与随机森林算法的手机终端换机推荐
- Chrome 谷歌浏览器将整个网页保存为图片
- Network(无向图割点,tarjan)
- 数据分析师是什么,深度解析数据分析师
- css背景图与html插入img的区别,css背景图与html插入img的区别
- Android仿qq登陆界面
- See system logs and ‘systemctl status docker.service‘ for details
- jsp左侧菜单栏_HTML页面左侧菜单栏切换实现右侧主体内容改变
- h3c服务器系统丢失,某局点H3C FlexServer R390服务器阵列失败数据丢失的经验案例...
- input标签 设置纯数字输入
- 十张图,看数据分析如何赋能销售
- entity、bo、vo、po、dto、pojo如何理解和区分?
- 计算机网络三大必备书,网络十大神书据说都看过的可以成仙