基于串行同步接口的数码管显示(MSP430G2553)

基于串行同步接口的数码管显示

由于一位数码管的驱动需要8个并行IO口进行输出,若驱动多位数码管则对单片机管脚的需求量过大,所以采用了74HC164芯片将串行数据并行输出,满足驱动数码管的要求。

74HC164是一种可以将串行数据并行输出的芯片,其芯片和原理图如下。

74HC164 芯片和原理图
Q0-Q7为八个并行数据输出管脚;
VCC 接 MPS430G2553 的 +3.3V 电源;
GND 接地;
CP(CLK) 为 74HC164 的时钟,主要靠 MSP430G2553单片机提供;
DSA、DSB 为数据输入端;
MR 为 74HC164 的使能端。

下图为 74HC164 的功能表和时序图
74HC164功能表
时序图
功能表中"X"为任意态,即数据可以是0,也可以是1;
箭头为上升沿,即时钟拉高的一瞬间。

根据功能表可以看出,当使能MR为低电平时,无论CLK、A、B取什么值,输出都为0b0000_0000,即0x00,输出不受输入的影响。当使能MR为高电平时,时钟CLK会影响输出。当CLK为低电平时,输出恒为0x00,当检测到时钟的上升沿时,输出跟数据A、B有关。当A、B同时为“1”时,Q0置一,其余位数右移一位。当A、B中有一个为“0”时,无论另一个是多少,Q0都置零,其余位右移一位。

在实际操作中,由于数据端口A、B同时为“1”时才输出“1”,一者为“0”时便输出“0”,所以将A、B连接,使其两者数据相等,也能实现数据的传输。

为了方便74HC164与数码管的连接,采用了下表的对应关系。对应图
下面为基于MSP430G2553单片机,采用串行同步接口驱动一位数码管的程序。

P1.7 做数据管脚,P1.6 做同步时钟管脚

其中 BIT0 = 0b0000_0001;
BIT1 = 0b0000_0010;
以此类推,
BIT6 = 0b0100_0000;
BIT7 = 0b1000_0000;

#include<msp430.h>                          // 包含名称定义和对应地址或数据的头函数

void delay_1s(void);      		      	    // 声明 1s 延迟函数
void seg7_1ms(unsigned char seg7_data);     // 声明驱动 1 位数码管的同步串行数据接口驱动函数

const unsigned char decoder_seg7[10]        // 声明显示代码
  ={0xee,0x82,0xdc,0xd6,0xb2,0x76,0x7e,0xc2,0xfe,0xf6};
                                            // 共阴极数码管显示代码
                                            // MSP430 的 SPI 输出数据位顺序为高位在前,低位在后
                                            // 74164 与 数码管的连接顺序为:Q0--dp
                                            //                              Q1--c
                                            //                              Q2--d
                                            //                              Q3--e
                                            //                              Q4--g
                                            //                              Q5--f
                                            //                              Q6--a
                                            //                              Q7--b

int main(void)                         	 // 主函数
{
  unsigned char data_seg7;           	 // 声明显示数据变量
  WDTCTL=WDTPW+WDTHOLD;               	 // 关闭看门狗
  P1SEL&=~BIT7;                             // 设置 P1.7 端口为并行数字输入 / 输出口
  P1DIR|=BIT7;                              // 设置 P1.7 端口为输出口
  P1SEL&=~BIT6;                             // 设置 P1.6 端口为并行数字输入 / 输出口
  P1DIR|=BIT6;                              // 设置 P1.6 端口为输出口
  while(1)                                  // 重复执行
  {
    for(data_seg7=0; data_seg7<10; data_seg7++)
                                            // 利用循环语句产生显示数据
    {
      seg7_1ms(data_seg7);		        // 调用驱动 1 位数码管的同步串行数据接口驱动函数
      delay_1s( );      		        // 调用 1s 延迟函数
    }
  }
}


