华强柏安

 找回密码
 加入论坛
查看: 490|回复: 5

TM1638与STM32连接

[复制链接]
发表于 2019-7-10 11:13 | 显示全部楼层 |阅读模式


1、TM1638与STM32连接



1.1 硬件连接



    Vcc--电源+

    GND--电源地

    STB--PA0

    CLK--PA1

    DIO--PA2



1.2 驱动程序



TM1638.c文件:



/**********************************************************************************************

**Program Assignment: Driver for TM1638 digital tube

**Author        :

**Date              :

**Description       : This is a driver for the board which is controled by thechip of tm1638.

              The board has eight digital tubes which have eight segments and eight keys.

***********************************************************************************************/

                          //#include "stm32f10x.h"

#include "TM1638.h"



/*********************define and global variables*********************************************/

#define STB GPIO_Pin_0                          //chip-select line

#define CLK GPIO_Pin_1                                      //clock line

#define DIO GPIO_Pin_2                                                                      //data line

#define Set(x) GPIO_SetBits(GPIOA,(x))              //Sets the selected data port bits

#define Reset(x) GPIO_ResetBits(GPIOA,(x))          //Resets the selected data port bits

#define Get(x) GPIO_ReadInputDataBit(GPIOA,(x))==SET        //Read the specified input port pin





uint16_t const tm_dat[2][14]={{'0','1','2','3','4','5',     //the char and its segment code

            '6','7','8','9','.','-','_',' '},

            {0x3F,0x06,0x5B,0x4F,0x66,0x6D,

            0x7D,0x07,0x7F,0x6F,0x80,0x40,

            0x08,0x00}};



/***********************************************************************************************

*Function Name: RCC_Config      

*Purpose      : Configration Clock

***********************************************************************************************/

void RCC_Config(){

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

}



/***********************************************************************************************

*Function Name: GPIO_Config     

*Purpose      : Configration GPIO

***********************************************************************************************/

void GPIO_Config(){

    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;

    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Pin=STB|CLK|DIO;

    GPIO_Init(GPIOA,&GPIO_InitStructure);

}

/***********************************************************************************************

*Function Name: Write_Byte      

*Purpose      : Write one byte to the data port

*params       : byte  -------8-bits byte  

*return       : none

***********************************************************************************************/

void Write_Byte(uint8_t byte){

    uint8_t i=0;

    for(i=0;i<8;i++){

        Reset(CLK);

        if(byte&0x01){

            Set(DIO);

        }else{

            Reset(DIO);

        }

        Set(CLK);

        byte>>=1;

    }

}



/***********************************************************************************************

*Function Name: Read_Byte      

*Purpose      : Read one byte from data port

*params       : none

*return       : the 8-bits byte which is read from data port

***********************************************************************************************/

int8_t Read_Byte(){

    uint8_t i=0;

    uint8_t temp=0x00;

    for(i=0;i<8;i++){

        Set(CLK);

        temp>>=1;

        if(Get(DIO)){

            temp|=0x80;

        }

        Reset(CLK);

    }

    return temp;

}



/***********************************************************************************************

*Function Name: Write_Cmd      

*Purpose      : Write a conmand to the data port

*params       : cmd  -------8-bits byte,the conmand,check the data sheet to find the conmand

*return       : none

***********************************************************************************************/

void Write_Cmd(uint8_t cmd){

    Set(STB);

    Reset(STB);

    Write_Byte(cmd);

}



/***********************************************************************************************

*Function Name: Read_Key        

*Purpose      : Read the key number which has been pressed

*params       : none

*return       : the number of the key. 0-8.  "return 0" represents no key has been pressed.

***********************************************************************************************/

