IO口扩展(74HC595芯片、点阵一行循环显示)

我们可以用单片机IO口控制外围设备。由于单片机的IO口是非常有限的,如果我们想要控制更多的外围设备怎么办呢?我们首先想到的是有没有办法扩展一下IO口呢?我们可以使用74HC595芯片来扩展IO口,用三个IO口就可以控制8个IO口。

74HC595

74HC595是一个8位串行输入、并行输出的位移缓存器,其中并行输出为三态输出(即高电平、低电平、高阻抗)下面我们来看一下74HC595芯片的管脚图

Qa到Qh      为并行数据输出

Q‘h 串行数据输出

SCLR 低电平复位引脚

SCK 移位寄存器时钟输入

RCK 储存寄存器时钟输入

G 输出有效

SER 串行数据输入

那么我们怎么使用74HC595芯片呢?

数据在SCK上升沿输入(并且数据是一位一位的进SCK移位寄存器,且高四位先进),在RCK的上升沿进入到存储器中。

那么软件编程怎么操作才会出现上升沿呢?

我们先给一个低电平延时一下,然后给一个高电平,就会出现上升沿。

我们怎么才能使高位一位一位的进入SCK寄存器呢?

我们右移7为就可以得到最高位了。然后我们在左移一位就把次高位变成了最高位然后再重复右移。用一个循环,循环8次就就可以把一个字节的数据存在SCK寄存器中。

介绍了上面的相关内容之后我们怎么实现实验现象呢?

首先我们先把点阵粗略得当成 8个LED灯(后面会有介绍点阵的)我们先对点阵的列管脚都给低电平,这个时候我们只需要对行管脚进行操作就可以了。对行管脚给高电平,就可以使LED灯亮。

要想实现点阵一行一行的滚动显示。我们只需要对其中一行给高电平,其余给得低电平。为了方便操作我们可以定义一个数组保存每一行显示使对应的数据。然后我们只需要一个循环就可以实现了,为了有更好的实验效果,我们要进行消影,即把0X00传入到74HC595中,这个消影要放在显示之前。

代码如下

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现这个功能,我们需要将Atmega16与74HC595芯片连接起来,并且编写代码控制芯片输出数字。以下是具体步骤: 1. 连接Atmega16与74HC595芯片。将Atmega16的PB0, PB1和PB2引脚连接到74HC595芯片的SER, SRCLK和 RCLK引脚上。将74HC595芯片的Q0-Q7引脚连接到数码管的A-G和DP引脚上。 2. 初始化74HC595芯片。在代码中先对74HC595芯片进行初始化,将芯片的引脚输出设置为低电平。 3. 编写显示函数。编写一个函数,用于将要显示的数字通过74HC595芯片输出到数码管上。这个函数需要将数字转换为对应的数码管的A-G和DP引脚的状态,并且通过74HC595芯片输出到数码管上。 4. 主程序中调用显示函数。在主程序中,将要显示的数字传递给显示函数即可。 以下是示例代码: ```c #include <avr/io.h> #include <util/delay.h> void init_74HC595() { // 设置74HC595芯片的引脚输出为低电平 DDRB |= (1<<PB0) | (1<<PB1) | (1<<PB2); PORTB &= ~((1<<PB0) | (1<<PB1) | (1<<PB2)); } void display_number(int num) { // 数字和对应的数码管引脚状态的映射表 uint8_t digit_map[] = { 0b00111111, // 0 0b00000110, // 1 0b01011011, // 2 0b01001111, // 3 0b01100110, // 4 0b01101101, // 5 0b01111101, // 6 0b00000111, // 7 0b01111111, // 8 0b01101111 // 9 }; // 将数字拆分为十位和个位 int tens = num / 10; int ones = num % 10; // 将十位和个位数字转换为数码管引脚状态 uint8_t tens_state = digit_map[tens]; uint8_t ones_state = digit_map[ones]; // 依次输出十位和个位数字到数码管上 for (int i=0; i<8; i++) { // 先输出十位数字 PORTB &= ~(1<<PB2); // 将RCLK引脚设置为低电平 PORTB &= ~(1<<PB1); // 将SRCLK引脚设置为低电平 if (tens_state & (1<<i)) { PORTB |= (1<<PB0); // 将SER引脚设置为高电平 } else { PORTB &= ~(1<<PB0); // 将SER引脚设置为低电平 } PORTB |= (1<<PB1); // 将SRCLK引脚设置为高电平,将数据输出到74HC595芯片中 PORTB |= (1<<PB2); // 将RCLK引脚设置为高电平,将数据输出到数码管上 // 再输出个位数字 PORTB &= ~(1<<PB2); // 将RCLK引脚设置为低电平 PORTB &= ~(1<<PB1); // 将SRCLK引脚设置为低电平 if (ones_state & (1<<i)) { PORTB |= (1<<PB0); // 将SER引脚设置为高电平 } else { PORTB &= ~(1<<PB0); // 将SER引脚设置为低电平 } PORTB |= (1<<PB1); // 将SRCLK引脚设置为高电平,将数据输出到74HC595芯片中 PORTB |= (1<<PB2); // 将RCLK引脚设置为高电平,将数据输出到数码管上 _delay_us(100); // 稍作延时,等待数码管响应 } } int main() { init_74HC595(); while (1) { for (int i=0; i<100; i++) { display_number(i); _delay_ms(500); // 每隔500ms显示一个数字 } } return 0; } ``` 这个程序会依次显示0-99之间的数字。在`display_number()`函数中,将数字转换为对应的数码管引脚状态,并且通过74HC595芯片输出到数码管上。在主程序中,每隔500ms显示一个数字,直到程序结束。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值