stm32+DS1302+TM1638驱动程序

来源:互联网 发布:网络音响 编辑:程序博客网 时间:2024/06/16 09:35

TM1638数码管显示驱动程序(参考)

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 pinuint16_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<<i);    }    key2>>=1;    for(i=0;i<8;i++){        if(0x01<<i==key2)return i+1;    }    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);}             //===============================================//           向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)            //数据端口  PC11typedef 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);
0 0
原创粉丝点击