int8_t Read_Key(){

    uint8_t i=0;

    uint8_t key1=0x00;

    uint16_t key2=0x00;

    Write_Cmd(0x42);

    Set(DIO);                       //this is obligatory, check the data sheet,GPIO

    for(i=0;i<4;i++){

        key1=Read_Byte();

        key2|=(key1<

    }

    key2>>=1;

    for(i=0;i<8;i++){

        if(0x01<

    }

    return 0;

}



/***********************************************************************************************

*Function Name: Write_Dat      

*Purpose      : Write data to the location specified

*params       : addr  ------the address,0x00 to 0x0f

        dat   ------the data,segment code

*return       : none

***********************************************************************************************/

void Write_Dat(uint8_t addr,uint8_t dat){

    Write_Cmd(0x44);

    Write_Cmd(0xc0|addr);

    Write_Byte(dat);

}



/***********************************************************************************************

*Function Name: TM1638_SendData     

*Purpose      : Write data to the location specified

*params       : i     ------the bit code of digtal tube,0 to 7

        str   ------the string,the char which was not in tm_data will be replace with "''".

*return       : none

***********************************************************************************************/

void TM1638_SendData(uint8_t i,char * str){

    int j=0,k=0;

    unsigned char chr;

    for(;i<8;i++){

        k=0;

        for(j=0;j<14;j++){

            if(*str==tm_dat[0][j]){

                chr=tm_dat[1][j];

                k=1;

                break;

            }

        }



        if(k==0){

            chr=0x00;

        }



        if(*(str+1)=='.'){

            chr|=0x80;

            Write_Dat(i*2,chr);

            str++;

        }else{

            Write_Dat(i*2,chr);

        }

        str++;

        if(*str=='\0')break;

    }

}



/***********************************************************************************************

*Function Name: TM1638_SendIntData      

*Purpose      : Write Int data to the location specified

*params       : i     ------the bit code of digtal tube,0 to 7

        num   ------the Int.

*return       : none

***********************************************************************************************/

void TM1638_SendIntData(uint8_t i,int num)

{

    char a;

    a = num + '0';

    TM1638_SendData(i,&a);

}



/***********************************************************************************************

*Function Name: TM1638_Init     

*Purpose      : the initialization of tm1638

*params       : none

*return       : none

***********************************************************************************************/

void TM1638_Init(){

    int i=0;

    RCC_Config();

    GPIO_Config();

    Write_Cmd(0x8a);

    Write_Cmd(0x40);

    for(i=0;i<16;i++){

        Write_Byte(0x00);

    }

}



TM1638.h



#ifndef __TM1638_H

#define __TM1638_H            

#include "stm32f10x.h"



void RCC_Config(void);

void GPIO_Config(void);

void Write_Byte(uint8_t byte);

int8_t Read_Byte(void);

void Write_Cmd(uint8_t cmd);

int8_t Read_Key(void);

void Write_Dat(uint8_t addr,uint8_t dat);

void TM1638_SendData(uint8_t i,char * str);

void TM1638_SendIntData(uint8_t i,int num);

void TM1638_Init(void);





#endif



1.3 函数说明



用到的函数:void TM1638_SendData(uint8_t i,char * str);函数说明如下:



/***********************************************************************************************

*Function Name: TM1638_SendData     

*Purpose      : Write data to the location specified

*params       : i     ------the bit code of digtal tube,0 to 7

        str   ------the string,the char which was not in tm_data will be replace with "''".不显示数据的时候用"''"替换字符

*return       : none

***********************************************************************************************/



int8_t Read_Key(void);函数说明如下:



/***********************************************************************************************

*Function Name: Read_Key        

*Purpose      : Read the key number which has been pressed

*params       : none

*return       : the number of the key. 0-8.  "return 0" represents no key has been pressed.

***********************************************************************************************/



2.DS1302与STM32



2.1硬件连接



   Vcc--电源+

   GND--电源地

   CLK--PC12

   DAT--PC11

   RST--PC10



2.2驱动程序



DS1302.c的程序网上很多都不能用,查找了硬件时序,发现没问题,但是就是没办法用,下面的程序我亲自测过可以用的,如下:



#include "DS1302.h"

//#include "IO.h"

#include "delay.h"  

//*****************DS1302控制命令*******************

#define WRITE_SECOND              0x80

#define WRITE_MINUTE              0x82

#define WRITE_HOUR                0x84

#define WRITE_DAY                 0x86

#define WRITE_MONTH               0x88

#define WRITE_WEEK                0x8A

#define WRITE_YEAR                0x8C

#define WRITE_TIMER_FLAG          0xC0



#define READ_SECOND               0x81

#define READ_MINUTE               0x83

#define READ_HOUR                 0x85

#define READ_DAY                  0x87

#define READ_MONTH                0x89

#define READ_WEEK                 0x8B

#define READ_YEAR                 0x8D

#define READ_TIMER_FLAG           0xC1

#define WRITE_PROTECT             0x8E

_calendar_obj calendar;                         //时钟结构体

_next_obj next;                                    

//月份数据表                                          

u8 const table_week[12]={0,3,3,6,1,4,6,2,5,0,3,5}; //月修正数据表   

u8 BCD2HEX(u8 bcd_data)    //BCDtoHEX   

{   

    u8 temp;   

    temp=(bcd_data/16*10 + bcd_data%16);   

    return temp;   

}   

u8 HEX2BCD(u8 hex_data)    //HEXtoBCD   

{   

    u8 temp;   

    temp=(hex_data/10*16 + hex_data%10);   

    return temp;   

}   

//============================================

//函数名称:void Ds1302_Write_Byte (byte addr, byte dat)  

//功能:    串行发送地址、数据,先发低位,且在上升沿发送

//参数传递:有,地址和数据

//返回值:  无

//===========================================

void IO_Init(void)

{   

    GPIO_InitTypeDef  GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE); //使能PA,PB,PC端口时钟

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;                                                            //IO口速度为50MHz   

    //PC端口初始化   

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12;                      //设置PC10~PC12端口推挽输出

    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;                                                       //推挽输出  

    GPIO_Init(GPIOC, &GPIO_InitStructure);                                                                                          

}





void Ds1302_Write_Byte(u8 addr, u8 dat)     

{

    u8 i;

  DS1302_IO_OUT();                //数据端口定义为输出

  CE = 1;

    delay_us(10);

    SCLK = 0;

    delay_us(10);

    for(i=0;i<8;i++)

    {

        if(addr&0x01)

        {

            DIO = 1;

        }

        else

        {

            DIO = 0;

        }

        addr = addr>>1;

        SCLK = 1;

        delay_us(10);

        SCLK = 0;

        delay_us(10);



    }

    for(i=0;i<8;i++)            //写入数据:dat

  {

        if(dat&0x01)

        {

            DIO = 1;

        }

        else

        {

            DIO = 0;

        }

        dat = dat>>1;

        SCLK = 1;

        delay_us(10);

        SCLK = 0;

        delay_us(10);

  }

  CE = 0;;                     //停止DS1302总线

    delay_us(10);

}

//===============================================

//函数名称:byte Ds1302_Read_Byte ( byte addr )

//功能:    串行读取数据,先发低位,且在下降沿发送

//参数传递:有,地址

//返回值:  有,读取的数据

//===============================================

u8 Ds1302_Read_Byte(u8 addr)

{

  u8  i;

  u8  temp = 1;

    CE = 1;

    delay_us(10);

  for(i=0;i<8;i++)

  {      

    SCLK = 0;

        delay_us(10);

        if(addr&0x01)

    {

       DIO = 1;

    }

    else

    {

       DIO = 0;

    }

        addr = addr>>1;

        SCLK = 1;

        delay_us(10);

  }

  DS1302_IO_IN();                  //数据端口定义为输入

  for(i=0;i<8;i++)

  {

    temp = temp >> 1;                            //输出数据:temp

    SCLK = 0;

        delay_us(10);

        if(DIO_IN)

    {

       temp |= 0x80;

    }

        SCLK = 1;

        delay_us(10);

  }

  DS1302_IO_OUT();                //数据端口定义为输出                       

  SCLK = 0;

    delay_us(10);

    CE = 0;                         //停止DS1302总线

    delay_us(10);

    return temp;                    

}

//获得现在是星期几

//功能描述:输入公历日期得到星期(只允许1901-2099年)

//输入参数:公历年月日

//返回值:星期号                                                                                       

u8 RTC_Get_Week(u16 year,u8 month,u8 day)

{   

    u16 temp2;

    u8 yearH,yearL;

    yearH=year/100;

    yearL=year%100;                                     //如果为21世纪,年份数加100  

    if (yearH>19)yearL+=100;                    //所过闰年数只算1900年之后的  

    temp2=yearL+yearL/4;

    temp2=temp2%7;

    temp2=temp2+day+table_week[month-1];

    if (yearL%4==0&&month<3)temp2--;

    return(temp2%7);

}   
请打赏
 楼主| 发表于 2019-7-10 11:15 | 显示全部楼层
2.DS1302与STM32



2.1硬件连接



   Vcc--电源+

   GND--电源地

   CLK--PC12

   DAT--PC11

   RST--PC10



2.2驱动程序



DS1302.c的程序网上很多都不能用,查找了硬件时序,发现没问题,但是就是没办法用,下面的程序我亲自测过可以用的,如下:



#include "DS1302.h"

//#include "IO.h"

#include "delay.h"  

//*****************DS1302控制命令*******************

#define WRITE_SECOND              0x80

#define WRITE_MINUTE              0x82

#define WRITE_HOUR                0x84

#define WRITE_DAY                 0x86

#define WRITE_MONTH               0x88

#define WRITE_WEEK                0x8A

#define WRITE_YEAR                0x8C

#define WRITE_TIMER_FLAG          0xC0



#define READ_SECOND               0x81

#define READ_MINUTE               0x83

#define READ_HOUR                 0x85

#define READ_DAY                  0x87

#define READ_MONTH                0x89

#define READ_WEEK                 0x8B

#define READ_YEAR                 0x8D

#define READ_TIMER_FLAG           0xC1

#define WRITE_PROTECT             0x8E

_calendar_obj calendar;                         //时钟结构体

_next_obj next;                                    

//月份数据表                                          

u8 const table_week[12]={0,3,3,6,1,4,6,2,5,0,3,5}; //月修正数据表   

u8 BCD2HEX(u8 bcd_data)    //BCDtoHEX   

{   

    u8 temp;   

    temp=(bcd_data/16*10 + bcd_data%16);   

    return temp;   

}   

u8 HEX2BCD(u8 hex_data)    //HEXtoBCD   

{   

    u8 temp;   

    temp=(hex_data/10*16 + hex_data%10);   

    return temp;   

}   

//============================================

//函数名称:void Ds1302_Write_Byte (byte addr, byte dat)  

//功能:    串行发送地址、数据,先发低位,且在上升沿发送

//参数传递:有,地址和数据

//返回值:  无

//===========================================

void IO_Init(void)

{   

    GPIO_InitTypeDef  GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE); //使能PA,PB,PC端口时钟

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;                                                            //IO口速度为50MHz   

    //PC端口初始化   

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12;                      //设置PC10~PC12端口推挽输出

    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;                                                       //推挽输出  

    GPIO_Init(GPIOC, &GPIO_InitStructure);                                                                                          

}





