打印

msp430f5438a和tm1638

[复制链接]
2404|33
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主

// ***两者的电路连接:P4.0--DIO   P4.1--STB   P4.2--CLK  tm1638的VCC和GND接5V的电源箱***

// STB=0 ---> P4OUT &= 0x05
// STB=1 ---> P4OUT |= 0x02
// CLK=0 ---> P4OUT &= 0x02
// CLK=1 ---> P4OUT |= 0x06
// DIO=0 ---> P4OUT &= 0x06
// DIO=1 ---> P4OUT |= 0x01


#include<TM1638_zj.h>

#include"msp430f5438a.h"



#define  STB_0   P4OUT &= 0x05
#define  STB_1   P4OUT |= 0x02
#define  CLK_0   P4OUT &= 0x03
#define  CLK_1   P4OUT |= 0x06
#define  DIO_0   P4OUT &= 0x06
#define  DIO_1   P4OUT |= 0x01
#define  DIO_IN  P4DIR &= ~BIT0
#define  DIO_OUT P4DIR |= BIT0      //CLK  STB 一直为输出   P4DIR |= BIT0 + BIT1 + BIT2

unsigned char tap1[16] = {0x6f, 0x00, 0xf3, 0x00, 0xbf, 0x00, 0x6d, 0x00, 0x45, 0x00, 0x1d, 0x00, 0x7d, 0x00, 0x01, 0x00}; //12345678,从地址00H写入
unsigned char tap2[16] = {0xf6, 0x00, 0xcf, 0x00, 0xfd, 0x00, 0xb6, 0x00, 0xa2, 0x00, 0xa8, 0x00, 0xae, 0x00, 0x01, 0x00}; //87654321,从地址00H写入
unsigned int j;

/****延时程序*******/
void delay_zj(unsigned long time)
         {
          while(time--) ;                   
         }
         

void DigitalTube1(void)    //数码管显示,地址自动增加,12345678
{
  unsigned char i;
  Write_COM(0x8a);  //  打开显示,脉冲宽度4/16
  Write_COM(0x40);  //  写数据到显示寄存器,地址自动增加模式
  STB_0;          //  变低为了写命令字节(地址),然后需要直接开始传送数据,传送完成后,才能再次置1
  TM1638_Write(0xc0);  //  地址从 00H 开始
  j=0;
  for(i=0;i<16;i++)
  {
    TM1638_Write(tap1[j]);
    j++;
  }
  STB_1;  
}

void DigitalTube2(void)    //数码管显示,固定地址,87654321
{
  unsigned char i, ads;
  Write_COM(0x8a);
  Write_COM(0x8a);  //  打开显示,脉冲宽度4/16(只用了一条命令语句,和初始化函数不同)
  Write_COM(0x44);  //  写数据到显示寄存器,固定地址模式
  ads = 0xc0;
  j=0;
  for(i=0;i<8;i++)
  {
    STB_0;
    TM1638_Write(ads);  //  地址从 00H 开始
    TM1638_Write(tap2[j]);
    STB_1;
    ads = ads + 2;
    j = j + 2;
  }
}

void TM1638_Write(unsigned char        DATA)                        //写数据函数
{
        unsigned char i;
        DIO_OUT;
        for(i=0;i<8;i++)
        {
                CLK_0;
                if(DATA&0X01)                       //从最低位开始写入
                        DIO_1;
                else
                        DIO_0;
                DATA>>=1;
                CLK_1;                            //给一个上升沿,完成写入
        }
}


               
void Write_COM(unsigned char cmd)                //发送命令字,后面不需要传送数据的子程序调用
{
        STB_0;                     //在STB下降沿后由DIO输入的第一个字节作为一条指令。
        TM1638_Write(cmd);         //经过译码,取最高B7、B6两位比特位以区别不同的指令。
        STB_1;                     //上升沿写入,STB为高时,CLK被忽略
}



void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT

  P4DIR |= BIT0 + BIT1 + BIT2;                       //P4.0--DIO   P4.1--STB    P4.2--CLK

  P7SEL |= BIT0 + BIT1;                       //Enable XT1
  UCSCTL6 &= ~(XT1OFF);
  UCSCTL6 |= XCAP_3;                  //  到底是把这个电容接到哪里???

  do
  {
    UCSCTL7 &= ~XT1LFOFFG;
  }while(UCSCTL7&XT1LFOFFG);
  while(1)
  {
  DigitalTube1();
  delay_zj(50000);
  DigitalTube2();
  delay_zj(50000);
  }
  
}

