打印
[应用方案]

基于M0516的SPI驱动的10X7段共阳数码管的TM1668驱动程序

[复制链接]
6517|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 缥缈九哥 于 2013-12-9 12:22 编辑

测试了一个用M0516的SPI驱动TM1668驱动的10个7段数码管驱动,需要做行列段的转换驱动表,请同行们指正。
源码:/******************************************************************************
* @file     tM1668.c
* @brief    The Driver code for 10 7-Segment-Digital LED
* @version  1.0.0
* @date     06, december 2013
*
* @note
* Copyright (C) 2000-2013 PM9GZY by yuanxihua@21cn.com. All rights reserved.
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include "M051Series.h"
#include "rfid.h"
/*
//make by yuanxihua@21cn.com
____________________________________________
|        M0517LBN                                          TM1668                |
|                                                                                         |
|        P14        SPISS0                ---->                STB                        |
|        P15        MOSI0                 ---->                DIO                        |
|        P16        MISO0                 <----                DIO                        |
|        P17        SCLK0                ---->                CLK                        |
|___________________________________________|
*/
//const unsigned char  TM1668_7X8_CODE[]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0X7F, 0x39, 0x3F, 0x79, 0x71};/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
const unsigned short int TM1668_10X7_CODE[]={0xffed,0x2f9f,0x2ffb,0x7b6d,0xfd45,0xff71,0xcf7c};
void SPI0_Init(void);
void SPI0_Write_Byte(uint8_t data);
void TM1668_Init(void){SPI0_Init();}
void TM1668_Read_Key(uint8_t *key);
void TM1668_Write_ADDR_INC(uint8_t *data);
void TM1668_DISPLAY(uint8_t *led);
void TM1668_Number(uint32_t data1,uint32_t data2);

void SPI0_Init(void)
{
    /* Unlock protected registers */
    SYS_UnlockReg();
        
    /* Set P1.4, P1.5, P1.6, P1.7 for SPI0 */
    SYS->P1_MFP = SYS_MFP_P14_SPISS0 | SYS_MFP_P15_MOSI_0 | SYS_MFP_P16_MISO_0 | SYS_MFP_P17_SPICLK0;

    /* Configure SPI0 as a master, clock idle high, rising clock edge Tx, rising edge Rx and 8-bit LSB transaction */
    SPI0->CNTRL = SPI_CNTRL_MASTER_MODE | SPI_CNTRL_CLK_IDLE_HIGH | SPI_CNTRL_TX_RISING |
                                  SPI_CNTRL_RX_RISING   | SPI_CNTRL_LSB_FIRST     | SPI_CNTRL_TX_BIT_LEN(8);
                                         
        /* SPI_SSR setting to force SPI master SS signal to high by software */
        SPI0->SSR = SPI_SSR_SW_SS_PIN_HIGH;
        
        /* Disable the automatic slave select function of the user-specified SPI port */
        _SPI_DISABLE_HW_AUTO_SLAVE_SELECT(SPI0);

    /* Set IP clock divider. SPI clock rate = HCLK / ((1+1)*2) = 12MHz */
    SPI0->DIVIDER = (SPI0->DIVIDER & (~SPI_DIVIDER_DIVIDER_Msk)) | SPI_DIVIDER_DIV(1);
        
        /* Clear Tx register of SPI1 to avoid send non-zero data to Master. Just for safe. */
    _SPI_WRITE_TX_BUFFER0(SPI1, 0);

        /* Lock protected registers */
    SYS_LockReg();
}
void SPI0_Write_Byte(uint8_t data)
{
        //片选脚设为低电平状态
        SPI0->SSR = SPI_SSR_SW_SS_PIN_LOW;
        //发送数据
        _SPI_WRITE_TX_BUFFER0(SPI0, data);_SPI_SET_GO(SPI0);
        //等待发送数据完毕
        while(_SPI_GET_BUSY_STATUS(SPI0)){;}
        //片选脚设为高电平状态
        SPI0->SSR = SPI_SSR_SW_SS_PIN_HIGH;
}
void TM1668_Read_Key(uint8_t *key)
{
        //片选脚设为低电平状态
        SPI0->SSR = SPI_SSR_SW_SS_PIN_LOW;
        //Command1: 数据读写设置命令
        //发送数据
        _SPI_WRITE_TX_BUFFER0(SPI0, 0x42);_SPI_SET_GO(SPI0); //读键扫数据
        //等待发送数据完毕
        while(_SPI_GET_BUSY_STATUS(SPI0)){;}
        //配置MOSI为高阻输入的AIN口
        SYS->P1_MFP = SYS_MFP_P15_AIN5;
    for(uint8_t i=0;i<5;i++)
    {
                SYS->P1_MFP = SYS_MFP_P15_MOSI_0;
                //发送数据
                _SPI_WRITE_TX_BUFFER0(SPI0, 0xff);_SPI_SET_GO(SPI0);
                //等待发送数据完毕
                while(_SPI_GET_BUSY_STATUS(SPI0)){;}
                //读取数据
                 key=_SPI_GET_RX0_DATA(SPI0);
    }
        //配置P15为MOSI口
        SYS->P1_MFP = SYS_MFP_P15_MOSI_0;
        //片选脚设为高电平状态
        SPI0->SSR = SPI_SSR_SW_SS_PIN_HIGH;
}
void TM1668_Write_ADDR_INC(uint8_t *data)
{
        //Command1: 显示模式设置命令
        SPI0_Write_Byte(0x03);//显示模式:7位10段
        //Command2: 数据读写设置命令
        SPI0_Write_Byte(0x40);//写数据到显示寄存器
    //片选脚设为低电平状态
        SPI0->SSR = SPI_SSR_SW_SS_PIN_LOW;
        //Command3: 显示地址设置命令
        _SPI_WRITE_TX_BUFFER0(SPI0, 0xC0);_SPI_SET_GO(SPI0);//显示地址=0X00
    //等待传送退出
    while(_SPI_GET_BUSY_STATUS(SPI0)){;}
        for(uint32_t i=0;i<14;i++)//Data1~n: 显示数据,以Command3指定的地址为起始地址(最多14 bytes)
        {
                //发送数据
                _SPI_WRITE_TX_BUFFER0(SPI0, data);_SPI_SET_GO(SPI0);
                //等待发送数据完毕
                while(_SPI_GET_BUSY_STATUS(SPI0)){;}
        }
        //片选脚设为高电平状态
        SPI0->SSR = SPI_SSR_SW_SS_PIN_HIGH;
        //Command4: 显示控制命令
        SPI0_Write_Byte(0x88);//显示开,亮度脉冲宽度为1/16:0x88,设置脉冲宽度为14/16:0x8F
}
void TM1668_DISPLAY(uint8_t *led)
{
        uint16_t TM1668[7],*code=(uint16_t*)TM1668_10X7_CODE;
        memset(TM1668,0,sizeof(TM1668));
//        for(uint8_t i=0;i<10;i++){DBG_PRINTF("led[%d]=%d\n\r",i,led);}
        for(uint8_t i=0;i<10;i++){for(uint8_t j=0;j<7;j++){TM1668[j]|=((led>0xf)?0:(code[j]>>led)&1)<<i;}}
        TM1668_Write_ADDR_INC((uint8_t *)(&TM1668[0]));
}
void TM1668_Number(uint32_t data1,uint32_t data2)
{
        uint8_t led[10],*p=&led[3],*q=&led[9];
        if((data1>9999)||(data2>999999)) return;
        memset(led,' ',sizeof(led));led[3]=led[9]=0;
        for(uint32_t i=data1;i!=0;i/=10){*p--=i%10;}
        for(uint32_t i=data2;i!=0;i/=10){*q--=i%10;}
//        for(uint8_t i=0;i<10;i++){DBG_PRINTF("led[%d]=%d\n\r",i,led);}
        TM1668_DISPLAY(led);
}
void TM1668_Test(void)
{
        uint8_t i=0;
        TM1668_Init();
/*    while(1)
    {
                //SPI0_Write_Byte(0x55);
                if(++i>9)i=0;
                uint32_t data0=i*10+i,data1=data0*100+data0,data2=data1*100+data0;
                DBG_PRINTF("*** 9G-M0517LBN V1.00 %04d %06d...\n\r",data1,data2);
                TM1668_Number(data1,data2);
                for(uint16_t i=0;i<500;i++){SYS_SysTickDelay(1000);}
    }
*/
        i=i;
        uint32_t j=0,k=0;
    while(1)
    {
                //SPI0_Write_Byte(0x55);
                if(j++>9999){j=0;} if(k++>999999)k=0;
                DBG_PRINTF("*** 9G-M0517LBN V1.00 %04d %06d...\n\r",j,k);
                TM1668_Number(j,k);
//                for(uint16_t i=0;i<100;i++){SYS_SysTickDelay(1000);}
    }
}//缥缈九哥测试通过
沙发
niuyaliang| | 2013-12-13 22:16 | 只看该作者
虽然没用过,还是给九哥顶起

