⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ht7289b-c.c

📁 ht7289b文档
💻 C
字号:
// ht7289b-c.c
// pic16f84a, 4.0MHz XTAL
// hi-tech picc compiler v9.50
#include <pic.h>

__CONFIG(XT & WDTEN & PWRTEN);

// spi interface define
#define CS    RA2          // I/O数据
#define SDA   RA1
#define SCK   RA0
#define CS_C  TRISA2       // I/O方向
#define SDA_C TRISA1
#define SCK_C TRISA0 

// global variables
unsigned char timeCount;
unsigned char byteCount;
unsigned char spiBuffer[16];

struct 
{
    unsigned b0 : 1;
    unsigned b1 : 1;
} flag;

#define KEY_ARQ flag.b0                // 重发标志
#define DAT_ARQ flag.b1

/*******************************************************/
/*****************SPI 收发程序**************************/
/*******************************************************/
// delay 500us
void Delay500us(void)
{
    unsigned char i;
    
    for (i = 165; i != 0; i--)
    {
    }
    
    NOP();	       // 该语句不能省,否则for{}语句会被编译器优化掉
}

// delay 50us
void Delay50us(void)
{
    unsigned char i;
    
    for (i = 15; i != 0; i--)
    {
    }
    
    NOP();	       // 该语句不能省
}

// delay 20us
void Delay20us(void)
{
    unsigned char i;
    
    for (i = 5; i != 0; i--)
    {
    }
    
    NOP();	       // 该语句不能省
}

// Get Data from SPI
unsigned char GetSPIByte(void)
{
    unsigned char i, temp;
    
    SDA_C = 1;                         // SDA as input
    
    i = 8;                             // 8 bits
    do 
    {
        SCK = 0;
        NOP();                         // SCK拉低至少4us
        NOP();
        NOP();
        NOP();
        
        SCK = 1;
        temp <<= 1;
        if (SDA == 1)
        {
            temp |= 0x01;
        }
        
        NOP();                         // SCK为高至少4us
    } while (--i != 0);
    
    return temp;
}

// Put Data to SPI   
void PutSPI(unsigned char len)
{
    unsigned char i, j, temp;
    
    SCK   = 1;                         // SCK输出高
    SCK_C = 0;   
    CS    = 0;                         // CS拉低
    CS_C  = 0;  
    SDA_C = 0;                         // SDA作为输出
    
    Delay50us();                       // 从CS拉低到SCK下降沿延时50us
    
    i = 0;
    do 
    {
        temp = spiBuffer[i];
        
        j = 8;                         // 8 bits
        do 
        {
            SCK = 0;                   // SCK拉低至少4us
            SDA = 0;
            if ((temp & 0x80) != 0)
            {
                SDA = 1;
            }
            temp <<= 1;
            NOP();
            
            SCK = 1;                   // SCK为高至少4us    
            NOP();
        } while (--j != 0);
        
        i++;                           // 下一字节
        NOP();                         // 字节之间时间间隔至少8us
    } while (--len != 0);     
    
    SDA_C = 1;                         // 发送完毕SDA作为输入
}	

// stop SPI
void StopSPI(void)
{
    CS = 1;
}

