display[8] 为 LED显示缓存
//基于NUC120学习套件用HC595和LS164驱动7位数码管
//作者:hzy41y
//最后更新日期2012年06月13日11:06
#include <stdio.h>
#include <string.h>
#include "NUC1xx.h"
#include "Driver\DrvSYS.h"
#include "Driver\DrvGPIO.h"
#include "DrvTimer.h"
#include "hzy.h"
#define SCL595_set DrvGPIO_SetBit(E_GPC,14)
#define SCL164_set DrvGPIO_SetBit(E_GPC,15)
#define SDA_set DrvGPIO_SetBit(E_GPC,6)
#define SCL595_clr DrvGPIO_ClrBit(E_GPC,14)
#define SCL164_clr DrvGPIO_ClrBit(E_GPC,15)
#define SDA_clr DrvGPIO_ClrBit(E_GPC,6)
uint16_t timer; //全局时间延时变量
uint8_t tabl[] = {0xfa,0x60,0xdc,0xec,0x66,0xae,0xbe,0xe0,0xfe,0xee,0x08,0x10,0x04};
/* 0 1 2 3 4 5 6 7 8 9
display[0]对应LED左边第一位,display[6]对应LED最后第七位;
display[7]为闪烁使能,最高位对应LED左边第一位,那位为0则闪烁 */
uint8_t display[8]; //LED显示缓存
//***定时器回调函数*************//
void Timer0_Callback(void) // Timer0 interrupt subroutine
{ static uint16_t S_counter; //各位闪烁计数器
static uint8_t S_Enable; //各位闪烁使能
static uint8_t ch; //1-7显示通道变量
static hzy_b bit;
uint8_t j;
uint8_t display1;
if(bit.bg)
bit.bn=S_Enable>>7;
else bit.bn=1; //判Led相对位要闪烁
S_Enable<<=1; //判Led相对位不闪烁
display1=display[ch];
for(j=8;j>0;j--)
{ if(bit.bn)
{ if(display1>>7)SDA_set;
else SDA_clr;
display1<<=1;
}else SDA_clr; //判Led相对位要闪烁595各段输出为低电平
SCL595_set;
SCL595_clr; // 595--11pin
}
if(ch==0)SDA_clr;
else SDA_set; // 595--14pin和164--1pin/2pin
SCL164_set;
SCL164_clr; // 595--12pin/13pin 和164--8pin
ch++; //显示通道加1
if(ch==8)
{ SCL164_set;SCL164_clr;ch=0;
S_Enable=display[7];
}
S_counter++;
if(S_counter==500)
{ bit.bg=!bit.bg;
S_counter=0;
}
timer++; //全局时间延时变量
TIMER0->TISR.TIF =1;
}
//---------TIMER0初始化-----------------------------//
void InitTIMER0(void)
{
//第1步。启用和选择时钟源 /
SYSCLK->CLKSEL1.TMR0_S = 0; // Timer0的时钟源选择12MHZ
SYSCLK->APBCLK.TMR0_EN =1; //使能定时器时钟源
//第2步。选择操作模式//
TIMER0->TCSR.MODE=1; //选择定期模式,运作模
/*第3步。选择了时间周期=(周期定时器时钟输入)*(8位预分频+1)*(24位TCMP)
Step 3. Select Time out period = (Period of timer clock input) * (8-bit Prescale + 1) * (24-bit TCMP)*/
TIMER0->TCSR.PRESCALE=255; // Set Prescale [0~255]
TIMER0->TCMPR = 100; // Set TCMPR [0~16777215]
// (1/12000000)*(255+1)*(2765)=
/* Step 4. Enable interrupt */
TIMER0->TCSR.IE = 1;
TIMER0->TISR.TIF = 1; //Write 1 to clear for safty
NVIC_EnableIRQ(TMR0_IRQn); //Enable Timer0 Interrupt
/* Step 5. Enable Timer module */
DrvTIMER_SetTimerEvent(E_TMR0,1,(TIMER_CALLBACK) Timer0_Callback,0);
TIMER0->TCSR.CRST = 1; //Reset up counter
TIMER0->TCSR.CEN = 1; //Enable Timer0
// TIMER0->TCSR.TDR_EN=1; // Enable TDR function
}
//***************IO和显示初始化*****************************//
void init()
{ uint8_t i;
DrvGPIO_Open( E_GPA, 2, E_IO_OUTPUT );
DrvGPIO_Open( E_GPC, 6, E_IO_QUASI ); //标准数字双向口
DrvGPIO_Open( E_GPC, 14, E_IO_QUASI );
DrvGPIO_Open( E_GPC, 15, E_IO_QUASI );
for(i=0;i<7;i++)
{ display[i]=tabl[8];}
display[7]=0x00; //设置闪烁位
InitTIMER0();
timer=0;
while (timer<5000);
for(i=0;i<7;i++)
{ display[i]=tabl[i];}
display[7]=0xFF; //设置闪烁位
timer=0;
while (timer<5000);
}
/*----------------------------------------------------------------------------
MAIN function
----------------------------------------------------------------------------*/
int32_t main (void)
{
UNLOCKREG();
SYSCLK->PWRCON.XTL12M_EN = 1;
LOCKREG();
init();
while(1);
}
display[0]对应LED左边第一位,display[6]对应LED最后第七位;
display[7]为闪烁使能,最高位对应LED左边第一位,那位为0则闪烁 |