void Ds1302_Write_Byte(u8 addr, u8 dat)     

{

    u8 i;

  DS1302_IO_OUT();                //数据端口定义为输出

  CE = 1;

    delay_us(10);

    SCLK = 0;

    delay_us(10);

    for(i=0;i<8;i++)

    {

        if(addr&0x01)

        {

            DIO = 1;

        }

        else

        {

            DIO = 0;

        }

        addr = addr>>1;

        SCLK = 1;

        delay_us(10);

        SCLK = 0;

        delay_us(10);



    }

    for(i=0;i<8;i++)            //写入数据:dat

  {

        if(dat&0x01)

        {

            DIO = 1;

        }

        else

        {

            DIO = 0;

        }

        dat = dat>>1;

        SCLK = 1;

        delay_us(10);

        SCLK = 0;

        delay_us(10);

  }

  CE = 0;;                     //停止DS1302总线

    delay_us(10);

}

//===============================================

//函数名称:byte Ds1302_Read_Byte ( byte addr )

//功能:    串行读取数据,先发低位,且在下降沿发送

//参数传递:有,地址

//返回值:  有,读取的数据

//===============================================

u8 Ds1302_Read_Byte(u8 addr)

{

  u8  i;

  u8  temp = 1;

    CE = 1;

    delay_us(10);

  for(i=0;i<8;i++)

  {      

    SCLK = 0;

        delay_us(10);

        if(addr&0x01)

    {

       DIO = 1;

    }

    else

    {

       DIO = 0;

    }

        addr = addr>>1;

        SCLK = 1;

        delay_us(10);

  }

  DS1302_IO_IN();                  //数据端口定义为输入

  for(i=0;i<8;i++)

  {

    temp = temp >> 1;                            //输出数据:temp

    SCLK = 0;

        delay_us(10);

        if(DIO_IN)

    {

       temp |= 0x80;

    }

        SCLK = 1;

        delay_us(10);

  }

  DS1302_IO_OUT();                //数据端口定义为输出                       

  SCLK = 0;

    delay_us(10);

    CE = 0;                         //停止DS1302总线

    delay_us(10);

    return temp;                    

}

//获得现在是星期几

//功能描述:输入公历日期得到星期(只允许1901-2099年)

//输入参数:公历年月日

//返回值:星期号                                                                                       

u8 RTC_Get_Week(u16 year,u8 month,u8 day)

{   

    u16 temp2;

    u8 yearH,yearL;

    yearH=year/100;

    yearL=year%100;                                     //如果为21世纪,年份数加100  

    if (yearH>19)yearL+=100;                    //所过闰年数只算1900年之后的  

    temp2=yearL+yearL/4;

    temp2=temp2%7;

    temp2=temp2+day+table_week[month-1];

    if (yearL%4==0&&month<3)temp2--;

    return(temp2%7);

}            

//===============================================

//           向DS1302写入时钟数据

//===============================================

void RTC_Set(u16 year,u8 mon,u8 day,u8 hour,u8 min,u8 sec)

{   

    u8 WR_week;

    u8 WR_yearL = 0;

    if(year>=2000)

    {

        WR_yearL = year - 2000;

    }

    WR_week = RTC_Get_Week(year,mon,day);                        //根据写入的日期算星期几

    Ds1302_Write_Byte(WRITE_PROTECT,0x00);           //关闭写保护

    Ds1302_Write_Byte(WRITE_SECOND,0x80);            //暂停

//  Ds1302_Write_Byte(ds1302_charger_add,0xa9);    //涓流充电

    Ds1302_Write_Byte(WRITE_YEAR,HEX2BCD(WR_yearL)); //年

    Ds1302_Write_Byte(WRITE_MONTH,HEX2BCD(mon));     //月

    Ds1302_Write_Byte(WRITE_DAY,HEX2BCD(day));       //日

    Ds1302_Write_Byte(WRITE_HOUR,HEX2BCD(hour));     //时

    Ds1302_Write_Byte(WRITE_MINUTE,HEX2BCD(min));    //分

    Ds1302_Write_Byte(WRITE_SECOND,HEX2BCD(sec));    //秒

    Ds1302_Write_Byte(WRITE_WEEK,HEX2BCD(WR_week));  //周

    Ds1302_Write_Byte(WRITE_PROTECT,0x80);           //打开写保护

}



//========================================

//           从DS1302读出时钟数据

//========================================

void GetTime(void)  

{

//  u8  i,tmp;

    calendar.w_year  = BCD2HEX(Ds1302_Read_Byte(READ_YEAR));                    //年

    calendar.w_month = BCD2HEX(Ds1302_Read_Byte(READ_MONTH));         //月

    calendar.w_date  = BCD2HEX(Ds1302_Read_Byte(READ_DAY));           //日

    calendar.hour    = BCD2HEX(Ds1302_Read_Byte(READ_HOUR));          //时

    calendar.min     = BCD2HEX(Ds1302_Read_Byte(READ_MINUTE));        //分

    calendar.sec     = BCD2HEX(Ds1302_Read_Byte(READ_SECOND)&0x7F);     //秒

    calendar.week    = BCD2HEX(Ds1302_Read_Byte(READ_WEEK));          //周

    calendar.w_year  = calendar.w_year+2000;

}









//==========================================

//              DS1302初始化

//==========================================

void Ds1302_Init(void)

{

    IO_Init();

  CE = 0;                                           //RST脚置低

  SCLK = 0;                                         //SCK脚置低

    Ds1302_Write_Byte(WRITE_SECOND,0x00);           //开始  

  //RTC_Set(2017,4,18,15,23,2) ;

}

//*******************以下UTC时间计算部分函数*****************

//判断是否是闰年函数

//月份   1  2  3  4  5  6  7  8  9  10 11 12

//闰年   31 29 31 30 31 30 31 31 30 31 30 31

//非闰年 31 28 31 30 31 30 31 31 30 31 30 31

//输入:年份

//输出:该年份是不是闰年.1,是.0,不是

u8 Is_Leap_Year(u16 year)

{            

    if(year%4==0)                                                               //必须能被4整除

    {

        if(year%100==0)

        {

            if(year%400==0)return 1;                                    //如果以00结尾,还要能被400整除        

            else return 0;   

        }else return 1;   

    }else return 0;

}                  



DS1302.h内容如下:



#ifndef __DS1302_H

#define __DS1302_H

#include "sys.h"

#endif





//-------------------------------------------------------------------------*

//文件名:  DS1302.h (实时时钟头文件)                                          *

//-------------------------------------------------------------------------*

//IO方向设置



#define CE                  PCout(10)           // PC10

#define DIO                 PCout(11)           // PC11

#define SCLK                PCout(12)           // PC12



#define DS1302_IO_IN()  {GPIOC->CRH&=0xFFFF0FFF;GPIOC->CRH|=0x00008000;}                //低八位引脚的PC11脚定义为输入

#define DS1302_IO_OUT() {GPIOC->CRH&=0xFFFF0FFF;GPIOC->CRH|=0x00003000;}        //低八位引脚的PC11脚定义为输出

//IO操作函数                                               

#define DIO_OUT PCout(11)           //数据端口  PC11

#define DIO_IN  PCin(11)            //数据端口  PC11

typedef struct

{

    u8  sec;

    u8  min;

    u8  hour;

    u8  day;

    u8  mon;

  u16 year;

    u8  week;

}_next_obj;

extern _next_obj next;

typedef struct

{

    vu8 hour;

    vu8 min;

    vu8 sec;            

    //公历日月年周

    vu16 w_year;

    vu8  w_month;

    vu8  w_date;

    vu8  week;      

}_calendar_obj;

extern _calendar_obj calendar;  //日历结构体



extern u32 RTC_sec_sum;                                                     //当前时间的总秒值

extern u32 Program_sec_sum;                                             //当前编程任务的总秒值,与RTC_sec_sum进行比较

void RTC_Set(u16 year,u8 mon,u8 day,u8 hour,u8 min,u8 sec);

void GetTime(void);

void NEXT_Date(u8 day);

u8 RTC_Pro_count(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec,u8 mode);//编程任务时间计算

u8 Pro_Get_time(u32 ttt);                               //编程模式无效时间时计算下次开始的日期

void Ds1302_Init(void);
 楼主| 发表于 2019-7-11 18:28 | 显示全部楼层

TM1639与STM32连接

#include "BitOpt.h"
#include "TM1639.h"
#include "spce061a.h"


BIT16 *bitPort1639     = (BIT16*)P_IOA_Data;
BIT16 *bitPort_Dir1639 = (BIT16*)P_IOA_Dir;
BIT16 *bitPort_Att1639 = (BIT16*)P_IOA_Attrib;

//
#define DIO          WRB0(bitPort1639)
#define DIO_DIR      WRB0(bitPort_Dir1639)
#define DIO_ATT      WRB0(bitPort_Att1639)

#define CLK        WRB1(bitPort1639)
#define CLK_DIR      WRB1(bitPort_Dir1639)
#define CLK_ATT      WRB1(bitPort_Att1639)

#define STB          WRB2(bitPort1639)
#define STB_DIR      WRB2(bitPort_Dir1639)
#define STB_ATT      WRB2(bitPort_Att1639)

//
#define MD_WRITE        0x40 //���õ�ַ�Զ���һ��ʽд�Դ�
#define MD_AUTO         MD_WRITE
#define MD_NORMAL       MD_WRITE

#define MD_READKEY      0x42 //����������
#define MD_FIX          0x44 //���ù̶���ַ��ʽд�Դ�
#define MD_TEST         0x48 //����ģʽ


//****************************************************************
// д������1���ֽ�(8bit)��LED_IC����ʼ  
//����8BIT����
//��ʱ�ӵ�������ͨ��MCU��LED����IC����TM16xxд����
//----------------------------------------------------------------
void indate(unsigned char input)
{
unsigned int i;

//DIO�����
DIO_DIR = 1;
DIO_ATT = 1;

STB=0;                //��֤��STB��Ϊ�͵�ƽ������������֮ǰ�˿ڵ�״̬
                        //��֤������ʵ�������в�����֡��˿���ʧ��
for(i=0;i<8;i++) {
    CLK=0;              //�Ƚ���CLK������
    if((input & 0x01)!=0)
      DIO=1;            //��Ҫ���͵����ݵĵ�λΪ��1������ѡ�DIO������
    else
      DIO=0;            //��Ҫ���͵����ݵĵ�λΪ��0������ѡ�DIO���ø�
    CLK=1;              //��ʱ�ӵ�������
    input=input>>1;     //׼������һ��BIT
}                     //����һ���ֽں��˳�ѭ��
}

//****************************************************************
// д������1���ֽ�(8bit)��LED_IC����ʼ  
//��LED_IC����1���ֽ�(8bit)����ʼ  
//���8BIT����
//��ʱ�ӵ�������ͨ��MCU��LED����IC����TM16xx������
//----------------------------------------------------------------
unsigned char outdate()
{
unsigned char i,out=0;     

//DIO����������
DIO_DIR = 0;
DIO_ATT = 0;
DIO      = 1;

STB=0;                  //��֤��STB��Ϊ�͵�ƽ������������֮ǰ�˿ڵ�״̬
                          //��֤������ʵ�������в�����֡��˿���ʧ��
for(i=0;i<8;i++) {
    CLK=0;                //�Ƚ���CLK������
    out=out>>1;
    if(DIO == 0)  
        out=out & 0x7f;   //�����DIO��Ϊ�͵�ƽ�����out�����λ�塰0����������λ���ֲ���
    else                  //�����DIO��Ϊ�ߵ�ƽ�����out�����λ�á�1����������λ���ֲ���
        out=out | 0x80;  
    CLK=1;                //��ʱ�ӵ�������
}
return(out);            //���ض�����1�ֽ�����
}

//****************************************************************
//���ù̶���ַ��ʽ�����ַ�����ݿ�ʼ
//���ù̶���ַ��ʽ
//----------------------------------------------------------------
/*
void display2(unsigned char adress,unsigned char data)
{
DIO=1;
CLK=1;
STB=1;                      //ͨѶ��ʼǰͨѶ�˿�ȫ����ʼ��Ϊ��1��

indate(MD_FIX);             //������������
STB=1;
indate(adress);             //����ʾ���ݶ�Ӧ�ĵ�ַ
indate(data);               //���֡�STB��=��0������1BYTE��ʾ����
STB=1;                      //������ʾ���ݺ
 楼主| 发表于 2019-7-11 18:30 | 显示全部楼层
另 TM1639与STM32连接
数码管和按键驱动芯片TM1639驱动代码2010年06月24日 星期四 00:28

//********************************************************************************************************************************
//TM1639.h
//数码管和按键驱动芯片TM1639函数接口和芯片操作相关宏定义
//********************************************************************************************************************************

#ifndef _TM1639_H
#define _TM1639_H

//位使能
#define DIG0 0xc0
#define DIG1 0xc2
#define DIG2 0xc4
#define DIG3 0xc6
#define DIG4 0xc8
#define DIG5 0xca
#define DIG6 0xcc
#define DIG7 0xce

//显示亮度级别
#define LEVEL_OFF   0x80
#define LEVEL_1     0x88
#define LEVEL_2     0x89
#define LEVEL_4     0x8a
#define LEVEL_10    0x8b
#define LEVEL_11    0x8c
#define LEVEL_12    0x8d
#define LEVEL_13    0x8e
#define LEVEL_14    0x8f


//初始化IC端口
void InitTM1639();
//连续传送多个数据
void SeriesInData (unsigned char starAddr,unsigned char *data,unsigned char loop,unsigned char level);
//传送一个数据(本质是连续模式)
void OneByteInData(unsigned char starAddr,unsigned char *data,unsigned char level);
//清楚所有显示数据
void ClearAll();
//读取按键键值
void KeyRead(int *key);
//测试模式,内部使用,检验硬件完整性
void ICTest();

#endif

//********************************************************************************************************************************
//TM1639.C
//数码管和按键驱动芯片TM1639函数代码
//********************************************************************************************************************************


#include "BitOpt.h"
#include "TM1639.h"
#include "spce061a.h"

//端口位操作全局变量,根据情况修改端口
BIT16 *bitPort1639     = (BIT16*)P_IOA_Data;    //谁知这是什么单片机端口?
BIT16 *bitPort_Dir1639 = (BIT16*)P_IOA_Dir;
BIT16 *bitPort_Att1639 = (BIT16*)P_IOA_Attrib;

//端口设置,根据情况修改端口位
#define DIO          WRB0(bitPort1639)
#define DIO_DIR      WRB0(bitPort_Dir1639)
#define DIO_ATT      WRB0(bitPort_Att1639)

#define CLK        WRB1(bitPort1639)
#define CLK_DIR      WRB1(bitPort_Dir1639)
#define CLK_ATT      WRB1(bitPort_Att1639)

#define STB          WRB2(bitPort1639)
#define STB_DIR      WRB2(bitPort_Dir1639)
#define STB_ATT      WRB2(bitPort_Att1639)

//工作模式,可以进行|组合
#define MD_WRITE        0x40 //采用地址自动加一方式写显存
#define MD_AUTO         MD_WRITE
#define MD_NORMAL       MD_WRITE

#define MD_READKEY      0x42 //读按键命令
#define MD_FIX          0x44 //采用固定地址方式写显存
#define MD_TEST         0x48 //测试模式


//****************************************************************
// 写入输入1个字节(8bit)到LED_IC程序开始
//输入8BIT数据
//在时钟的上升沿通过MCU向LED驱动IC——TM16xx写数据
//----------------------------------------------------------------
void indate(unsigned char input)
{
unsigned int i;

//DIO设为输出
DIO_DIR = 1;
DIO_ATT = 1;

STB=0;                //保证“STB”为低电平,程序不依赖于之前端口的状态
                        //保证程序在实际运行中不会出现“端口迷失”
for(i=0;i<8;i++) {
    CLK=0;              //先将“CLK”清零
    if((input & 0x01)!=0)
      DIO=1;            //需要传送的数据的低位为“1”,则把“DIO”清零
    else
      DIO=0;            //需要传送的数据的低位为“0”,则把“DIO”置高
    CLK=1;              //送时钟的上升沿
    input=input>>1;     //准备送下一个BIT
}                     //送完一个字节后退出循环
}

//****************************************************************
// 写入输入1个字节(8bit)到LED_IC程序开始
//从LED_IC读入1个字节(8bit)程序开始
//输出8BIT数据
//在时钟的上升沿通过MCU从LED驱动IC——TM16xx读数据
//----------------------------------------------------------------
unsigned char outdate()
{
unsigned char i,out=0;   

//DIO设为上拉输入
DIO_DIR = 0;
DIO_ATT = 0;
DIO      = 1;

STB=0;                  //保证“STB”为低电平,程序不依赖于之前端口的状态
                          //保证程序在实际运行中不会出现“端口迷失”
for(i=0;i<8;i++) {
    CLK=0;                //先将“CLK”清零
    out=out>>1;
    if(DIO == 0)
        out=out & 0x7f;   //如果“DIO”为低电平,则把out的最高位清“0”,其他各位保持不变
    else                  //如果“DIO”为高电平,则把out的最高位置“1”,其他各位保持不变
        out=out | 0x80;
    CLK=1;                //送时钟的上升沿
}
return(out);            //返回读到的1字节数据
}

//****************************************************************
//采用固定地址方式传输地址和数据开始
//采用固定地址方式
//----------------------------------------------------------------
/*
void display2(unsigned char adress,unsigned char data)
{
DIO=1;
CLK=1;
STB=1;                      //通讯开始前通讯端口全部初始化为“1”

indate(MD_FIX);             //数据设置命令
STB=1;
indate(adress);             //传显示数据对应的地址
indate(data);               //保持“STB”=“0”,传1BYTE显示数据
STB=1;                      //传完显示数据后将“STB”置“1”
}
*/
/****************************************************************
初始IC三个端口
DIO,CLK,STB全部设置成不带反相器高电平输出
****************************************************************/
void InitTM1639()
{
CLK_DIR = 1;
CLK_ATT = 1;
CLK     = 1;

STB_DIR = 1;
STB_ATT = 1;
STB     = 1;

DIO_DIR = 1;
DIO_ATT = 1;
DIO     = 1;
}