使用特权

评论回复
板凳
ZG11211| | 2013-12-14 13:39 | 只看该作者
顶九哥,前阵子无聊我也仿制了一个电子看板,用了4片TM1638,是8X8的驱动

电子看板.jpg (46.36 KB )

阅读权限: 1

电子看板.jpg

使用特权

评论回复
地板
zxf0168| | 2013-12-15 16:56 | 只看该作者
ZG11211 发表于 2013-12-14 13:39
顶九哥,前阵子无聊我也仿制了一个电子看板,用了4片TM1638,是8X8的驱动

你的电子看板很给力啊:lol

使用特权

评论回复
5
ZG11211| | 2013-12-15 22:11 | 只看该作者
:lol                    ..             :lol

使用特权

评论回复
6
缥缈九哥|  楼主 | 2013-12-16 15:39 | 只看该作者
顶起

使用特权

评论回复
7
zxf0168| | 2013-12-16 23:21 | 只看该作者
九哥,你的表情是故意插入的么

使用特权

评论回复
8
缥缈九哥|  楼主 | 2013-12-20 02:46 | 只看该作者
不是故意的。发代码不会发,得请教一下如何禁止表情了。

使用特权

评论回复
9
niuyaliang| | 2014-4-14 14:49 | 只看该作者
给九哥顶起

使用特权

评论回复
10
szjosun| | 2014-4-28 08:28 | 只看该作者
顶起!

使用特权

评论回复
11
lzyyoumuren| | 2014-12-27 16:55 | 只看该作者

使用特权

评论回复
12
缥缈九哥|  楼主 | 2016-4-19 22:01 | 只看该作者
顶起

使用特权

评论回复
13
734774645| | 2016-4-20 23:10 | 只看该作者
工作不养闲人,团队不养懒人。赚不到钱赚知识,赚不到知识赚经历,赚不到经历赚阅历,让人迷茫的原因只有一个,那就是本该拼搏的年纪,却想得太多,做的太少

使用特权

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

本版积分规则

个人签名:童时不懂世事艰,笑谈学成锦衣还。岁月无声已先过,男儿有泪空自弹。    莫待沾霜愁上发,须嬴吐气喜开颜。拼搏半年誓如愿,不到长城心不甘。

67

主题

1868

帖子

271

粉丝