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