ATmega8仿真——LED 数码管的学习
1. I/O 口的结构及特点
- Atmega8 有23 个I/O 引脚,分成3 个8 位的端口B、C 和D,其中C 口只有7 位
- Atmega8 采用3个8位寄存器来控制I/O端口,它们分别是:方向寄存器DDRx、数据寄存器PORTx、输入引脚寄存器PINx
x为B或C 或D,分别代表B口、C口或D 口;
n为0~7,代表寄存器中的位置;
其中DDRx 和PORTx 是可读写寄存器,而PINx 为只读寄存器;
每个I/O引脚内部都有独立的上拉电阻电路,可通过程序设置内部上拉电阻是否有效。
方向寄存器DDRx中的每个位用于控制I/O口一个引脚的输入输出方向,即控制I/O口的工作模式为输出模式还是输入模式。
- 当DDRxn=1 时,I/O 的Pxn 引脚处于输出模式。此时
若PORTxn=1时,I/O引脚呈高电平,同时可提供输出20mA 的电流;
若PORTxn=0时,I/O引脚呈低电平,同时可吸收20mA 的电流。
- 当 DDRxn=0 时,I/O 的Pxn 引脚处于输入模式。此时
引脚寄存器PINxn 中的数据就是外部引脚的实际电平;
此时可通过PORTxn 的设置可控制内部的上拉电阻使用或不使用。
注意事项:
- 使用AVR的I/O 口,首先应正确设置其工作模式(输入模式还是输出模式),设置DDRx;
- 当I/O工作在输入模式(DDRxn=0)时,读取引脚上的电平应取PINxn的值,而不是PORTxn的值;
- 当I/O口工作在输入模式(DDRxn=0)时,应根据实际情况设置内部上拉电阻,利用内部上拉电阻可以节省外部上拉电阻;
- 将I/O空工作模式由输出模式设置为输入模式后,必须等待一个时钟周期后才能正确的读到外部引脚的值
2. 跑马灯程序控制发光二极管
我们选择用PD0~PD7来控制8个发光二极管循环点亮,从而实现“跑马灯”
所以电路图如图所示:
C程序如下:
1 //延时1MS 2 void delay_1ms() 3 { 4 unsigned int i; 5 for(i=1;i<(unsigned int)(1144-2);i++) 6 ; 7 } 8 //延时nMS 9 void delay_ms(unsigned int n) 10 { 11 unsigned int i=0; 12 for(i=0;i<n;i++) 13 { 14 delay_1ms(); 15 } 16 } 17 //主函数,依次顺序打开LED 18 int main() 19 { 20 unsigned char i; 21 DDRD = 0xFF; //设置D口为输出模式 22 PORTD = 0xFF; //置高电平 23 while(1) 24 { 25 for(i=0;i<8;i++) //顺序打开LED 26 { 27 PORTD = ~(1<<i); //点亮的位置低电平 28 delay_ms(200); 29 } 30 } 31 return 0; 32 }
跑马灯
问:如果改变 delay_ms 的时间会变的怎样呢?
=> 跑马灯的变换速度改变。
问:如果直接让 PORTD = ( 1<<i )呢?
=> PORTD = ~( 1<<i ):每次只亮一个灯;
=> PORTD = ( 1<<i ):每次只有一个灯是不亮的,其余灯都亮着。
问:能不能添加或修改程序,改变灯亮的顺序和时间呢?
=> 改变循环条件就可以改变亮灯的顺序,如把i++改为i+=2,即可实现隔一盏灯亮一个;
=> 亮灯时间改变延迟时间delay_ms()的传入参数即可。
3. 单个LED数码管练习
给数码管的a、b、c、d、e、f、g七个发光二极管加不同的电平,二极管显示不同亮暗的组合就可以显示不同的字形;
以1为高电平,0为低电平,给出字形码表:
即0x3F表示的就是字型‘0’,0x06表示的就是字型‘1’......;
所以直接把这种对应关系存到一个Char型数组里(一个Char型是8位);
想要对应的a、b、c、d、e、f、g七个发光二极管展示亮与暗,我们选用PD0~7这8位来控制;
如:想要展示字型‘0’ => ‘0’对应字形码是0x3F => 其中发光二极管的a~f均为亮状态 => PD0~5均为低电平(低电平亮灯)。
我们用一个LED数码管显示数字0~9,仍然使用PD口控制,循环显示数字
电路图如图所示:
了解理论知识后便可以开始编程:(延时函数与上面相同)
1 void main() 2 { 3 unsigned char i; 4 unsigned char num[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; 5 6 DDRD = 0xFF; //设置D口为输出模式 7 PORTD = 0xFF; //置高电平 8 9 while(1) 10 { 11 for(i=0;i<10;i++) //LED数码管顺序显示字型0~9 12 { 13 PORTD = num[i]; 14 delay_ms(500); 15 } 16 } 17 }
单个LED数码管
问:想显示A~F 怎么办呢?
=> num[] 数组再添加多几个元素,分别是A~F对应的字形码。
问:能不能显示像H,L 一类的字母呢?
=> 能,想要显示字母H,只需要二极管的b、c、e、f、g亮即可;
=> 想要显示字母L,只需要二极管的d、e、f亮即可。
问:改变了delay_ms 函数的延时时间会怎样呢?
=> 数字之间的显示间隔边长。
问:要显示小数点我们应该怎么办呢?
=> 在字形码表中可以看出,最高位h是没有作用的,所以可以用h位来控制小数点,当最高位为1时小数点亮,为0时不亮;
=> 如0x5B表示‘2’,那么0x5B + 0x80表示‘2.’。
4.多个LED数码管实验
静态显示:3小节的内容便是静态展示
动态显示:采用各数码管循环轮流的显示的方法,当循环频率较高时,利用人眼的暂留特性,感觉不到数码管的闪烁,就像看到数码管在同时发光一样,类似电影的原理。
两者对比:动态显示比静态显示占用资源少,耗电少;但是稳定性却差,程序设计也更为复杂,MCU负担重。
动态显示需要一个接口完成字形码的输出,另外一个接口完成各数码管的轮流显示;
我们要实现从“000.0”到“999.9”的数字变化显示过程;
用PB口做字形码的输出口,用PC0~PC3控制数码管的轮转流显示;
从左数起,其中PC0表示第0个数,PC1表示第1个数,PC2表示第3个数(该数显示小数点),PC3表示第4个数;所以只有第三个数是特殊的;
参考原理图如下:
代码实现如下:
1 void main() 2 { 3 //PB口做字形码的输出口,PC0~PC3控制数码管的轮流显示 4 unsigned char i,j; 5 static unsigned char LedNum[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; 6 //显示小数点要加0x80 7 unsigned char CountNum[4] = {0,0,0,0}; //计数的百、十、个位和十分位 8 DDRB = 0xFF; //设置B口为输出模式 9 PORTB = 0xFF; //置高电平 10 DDRC = 0x0F; 11 PORTC = 0xFF; 12 13 while(1) 14 { 15 i=0; //用于PC0~PC3的轮转 16 for(j=0;j<10;j++) //依次显示4S"000.0" 17 { 18 i = ++i%4; 19 PORTC&=~(1<<i); 20 if(2==i) //如果是第三个数字则加个小数点显示 21 PORTB = LedNum[0] + 0x80; 22 else //其余情况都没有小数点显示 23 PORTB = LedNum[0]; 24 delay_ms(10); 25 PORTC|= 0xFF;//复位,切换到下一个输出口 26 } 27 CountNum[0] = CountNum[1] = CountNum[2] = CountNum[3] = 0; //用于实现4位数的加一变化 28 while(1) 29 { 30 //计数加1,满9进位、后置0 31 if(CountNum[3]++==9) 32 { 33 CountNum[3] = 0; 34 if(9 == CountNum[2]++) 35 { 36 CountNum[2] = 0; 37 if(9 == CountNum[1]++) 38 { 39 CountNum[1] = 0; 40 CountNum[0]++; 41 } 42 } 43 } 44 //显示计数值 45 for(i=0;i<4;i++) 46 { 47 PORTC&=~(1<<i); 48 if(2 == i) 49 PORTB = LedNum[CountNum[i]] + 0x80; 50 else 51 PORTB = LedNum[CountNum[i]]; 52 delay_ms(10); 53 PORTC|=0xFF; 54 } 55 //999.9的时候退出 56 if(CountNum[0]==9 && CountNum[1]==9 && CountNum[2]==9 && CountNum[3]==9) 57 break; 58 } 59 } 60 }
多个LED数码管
ATmega8仿真——LED 数码管的学习相关推荐
- LED数码管仿真显示程序
在电子设备上广泛地使用LED数码管显示数据,在许多应用软件中也经常模拟LED数码管显示数据,使程序画面看起来很有特色.使用Delphi 程序实现LED数码管的仿真显示非常容易,具体步骤如下: 1.启动 ...
- 【STM32 .Net MF开发板学习-25】LED数码管显示
在单片机系统中,LED数码管的应用是很常见的,不过对我们偏软件开发的人来说,要想研究LED还得储备一定的知识才能进行近一步的工作.不过采用.NET Micro Framework系统,我们马上就可以站 ...
- 单片机按键控制数码管c语言程序,基于单片机的按键控制LED数码管共阴极动态显示电路设计报告(毕业论文).doc...
基于单片机的按键控制LED数码管共阴极动态显示电路设计报告(毕业论文) 物理与电子工程学院2014级课程设计 PAGE IV 物理与电子工程学院 <单片机原理与接口技术> 课程设计报告书 ...
- stk在计算机仿真中的应用_学习电路仿真:proteus电路仿真软件在ARM中的应用解析...
目前,使用较多的电路仿真软件为proteus,因此学习这款电路仿真软件的朋友也通常较多.本文中,将基于protues电路仿真软件,对proteus在ARM开发中的应用加以解析,一起来了解下吧. 现在, ...
- 【雕爷学编程】Arduino动手做(47)---七段LED数码管模块
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器和模块,依照实践(动手试试)出真知的理念,以学习和交流为目的,这里准备 ...
- 基于单片机的LED数码管循环移位显示
单片机系统基础实验--LED数码管循环移位显示 第一部分 前言 第二部分 数码管的原理构成 LED数码管的结构 LED数码管的工作原理 LED数码管的字形编码 LED数码管的控制方式 第三部分 设计项 ...
- 用四位led数码管作显示器的篮球比赛24秒计时器求c语言代码,单片机编程控制LED七段数码管作显示的篮球赛计时计分系统...
本次设计用由AT89C51编程控制LED七段数码管作显示的球赛计时计分系统.系统应具有赛程定时设置,赛程时间暂停,及时刷新甲.乙双方的成绩以及赛后成绩暂存等功能. 内容包括:显示.键盘.时钟等内容设计 ...
- LED数码管段码生成
LED数码管段码计算器 前言 最近在复习单片机的知识,写编写LED数码管的驱动时,嫌计算太麻烦,就做了个WinForm项目 正文 原理 这里的LED数码管指的是8段数码管 我们可以看到每个LED数码管 ...
- 51单片机数码管滚动显示学号_数协微课 | LED数码管与51单片机应用
遇见工学,学在工学 停课不停学 数协电子组教学微课 它又来了 让我们开始学起来吧! 本期学习内容 LED数码管的结构与工作原理及相关原理图介绍 51单片机的应用:静态数码管显示.动态数码管显示 LED ...
最新文章
- Delphi(Tuxedo,BDE,ADO)三合一数据集组件HsTxQuery
- java hashset 源码_Java集合源码分析-HashSet和LinkedHashSet
- C# 发邮件类可发送附件
- 如何使用python效率办公_日常office工作中如何用python提升效率014
- SAP Spartacus B2cStorefrontModule里提供的默认配置
- Selenium利用POI读写excel文件
- 2. Android Basic 搭建Android开发环境
- QImage互转cv::Mat
- Lightbox插件
- Ubuntu安装MySQL
- 最常用20000英语单词表_家长最值得一看的文章如何培养孩子好的学习习惯!
- C++语言风格流变史
- 什么样的微信头像最撩人?
- 《信息物理融合系统(CPS)设计、建模与仿真——基于 Ptolemy II 平台》——2.4 注释及参数设置...
- java补空格_JAVA STRING 对象自动补齐空格
- uni-app iOS发布
- 硬件电路中的7个常用接口你都清楚吗?
- c语言调试时窗口一闪就没了,VS2012编译C语言代码运行出现黑框一闪就没了
- 博图sodt定时器的用法_图文详解|西门子博途中的定时器指令
- com.sun.mail.smtp.SMTPSendFailedException:554 5.2.0 STOREDRV.Submission.Exception
热门文章
- 开源众包and公安行业的联姻。大项目,久合作。只要你的技术符合。金矿等着你!...
- 区块链下的保护个人信息安全武器
- TechnoStar.Venus-Pre.3.0 有限元建模处理器
- 图像仿射变换原理3:仿射变换类型及变换矩阵详解
- matlab可以拟合分段函数吗,如何用matlab拟合出分段函数
- 数据仓库【多维分析】
- python倒数怎么求_python实现计算倒数的方法
- 基于fitnesse项目去搭建自动化测试框架
- linux系统32位镜像下载,centos6.5下载
- linux 6.5升级nss,centos6.5 - centos 6.5系统PHP环境下的CURL库的SSL Version默认为NSS,怎么变更为OpenSSL?...