相关帖子

沙发
吉祥peacock|  楼主 | 2017-11-11 11:35 | 只看该作者
程序运行之后,tm1638没有反应

使用特权

评论回复
板凳
吉祥peacock|  楼主 | 2017-11-11 11:39 | 只看该作者
刚刚开始学习的妹子,希望有人能帮忙一下~

微信图片_20171111113736.jpg (394.84 KB )

连接图

连接图

使用特权

评论回复
地板
dirtwillfly| | 2017-11-11 15:58 | 只看该作者
这种情况,大部分是时序问题。建议先用逻辑分*析仪或者示波器观察一下时序

使用特权

评论回复
5
吉祥peacock|  楼主 | 2017-11-15 15:00 | 只看该作者
dirtwillfly 发表于 2017-11-11 15:58
这种情况,大部分是时序问题。建议先用逻辑分*析仪或者示波器观察一下时序 ...

谢谢回复   用示波器看了一下    三个端口输出的都是正弦波  感觉很明显不对啊   但是不知道从哪里改

使用特权

评论回复
6
吉祥peacock|  楼主 | 2017-11-15 15:08 | 只看该作者
dirtwillfly 发表于 2017-11-11 15:58
这种情况,大部分是时序问题。建议先用逻辑分*析仪或者示波器观察一下时序 ...

我又看到一个别的他们两个之间的通信程序,是用了SPI通信方式写的, 用了专门的数据接收P3.5 发送 P3.4 端口和时钟发送P3.1 端口,但是我稍微修改了一下  用到了msp430f5438a上    示波器输出的波形也还是不对。参考链接 forum.43oh.com/topic/2270-tm1638-leds-interface-_version-170-available

使用特权

评论回复
7
吉祥peacock|  楼主 | 2017-11-15 15:26 | 只看该作者
dirtwillfly 发表于 2017-11-11 15:58
这种情况,大部分是时序问题。建议先用逻辑分*析仪或者示波器观察一下时序 ...

我又看到一个别的他们两个之间的通信程序,是用了SPI通信方式写的, 用了专门的数据接收P3.5 发送 P3.4 端口和时钟发送P3.1 端口,但是我稍微修改了一下  用到了msp430f5438a上    示波器输出的波形也还是不对。参考链接 forum.43oh.com/topic/2270-tm1638-leds-interface-_version-170-available

使用特权

评论回复
8
dirtwillfly| | 2017-11-15 16:36 | 只看该作者
吉祥peacock 发表于 2017-11-15 15:26
我又看到一个别的他们两个之间的通信程序,是用了SPI通信方式写的, 用了专门的数据接收P3.5 发送 P3.4  ...

这个程序是基于g2553的,需要移植到f5438a才可以

使用特权

评论回复
9
吉祥peacock|  楼主 | 2017-11-15 17:09 | 只看该作者
dirtwillfly 发表于 2017-11-15 16:36
这个程序是基于g2553的,需要移植到f5438a才可以

所谓移植  就是把里面用到的端口改成5438a的对应端口和寄存器指令吧  我都改了  但是还是不可以

使用特权

评论回复
10
吉祥peacock|  楼主 | 2017-11-15 17:10 | 只看该作者

/***** STB-- P3.1  
***** DIO-- P3.5  P3.4  
***** CLK-- P3.0
****************************************/

#include "msp430f5438a.h"
#define STB_1  P3OUT |= BIT1
#define STB_0  P3OUT &= ~BIT1


/****
#define CLK_1  P3OUT |= BIT0
#define CLK_0  P3OUT &= ~BIT0
#define DIO_1
#define DIO_0
#define DIO_IN
#define DIO_OUT
****/


#define RED_TM1638 0x01 //RED Led
#define GRE_TM1638 0x02 //Green Led
#define DATA_WRITE_INCR_ADDR 0x40 //地址自动增加写数据命令  Command to switch TM1638 for automatic increment address mode  
#define DATA_WRITE_FIX_ADDR 0x44 //固定地址写数据命令  Command to switch TM1638 for fix address mode
#define DATA_READ_KEY_SCAN_MODE 0x42 //读取按键值命令  Command for read key code from TM1638
#define ADDRSET 0xC0 //地址从00H开始  Command to set address 0x00
#define DISP_ON 0x8F //打开显示 最大亮度Command to Display ON and set (max) brightness
#define DISP_OFF 0x80 //关闭显示 Command to Display OFF
#define DISP_ON 0x8F //打开显示 最大亮度Command to Display ON and set (max) brightness
#define DISP_OFF 0x80 //关闭显示 Command to Display OFF

