CH579M驱动74HC595数码管屏实战

CH579M驱动74HC595数码管屏移植实战
CH579M板子到手已有几个月,之前都是官网实例在修改下载-连接测试,GPIO,UART,网口各种通信虽说好调但毕间竟自己写得少没有大改动困难容易解决。现将用该板外扩的IO接口驱动由两片74HC595控制的6位数码管。
简单介绍 一下数码显示板,74HC595其中一片控制6位数码管的位码段,另一片负责显示数据段。整块数显板接口VCC GND ST DAT CLK.
整个项目移植在网络例程中添加文件
在这里插入图片描述
根据官网的习惯,我们来新建两文件,.h文件

#ifndef CH57x_HC595_H
#define CH57x_HC595_H

#ifdef __cplusplus
extern “C” {
#endif

#include “CH579SFR.h”
#include “core_cm0.h”
#define ST_H GPIOA_SetBits(GPIO_Pin_0) //74HC595锁存
#define ST_L GPIOA_ResetBits(GPIO_Pin_0)
#define DATOUT_H GPIOA_SetBits(GPIO_Pin_3) //74HC595串行
#define DATOUT_L GPIOA_ResetBits(GPIO_Pin_3) //74HC595串行
#define CLK_H GPIOA_SetBits(GPIO_Pin_7) //74HC595时钟信号
#define CLK_L GPIOA_ResetBits(GPIO_Pin_7) //74HC595时钟信号
#define KEYIN_H GPIOB_SetBits(GPIO_Pin_22) //74HC595时钟信号
#define KEYIN_L GPIOB_ResetBits(GPIO_Pin_22) //74HC595时钟信号

void Led_Lock(void);
void delay(unsigned int x);
void Led_Send_Byte(unsigned char data);
void diplay_6led(unsigned char wd,unsigned char sd,unsigned char led_dat);
void Menusetup(void);

#endif // CH57x_HC595_H
该文件定义了对应3个信号线的置1、置0宏,定义.C文件所定义的驱动函数。主要显示函数diplay_6led(unsigned char wd,unsigned char sd,unsigned char led_dat);主程序也只运行此函数。接下来编定.c文件
/********************************** © COPYRIGHT *******************************

  • File Name : CH57x_HC595.c
  • Author : ZXH(江山江汇)
  • Version : V1.1
  • Date : 2020/10/01
  • Description
    *******************************************************************************/

#include “CH57x_common.h”
#include “CH57x_HC595.h”
#define counter 500 //数码管延时长宏
void Menusetup(void);
unsigned char m,k,dis_wd,dis_sd;
unsigned char tempwd,tempsd,savewd,savesd,page,pwd;

unsigned char Dm_tab[]=
{
//0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90 //0-9共阳极代码
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f //0-9共阴极代码

};
unsigned char led_tab[]=
{
0x08,//电源灯亮
0x09,//电源温度控制亮
0x0a,//电源湿度控制亮
0x0b,//电源温湿都亮
0x0c//报警+电源

};
unsigned char Wm_tab[]=
{
0xfe, //上12十位11111110
0xfd, //上9个位带小数位11111101
0xfb, //上8小数为11111011
0xf7, //下12十位11110111
0xef, //下9-个位带小数点11101111
0xdf, //下8-小数位11011111
0xbf,//控四LED灯的位
0x7f,//送监别码时段用于判断按建位置及建值。
0xff

};

/*******************************************************************************

  • Function Name :HC595C驱动
  • Description : 采样数据粗调,获取偏差值
  •              注意,使用粗调校准,必须保证 PA5(AIN1)设置为浮空输入模式,管脚外部不要有电压
    
  • Input : None
  • Return : 偏差值
    *******************************************************************************/

/********************************************************************/
void delay(unsigned int x)//延时函数
{
unsigned int i,j;
for(i=0;i<x;i++)
for(j=0;j<2;j++);
}

//*****************************************
void Led_Send_Byte(unsigned char data) //字节传送
{
unsigned char i,temp;
temp=data;
for(i=0;i<8;i++)
{
if((temp & 0x80)==0)
{DATOUT_L;}
else
{DATOUT_H;}
CLK_L;
// delay(20);
CLK_H;
// delay(20);
CLK_L;
temp=temp<<1;
}
}
void Led_Lock(void) //锁存信号发生
{
ST_L;
//delay(20);
ST_H;
//delay(20);
ST_L;
}
void diplay_6led(unsigned char wd,unsigned char sd,unsigned char led_dat)

{
Led_Send_Byte(Wm_tab[0]);
Led_Send_Byte(Dm_tab[wd/10]);//Dm_tab[wd/100]

		Led_Lock();//送2位锁存

		delay(counter);//延时可调频率
		
		Led_Send_Byte(Wm_tab[6]);
		Led_Send_Byte(0x00);
		Led_Lock();	//消隐信号后锁

delay(5);

//后一们为小数位要用0X80点亮小数点(Dm_tab[wd%100/10])||(0x80)
Led_Send_Byte(Wm_tab[1]);
Led_Send_Byte(Dm_tab[wd%10]|0x80);
Led_Lock();//送2位锁存
delay(counter);
Led_Send_Byte(Wm_tab[6]);
Led_Send_Byte(0x00);
Led_Lock();

delay(5);

		Led_Send_Byte(Wm_tab[2]);
		Led_Send_Byte(Dm_tab[0]);//小数位只显示0
		Led_Lock();
		delay(counter);
		Led_Send_Byte(Wm_tab[6]);
		Led_Send_Byte(0x00);
		Led_Lock();

delay(5);		
	
		Led_Send_Byte(Wm_tab[3]);
		Led_Send_Byte(Dm_tab[sd/10]);
		Led_Lock();
			
delay(counter);
		Led_Send_Byte(Wm_tab[6]);
		Led_Send_Byte(0x00);
		Led_Lock();

delay(5);

//后一们为小数位要用0X80点亮小数点Dm_tab[sd%100/10])||(0x80)
Led_Send_Byte(Wm_tab[4]);
Led_Send_Byte(Dm_tab[sd%10]|0x80);
Led_Lock();
delay(counter);
Led_Send_Byte(Wm_tab[6]);
Led_Send_Byte(0x00);
Led_Lock();

delay(5);

		Led_Send_Byte(Wm_tab[5]);
		Led_Send_Byte(Dm_tab[0]);//小数位只显示0
		Led_Lock();
		delay(counter);
		Led_Send_Byte(Wm_tab[6]);
		Led_Send_Byte(0x00);
		Led_Lock();
		delay(5);

//下面是控制四只LED发光管的

		Led_Send_Byte(Wm_tab[6]);
		Led_Send_Byte(led_tab[led_dat]);
		Led_Lock();
	delay(counter);	
		Led_Send_Byte(Wm_tab[6]);
		Led_Send_Byte(0x00);
		Led_Lock();
		
delay(5);
		                                  
}

void Menusetup()//设置预值并保存

{
if(page==1)//显示温度调节画面
{

		Led_Send_Byte(Wm_tab[0]);
		Led_Send_Byte(Dm_tab[0]);//上LED显示001
		Led_Lock();//送2位锁存
		
	
	mDelayuS(200);//延时可调频率
		
		Led_Send_Byte(Wm_tab[6]);
		Led_Send_Byte(0x00);
		Led_Lock();	//消隐信号后锁//上1数码管

//后一们为小数位要用0X80点亮小数点(Dm_tab[wd%100/10])||(0x80)
Led_Send_Byte(Wm_tab[1]);
Led_Send_Byte(Dm_tab[0]);
Led_Lock();//送2位锁存
if(KEYIN_L)//此时按建S1被按下了要进入设置页面
{
mDelayuS(200);//抖动消除

			if(KEYIN_L)
			{
				while(KEYIN_L);
				pwd++;
				if(pwd>=20){pwd=0;}
			}
		}
		
	mDelayuS(200);
		Led_Send_Byte(Wm_tab[6]);
		Led_Send_Byte(0x00);
		Led_Lock();/消隐信号后锁/上2数码管
		
		Led_Send_Byte(Wm_tab[2]);
		Led_Send_Byte(Dm_tab[1]);
		Led_Lock();
		if(KEYIN_L)//此时按建S1被按下了要进入设置页面
		{
		mDelayuS(200);//抖动消除
			
			if(KEYIN_L)
			{
				while(KEYIN_L);
				pwd--;
				if(pwd==0)
				{pwd=20;}
			}
		}
mDelayuS(200);
		Led_Send_Byte(Wm_tab[6]);
		Led_Send_Byte(0x00);
		Led_Lock();///消隐信号后锁///上3数码管



	
		Led_Send_Byte(Wm_tab[3]);//上LED显示savewd的值
		Led_Send_Byte(Dm_tab[pwd/10]);
		Led_Lock();
		if(KEYIN_L)//此时按建S1被按下了要进入设置页面
		{
		mDelayuS(200);//抖动消除
			
			if(KEYIN_L)
			{
				while(KEYIN_L);
				page++;
				if(page>=4){page=0;}
			}
		}
mDelayuS(200);
		Led_Send_Byte(Wm_tab[6]);
		Led_Send_Byte(0x00);
		Led_Lock();//消隐信号后锁/下1数码管

//后一们为小数位要用0X80点亮小数点Dm_tab[sd%100/10])||(0x80)
Led_Send_Byte(Wm_tab[4]);
Led_Send_Byte(Dm_tab[pwd%10]);
Led_Lock();
mDelayuS(200);
Led_Send_Byte(Wm_tab[6]);
Led_Send_Byte(0x00);
Led_Lock();//消隐信号后锁/下2数码管

		Led_Send_Byte(Wm_tab[5]);
		Led_Send_Byte(Dm_tab[1]);//要显示1(111为通过密码)
		Led_Lock();
		mDelayuS(200);
		Led_Send_Byte(Wm_tab[6]);
		Led_Send_Byte(0x00);
		Led_Lock();//消隐信号后锁/下3数码管

//下面是控制四只LED发光管的

		Led_Send_Byte(Wm_tab[6]);
		Led_Send_Byte(led_tab[0]);//设置菜单时只有电源指示灯亮
		Led_Lock();
	mDelayuS(200);	
		Led_Send_Byte(Wm_tab[6]);//消隐技术关闭所有LED灯
		Led_Send_Byte(0x00);
		Led_Lock();
}

// /***********************************
else if(page2&&pwd11)//显示湿度调节画面
{

		Led_Send_Byte(Wm_tab[0]);
		Led_Send_Byte(Dm_tab[0]);//上LED显示002 显0
		
		Led_Lock();//送2位锁存
	
	mDelayuS(200);//延时可调频率
		
		Led_Send_Byte(Wm_tab[6]);
		Led_Send_Byte(0x00);
		Led_Lock();	//消隐信号后锁//上1数码管

//后一们为小数位要用0X80点亮小数点(Dm_tab[wd%100/10])||(0x80)
Led_Send_Byte(Wm_tab[1]);
Led_Send_Byte(Dm_tab[0]);//显0
Led_Lock();//送2位锁存
if(KEYIN_L)//此时按建S1被按下了要进入设置页面
{
mDelayuS(200);//抖动消除

			if(KEYIN_L)
			{
				while(KEYIN_L);
				savewd++;
				if(savewd>=100){savewd=0;}
			}
		}
		mDelayuS(200);
		Led_Send_Byte(Wm_tab[6]);
		Led_Send_Byte(0x00);
		Led_Lock();/消隐信号后锁/上2数码管
		
		Led_Send_Byte(Wm_tab[2]);
		Led_Send_Byte(Dm_tab[2]);//显2
		Led_Lock();
			if(KEYIN_L)//此时按建S1被按下了要进入设置页面
		{
			mDelayuS(200);//抖动消除
			
			if(KEYIN_L)
			{
				while(KEYIN_L);
				savewd--;
				if(savewd<=0){savewd=99;}
			}
		}
	mDelayuS(200);
		Led_Send_Byte(Wm_tab[6]);
		Led_Send_Byte(0x00);
		Led_Lock();///消隐信号后锁///上3数码管
	
		Led_Send_Byte(Wm_tab[3]);//上LED显示savewd的值
		Led_Send_Byte(Dm_tab[savewd/10]);
		Led_Lock();
			if(KEYIN_L)//此时按建S1被按下了要进入设置页面
		{
		mDelayuS(200);//抖动消除
			
			if(KEYIN_L)
			{
				while(KEYIN_L);
				page++;
				if(page>=4){page=0;}
			}
		}
	mDelayuS(200);
		Led_Send_Byte(Wm_tab[6]);
		Led_Send_Byte(0x00);
		Led_Lock();//消隐信号后锁/下1数码管

//后一们为小数位要用0X80点亮小数点Dm_tab[sd%100/10])||(0x80)
Led_Send_Byte(Wm_tab[4]);
Led_Send_Byte(Dm_tab[savewd%10]|0x80);
Led_Lock();
mDelayuS(200);
Led_Send_Byte(Wm_tab[6]);
Led_Send_Byte(0x00);
Led_Lock();//消隐信号后锁/下2数码管

		Led_Send_Byte(Wm_tab[5]);
		Led_Send_Byte(Dm_tab[0]);
		Led_Lock();
mDelayuS(200);
		Led_Send_Byte(Wm_tab[6]);
		Led_Send_Byte(0x00);
		Led_Lock();//消隐信号后锁/下3数码管

//下面是控制四只LED发光管的

		Led_Send_Byte(Wm_tab[6]);
		Led_Send_Byte(led_tab[0]);//设置菜单时只有电源指示灯亮
		Led_Lock();
mDelayuS(200);
		Led_Send_Byte(Wm_tab[6]);//消隐技术关闭所有LED灯
		Led_Send_Byte(0x00);
		Led_Lock();
	



}
	else if(page==3&&pwd==11)//显示湿度调节画面
{

		Led_Send_Byte(Wm_tab[0]);
		Led_Send_Byte(Dm_tab[0]);//上LED显示003 显0
		
		Led_Lock();//送2位锁存
	
	mDelayuS(200);//延时可调频率
		
		Led_Send_Byte(Wm_tab[6]);
		Led_Send_Byte(0x00);
		Led_Lock();	//消隐信号后锁//上1数码管

//后一们为小数位要用0X80点亮小数点(Dm_tab[wd%100/10])||(0x80)
Led_Send_Byte(Wm_tab[1]);
Led_Send_Byte(Dm_tab[0]);//显0
Led_Lock();//送2位锁存
if(KEYIN_L)//此时按建S1被按下了要进入设置页面
{
mDelayuS(200);//抖动消除

			if(KEYIN_L)
			{
				while(KEYIN_L);
				savesd++;
				if(savesd>=100){savesd=0;}
			}
		}
	mDelayuS(200);
		Led_Send_Byte(Wm_tab[6]);
		Led_Send_Byte(0x00);
		Led_Lock();/消隐信号后锁/上2数码管
		
		Led_Send_Byte(Wm_tab[2]);
		Led_Send_Byte(Dm_tab[3]);//显3
		Led_Lock();
			if(KEYIN_L)//此时按建S1被按下了要进入设置页面
		{
		mDelayuS(200);//抖动消除
			
			if(KEYIN_L)
			{
				while(KEYIN_L);
				savesd--;
				if(savesd<=0){savesd=99;}
			}
		}
	mDelayuS(200);
		Led_Send_Byte(Wm_tab[6]);
		Led_Send_Byte(0x00);
		Led_Lock();///消隐信号后锁///上3数码管
	
		Led_Send_Byte(Wm_tab[3]);//上LED显示savewd的值
		Led_Send_Byte(Dm_tab[savesd/10]);
		Led_Lock();
			if(KEYIN_L)//此时按建S1被按下了要进入设置页面
		{
		mDelayuS(200);//抖动消除
			
			if(KEYIN_L)
			{
				while(KEYIN_L);
				page++;
				if(page>=4){page=0;}
			}
		}
		mDelayuS(200);
		Led_Send_Byte(Wm_tab[6]);
		Led_Send_Byte(0x00);
		Led_Lock();//消隐信号后锁/下1数码管

//后一们为小数位要用0X80点亮小数点Dm_tab[sd%100/10])||(0x80)
Led_Send_Byte(Wm_tab[4]);
Led_Send_Byte(Dm_tab[savesd%10]|0x80);
Led_Lock();
mDelayuS(200);
Led_Send_Byte(Wm_tab[6]);
Led_Send_Byte(0x00);
Led_Lock();//消隐信号后锁/下2数码管

		Led_Send_Byte(Wm_tab[5]);
		Led_Send_Byte(Dm_tab[0]);
		Led_Lock();
	mDelayuS(200);
		Led_Send_Byte(Wm_tab[6]);
		Led_Send_Byte(0x00);
		Led_Lock();//消隐信号后锁/下3数码管

//下面是控制四只LED发光管的

		Led_Send_Byte(Wm_tab[6]);
		Led_Send_Byte(led_tab[0]);//设置菜单时只有电源指示灯亮
		Led_Lock();
	mDelayuS(200);
		Led_Send_Byte(Wm_tab[6]);//消隐技术关闭所有LED灯
		Led_Send_Byte(0x00);
		Led_Lock();
}
else
{page=0;}

}
//************************************
本实战主要实现对74HC595的基本显示即 diplay_6led(unsigned char wd,unsigned char sd,unsigned char led_dat)
,其它功能界面按键未作编写,将上述两文件加入项目
在这里插入图片描述

在这里插入图片描述

并在这里插入图片描述
并在下面界面对头文件指定路径在这里插入图片描述
主程序文件
#include “CH57x_common.h”
#include “CH57x_HC595.h”
__align(4) UINT8 RxBuffer[ MAX_PACKET_SIZE ]; // IN, must even address
__align(4) UINT8 TxBuffer[ MAX_PACKET_SIZE ]; // OUT, must even address

char test[20]=“This is a GPIO test!”;
int main()
{
unsigned char m;
GPIOA_ModeCfg( GPIO_Pin_7, GPIO_ModeOut_PP_20mA );
GPIOA_ModeCfg( GPIO_Pin_3, GPIO_ModeOut_PP_20mA );
GPIOA_ModeCfg( GPIO_Pin_0, GPIO_ModeOut_PP_20mA );//PB0推挽输出
GPIOA_ModeCfg( GPIO_Pin_12, GPIO_ModeOut_PP_20mA );//PB0推挽输出
GPIOB_ModeCfg( GPIO_Pin_4, GPIO_ModeOut_PP_20mA );//PB0推挽输出
GPIOB_ModeCfg( GPIO_Pin_7, GPIO_ModeOut_PP_20mA );//PB0推挽输出
/配置串口1/
GPIOA_SetBits(GPIO_Pin_9);
GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU); // RXD-配置上拉输入
GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);// TXD-配置推挽输出,注意先让IO口输出高电平
UART1_DefInit();
while(1)
{ for(m=0;m<40;m++)
{
diplay_6led(78,56,0);
}
GPIOB_SetBits(GPIO_Pin_0);//GPIO0输出高电平
//GPIOA_SetBits(GPIO_Pin_12);//GPIO0输出高电平
GPIOB_SetBits(GPIO_Pin_4);//GPIO0输出高电平
GPIOB_SetBits(GPIO_Pin_7);//GPIO0输出高电平
//PRINT(“gpio_set=%d\r\n”,GPIOB_ReadPortPin(GPIO_Pin_0));//打印引脚状态
//UART1_SendString(test,20);
//mDelaymS(2000);
//GPIOB_ResetBits(GPIO_Pin_0);//GPIO0输出低电平
//GPIOA_ResetBits(GPIO_Pin_12);//GPIO0输出高电平
//GPIOB_ResetBits(GPIO_Pin_4);//GPIO0输出低电平
//GPIOB_ResetBits(GPIO_Pin_7);//GPIO0输出低电平
//PRINT(“gpio_reset=%d\r\n”,GPIOB_ReadPortPin(GPIO_Pin_0));//打印引脚状态
//PRINT(“浙江省江山江汇电气有限公司欢迎您!!!!!!!!!!!!!!!!\r”);

	//diplay_6led(0,0,3);
	//mDelaymS(1000);
}

}
主程序配置3信号引脚,啥也没做尽刷屏了!
在这里插入图片描述
来看看效果吧 (之前担心数码板5V与3.3V逻辑不同会有不同,这下看来完全可以适用3.3V电源。)
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个基于CH579M芯片和OLED幕的物联网应用程序,可以实时显示当前时间: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ch579.h> #include <ch579usb.h> #include <ch579i2c.h> #include <ch579uart.h> #include <ch579gpio.h> #include <ch579spi.h> #include <ch579adc.h> #include <ch579timer.h> #include <ch579iic.h> #include "oled.h" #define I2C_CLOCK_FREQ 400000 #define OLED_ADDR 0x78 /* OLED I2C接口初始化 */ void oled_i2c_init(void) { IICInit(I2C_CLOCK_FREQ); } /* OLED初始化 */ void oled_init(void) { oled_i2c_init(); OLED_Init(); } /* OLED幕显示时间 */ void oled_show_time(void) { /* 获取当前时间 */ RTC_TIME_Type rtcTime; RTC_GetTime(&rtcTime); /* 显示时间到OLED幕 */ OLED_ShowString(0, 0, "Time: ", 16); OLED_ShowNum(48, 0, rtcTime.hour, 2, 16); OLED_ShowChar(64, 0, ':', 16); OLED_ShowNum(80, 0, rtcTime.minute, 2, 16); OLED_ShowChar(96, 0, ':', 16); OLED_ShowNum(112, 0, rtcTime.second, 2, 16); OLED_Refresh_Gram(); } int main(void) { /* 初始化OLED幕 */ oled_init(); /* 初始化RTC时间 */ RTC_TIME_Type rtcTime; rtcTime.year = 2021; rtcTime.month = 9; rtcTime.day = 22; rtcTime.hour = 0; rtcTime.minute = 0; rtcTime.second = 0; RTC_SetTime(&rtcTime); /* 循环显示当前时间 */ while (1) { oled_show_time(); delay_ms(1000); } return 0; } ``` 上述代码中,我们使用了CH579M芯片的RTC模块来获取当前时间,并使用OLED幕显示当前时间。我们还需要引入一个OLED幕的库文件来实现OLED幕的初始化和显示功能,这里我们使用了一个名为"oled.h"的头文件,具体实现可以参考如下代码: ```c #ifndef __OLED_H__ #define __OLED_H__ #include <stdio.h> #include <string.h> #include <ch579i2c.h> void OLED_Init(void); void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size); void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size); void OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size); void OLED_ShowChinese(uint8_t x,uint8_t y,uint8_t no); void OLED_DrawBMP(uint8_t x0, uint8_t y0,uint8_t x1, uint8_t y1,uint8_t BMP[]); void OLED_Set_Pos(unsigned char x, unsigned char y); void OLED_Fill(unsigned char fill_Data); void OLED_CLS(void); void OLED_ON(void); void OLED_OFF(void); void OLED_Refresh_Gram(void); #endif ``` 上述代码中,我们定义了一些函数来实现OLED幕的初始化、字符、字符串、数字、图像等显示功能,具体实现可以参考对应函数的定义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值