[资料分享] HD7279A控制数码管(IAR环境)

灞波儿奔   2020-6-11 21:19 楼主

/***************************************************************************
IAR环境,HD7279A,P4.0~CS,P4.1~CLK,P4.2~DATA,P4,3~KAY,
DATA为串口数据口,时序图如下:
CS:    ---------_________________________--------
CLK:   ___________---___---___---___---__________
DATA:  ---------~~~---~~~---~~~~---~~~-----------
由430将显示数据一次性送到7279,再由7279显示
通过定时器TimerA将数值不断改变,当主函数发现数值改变后,再将新的数值写到
HD7279A中,这样便起到了节约CPU资源的作用。数值由数码管显示,由于HD7279含有
寄存器的原因,所以只单片机将要显示的数字和位置的信息传给HS7279A即可显示,而
无需单片机扫描。
***************************************************************************/

#include "msp430x15x.h"

#define      DATADIR      P4DIR    //  定义端口方向
#define      DATAOUT      P4OUT    //  定义输出端口

#define      CS_L         DATAOUT &= ~BIT0;  //  7279的片选输出低电平
#define      CLK_L        DATAOUT &= ~BIT1;  //  7279的时钟输出低电平
#define      DATA_L       DATAOUT &= ~BIT2;  //  7279的数据输出低电平

#define      CS_H         DATAOUT |= BIT0;  //  7279的片选输出高电平
#define      CLK_H        DATAOUT |= BIT1;  //  7279的时钟输出高电平
#define      DATA_H       DATAOUT |= BIT2;  //  7279的数据输出高电平
         
#define      DP           0X80    //  显示小数点
#define      CMD_REST     0XA4    //  7279的复位命令
#define      CMD_LEFT     0XA1    //  7279的左移位命令
#define      CMD_RIGHT    0XA0    //  7279的读缓冲命令

#define      CMD_MODE_1   0X80    // 按方式0译码
#define      CMD_MODE_2   0XC8    // 按方式1译码
#define      CMD_MODE_3   0X90    // 输入数据不译码

#define      CMD_SHOW     0X88    // 闪烁

typedef unsigned int uint16;

char tab_num[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
                0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};

uint16 tym,tym_delay;

void delay_nop(uint16 u)                             // 延时多少个机器周期
{
  for(;u>0;u--)
    _NOP();
}

void Send_1_byte(char send)                          // 发送一个字节
{
  char temp,i;  
  CS_L;                                                             // 置低片选信号
  for(i=0;i<8;i++)
  {
    temp = send & 0x80;                                       // 发送高位
    if(temp!=0)   {DATA_H;}
    else          {DATA_L;}
    CLK_H;                                                             // 置高时钟位
    send <<= 1;                                                         // 左移一位
    CLK_L;                                                                // 置低时钟位
  }
  CS_H;                                                                 // 置高片选信号
}

void Send_2_byte(char send1,char send2)         // 发送两个字节
{
   char temp,i;
   CS_L;
   for(i=0;i<16;i++)
   {
      if(i<8)      temp = send1 & 0x80;                      // 发送高位
      else         temp = send2 & 0x80;
      if(temp!=0)  {DATA_H;}                                   // 如果不为0,输出高电位
      else         {DATA_L;}                                      // 如果为0,则输出低电位
      CLK_H;                                                           // 置高时钟位
      if(i<8)      send1 <<= 1;                                    // 左移一位
      else         send2 <<= 1;
      CLK_L;                                                           // 置低时钟位
      if(i==7)     _NOP();
   }
  CS_H;                                                                 // 置高片选信号  
}

void Write7279()
{
//  char i;
//  Send_1_byte(0xbf);                                                                 // 用于测试
//  Send_1_byte(0xa4);                                                                //复位指令
  Send_2_byte(CMD_MODE_2|0X03,tab_num[tym/1000]);         //  取千位
  Send_2_byte(CMD_MODE_2|0X02,tab_num[tym/100%10]);    //  取百位
  Send_2_byte(CMD_MODE_2|0X01,tab_num[tym/10%10]);      //  取十位
  Send_2_byte(CMD_MODE_2|0X00,tab_num[tym%10]);           //  取个位
//  Send_1_byte(0xa1);                                                               //左移指令
  
}

void main( void )
{
  uint16 ram;
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;
  TACTL  = TASSEL_1 + TACLR + MC_1;  // + TAIE 时钟源MCLK,增计模式,开总中断,清除定时器
  CCTL0 |= CCIE;                //允许中断
  CCR0   = 2000;               //设置寄存器的值
//  _EINT();                        //溢出中断
  _BIS_SR(GIE);                //开总中断
  
  DATADIR = 0X07;
  ram = tym;                     //使两者的值相等
  Write7279();                   //显示初始化
  while(1)
  {
    if(ram!=tym)                //当tym的值有变动时,调用7279
    {
      Write7279();             //显示新数值
      ram = tym;                 //使ram和tym的值相同,以确定下一次tym的值的变动
    }
    delay_nop(1);              //延时一个机器周期
  }
}

#pragma vector = TIMERA0_VECTOR
__interrupt void Timer_A0(void)
{
   tym_delay++;                                                                   //进入中断tym_delay的值加一
   if(tym_delay>=20)   {tym++;tym_delay=0;}                       //当tym_delay为20时,tym加一
   if(tym>1000)        tym = 0;                                                //当tym为1000时清零
}

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复