// 主程序
void main(void)
{
    // init I/O
    CLRWDT();
    INTCON = 0;	
    TMR0   = 6;
    OPTION = 0x01;                 // TMR0 prescaler 1:4
    PORTA  = 0x05;                 // CS & SCK output high, SDA as input
    TRISA  = 0x0a;
    
    timeCount = 206;
    while (1)
    {
        while (!T0IF) ;           // 等待1ms定时到 
        
        INTCON = 0;
        TMR0   = 6;
        OPTION = 0x01;            // TMR0 prescaler 1:4
        CLRWDT();                 // 清WDT
        
        if (++timeCount == 0)     // 50ms
        {
            timeCount = 206;
            
            KEY_ARQ   = 0;
            /***********************************************************/
            /*******************50ms读取一次按键***********************/
            /***********************************************************/ 
        ReadKey:
            spiBuffer[0] = 0xc0;        // 0xc0--命令
            spiBuffer[1] = 0x03;        // 0x03--按键滤波参数,表示15ms按键有效
            spiBuffer[2] = 0x0a;        // 0x0a--命令字尾
            PutSPI(3);                  // 3个字节
            
            Delay20us();
            spiBuffer[0] = GetSPIByte();     // 按键返回
            spiBuffer[1] = GetSPIByte();
            spiBuffer[2] = GetSPIByte();
            
            StopSPI();                  // 结束SPI通讯
            
            if (spiBuffer[0] != 0xac)        // 返回命令字错误
            {
                goto KeyError;
            }
            
            if (spiBuffer[2] != 0x0a)        // 返回命令字尾错误
            {
                goto KeyError;
            }    
            
            if ((spiBuffer[1] & 0x7f) >= 0x38)   // 无按键
            {
                goto KeyEnd;
            }
            
            if (spiBuffer[1] >= 0x80)       // 本演示程序不处理连击键
            {
                goto KeyEnd;
            }
            
            byteCount = 0;    
            switch (spiBuffer[1])
            {
            case 0x0:
                // 显示复位
                spiBuffer[0] = 0xd0;       
                spiBuffer[1] = 0xaa;
                spiBuffer[2] = 0x55;
                spiBuffer[3] = 0x0a;
                byteCount    = 4;
                break;
                
            case 0x01:
                // 直接显示: DIG0-DIG7对应显示A-DP段
                spiBuffer[0]  = 0xd6;      
                spiBuffer[1]  = 0x80;
                spiBuffer[2]  = 0x80;
                spiBuffer[3]  = 0x40;
                spiBuffer[4]  = 0x20;
                spiBuffer[5]  = 0x10;
                spiBuffer[6]  = 0x08;
                spiBuffer[7]  = 0x04;
                spiBuffer[8]  = 0x02;
                spiBuffer[9]  = 0x01;
                spiBuffer[10] = 0x0a;
                byteCount     = 11;
                break;
                
            case 0x02:
                // 译码显示: DIG0-DIG7对应显示数字1-5,6(带小数点),7-8
                spiBuffer[0]  = 0xdc;   
                spiBuffer[1]  = 0x80;
                spiBuffer[2]  = 0x01;
                spiBuffer[3]  = 0x02;
                spiBuffer[4]  = 0x03;
                spiBuffer[5]  = 0x04;
                spiBuffer[6]  = 0x05;
                spiBuffer[7]  = 0x86; 
                spiBuffer[8]  = 0x07;
                spiBuffer[9]  = 0x08;
                spiBuffer[10] = 0x0a;
                byteCount     = 11;
                break;
                
            case 0x03:
                // 译码显示: DIG0-DIG7对应显示数字A-F, [blank], -
                spiBuffer[0]  = 0xdc;
                spiBuffer[1]  = 0x80;
                spiBuffer[2]  = 0x0a;
                spiBuffer[3]  = 0x0b;
                spiBuffer[4]  = 0x0c;
                spiBuffer[5]  = 0x0d;
                spiBuffer[6]  = 0x0e;
                spiBuffer[7]  = 0x0f;
                spiBuffer[8]  = 0x10;
                spiBuffer[9]  = 0x1e;
                spiBuffer[10] = 0x0a;
                byteCount     = 11;
                break;
                
            case 0x08:
                // 位闪烁: DIG5闪烁
                spiBuffer[0] = 0xd0;
                spiBuffer[1] = 0x10;
                spiBuffer[2] = 0x04;
                spiBuffer[3] = 0x0a;
                byteCount    = 4;
                break;
                
            case 0x09:
                // 段闪烁: DIG5的DP段闪烁
                spiBuffer[0] = 0xd0;
                spiBuffer[1] = 0x1d;
                spiBuffer[2] = 0x01;
                spiBuffer[3] = 0x0a;
                byteCount    = 4;
                break;
                
            case 0x0a:
                // 闪烁频率: 1Hz
                spiBuffer[0] = 0xd0;
                spiBuffer[1] = 0x20;
                spiBuffer[2] = 0x01;
                spiBuffer[3] = 0x0a;
                byteCount    = 4;
                break;
                
            case 0x0b:
                // 闪烁频率: 5Hz
                spiBuffer[0] = 0xd0;
                spiBuffer[1] = 0x20;
                spiBuffer[2] = 0x03;
                spiBuffer[3] = 0x0a;
                byteCount    = 4;
                break;
                
            case 0x10:
                // 亮度调节: 1/16(最暗)
                spiBuffer[0] = 0xd0;
                spiBuffer[1] = 0x30;
                spiBuffer[2] = 0x01;
                spiBuffer[3] = 0x0a;
                byteCount    = 4;
                break;
                
            case 0x11:
                // 亮度调节: 1/4
                spiBuffer[0] = 0xd0;
                spiBuffer[1] = 0x30;
                spiBuffer[2] = 0x04;
                spiBuffer[3] = 0x0a;
                byteCount    = 4;
                break;
                
            case 0x12:
                // 亮度调节: 1/2
                spiBuffer[0] = 0xd0;
                spiBuffer[1] = 0x30;
                spiBuffer[2] = 0x08;
                spiBuffer[3] = 0x0a;
                byteCount    = 4;
                break;
                
            case 0x13:
                // 亮度调节: 全亮
                spiBuffer[0] = 0xd0;
                spiBuffer[1] = 0x30;
                spiBuffer[2] = 0x00;
                spiBuffer[3] = 0x0a;
                byteCount    = 4;
                break;
                
            case 0x18:
                // 位隐显: DIG0隐显
                spiBuffer[0] = 0xd0;
                spiBuffer[1] = 0x00;
                spiBuffer[2] = 0x80;
                spiBuffer[3] = 0x0a;
                byteCount    = 4;
                break;
                
            case 0x19:
                // 位显示: DIG0显示
                spiBuffer[0] = 0xd0;
                spiBuffer[1] = 0x70;
                spiBuffer[2] = 0x80;
                spiBuffer[3] = 0x0a;
                byteCount    = 4;
                break;
                
            case 0x1a:
                // 段关闭: DIG1的G段关闭
                spiBuffer[0] = 0xd0;
                spiBuffer[1] = 0x09;
                spiBuffer[2] = 0x02;
                spiBuffer[3] = 0x0a;
                byteCount    = 4;
                break;
                
            case 0x1b:
                // 段点亮: DIG1的G段电亮
                spiBuffer[0] = 0xd0;
                spiBuffer[1] = 0x79;
                spiBuffer[2] = 0x02;
                spiBuffer[3] = 0x0a;
                byteCount    = 4;
                break;
                
            default:
                break;
            }
            
            if (byteCount == 0)         // 未知按键,不处理
            {
                goto KeyEnd;
            }
            
            Delay50us();                // 连续两次数据收发至少延时50us
            DAT_ARQ   = 0;
            
            for (; ;)
            {
                PutSPI(byteCount);

                Delay20us();
                if (GetSPIByte() == 0xaa)   // 数据发送成功
                {
                    StopSPI();
                    goto KeyEnd;
                }
                
                StopSPI();
                if (DAT_ARQ == 1)           // 只重发一次
                {
                    goto KeyEnd;
                }
                Delay500us();
                DAT_ARQ = 1;               // 发送失败则延时500us后重发
            }
            
        KeyError:
            if (KEY_ARQ != 1)              // 之前未重发
            {
                Delay500us();
                KEY_ARQ = 1;
                
                goto ReadKey;
            }

        KeyEnd:;
        }       
    }    
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -