感谢北京化工大学何宾老师的课程指导,今天我们分享一个利用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应用实现相关推荐

  1. 一个单片机ADC的挖坑填坑之旅

    [导读] 本文来解析一个盆友在使用STM32采集电池电压踩过的坑.以STM32F4 的ADC属于逐次逼近SAR 型ADC为例进行分析,参考STM32F405xx  Datasheet,对于如何编写AD ...

  2. STM8单片机ADC带缓存的连续采样模式

      在上一篇文章中说了STM8的ADC连续采样模式,为了提高采样的精度和速率,STM8单片机还提供了带缓存的连续采样模式,也就是说ADC会连续采集8个数据,放在缓存中,读取数据时可以一次从缓存中读取8 ...

  3. 单片机ADC采样算法----递推平均值采样法

    在上一篇文章单片机ADC采样算法---平均值采样法中分析了平均值采样法的使用,上篇文章中的平均值采样法是连续采样100个数据,然后求平均值,这种方法存在一个问题,就是采集100个值之后,下一次又重新采 ...

  4. 单片机ADC采样算法----平均值采样法

    单片机在模拟电路中使用的时候,经常需要用到AD功能,而通过单片机ADC采集回来的数据往往不能直接使用,在不同场合下需要对采集到的数据要通过不同的算法对数据进行处理,先来看看最简单的平均值采样法. 平均 ...

  5. 51单片机ADC模数转换

    51单片机ADC模数转换 ADC介绍 1.ADC简介 ​        ADC(analog to digital converter)也称为模数转换器,是指一个将模拟信号转变为数字信号.单片机在采集 ...

  6. STC8单片机ADC采样注意事项

    STC8单片机ADC采样注意事项 STC8单片机ADC采样注意事项 最近在做一个模块,使用宏晶公司的STC8单片机开发,模块主要使用了单片机的ADC采样功能,因为需要10个以上的通道,而且模块要经常震 ...

  7. CH559L单片机ADC介绍以及ADC采样案例

    CH559L单片机ADC介绍以及ADC采样案例 ✨本案例基于Keil环境下开发.

  8. 1.ME32F103单片机ADC和DMA

    1. ME32F103单片机ADC和DMA 1.1 ADC配置 ADC_Init(10000, VDDA); // 设置ADC时钟频率和参考电压 ADC_SetupChannels(AD10 < ...

  9. adc0832工作原理详解_单片机ADC的工作原理

    单片机的ADC可以将模拟量转化为数字量 不同品牌的单片机ADC的配置方法有一定的差异,但基本方法和原理是一样的,启动ADC转换后,可以等待转换完成然后读取数据,或者设置为转换完成产生中断然后读取数据. ...

最新文章

  1. Java排序算法:冒泡排序
  2. 北京出台自动驾驶新规:自动驾驶车辆须配备司机应急
  3. windows和linux文件的转换
  4. 2.2.2 进程调度的 时机 切换与过程 调度方式
  5. javascript学习笔记 null和undefined
  6. 移动spa商城优化记(一)---首屏优化篇
  7. [开心学php100天]第五天:string函数(上)
  8. 60-140-040-使用-DataSink-Data Sink 介绍
  9. Kafka 分布式消息系统详解
  10. linux ftp配置和使用
  11. 防病毒必务宝典—计算机病毒专杀进程列表(转)
  12. x64位xp连接位于32位xp系统上的打印机
  13. qq空间把android改成iphone,qq空间利用代码修改iPhone6 Plus详细方法 qq空间修改手机型号教程...
  14. 创建qt DLL文件,并在代码中调用
  15. 解决NVIDIA官网打开速度过慢的 CUDA下载界面打开过慢
  16. 【编解码】从零开始写H264解码器(1) 总纲
  17. html页面调节图片大小,怎么用css设置图片大小?
  18. PET,CT图像融合笔记
  19. dubbo配置timeout
  20. WEB财务报表设计器的实现

热门文章

  1. 【转载】Tomcat崩溃事件
  2. 《倔强萝卜》让人捧腹大笑 票房黑马崛起后劲十足
  3. 信息系统管理工程师复习笔记02 计算机网络通信与信息安全 原创整理
  4. 数电课设之一路交通灯
  5. 出主意:阻止了对方倒苦水(错误行为)
  6. 第十四届蓝桥杯校内模拟赛第二期-Java个人题解(仅供参考)
  7. 中国/玩具鸭舰队/漂流15年 今夏将抵英国
  8. 如何用人机料法环来分析产品质量?
  9. 蚂蚁金服6面,成功唬住面试官拿了36K,突然感觉Java面试貌似不太难...
  10. 一起来看流星雨剧情简介/剧情介绍/剧情分集介绍第二十三集