/****************************************************************
连续传递数据,数据最多16byte
statAddr:起始地址
data:    连续写入数据的起始数据地址
len:     连续写入数据的长度,len*2+DIG0 < DIG7
leve:    亮度级别
注:如果len*2+DIG0地址>DIG7那么,多出来的地址返回到DIG0,如此循环。
本函数可以防止上电后马上传显示数据,会出现乱码。
****************************************************************/
void SeriesInData(unsigned char starAddr,unsigned char *data,unsigned char len,unsigned char level)
{
int i;

//通讯开始前通讯端口全部初始化为“1”
DIO=1;
CLK=1;
STB=1;                     

indate(MD_AUTO);                 //传数据设置命令,设置采用地址自动加1方式写显示数据,
STB=1;                          //数据设置命令传完后需要将“STB”置“1”
indate(starAddr);               //传起始地址

//关键部分(数据分两次传递到两个地址里面去)
for(i = 0;i < len;++i) {
    indate(*data & 0x0f);         //低地址
    indate(*data >> 4 & 0x0f);    //高地址
    ++data;
}

STB=1;                      //传完所有的显示数据后(最多14BYTE)后,将“STB置“1”
indate(level);
STB=1;                      //显示控制命令传完后将“STB”置“1”
}

/****************************************************************
连续一位数码管数据
statAddr:起始地址
data:    连续写入数据的起始数据地址
leve:    亮度级别
注:本质上这个函数也是使用连续模式写入的,非连续模式我写不进去。
这个函数可以防止由于使用SeriesInData函数导致写入长度越界
****************************************************************/
void OneByteInData(unsigned char starAddr,unsigned char *data,unsigned char level)
{
DIO=1;
CLK=1;
STB=1;                      //通讯开始前通讯端口全部初始化为“1”

indate(MD_AUTO);            //传数据设置命令,设置采用地址自动加1方式写显示数据,
STB=1;                      //数据设置命令传完后需要将“STB”置“1”
indate(starAddr);           //传起始地址

//关键部分(数据分两次传递到两个地址里面去)
indate(*data & 0x0f);       //低地址
indate(*data >> 4 & 0x0f); //高地址

STB=1;                      //传完所有的显示数据后(最多14BYTE)后,将“STB置“1”
indate(level);
STB=1;                      //显示控制命令传完后将“STB”置“1
}

/****************************************************************
清除所有数据
从第一位数码管(地址DIG0)开始连续清除8位数码管数据,并且关闭显示。
调用情况1:
由于上点过程中数码管显示的数据是随机的,可以先调用此函数对数码管清屏。
调用情况2:
如果系统运行过程当中显示的位数不一定(有时显示3位有时显示5位),
那么当从高位切换到低位的时候需要对多余的几位进行清显操作,
可一直接调用此ClearAll函数,也可以调用OneByteInData函数逐位写0清显
****************************************************************/
void ClearAll()
{
unsigned int i;             //i——控制本次需要传多少个字节显示数据
   
//通讯开始前通讯端口全部初始化为“1”
DIO=1;
CLK=1;
STB=1;                     

indate(MD_AUTO);            //传数据设置命令,设置采用地址自动加1方式写显示数据,
STB=1;                      //数据设置命令传完后需要将“STB”置“1”
indate(DIG0);               //传起始地址
                              //地址命令传完后,“STB”保持为“0”继续传需要显示的数据
for(i=0;i<16;i++)           //datacount=2*grid=2*5=10???
      indate(0);              //在连续传显示的数据过程中,“STB”一直保持为”0“
      
STB=1;                      //传完所有的显示数据后(最多14BYTE)后,将“STB置“1”
indate(0x80);               //传显示控制命令
STB=1;                      //显示控制命令传完后将“STB”置“1
}

/****************************************************************
按键扫描程序
key:存储按键按下的信息int形数据,最多一次可以得到两个按键按下的结果
key1或key2:4、8、64、128,每个变量可以指示4个按键按下,key1或key2里面允许组合两个按键,
****************************************************************/

void KeyRead(int *key)
{
unsigned char key1,key2;
STB=1;

indate(MD_READKEY);         //传数据设置命令,设置为读按键   
                              //“STB”保持为“0”,读键值
key1 = outdate();
key2 = outdate();
*key = key1 | (key2 << 8);

STB=1;                      //读键结束将“STB”置“1”
*P_IOA_Dir = 0xffff;
}