unsigned int Num[]= //Code table of symbols
{
0x3F, //0
0x06, //1
0x5B, //2
0x4F, //3
0x66, //4
0x6D, //5
0x7D, //6
0x07, //7
0x7F, //8
0x6F, //9
0x40, //Minus
0x63, //Degree
0x39, //"C"
0x00, //Blank
0x3E //"U"
};


unsigned int ERROR_DATA[] = {
0x79, // E
0x50, // r
0x50, // r
0x5C, // o
0x50, // r
0,
0,
0
};



void init_Ports()
{
  P3OUT = 0x00; // P1 setup for LED & STROBE output
   //P2OUT = 0x00; // P2 setup for output
  P3DIR = BIT1;//  P1.0  P1.5  P1.6 都是输出方向
  P3SEL = BIT0 + BIT4 + BIT5; // 打开P1.1  P1.2  P1.4 的第二功能  Set secondary functions for PORT1
  //P1SEL2 = BIT0 + BIT4 + BIT5; // P3.4 - TXD, P3.5 - RXD
  STB_1; //  STB = 1  Chip Select, Set STROBE = "1"     
}

void init_WDT()
{
  WDTCTL = WDTPW + WDTHOLD; //Stop watchdog
}


void init_SPI()
{
  UCA0CTL0 |= UCCKPL + UCMST + UCSYNC; // 第一个边沿更新数据,第二个边沿捕获数据(先输出后输入!!!) ,不工作状态是高电平
                                     // 3-pin, 8-bit SPI master
                                     // 主机模式,同步通讯
  UCA0CTL1 |= UCSSEL_2; // fBRCLK = SMCLK = 1.045MHz
  UCA0BR0 |= 0x02; // fBitClock = fBRCLK/2
  UCA0BR1 = 0; //
  UCA0MCTL = 0; // No modulation
  UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
}


void SendCommand(unsigned char Command) //Transmit Command
{
  STB_0; //Set STROBE = "0"
  _NOP();
  _NOP();
  STB_1; //Set STROBE = "1"
  _NOP();
  _NOP();
  STB_0; //Set STROBE = "0"
  _NOP();
  UCA0TXBUF = Command;   // 把命令发出去
  while (!(UCA0IFG & UCTXIFG));  //等待命令发送完毕
  STB_1; //Set STROBE = "1"
}


void SendData(unsigned int address, unsigned int data)  // Transmit Data  向指定地址address中,写入数据data
{
  unsigned int t;
  SendCommand(DATA_WRITE_FIX_ADDR);  //地址自动增加模式写数据
  STB_0; //Set STROBE = "0"
  UCA0TXBUF = (0xC0 | address);  //发送开始地址adderssc
  for(t=0; t<8; t++)    //连续写入八个地址的数据
  {
    while (!(UCA0IFG & UCTXIFG));
    UCA0TXBUF = data;    // 一个字节整体写入
  }

  while (!(UCA0IFG & UCTXIFG));
  STB_1; //Set STROBE = "1"
}


void ShowDig(int position, int Data, int Dot) //show single digit
{
  SendData(position << 1, Data | (Dot ? 0x80 : 0) );
}


void ClearDig(unsigned int pos, unsigned int dot)
{
  ShowDig(pos, 0x00, dot);
}


void ShowLed(int Number, int Color)
{
  SendData((Number << 1)-1, Color);
}


void ShowLeds(int color)
{
  unsigned int i;
  for (i=1; i<9; i++)
  {
    ShowLed (i, color);
  }
}


void DisplayClean()   //Clean RAM of TM1638   清空数码管显示
{
  int i;
  for (i=0; i<17; i++)
  {
    SendData(i, 0x00);
  }
}


void SetupDisplay(char active, char intensity)
{
  SendCommand (0x80 | (active ? 8 : 0) | intensity);   //显示控制命令写入
  STB_1; // Set STROBE = "1"
}


void init_Display()
{
  __delay_cycles(100000); //Time to initial TM1638
  DisplayClean(); //Clean display
  SendCommand(DISP_OFF); //Display off
  SendCommand(DATA_WRITE_FIX_ADDR); //Set address mode
  SendCommand(ADDRSET); //Set first adress
}


