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 的设置可控制内部的上拉电阻使用或不使用。

注意事项:

  1. 使用AVR的I/O 口,首先应正确设置其工作模式(输入模式还是输出模式),设置DDRx;
  2. 当I/O工作在输入模式(DDRxn=0)时,读取引脚上的电平应取PINxn的值,而不是PORTxn的值;
  3. 当I/O口工作在输入模式(DDRxn=0)时,应根据实际情况设置内部上拉电阻,利用内部上拉电阻可以节省外部上拉电阻;
  4. 将I/O空工作模式由输出模式设置为输入模式后,必须等待一个时钟周期后才能正确的读到外部引脚的值

2. 跑马灯程序控制发光二极管

  我们选择用PD0~PD7来控制8个发光二极管循环点亮,从而实现“跑马灯”

所以电路图如图所示:

C程序如下:

 //延时1MS
void delay_1ms()
{
unsigned int i;
for(i=;i<(unsigned int)(-);i++)
;
}
//延时nMS
void delay_ms(unsigned int n)
{
unsigned int i=;
for(i=;i<n;i++)
{
delay_1ms();
}
}
//主函数,依次顺序打开LED
int main()
{
unsigned char i;
DDRD = 0xFF; //设置D口为输出模式
PORTD = 0xFF; //置高电平
while()
{
for(i=;i<;i++) //顺序打开LED
{
PORTD = ~(<<i); //点亮的位置低电平
delay_ms();
}
}
return ;
}

跑马灯

问:如果改变 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口控制,循环显示数字

电路图如图所示:

了解理论知识后便可以开始编程:(延时函数与上面相同)

 void main()
{
unsigned char i;
unsigned char num[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; DDRD = 0xFF; //设置D口为输出模式
PORTD = 0xFF; //置高电平 while()
{
for(i=;i<;i++) //LED数码管顺序显示字型0~9
{
PORTD = num[i];
delay_ms();
}
}
}

单个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个数;所以只有第三个数是特殊的;

参考原理图如下:

代码实现如下:

 void main()
{
//PB口做字形码的输出口,PC0~PC3控制数码管的轮流显示
unsigned char i,j;
static unsigned char LedNum[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
//显示小数点要加0x80
unsigned char CountNum[] = {,,,}; //计数的百、十、个位和十分位
DDRB = 0xFF; //设置B口为输出模式
PORTB = 0xFF; //置高电平
DDRC = 0x0F;
PORTC = 0xFF; while()
{
i=; //用于PC0~PC3的轮转
for(j=;j<;j++) //依次显示4S"000.0"
{
i = ++i%;
PORTC&=~(<<i);
if(==i) //如果是第三个数字则加个小数点显示
PORTB = LedNum[] + 0x80;
else //其余情况都没有小数点显示
PORTB = LedNum[];
delay_ms();
PORTC|= 0xFF;//复位,切换到下一个输出口
}
CountNum[] = CountNum[] = CountNum[] = CountNum[] = ; //用于实现4位数的加一变化
while()
{
//计数加1,满9进位、后置0
if(CountNum[]++==)
{
CountNum[] = ;
if( == CountNum[]++)
{
CountNum[] = ;
if( == CountNum[]++)
{
CountNum[] = ;
CountNum[]++;
}
}
}
//显示计数值
for(i=;i<;i++)
{
PORTC&=~(<<i);
if( == i)
PORTB = LedNum[CountNum[i]] + 0x80;
else
PORTB = LedNum[CountNum[i]];
delay_ms();
PORTC|=0xFF;
}
//999.9的时候退出
if(CountNum[]== && CountNum[]== && CountNum[]== && CountNum[]==)
break;
}
}
}

多个LED数码管

ATmega8仿真——LED 数码管的学习的更多相关文章

  1. ATmega8仿真——外部中断的学习

    前面我们学习了ATmega8的I/O口作为通用数字输入/输出口来用时对LED数码管控制和扫描按键的应用: 但ATmega8多数的I/O口都是复用口,除了作为通用数字I/O使用,还有其第二功能,这里我们 ...

  2. ATmega8仿真——键盘扫描的学习

    1.按键的使用特点 按键的应用主要是在按键闭合时改变电路的电平,但是一般情况下按键的开关都是机械弹性触点开关,即利用触点的接触和分离来实现电路的通断,所以在按键按下和释放时往往会产生抖动干扰. 消除抖 ...

  3. 【雕爷学编程】Arduino动手做(47)---七段LED数码管模块

    37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器和模块,依照实践(动手试试)出真知的理念,以学习和交流为目的,这里准备 ...

  4. 【Arduino】8地点LED数码管(3461BS)

    淘宝买了一块3461BS的8地点LED数码管,婴儿就迫不及待地尝试,结果看到了文件,好家伙无Arduino测试程序. 莫急~莫急~无论如何串行操作,大不了呗瞎蒙! 以下几点是在更有趣的点瞎蒙: 1.须 ...

  5. 单线制DS18B20温度传感器LED数码管显示当前的温度值

    /******************************************* 程序功能:利用单线制DS18B20温度传感器 LED数码管显示当前的温度值 ***************** ...

  6. 硬件原理系列之LED数码管(一)

    LED数码管也叫数码显示器,由8段(7段,8多一位小数点)发光二极管组成,控制不同组合,就可以显示不同字符 dp示小数点,COM为公共端,根据连接方式的不同,分为共阴极和共阳极 工作原理:若选用共阴极 ...

  7. 【.NET 与树莓派】LED 数码管驱动模块——TM1638

    LED 数码管,你可以将它看做是 N 个发光二级管的组合,一个灯负责显示一个段,七个段组合一位数字,再加一个小数点,这么一来,一位数码管就有八段.一般,按照顺时针的方向给每个段编号. 上图中的 h 就 ...

  8. 音响音箱/恒温壶/电量显示/电子数字时钟等LED数码管显示驱动IC-VK1640B 8段12位/12段8位显示

    市面上最常用的数码管为七段/八段显示,八段数码管比七段数码管多一个发光二极管单元(比七段数码管多一个点),又按能显示多少个"8"可分为1位.2位.4位等等.数码管又分为共阳极驱动/ ...

  9. 4位或者5位led数码显示,485通信modbus,支持任意小数点写入,工业标准设置,可和plc,dcs,组态完美对接,支持定制修改

    MRD-5030具有4位8段数码管,支持通过工业标注协议Modbus(Modbus-RTU)控制显示,支持任意小数点的显示.数据以半双工方式通信.电源端口和通信端口都具有防浪涌,防雷600W保护,能够 ...

随机推荐

  1. QtPropertyBrowser+vs2010的安装与配置

    之前编译过一次QtPropertyBrowser2.5,见文章http://www.cnblogs.com/aminxu/p/4516469.html,当时很激动,编译成功,lib也都编译通过,程序调 ...

  2. handsontable 和 echarts都定义了require方法,初始化时冲突了,怎么办?

    echarts初始化时报这个错误. require.config is not a function  方案一: 让其中一方的初始化不依赖于 require即可 1.去掉 var testDrowEc ...

  3. Altium制作DC002的PCB封装和3D模型

    Altium制作DC002的PCB封装和3D模型 常用的电源连接器(Dc Power Jack Connector)DC002.DC005等等型号的3D模型在网上很难找到合适的,我们可以选择CUI 公 ...

  4. javascript 大中小括号的区别

    小括号 JavaScript中小括号有五种语义 语义1,函数声明时参数表 function func(arg1,arg2){ // ... } 语义2,和一些语句联合使用以达到某些限定作用 // 和f ...

  5. php中查询时间

    在做查询过程中,例如要实现查上个月从第一天到最后一天的佣金(提成),那我们在程序实现过程中就要让程序在上个月的范围内查询,第一天是比较好办,但最后一天就不定,要去写段函数进行月份及年份判断来得出上个月 ...

  6. mvc, web mvc, spring web mvc 区别

    1. MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用于组织代码用一种业务逻辑和数据显示分离的 ...

  7. 前端面试总结——http、html和浏览器篇

    1.http和https https的SSL加密是在传输层实现的. (1)http和https的基本概念 http: 超文本传输协议,是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和 ...

  8. Spring中手动增加配置文件中占位符引用的变量

    在项目中遇到一个这样的需求,项目的配置文件由外部传入,这时spring配置文件那些占位符变量该如何取值呢? 解决这个问题的做法有几种,我想到的大概有以下三种: 1.通过系统属性来实现,把外部传入的配置 ...

  9. 1066. [SCOI2007]蜥蜴【最大流】

    Description 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃 到边界外. 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到 ...

  10. 关于jquery的click()方法

    昨天,有个同事研究了以下jqury的click()方法,代码如下: <!DOCTYPE html> <html> <head> <meta charset=& ...