- int8_t const table[11] = { 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//共阴
- int8_t const dig[8] ={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
- uint8_t blink; //闪烁标志位
- void hc595enb(void) //数据选通
- {
- hc595_cs_clr;
- hc595_cs_set;
- hc595_cs_clr;
- }
- void hc595rst(void) //595复位
- {
- hc595_rst_set;
- hc595_clk_clr;
- hc595_rst_clr;
- hc595_rst_set;
- hc595enb();
- }
- void hc595outbyte(int8_t disdata) //595输出数据 单字节
- {
- int8_t dl; //显示数据移位
- for(dl=0;dl<=7;dl++)
- {
- if(disdata&0x80) hc595_data_set;
- else
- hc595_data_clr;
- disdata<<=1;
- hc595_clk_set;
- hc595_clk_clr;
- }
- }
- void hc595out(int8_t data_h,int8_t data_l) //数据输出 高位在前,低位在后。低位为第一通道输出
- {
- hc595outbyte(data_h);
- hc595outbyte(data_l);
- hc595enb();
- }
- void display(int8_t buffer[8])
- {
-
- static unsigned char scan;
- switch(scan)
- {
- case 0x00:
- hc595out(dig[scan],table[buffer[scan]]);
- scan++;
- break;
- case 0x01:
- hc595out(dig[scan],table[buffer[scan]]);
- scan++;
- break;
- case 0x02:
- if(blink)
- {
- hc595out(dig[scan],table[10]);
- }
- else
- {
- hc595out(dig[scan],table[buffer[scan]]);
- }
- scan++;
- break;
- case 0x03:
- hc595out(dig[scan],table[buffer[scan]]);
- scan++;
- break;
- case 0x04:
- hc595out(dig[scan],table[buffer[scan]]);
- scan++;
- break;
- case 0x05:
- if(blink)
- {
- hc595out(dig[scan],table[10]);
- }
- else
- {
- hc595out(dig[scan],table[buffer[scan]]);
- }
- scan++;
- break;
- case 0x06:
- hc595out(dig[scan],table[buffer[scan]]);
- scan++;
- break;
- case 0x07:
- hc595out(dig[scan],table[buffer[scan]]);
- scan=0;
- break;
- default:
- break;
- }
- }
595头文件- #ifndef __HC595_H__
- #define __HC595_H__
- #define hc595_data_set DrvGPIO_SetBit(E_GPA,9)
- #define hc595_data_clr DrvGPIO_ClrBit(E_GPA,9)
- #define hc595_clk_set DrvGPIO_SetBit(E_GPA,8)
- #define hc595_clk_clr DrvGPIO_ClrBit(E_GPA,8)
- #define hc595_cs_set DrvGPIO_SetBit(E_GPA,7)
- #define hc595_cs_clr DrvGPIO_ClrBit(E_GPA,7)
- #define hc595_rst_set DrvGPIO_SetBit(E_GPA,9)
- #define hc595_rst_clr DrvGPIO_ClrBit(E_GPA,9)
- void hc595enb(void);
- void hc595rst(void);
- void hc595outbyte(int8_t disdata);
- void hc595out(int8_t data_h,int8_t data_l);
- void display(int8_t buffer[8] );
- #endif
主程序调用:- TimeEnable();
- if(SYSTime)
- {
- display(disp_buffer); //显示
- if(++SYSms==500)
- {
- SYSms=0;
- DrvRTC_Read(DRVRTC_CURRENT_TIME, &sCurTime); // (读取当前时间,存放指针)
- disp_buffer[6]= sCurTime.u32cHour/10;
- disp_buffer[7]= sCurTime.u32cHour%10;
- disp_buffer[4]= sCurTime.u32cMinute/10 ;
- disp_buffer[3]= sCurTime.u32cMinute%10 ;
- disp_buffer[1]= sCurTime.u32cSecond/10;
- disp_buffer[0]= sCurTime.u32cSecond%10;
- if (DrvGPIO_GetBit(E_GPA,5))
- DrvGPIO_ClrBit(E_GPA,5);
- else
- DrvGPIO_SetBit(E_GPA,5);
- }
- }
-
- }
- }
全部程序:
代码简要分析
int8_t SYS1ms,SYSTime; //
int16_t SYSms;
#define TimeEnable() SYSTime=0; if(SYS1ms){ SYSTime=1; SYS1ms=0; }
TimeEnable()在死循环程序中使用
每一次执行的时候SYSTime都清零,但是如果SYS1ms置位的时候SYSTime也就置位了
if(SYSTime)
{
display(disp_buffer); //显示
}
这个时候就调用数码管显示函数了。
SYS1ms什么时候置位呢?
是在定时器中断里:
void Timer0_Callback (void)
{
SYS1ms=1;
}
如果我们定时器设置10毫秒中断一次,那么数码管显示函数就是10毫秒调用一次
数码管扫描的频率就是100HZ,超过人眼的视觉暂留的了,数码管显示的就很稳定,没有闪烁感了!
有的朋友可能会说为什么不在定时器中断直接调用显示函数呢?
这样做的好处在那里呢?
大家可以搜索一下以前牛人农民讲习所所长的大作。
我们后来加按键检测程序也要用到它的!