找回密码
 立即注册
搜索
0赞
赞赏
手机版
扫码打开手机版
把文字装进口袋

跑马灯程序控制发光二极管设计方案

李悔之2015 2022-8-11 10:29:36
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个发光二极管循环点亮,从而实现“跑马灯”
        所以电路图如图所示:
       

        问:如果改变 delay_ms 的时间会变的怎样呢?
        => 跑马灯的变换速度改变。
        问:如果直接让 PORTD = ( 1<i )呢?/pp style="text-indent: 2em;"        =PORTD = ~( 1i ):每次只亮一个灯;/pp style="text-indent: 2em;"        =PORTD = ( 1i ):每次只有一个灯是不亮的,其余灯都亮着。/pp style="text-indent: 2em;"        问:能不能添加或修改程序,改变灯亮的顺序和时间呢?/pp style="text-indent: 2em;"        = 改变循环条件就可以改变亮灯的顺序,如把i++改为i+=2,即可实现隔一盏灯亮一个;/pp style="text-indent: 2em;"        = 亮灯时间改变延迟时间delay_ms()的传入参数即可。/pp style="text-indent: 2em;"        strong3. 单个a href='http://www.hqchip.com/app/957' target='_blank'  class='arckwlink_hide'uLED/u/a数码管练习/strong/pp style="text-indent: 2em;"        /pp style="text-indent: 2em;"        给数码管的a、b、c、d、e、f、g七个发光二极管加不同的电平,二极管显示不同亮暗的组合就可以显示不同的字形;/pp style="text-indent: 2em;"        以1为高电平,0为低电平,给出字形码表:/pp align="center"style="text-indent: 2em;"        /pp style="text-indent: 2em;"        即0x3F表示的就是字型‘0’,0x06表示的就是字型‘1’......;/pp style="text-indent: 2em;"        所以直接把这种对应关系存到一个Char型数组里(一个Char型是8位);/pp style="text-indent: 2em;"        想要对应的a、b、c、d、e、f、g七个发光二极管展示亮与暗,我们选用PD0~7这8位来控制;/pp style="text-indent: 2em;"        如:想要展示字型‘0’=‘0’对应字形码是0x3F=>其中发光二极管的a~f均为亮状态=>PD0~5均为低电平(低电平亮灯)。
        我们用一个LED数码管显示数字0~9,仍然使用PD口控制,循环显示数字
        电路图如图所示:
       

        了解理论知识后便可以开始编程:(延时函数与上面相同)
        单个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的轮转
<div style="text-indent: 2em;">        16    for(j=0;j

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

使用道具 举报

您需要登录后才可以回帖 立即登录
太赞了
2022-8-11 14:14:49
2022-8-12 20:47:40
还是看不懂,复杂
2022-8-15 18:00:24
感觉不错
2022-8-18 15:13:08
不错
2022-8-19 18:46:11
不错哦  喜欢 嘿嘿
2022-8-22 04:16:56
必须支持。。。。。。。
2022-8-24 13:47:40
前排求粉 哥已经收藏!此贴必火!
2022-8-28 17:05:13
很给力。。。。很喜欢
2022-8-28 20:49:46
12下一页
返回顶部