/****************************************************************
测试模式,内部使用,检验硬件完整性
****************************************************************/
void ICTest()
{
STB=1;
indate(MD_TEST);
STB=1;
indate(0x8c);
STB=1;
}

 楼主| 发表于 2019-7-12 08:56 | 显示全部楼层
https://wenku.baidu.com/view/34aa72eb551810a6f52486a0.html
TM1639_单片机的好助手

https://wenku.baidu.com/view/2b2 ... ;sxts=1562892753431
基于单片机与TM1639的多功能数字钟设计
 楼主| 发表于 2019-7-14 11:57 | 显示全部楼层
STM32硬件SPI控制TM1638按键数码管LED显示模块

 

从淘宝买来的,TM1638专门是控制LED的,LED组合起来就可以变成数码管,还有按键,这个我就没管了,不想管了,发这个帖子只是为了记录下经验,待以后会过头来看的时候,可以一遍就知道,所以尽量写得详细点。
   手头上的项目用的是共阳极,而我买的是共阴极的,而且例程给的是STM32模拟IO实现的。

太浪费资源了,想尽办法折腾了1整体,终于搞定了SPI硬件实现的方式。写点东西给大家分享下,免得走弯路。本次重点介绍SPI硬件配置方面。
---------------------



3.3V供电;

STM32F103c8t6;

SPI1;

SPI_Direction_1Line_Tx;

完整程序如下:

//TM1638.C文件

#ifdef   USE_TM1638_SPI

 

 

#defineTM1638_SPIx                        SPI1

#defineTM1638_SPI_APBxClock_FUN          RCC_APB2PeriphClockCmd

#defineTM1638_SPI_CLK                    RCC_APB2Periph_SPI1

#defineTM1638_SPI_GPIO_APBxClock_FUN     RCC_APB2PeriphClockCmd

#defineTM1638_SPI_GPIO_CLK               RCC_APB2Periph_GPIOA 

 

 

 

#defineTM1638_SPI_SCK_PORT               GPIOA 

#defineTM1638_SPI_SCK_PIN                GPIO_Pin_5

#defineTM1638_SPI_SCK_Low()            GPIO_ResetBits(TM1638_SPI_SCK_PORT, TM1638_SPI_SCK_PIN)

#defineTM1638_SPI_SCK_High()           GPIO_SetBits(TM1638_SPI_SCK_PORT, TM1638_SPI_SCK_PIN)

 

  

#defineTM1638_SPI_MISO_PORT               GPIOA

#defineTM1638_SPI_MISO_PIN               GPIO_Pin_6

 

#defineTM1638_SPI_MOSI_PORT               GPIOA

#defineTM1638_SPI_MOSI_PIN               GPIO_Pin_7

#defineTM1638_SPI_MOSI_Low()            GPIO_ResetBits(TM1638_SPI_MOSI_PORT, TM1638_SPI_MOSI_PIN)

#defineTM1638_SPI_MOSI_High()           GPIO_SetBits(TM1638_SPI_MOSI_PORT, TM1638_SPI_MOSI_PIN)

 

 

#defineTM1638_SPI_CS_CLK                 RCC_APB2Periph_GPIOA   

#defineTM1638_SPI_CS_PORT                 GPIOA  

#defineTM1638_SPI_CS_PIN                 GPIO_Pin_3

#defineTM1638_SPI_CS_ENABLE()            GPIO_ResetBits(TM1638_SPI_CS_PORT, TM1638_SPI_CS_PIN)

#defineTM1638_SPI_CS_DISABLE()           GPIO_SetBits(TM1638_SPI_CS_PORT, TM1638_SPI_CS_PIN)

 

#defineTM1638_CE_CLK                     RCC_APB2Periph_GPIOA   

#defineTM1638_CE_PORT                     GPIOA

#defineTM1638_CE_PIN                     GPIO_Pin_3

#defineTM1638_CE_LOW()                   GPIO_ResetBits(TM1638_CE_PORT, TM1638_CE_PIN)

#defineTM1638_CE_HIGH()                  GPIO_SetBits(TM1638_CE_PORT, TM1638_CE_PIN)

 

#defineTM1638_IRQ_CLK                    RCC_APB2Periph_GPIOA   

#defineTM1638_IRQ_PORT                    GPIOA

#defineTM1638_IRQ_PIN                     GPIO_Pin_2

#defineTM1638_IRQ_PIN_READ()             GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2)

 

 

 

 

voidTM1638_GPIO_init(void)

 

{  

    GPIO_InitTypeDef GPIO_InitStructure;

       SPI_InitTypeDef  SPI_InitStructure;

 

       TM1638_SPI_APBxClock_FUN(TM1638_SPI_CLK,ENABLE); 

      TM1638_SPI_GPIO_APBxClock_FUN(RCC_APB2Periph_GPIOA,ENABLE);    

 

    GPIO_InitStructure.GPIO_Pin =GPIO_Pin_5|GPIO_Pin_7|GPIO_Pin_6;               //PB12上拉防止W25X的干扰

    GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;        //推挽输出

    GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;

    GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化指定IO

 

   

    GPIO_InitStructure.GPIO_Pin= GPIO_Pin_4|GPIO_Pin_3;              //PB12上拉防止W25X的干扰

    GPIO_InitStructure.GPIO_Mode= GPIO_Mode_Out_PP;       //推挽输出

    GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;

    GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化指定IO

 

       TM1638_SPI_CS_DISABLE();            //SPI片选取消                   

  

    SPI_Cmd(TM1638_SPIx, DISABLE); // SPI外设不使能

  

    SPI_InitStructure.SPI_Direction =  SPI_Direction_1Line_Tx;  //SPI设置为双线双向全双工

    SPI_InitStructure.SPI_Mode =SPI_Mode_Master;      //SPI主机

       SPI_InitStructure.SPI_DataSize =SPI_DataSize_8b;      //发送接收8位帧结构

    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;     //时钟悬空低

    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;   //数据捕获于第1个时钟沿

    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;      //NSS信号由软件控制

    SPI_InitStructure.SPI_BaudRatePrescaler =SPI_BaudRatePrescaler_4;        //定义波特率预分频的值:波特率预分频值为16

    SPI_InitStructure.SPI_FirstBit =SPI_FirstBit_LSB;//SPI_FirstBit_MSB; //数据传输从MSB位开始

    SPI_InitStructure.SPI_CRCPolynomial = 7;   //CRC值计算的多项式

    SPI_Init(TM1638_SPIx,&SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器

 

    SPI_Cmd(TM1638_SPIx, ENABLE); //使能SPI外设

             

    //TM1638_CE_HIGH() ;

    TM1638_SPI_CS_ENABLE();        //SPI片选取消                   

}

 

void TM1638_SPIx_SetSpeed(SPI_TypeDef*SPIx, uint8_t SPI_BaudRatePrescaler)

{

  /* Check the parameters */

  assert_param(IS_SPI_ALL_PERIPH(SPIx));

 assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));

    SPIx->CR1&=0XFFC7;

    SPIx->CR1|=SPI_BaudRatePrescaler;  //设置SPI2速度

    SPI_Cmd(SPIx,ENABLE);

}

uint8_tTM1638_SPIx_ReadWriteByte(SPI_TypeDef* SPIx, uint8_t TxData)

 

{      

    SPI_I2S_SendData(SPIx, TxData); //通过外设SPIx发送一个数据

      while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY) == RESET);//等待发送完成

}

 

 

void  TM1638_Write_Reg(uint8_t value)

{

  TM1638_SPI_CS_ENABLE();                 //使能SPI传输

 

 TM1638_SPIx_ReadWriteByte(TM1638_SPIx,value);      //写入寄存器的值

  TM1638_SPI_CS_DISABLE();                 //禁止SPI传输   

}

 

voidWrite_DATA(unsigned char add,unsigned char DATA)     //指定地址写入数据

 

{

    TM1638_Write_Reg(0x44);

    TM1638_SPI_CS_ENABLE() ;

    //TM1638_Write(0xc0|add);

        TM1638_SPIx_ReadWriteByte(TM1638_SPIx,0xc0|add);    //设置起始地址

        TM1638_SPIx_ReadWriteByte(TM1638_SPIx,DATA);    //设置起始地址

    //TM1638_Write(DATA);

    TM1638_SPI_CS_DISABLE();

}

 

/*

voidWrite_oneLED(unsigned char num,unsigned char flag)   //单独控制一个LED函数,num为需要控制的led序号,flag为0时熄灭,不为0时点亮

{

    if(flag)

        Write_DATA(2*num+1,1);

    else

        Write_DATA(2*num+1,0);

}  */

voidWrite_allLED(unsigned char LED_flag)                 //控制全部LED函数,LED_flag表示各个LED状态

{

    unsigned char i;

    for(i=0;i<8;i++)

        {

            if(LED_flag&(1<<i))

                //Write_DATA(2*i+1,3);

                Write_DATA(2*i+1,1);

            else

                Write_DATA(2*i+1,0);

        }

}

voidinit_TM1638(void)

 

{

    unsigned char i;

    TM1638_GPIO_init();

    TM1638_SPIx_SetSpeed(TM1638_SPIx,SPI_BaudRatePrescaler_4);//spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)    

 

    TM1638_Write_Reg(0x8b);       //亮度 (0x88-0x8f)8级亮度可调

    TM1638_Write_Reg(0x40);       //采用地址自动加1

    TM1638_SPI_CS_ENABLE() ;                 //

    TM1638_SPIx_ReadWriteByte(TM1638_SPIx,0xc0);    //设置起始地址

 

    for(i=0;i<16;i++)     //传送16个字节的数据

        TM1638_SPIx_ReadWriteByte(TM1638_SPIx,0x00);

   

    TM1638_SPI_CS_DISABLE();

}

#endif

 

//main.C文件

 

/* 包含头文件 ----------------------------------------------------------------*/

#include"stm32f10x.h"

#include"bsp/usart/bsp_debug_usart.h"

#include"bsp/NRF24l01/NRF24l01.h"

#include"bsp/TM1638/bsp_tm1638.h"

 

 

unsignedchar LedTab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,

                          0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};

 

/* 私有类型定义 --------------------------------------------------------------*/

 

/* 私有宏定义 ----------------------------------------------------------------*/

 

/* 私有变量 ------------------------------------------------------------------*/

/* 扩展变量------------------------------------------------------------------*/

/* 私有函数原形 --------------------------------------------------------------*/

staticvoid Delay(uint32_t time);

 

 

 

/* 函数体 --------------------------------------------------------------------*/

 

/**

  * 函数功能: 主函数.

  * 输入参数: 无

  * 返 回 值: 无

  * 说    明: 无

  */

intmain(void)

{

uint8_ti;

  uint8_t tmp_buf[33]="硬石开发板 NRF24L01 实验";

  unsigned char num[8];    //各个数码管显示的值

 

  /* 调试串口初始化配置,115200-N-8-1.使能串口发送和接受 */

  DEBUG_USART_Init(); 

 

  /* 调用格式化输出函数打印输出数据 */

  printf("这是一个NRF24L012.4G无线数据传输模块测试实验\n");

 

 

 

  init_TM1638();

 

  /* 无限循环 */

 

     Delay(200);

  for(i=0;i<8;i++)

    Write_DATA(i<<1,tab[0]);                 //初始化寄存器

   

    while(1)

    {

               Delay(100);

        if(i<8)

        {

            num++;

            //while(Read_key()==i);          //等待按键释放

            if(num>15)

            num=0;

            Write_DATA(i*2,tab[num]);

            Write_allLED(1<<i);

                i++;                          //读按键值

 

        }

        else

            i= 0;

 

 

    }

}

 

/**

  * 函数功能: 简单粗暴的延时函数

  * 输入参数: time;延时时间设置

  * 返 回 值: 无

  * 说    明:使用这种死循环方式的延时函数是没办法精确控制延时时间长短,

  *           只是大概的延时时间,所以基本上都是通过不断修改输入参数

  *           大小然后下载到开发板上看实验效果。

  */

staticvoid Delay(uint32_t time)

{

  uint32_t i,j;

 

  for(i=0;i<time;++i)

  {

    for(j=0;j<10000;++j)

    {      

      //空循环,什么都不做       

    }

  }

}
---------------------
作者:cymzhbin
来源:CSDN
原文:https://blog.csdn.net/cymzhbin/article/details/80613095
版权声明:本文为博主原创文章,转载请附上博文链接!
您需要登录后才可以回帖 登录 | 加入论坛

本版积分规则

快速回复 返回顶部 返回列表