void seg7_1ms(unsigned char seg7_data)      // 驱动 1 位数码管的同步串行数据接口驱动函数
                                            // P1.7 数据管脚,P1.6 同步时钟管脚
{
  unsigned char code_seg7;           	 // 声明显示代码变量
  code_seg7= decoder_seg7 [seg7_data];      // 数据译码
// 同步串行接口初始化
  P1OUT&=~BIT6;                        	 // P1.6 输出低电平
  P1OUT&=~BIT7;                        	 // P1.7 输出低电平
// 逐位输出 1 个字节的 8 个数据位
// 输出第 1 位数据(MSB) 
// 产生数据信号
  if(code_seg7&0x80)                 			
  {
    P1OUT|=BIT7;                     	 // P1.7 输出高电平
  }
  else
  {
    P1OUT&=~BIT7;                      	 // P1.7 输出低电平
  }
// 产生同步时钟信号
  P1OUT|=BIT6;                         	 // P1.6 输出高电平
  P1OUT&=~BIT6;                             // P1.6 输出低电平

// 输出第 2 位数据 
// 产生数据信号
  if(code_seg7&0x40)                 			
  {
    P1OUT|=BIT7;                 	         // P1.7 输出高电平
  }
  else
  {
    P1OUT&=~BIT7;                      	    // P1.7 输出低电平
  }
// 产生同步时钟信号
  P1OUT|=BIT6;                         	    // P1.6 输出高电平
  P1OUT&=~BIT6;                        	    // P1.6 输出低电平
  
// 输出第 3 位数据
// 产生数据信号
  if(code_seg7&0x20)                 			
  {
    P1OUT|=BIT7;                      	    // P1.7 输出高电平
  }
  else
  {
    P1OUT&=~BIT7;                      	    // P1.7 输出低电平
  }
// 产生同步时钟信号
  P1OUT|=BIT6;                         	    // P1.6 输出高电平
  P1OUT&=~BIT6;                        	    // P1.6 输出低电平
  
// 输出第 4 位数据 
// 产生数据信号
  if(code_seg7&0x10)                 			
  {
    P1OUT|=BIT7;                      	    // P1.7 输出高电平
  }
  else
  {
    P1OUT&=~BIT7;                      	    // P1.7 输出低电平
  }
// 产生同步时钟信号
  P1OUT|=BIT6;                         	    // P1.6 输出高电平
  P1OUT&=~BIT6;                        	    // P1.6 输出低电平
  
// 输出第 5 位数据
// 产生数据信号
  if(code_seg7&0x08)                 			
  {
    P1OUT|=BIT7;                      	    // P1.7 输出高电平
  }
  else
  {
    P1OUT&=~BIT7;                      	    // P1.7 输出低电平
  }
// 产生同步时钟信号
  P1OUT|=BIT6;                         	    // P1.6 输出高电平
  P1OUT&=~BIT6;                        	    // P1.6 输出低电平

// 输出第 6 位数据
// 产生数据信号
  if(code_seg7&0x04)                 			
  {
    P1OUT|=BIT7;                      	    // P1.7 输出高电平
  }
  else
  {
    P1OUT&=~BIT7;                      	    // P1.7 输出低电平
  }
// 产生同步时钟信号
  P1OUT|=BIT6;                         	    // P1.6 输出高电平
  P1OUT&=~BIT6;                        	    // P1.6 输出低电平
  
// 输出第 7 位数据
// 产生数据信号
  if(code_seg7&0x02)                 			
  {
    P1OUT|=BIT7;                      	    // P1.7 输出高电平
  }
  else
  {
    P1OUT&=~BIT7;                      	    // P1.7 输出低电平
  }
// 产生同步时钟信号
  P1OUT|=BIT6;                         	    // P1.6 输出高电平
  P1OUT&=~BIT6;                        	    // P1.6 输出低电平

// 输出第 8 位数据(LSB)
// 产生数据信号
  if(code_seg7&0x01)                 			
  {
    P1OUT|=BIT7;                      	    // P1.7 输出高电平
  }
  else
  {
    P1OUT&=~BIT7;                      	    // P1.7 输出低电平
  }
// 产生同步时钟信号
  P1OUT|=BIT6;                         	    // P1.6 输出高电平
  P1OUT&=~BIT6;                        	    // P1.6 输出低电平
}

void delay_1s(void)       		    // 1s 延迟函数
{
  unsigned long data_delay; 		    // 声明循环次数变量
// 利用循环语句实现时间延迟
  for(data_delay=0; data_delay<126654; data_delay++)
  {
  }
}
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
好的,这个问题涉及到数字显示和微控制器编程。以下是一个基本的思路: 1. 首先需要连接四位数码管到 MSP430G2553 微控制器。这可以通过 GPIO 引脚来实现,每个数码管需要 7 个引脚(分别对应 a~g 七段LED和一个共阳共阴极)。 2. 接下来需要编写程序来控制数码管。这可以通过 C 语言来实现,使用 MSP430G2553 的 GPIO 库来控制引脚。程序中需要定义每个数字的七段LED的状态,然后控制每个数码管的引脚输出来显示数字。 3. 最后需要编写一个循环来控制数字的流动显示。这可以通过设置计时器来实现,每隔一定时间更新显示的数字即可。 下面是一个示例程序,可以参考一下: ```c #include <msp430g2553.h> #define DELAY_MS 500 const unsigned char digit[] = { // a b c d e f g 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f }; void display_digit(unsigned char d, unsigned char pos) { P1OUT &= ~(BIT0 | BIT1 | BIT2 | BIT3); P2OUT &= ~(BIT0 | BIT1 | BIT2 | BIT3); switch (pos) { case 0: P1OUT |= BIT0; break; case 1: P1OUT |= BIT1; break; case 2: P1OUT |= BIT2; break; case 3: P1OUT |= BIT3; break; } P2OUT |= digit[d]; } void main(void) { WDTCTL = WDTPW + WDTHOLD; // 关闭看门狗 P1DIR |= BIT0 | BIT1 | BIT2 | BIT3; // 设置P1.0~P1.3为输出 P2DIR |= BIT0 | BIT1 | BIT2 | BIT3; // 设置P2.0~P2.3为输出 unsigned char num[] = {2, 1, 0, 1, 0, 8, 1, 4}; unsigned char pos = 0; while (1) { display_digit(num[pos], pos); pos = (pos + 1) % 8; __delay_cycles(DELAY_MS * 1000); } } ``` 这个程序会将数字 21010814 在四位数码管上流动显示,每个数字的显示时间为 500ms。注意,这个程序只是一个示例,实际应用中需要根据具体的硬件连接和要求进行修改。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值