功 能: 点亮由FD650Bic驱动的电子屏,并实现按一下按键就数字加1,本来想时间周期里可以自动加1的,结果好像有冲突,以后再说 芯片型号STC15F104W
先找650b的厂家看资料,就看到了几个说明书。并没有想象中的源码,然后网上到处百度,找的的资料是偏面向对象的写法,看不懂,自己瞎撸吧。
显示屏板子就直接用的3代中九接收机的前面板,这里我们多。
最终效果。
中九的那个面板图也找了份。
话不多说,直接上源码吧。
先上hd650.h文件
#ifndef __FP__FD650__H #define __FP__FD650__H /*** type redefine ***/ typedef unsigned char MS_U8; typedef unsigned short MS_U16; typedef unsigned long MS_U32; typedef int MS_S32; typedef int MS_BOOL; /****************************begin for FD650 define struct***************************** */ #define LEDMAPNUM 40 //key mapping typedef struct { MS_U8 keyMapData; MS_U8 keyMapLevel; } MS_KEYMAP; //led mapping typedef struct _led_bitmap { MS_U8 character; MS_U8 bitmap; } led_bitmap; //数码管显示常量 static const led_bitmap bcd_decode_tab[LEDMAPNUM] = { {'0', 0x3F}, {'1', 0x06}, {'2', 0x5B}, {'3', 0x4F}, {'4', 0x66}, {'5', 0x6D}, {'6', 0x7D}, {'7', 0x07}, {'8', 0x7F}, {'9', 0x6F}, {'a', 0x77}, {'A', 0x77}, {'b', 0x7C}, {'B', 0x7C}, {'c', 0x58}, {'C', 0x39}, {'d', 0x5E}, {'D', 0x5E}, {'e', 0x79}, {'E', 0x79}, {'f', 0x71}, {'F', 0x71}, {'H', 0x76}, {'h', 0x74}, {'o', 0x5C}, {'t', 0x78}, {'l', 0x30}, {'L', 0x38}, {'N', 0x37},{'n', 0x37}, {'p', 0x73},{'P', 0x73}, {'O', 0x3F}, {'u', 0x1C}, {'U', 0x3E},{'S', 0x6D}, {'s', 0x6D},{'-', 0x40}, {' ', 0x00} };//BCD decode /****************************end for FD650 define struct***************************** */ /* *************************************硬件相关*********************************************** */ #define HIGH 1 #define LOW 0 #define FRONTPNL_START_TIME_MS 3 //((1000 / 50) / LED_NUM) #define FRONTPNL_PERIOD_TIME_MS 150 #define FP_LED_MAX_NUM 4 #define FrontPnl_MSECS_TICK 100 //100 msecs/tick #define FrontPnl_TICKS_SEC 1 //10 ticks/sec /* ********************************************************************************************* */ // 设置系统参数命令 #define FD650_BIT_ENABLE 0x01 // 开启/关闭位 #define FD650_BIT_SLEEP 0x04 // 睡眠控制位 #define FD650_BIT_7SEG 0x08 // 7段控制位 #define FD650_BIT_INTENS1 0x10 // 1级亮度 #define FD650_BIT_INTENS2 0x20 // 2级亮度 #define FD650_BIT_INTENS3 0x30 // 3级亮度 #define FD650_BIT_INTENS4 0x40 // 4级亮度 #define FD650_BIT_INTENS5 0x50 // 5级亮度 #define FD650_BIT_INTENS6 0x60 // 6级亮度 #define FD650_BIT_INTENS7 0x70 // 7级亮度 #define FD650_BIT_INTENS8 0x00 // 8级亮度 #define FD650_SYSOFF 0x0400 // 关闭显示、关闭键盘 #define FD650_SYSON ( FD650_SYSOFF | FD650_BIT_ENABLE ) // 开启显示、键盘 #define FD650_SLEEPOFF FD650_SYSOFF // 关闭睡眠 #define FD650_SLEEPON ( FD650_SYSOFF | FD650_BIT_SLEEP ) // 开启睡眠 #define FD650_7SEG_ON ( FD650_SYSON | FD650_BIT_7SEG ) // 开启七段模式 #define FD650_8SEG_ON ( FD650_SYSON | 0x00 ) // 开启八段模式 #define FD650_SYSON_1 ( FD650_SYSON | FD650_BIT_INTENS1 ) // 开启显示、键盘、1级亮度 #define FD650_SYSON_4 ( FD650_SYSON | FD650_BIT_INTENS4 ) // 开启显示、键盘、4级亮度 #define FD650_SYSON_8 ( FD650_SYSON | FD650_BIT_INTENS8 ) // 开启显示、键盘、8级亮度 // 加载字数据命令 #define FD650_DIG0 0x1400 // 数码管位0显示,需另加8位数据 #define FD650_DIG1 0x1500 // 数码管位1显示,需另加8位数据 #define FD650_DIG2 0x1600 // 数码管位2显示,需另加8位数据 #define FD650_DIG3 0x1700 // 数码管位3显示,需另加8位数据 #define FD650_DOT 0x0080 // 数码管小数点显示 // 读取按键代码命令 #define FD650_GET_KEY 0x0700 // 获取按键,返回按键代码 #endif
然后上主程序文件
/******************************************************************** 日 期:2022/05/28 功 能: 点亮由FD650Bic驱动的电子屏,并实现按一下按键就数字加1,本来想时间周期里可以自动加1的,结果好像有冲突再说 芯片型号STC15F104W 编 写:劲松电脑通讯 www.jvbaopeng.com */ #include <stc15.h> #include <fd650.h> #define uchar unsigned char #define FOSC 18432000L //定义主时钟 #define TIMS (65536-FOSC/1000) //1T模式,18.432MHz晶振 #define uint unsigned int //宏定义无符号整型,16位的unsigned int允许的取值范围是0~65535。 sbit FD650_SCL = P3^4; //屏驱动口 sbit FD650_SDA = P3^5; sbit LED1=P3^3; //灯 sbit key1=P3^2; //定义单片机P3口的第2位 (即P3.2)//为输入 这里是7脚,就是按键 // 微秒级延时 void DELAY(uchar i){ while(i--); } //显示屏开始信号:保持 CLK 为“1”电平,DAT 从“1”跳“0”,认为是开始信号 static void MDrv_FD650_Start( void ){ FD650_SDA = 1; FD650_SCL = 1; DELAY(5); FD650_SDA = 0; DELAY(5); FD650_SCL = 0; } //显示屏结束信号:保持 CLK 为“1”电平,DAT 从“0”跳“1”,认为是结束信号 static void MDrv_FD650_Stop( void ){ FD650_SDA = 0; FD650_SCL = 1; DELAY(5); FD650_SDA = 1; } //写一个数据 static void MDrv_FD650_WrByte( MS_U8 dat ) { MS_U8 i; for( i = 0; i != 8; i++ ) //数据循环8次,每一位判断数据是1还是0 { if( dat & 0x80 ){ //如dat为10010001,& 0x80,与10000000,结果为10000000,大于0,条件为真 FD650_SDA = 1; //所以只跟最前面的一位有关,首位为1结果为1,符合则让DTA输出1 }else{ FD650_SDA = 0; } DELAY(5); FD650_SCL = 1; //一个时钟脉冲传输一位数据//CLK为高电平时数据必须保持不变 dat <<= 1; DELAY(5); FD650_SCL = 0; //直到CLK为低电平,一位数据传输结束 } FD650_SDA = 1; //写入,CLK从0跳到1,再从1跳到0 //写入650的内存 DELAY(5); FD650_SCL = 1; DELAY(5); FD650_SCL = 0; } //写命令 static void MDrv_FD650_Write( MS_U16 cmd ) //write cmd { MDrv_FD650_Start(); MDrv_FD650_WrByte(((MS_U8)(cmd>>7)&0x3E)|0x40); MDrv_FD650_WrByte((MS_U8)cmd); DELAY(2); MDrv_FD650_Stop(); return; } /*读取要显示内容的对应地址 */ static MS_U8 MDrv_Led_Get_Code(MS_U8 cTemp) { MS_U8 i, bitmap = 0x00; for(i = 0; i < LEDMAPNUM; i++){ if(bcd_decode_tab[i].character == cTemp){ bitmap = bcd_decode_tab[i].bitmap; break; } } return bitmap; } /* *更新数据(文本数据地址,是否带中间两点) *点亮数码管,注意,如果只有3位的话依次是点亮2,3,4管 */ static void MDrv_FrontPnl_Update(MS_U8 *u8str, MS_BOOL Colon_flag) { int i; MS_U8 LedBuffer[4]; if(!u8str) return; for(i = 0; i < FP_LED_MAX_NUM; i++){ // FP_LED_MAX_NUM 最大显示位数,在.h文件里定义了,这里是4 LedBuffer[i] = MDrv_Led_Get_Code(u8str[i]); } MDrv_FD650_Write(FD650_SYSON_4);// 开启显示和键盘,4段显示方式 //发显示数据 MDrv_FD650_Write( FD650_DIG0 | LedBuffer[0] ); //点亮第一个数码管 if(Colon_flag){ MDrv_FD650_Write( FD650_DIG1 | LedBuffer[1] | FD650_DOT ); //点亮小数点 } MDrv_FD650_Write( FD650_DIG1 | LedBuffer[1] ); MDrv_FD650_Write( FD650_DIG2 | LedBuffer[2]); //点亮第三个数码管 MDrv_FD650_Write( FD650_DIG3 | LedBuffer[3] | 0); //点亮第四个数码管 } //数字转文本(待转换数字) static MS_U8 *mystring(int Num){ static MS_U8 dat[4]; dat[0]=Num%10000/1000+'0'; dat[1]=Num%1000/100+'0'; dat[2]=Num%100/10+'0'; dat[3]=Num%10+'0'; return dat; } //延迟 void delayms(unsigned int ms) { unsigned int i; do{ i = FOSC/13000; while(--i); } while(--ms); } //======================================================================== // 函数: void tm0_isr (void) interrupt TIMER0_VECTOR // 描述: timer0中断函数. 相当于于时间周期,大约1毫秒一个周期 // 参数: none. // 返回: none. //======================================================================== void tm0_isr (void) interrupt 1 using 1 { static uint key_time = 0; //局部计时 static int mymun = 0; key_time++; if(key_time>=(1000*2)){ mymun++; LED1 = ~LED1; //MDrv_FrontPnl_Update(mystring(mymun),0); //本来想让他按2秒走的,不晓得哪里冲突了,以后再说 key_time =0 ; } } //======================================================================== // 函数: TIME_INIT // 描述: 定时器初始 // 参数: none. // 返回: none. //======================================================================== void TIME_INIT(){ AUXR |=0x80; //定时器0设置为1t模式 TMOD = 0x00; //设置定时器为模式0(16位自动装载) TL0 = TIMS; //计时器初始化开始计时 TH0 = TIMS >> 8 ; //向右移动8位搞什么 TR0 = 1; ET0 = 1; EA = 1; } ///============================================== // void main(void) { int mm = 0; TIME_INIT(); MDrv_FrontPnl_Update((MS_U8*)" OFF",0); //来个初始显示,可以直接显示字符串的,传入文本指针 while(1) { if(key1==0) { delayms(30); //这里判断按键时长 if(key1==0) { while(!key1); //这个必须加,表示判断按键是否松开,不然按键时灯闪烁 mm++; MDrv_FrontPnl_Update(mystring(mm),0); //显示按键加1 } } } }最后源码也传到开源平台了,希望大家用的开心