本帖最后由 缥缈九哥 于 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);}
}
}//缥缈九哥测试通过 |
|