74HC595 是一个 8位 串行输入、并行输出 的 位移缓存器:
并行输出为 三态输出。
在 SCK 的上升沿,串行数据由 SDL输入 到内部的 8位位移缓存器,并由 Q7'输出,
而 并行输出 则是在 LCK的上升沿 将在 8位 位移缓存器 的数据存入到 8位 并行输出缓存器。
当 串行数据输入端 OE的控制信号为低使能时,并行输出端的输出值等于并行输出缓存器所存储的值。
#include<iostm8s105c6.h>
unsigned char number[8] , SMGtimes , SMGBit;
unsigned int ms_count;
unsigned int count_ms;
unsigned char count_time;
//数码管0 ~ F的代码数组
unsigned char const Data[16] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
unsigned char const Wu[8] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
//HC595 时钟端口控制
#define CLK_1 PA_ODR_ODR3 = 1
#define CLK_0 PA_ODR_ODR3 = 0
//HC595 数据端口控制
#define DAT_1 PA_ODR_ODR5 = 1
#define DAT_0 PA_ODR_ODR5 = 0
//HC595 各移位数据输出并口控制
#define RCLK_1 PA_ODR_ODR4 = 1
#define RCLK_0 PA_ODR_ODR4 = 0
/*******************************************************************************
**函数名称:void NumericDisplay_Init()
**功能描述:初始化位码控制芯片和段码控制芯片74HC164D的时钟和数据 相应的IO控制参数初始化
**入口参数:无
**输出:无
*******************************************************************************/
void NumericDisplay_Init()
{
//2片HC595芯片 CLK时钟引脚初始化
PA_DDR_DDR3 = 1; //设置端口PA->3的输入输出方向寄存器为输出方向
PA_CR1_C13 = 1; //设置为推挽输出
PA_CR2_C23 = 1; //设置输出速率为10MHZ
//2片HC595芯片 RCLK引脚初始化
PA_DDR_DDR4 = 1; //设置端口PA->4的输入输出方向寄存器为输出方向
PA_CR1_C14 = 1; //设置为推挽输出
PA_CR2_C24 = 1; //设置输出速率为10MHZ
//HC595芯片 DAT数据引脚初始化
PA_DDR_DDR5 = 1; //设置端口PA->5的输入输出方向寄存器为输出方向
PA_CR1_C15 = 1; //设置为推挽输出
PA_CR2_C25 = 1; //设置输出速率为10MHZ
}
/*******************************************************************************
**函数名称:void HC595_WriteData(unsigned char data , unsigned char wu)
**功能描述:数码管显示
**入口参数:data->要显示的数据 , wu->设置要第几位数码管显示
**输出:无
*******************************************************************************/
void HC595_WriteData(unsigned char data , unsigned char wu)
{
unsigned char i;
unsigned int tempdata;
tempdata = (unsigned int)(wu); //先把8位码放入16位里
tempdata <<= 8; //把8位位码移到高8位先发送
tempdata |= data; //再把段码8位放在低8位发送
RCLK_0; //先把输出存储锁存时钟线拉低
for(i = 0 ; i < 16 ; i++)
{
CLK_0; //数据输入时钟线拉低
if(tempdata & 0x8000) //判断数据,把数据架在输出数据位上
{
DAT_1;
}
else
{
DAT_0;
}
CLK_1; //把时钟线拉高,把移位数据输入并移位
tempdata <<= 1; //把新数据架在输出数据线上
}
CLK_0;
RCLK_1; //把输出存储锁存时钟线拉高,把595的移位数据输出到并口
}
/*******************************************************************************
**函数名称:void delay(unsigned int ms) Name: void delay(unsigned int ms)
**功能描述:大概延时
**入口参数:unsigned int ms 输入大概延时数值
**输出:无
*******************************************************************************/
void delay(unsigned int ms)
{
unsigned int x , y;
for(x = ms; x > 0; x--) /* 通过一定周期循环进行延时*/
for(y = 100 ; y > 0 ; y--);
}
/*******************************************************************************
**函数名称:void Timer4Init()
**功能描述:定时器2参数初始化
**入口参数:无
**输出:无
*******************************************************************************/
void Timer4Init()
{
TIM4_IER_UIE = 0; //先禁止定时器4更新中断
TIM4_EGR_UG = 0; //
TIM4_PSCR_PSC = 7; //定时器4时钟 = 16MHz / 128 = 125KHZ
TIM4_ARR = 125; //设定1定时器产生1毫秒重装载时的计数值,255是最大值
TIM4_CNTR = 0x00; //设定计数器的初值
TIM4_SR_UIF = 0; //清除更新中断标志
TIM4_SR_TIF = 0; //清除触发中断标志
TIM4_CR1_CEN = 1; //使能定时器4
TIM4_CR1_ARPE = 1; //使能预装载寄存器缓冲
TIM4_IER_UIE = 1; //使能更新中断
}
int main(void)
{
asm("sim"); //关闭系统总中断
CLK_CKDIVR = 0x00; //配套系统时钟为内部时钟16MHZ
NumericDisplay_Init(); //调用数码管驱动初始化函数,配置驱动芯片HC595对应IO口
// 对数据空间 赋值;
// number[0] = 1; //在第一数码管显示 1
// number[1] = 2; //在第二数码管显示 2
// number[2] = 3; //在第三数码管显示 3
// number[3] = 4; //在第四数码管显示 4
// number[4] = 5; //在第五数码管显示 5
// number[5] = 6; //在第六数码管显示 6
// number[6] = 7; //在第七数码管显示 7
// number[7] = 8; //在第八数码管显示 8
number[0] = 5; //在第一数码管显示 1
number[1] = 8; //在第二数码管显示 2
number[2] = 3; //在第三数码管显示 3
number[3] = 1; //在第四数码管显示 4
number[4] = 0; //在第五数码管显示 5
number[5] = 7; //在第六数码管显示 6
number[6] = 7; //在第七数码管显示 7
number[7] = 3; //在第八数码管显示 8
Timer4Init(); //调用定时器4初始化函数,通过定时器的中断控制来显示数码管
asm("rim"); //打开系统总中断
while(1)
{
number[0] = count_time / 100;
number[1] = count_time / 10 % 10;
number[2] = count_time % 10;
}
}
#pragma vector = 25 //设置定时器4重载的中断向量号 = 25
__interrupt void TIM4_UPDATE_IRQHandler(void)
{
TIM4_SR_UIF = 0; //清除中断标志
ms_count ++; //中断使 ms_count++ 做加法,记录1毫秒产生的中断次数
count_ms ++;
if(count_ms >= 100)
{
count_ms = 0; // 计时;
count_time ++; // 计数;
if(count_time >= 120 )
{
count_time = 120;
// TIM4_CR1_CEN = 0; //使能定时器4
}
}
if(ms_count >= 2) //2毫秒点亮一位数码管 , 就是快速显示,等于16毫秒显示完8个数码管,我们人眼根本反应不过来,感觉是8位数码管同时显示
{
ms_count = 0;
HC595_WriteData(Data[number[SMGtimes]] , Wu[SMGtimes]); //往数码管发送显示一个数码显示数据
SMGtimes++;
if(SMGtimes >= 3) //8位数据管循环显示
{
SMGtimes = 0 ;
}
}
}
联系人:客服在线
手机:全工:13903011251
电话:李R:13530006400
邮箱:729986191@qq.com
地址: GUANGDONG PROVINCE