void ShowError()
{
  unsigned int j;
  for (j=0; j<8; j++)
  {
    ShowDig(j, ERROR_DATA[j], 0);
  }
}

int GetKey()
{
  unsigned int KeyData = 0;
  unsigned int i;
  
  STB_0; // Set STROBE = "0"
  UCA0TXBUF = DATA_READ_KEY_SCAN_MODE;
  while (!(UCA0IFG & UCTXIFG));
  __delay_cycles(20); //wait to ready (see datasheet)                 ???????????????????????????

  UCA0TXBUF = 0xff; //Send dummy byte
  while (!(UCA0IFG & UCTXIFG)); //wait for buffer ready
                                // 1'st reseiving byte = bad

  for (i=0; i<4; i++)
  {
    UCA0TXBUF = 0xff;  //配合相位模式UCCKPH  先输出再输入
    while (!(UCA0IFG & UCTXIFG));
   KeyData |= UCA0RXBUF << i;   //  总共读入四个字节的数据,这个为什么需要移位呢????????????
  }
  STB_1; //Set STROBE = "1"
  return KeyData;
}

void main()
{
  unsigned int j;
  unsigned int Keys = 0;
  init_WDT();
  init_Ports();
  init_SPI();
  init_Display();

// Example program:
  while(1)
  {
    for (j=0; j<8; j++)//example set "01234567" on display
    {  
      ShowDig(j, Num[j], 0);
    }
  }

  SetupDisplay(1, 7); // Display ON, max brightness

  while(1)
  {
    ShowLeds(0); //switch all LEDs off
    switch(GetKey())
    {
      case 1: Keys = 1; break;
      case 2: Keys = 2; break;
      case 4: Keys = 3; break;
      case 8: Keys = 4; break;
      case 16: Keys = 5; break;
      case 32: Keys = 6; break;
      case 64: Keys = 7; break;
      case 128: Keys = 8; break;
      default: Keys = 0; break;
    }

    if (Keys)
    {
      ShowLed(Keys, GRE_TM1638);
    }
    ShowDig(7, Num[Keys], 1);
  }

//end of example program
}

使用特权

评论回复
11
dirtwillfly| | 2017-11-15 17:18 | 只看该作者
吉祥peacock 发表于 2017-11-15 17:09
所谓移植  就是把里面用到的端口改成5438a的对应端口和寄存器指令吧  我都改了  但是还是不可以 ...

端口,用到的内部模块,还有时钟频率

使用特权

评论回复
12
吉祥peacock|  楼主 | 2017-11-15 18:29 | 只看该作者
dirtwillfly 发表于 2017-11-15 17:18
端口,用到的内部模块,还有时钟频率

都改了  不知道为什么还是不可以    不过还是谢谢 你一直耐心的回答

使用特权

评论回复
13
dirtwillfly| | 2017-11-15 20:46 | 只看该作者
吉祥peacock 发表于 2017-11-15 18:29
都改了  不知道为什么还是不可以    不过还是谢谢 你一直耐心的回答

不客气。你可以观察一下时序,和tm1638的手册对比一下。

使用特权

评论回复
14
quickman| | 2017-11-15 22:35 | 只看该作者
程序在成功了吗?

使用特权

评论回复
15
jstgotodo| | 2017-11-15 22:35 | 只看该作者
吉祥peacock 发表于 2017-11-11 11:39
刚刚开始学习的妹子,希望有人能帮忙一下~

仿真器单步调试试试看。

使用特权

评论回复
16
iamaiqiyi| | 2017-11-15 22:36 | 只看该作者
建议测试一下IO的电平电压是否正常

使用特权

评论回复
17
quickman| | 2017-11-15 22:39 | 只看该作者
楼主怎么确定程序下载成功了?

使用特权

评论回复
18
jstgotodo| | 2017-11-15 22:39 | 只看该作者
吉祥peacock 发表于 2017-11-11 11:39
刚刚开始学习的妹子,希望有人能帮忙一下~

单步调试能够成功吗?

使用特权

评论回复
19
iamaiqiyi| | 2017-11-15 22:39 | 只看该作者
这个有可能是硬件电路的问题。

使用特权

评论回复
20
xiaoyaodz| | 2017-11-16 16:28 | 只看该作者
这个还真没有做过,楼主应该先检查硬件电路。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

17

帖子

0

粉丝